[PATCH 2/3] accel/habanalabs/gaudi2: drop support for never released firmware

2024-02-25 Thread Oded Gabbay
From: Ohad Sharabi 

Firmware files below 1.11 were never released to customers so no need
to support them externally.

Signed-off-by: Ohad Sharabi 
Reviewed-by: Oded Gabbay 
Signed-off-by: Oded Gabbay 
---
 drivers/accel/habanalabs/gaudi2/gaudi2.c | 47 ++--
 1 file changed, 3 insertions(+), 44 deletions(-)

diff --git a/drivers/accel/habanalabs/gaudi2/gaudi2.c 
b/drivers/accel/habanalabs/gaudi2/gaudi2.c
index 5be3432d29b3..c99edbf9f4ca 100644
--- a/drivers/accel/habanalabs/gaudi2/gaudi2.c
+++ b/drivers/accel/habanalabs/gaudi2/gaudi2.c
@@ -6314,26 +6314,6 @@ static void gaudi2_execute_hard_reset(struct hl_device 
*hdev)
WREG32(mmPSOC_RESET_CONF_SW_ALL_RST, 1);
 }
 
-static int gaudi2_get_soft_rst_done_indication(struct hl_device *hdev, u32 
poll_timeout_us)
-{
-   int i, rc = 0;
-   u32 reg_val;
-
-   for (i = 0 ; i < GAUDI2_RESET_POLL_CNT ; i++)
-   rc = hl_poll_timeout(
-   hdev,
-   mmCPU_RST_STATUS_TO_HOST,
-   reg_val,
-   reg_val == CPU_RST_STATUS_SOFT_RST_DONE,
-   1000,
-   poll_timeout_us);
-
-   if (rc)
-   dev_err(hdev->dev, "Timeout while waiting for FW to complete 
soft reset (0x%x)\n",
-   reg_val);
-   return rc;
-}
-
 /**
  * gaudi2_execute_soft_reset - execute soft reset by driver/FW
  *
@@ -6346,23 +6326,8 @@ static int gaudi2_get_soft_rst_done_indication(struct 
hl_device *hdev, u32 poll_
 static int gaudi2_execute_soft_reset(struct hl_device *hdev, bool 
driver_performs_reset,
u32 poll_timeout_us)
 {
-   int rc;
-
-   if (!driver_performs_reset) {
-   if (hl_is_fw_sw_ver_below(hdev, 1, 10)) {
-   /* set SP to indicate reset request sent to FW */
-   WREG32(mmCPU_RST_STATUS_TO_HOST, CPU_RST_STATUS_NA);
-
-   WREG32(mmGIC_HOST_SOFT_RST_IRQ_POLL_REG,
-   
gaudi2_irq_map_table[GAUDI2_EVENT_CPU_SOFT_RESET].cpu_id);
-
-   /* wait for f/w response */
-   rc = gaudi2_get_soft_rst_done_indication(hdev, 
poll_timeout_us);
-   } else {
-   rc = hl_fw_send_soft_reset(hdev);
-   }
-   return rc;
-   }
+   if (!driver_performs_reset)
+   return hl_fw_send_soft_reset(hdev);
 
/* Block access to engines, QMANs and SM during reset, these
 * RRs will be reconfigured after soft reset.
@@ -8165,13 +8130,7 @@ static void gaudi2_ack_module_razwi_event_handler(struct 
hl_device *hdev,
}
 
hbw_rtr_id = gaudi2_tpc_initiator_hbw_rtr_id[module_idx];
-
-   if (hl_is_fw_sw_ver_below(hdev, 1, 9) &&
-   !hdev->asic_prop.fw_security_enabled &&
-   ((module_idx == 0) || (module_idx == 1)))
-   lbw_rtr_id = DCORE0_RTR0;
-   else
-   lbw_rtr_id = 
gaudi2_tpc_initiator_lbw_rtr_id[module_idx];
+   lbw_rtr_id = gaudi2_tpc_initiator_lbw_rtr_id[module_idx];
break;
case RAZWI_MME:
sprintf(initiator_name, "MME_%u", module_idx);
-- 
2.34.1



[PATCH 3/3] accel/habanalabs/gaudi2: use single function to compare FW versions

2024-02-25 Thread Oded Gabbay
From: Ohad Sharabi 

Currently, the code contains 2 types of FW version comparison functions:
- hl_is_fw_sw_ver_[below/equal_or_greater]()
- gaudi2 specific function of the type
  gaudi2_is_fw_ver_[below/above]x_y_z()

Moreover, some functions use the inner FW version which should be only
stage during development but not version dependencies.

This commit aligns all APIs to a single function that just compares the
version and return an integers indicator (similar in some way to
strcmp()).

In addition, this generic function now considers also the sub-minor FW
version.

Signed-off-by: Ohad Sharabi 
Reviewed-by: Oded Gabbay 
Signed-off-by: Oded Gabbay 
---
 drivers/accel/habanalabs/common/firmware_if.c | 25 +++
 drivers/accel/habanalabs/common/habanalabs.h  | 20 +--
 drivers/accel/habanalabs/gaudi2/gaudi2.c  |  6 ++---
 3 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/drivers/accel/habanalabs/common/firmware_if.c 
b/drivers/accel/habanalabs/common/firmware_if.c
index 4bd02778a970..348418643709 100644
--- a/drivers/accel/habanalabs/common/firmware_if.c
+++ b/drivers/accel/habanalabs/common/firmware_if.c
@@ -40,6 +40,31 @@ static char *comms_sts_str_arr[COMMS_STS_INVLD_LAST] = {
[COMMS_STS_TIMEOUT_ERR] = __stringify(COMMS_STS_TIMEOUT_ERR),
 };
 
+/**
+ * hl_fw_version_cmp() - compares the FW version to a specific version
+ *
+ * @hdev: pointer to hl_device structure
+ * @major: major number of a reference version
+ * @minor: minor number of a reference version
+ * @subminor: sub-minor number of a reference version
+ *
+ * Return 1 if FW version greater than the reference version, -1 if it's
+ * smaller and 0 if versions are identical.
+ */
+int hl_fw_version_cmp(struct hl_device *hdev, u32 major, u32 minor, u32 
subminor)
+{
+   if (hdev->fw_sw_major_ver != major)
+   return (hdev->fw_sw_major_ver > major) ? 1 : -1;
+
+   if (hdev->fw_sw_minor_ver != minor)
+   return (hdev->fw_sw_minor_ver > minor) ? 1 : -1;
+
+   if (hdev->fw_sw_sub_minor_ver != subminor)
+   return (hdev->fw_sw_sub_minor_ver > subminor) ? 1 : -1;
+
+   return 0;
+}
+
 static char *extract_fw_ver_from_str(const char *fw_str)
 {
char *str, *fw_ver, *whitespace;
diff --git a/drivers/accel/habanalabs/common/habanalabs.h 
b/drivers/accel/habanalabs/common/habanalabs.h
index 48f0f3eea1ef..55495861f432 100644
--- a/drivers/accel/habanalabs/common/habanalabs.h
+++ b/drivers/accel/habanalabs/common/habanalabs.h
@@ -3596,25 +3596,6 @@ struct hl_ioctl_desc {
hl_ioctl_t *func;
 };
 
-static inline bool hl_is_fw_sw_ver_below(struct hl_device *hdev, u32 
fw_sw_major, u32 fw_sw_minor)
-{
-   if (hdev->fw_sw_major_ver < fw_sw_major)
-   return true;
-   if (hdev->fw_sw_major_ver > fw_sw_major)
-   return false;
-   if (hdev->fw_sw_minor_ver < fw_sw_minor)
-   return true;
-   return false;
-}
-
-static inline bool hl_is_fw_sw_ver_equal_or_greater(struct hl_device *hdev, 
u32 fw_sw_major,
-   u32 fw_sw_minor)
-{
-   return (hdev->fw_sw_major_ver > fw_sw_major ||
-   (hdev->fw_sw_major_ver == fw_sw_major &&
-   hdev->fw_sw_minor_ver >= fw_sw_minor));
-}
-
 /*
  * Kernel module functions that can be accessed by entire module
  */
@@ -3919,6 +3900,7 @@ void hl_mmu_dr_flush(struct hl_ctx *ctx);
 int hl_mmu_dr_init(struct hl_device *hdev);
 void hl_mmu_dr_fini(struct hl_device *hdev);
 
+int hl_fw_version_cmp(struct hl_device *hdev, u32 major, u32 minor, u32 
subminor);
 int hl_fw_load_fw_to_device(struct hl_device *hdev, const char *fw_name,
void __iomem *dst, u32 src_offset, u32 size);
 int hl_fw_send_pci_access_msg(struct hl_device *hdev, u32 opcode, u64 value);
diff --git a/drivers/accel/habanalabs/gaudi2/gaudi2.c 
b/drivers/accel/habanalabs/gaudi2/gaudi2.c
index c99edbf9f4ca..ba1518f2bf5c 100644
--- a/drivers/accel/habanalabs/gaudi2/gaudi2.c
+++ b/drivers/accel/habanalabs/gaudi2/gaudi2.c
@@ -3783,7 +3783,7 @@ static int gaudi2_sw_init(struct hl_device *hdev)
prop->supports_compute_reset = true;
 
/* Event queue sanity check added in FW version 1.11 */
-   if (hl_is_fw_sw_ver_below(hdev, 1, 11))
+   if (hl_fw_version_cmp(hdev, 1, 11, 0) < 0)
hdev->event_queue.check_eqe_index = false;
else
hdev->event_queue.check_eqe_index = true;
@@ -7879,7 +7879,7 @@ static bool gaudi2_handle_ecc_event(struct hl_device 
*hdev, u16 event_type,
bool has_block_id = false;
u16 block_id;
 
-   if (!hl_is_fw_sw_ver_below(hdev, 1, 12))
+   if (hl_fw_version_cmp(hdev, 1, 12, 0) >= 0)
has_block_id = true;
 
ecc_address = le64_to_cpu(ecc_data->ecc_address);
@@ -10029,7 +10029,7 @@ static void gaudi2_handle_eqe(struct hl_device *hdev, 
struct hl_eq_entr

[PATCH 1/3] accel/habanalabs/gaudi2: initialize field in correct function

2024-02-25 Thread Oded Gabbay
From: Ohad Sharabi 

supports_advanced_cpucp_rc is an asic property which should be
initialized in the gaudi2_set_fixed_properties(), where all of the
asic properties are initialized.

Signed-off-by: Ohad Sharabi 
Reviewed-by: Oded Gabbay 
Signed-off-by: Oded Gabbay 
---
 drivers/accel/habanalabs/gaudi2/gaudi2.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/accel/habanalabs/gaudi2/gaudi2.c 
b/drivers/accel/habanalabs/gaudi2/gaudi2.c
index fa1c4feb9f89..5be3432d29b3 100644
--- a/drivers/accel/habanalabs/gaudi2/gaudi2.c
+++ b/drivers/accel/habanalabs/gaudi2/gaudi2.c
@@ -2601,6 +2601,8 @@ static int gaudi2_set_fixed_properties(struct hl_device 
*hdev)
 
prop->hbw_flush_reg = mmPCIE_WRAP_SPECIAL_GLBL_SPARE_0;
 
+   prop->supports_advanced_cpucp_rc = true;
+
return 0;
 
 free_qprops:
@@ -3308,8 +3310,6 @@ static int gaudi2_late_init(struct hl_device *hdev)
struct gaudi2_device *gaudi2 = hdev->asic_specific;
int rc;
 
-   hdev->asic_prop.supports_advanced_cpucp_rc = true;
-
rc = hl_fw_send_pci_access_msg(hdev, CPUCP_PACKET_ENABLE_PCI_ACCESS,
gaudi2->virt_msix_db_dma_addr);
if (rc) {
-- 
2.34.1



RE: [PATCH v2] drm/lcdif: Do not disable clocks on already suspended hardware

2024-02-25 Thread Ying Liu
On Monday, February 26, 2024 3:28 PM, Marek Vasut  wrote:
> 0, and would trigger a warning from clocks core about this condition.

s/clocks/clock/

Liu Ying


Re: [PATCH v2 1/3] dt-bindings: display: msm: dp-controller: document X1E80100 compatible

2024-02-25 Thread Krzysztof Kozlowski
On 24/02/2024 23:34, Dmitry Baryshkov wrote:
> On Thu, 22 Feb 2024 at 17:55, Abel Vesa  wrote:
>>
>> Add the X1E80100 to the list of compatibles and document the is-edp
>> flag. The controllers are expected to operate in DP mode by default,
>> and this flag can be used to select eDP mode.
>>
>> Signed-off-by: Abel Vesa 
> 
> Rob, Krzysztof, Connor, gracious ping for the review. It would be
> really nice to merge this patchset during the next cycle. It also
> unbreaks several other patches.

That's not a netdev... or do you have the same subsystem profile
expecting reviews *from everyone* within two days?

Best regards,
Krzysztof



[PATCH] nouveau: report byte usage in VRAM usage.

2024-02-25 Thread Dave Airlie
From: Dave Airlie 

Turns out usage is always in bytes not shifted.

Fixes: 72fa02fdf833 ("nouveau: add an ioctl to report vram usage")
Signed-off-by: Dave Airlie 
---
 drivers/gpu/drm/nouveau/nouveau_abi16.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c 
b/drivers/gpu/drm/nouveau/nouveau_abi16.c
index cd14f993bdd1..80f74ee0fc78 100644
--- a/drivers/gpu/drm/nouveau/nouveau_abi16.c
+++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c
@@ -269,7 +269,7 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS)
break;
case NOUVEAU_GETPARAM_VRAM_USED: {
struct ttm_resource_manager *vram_mgr = 
ttm_manager_type(&drm->ttm.bdev, TTM_PL_VRAM);
-   getparam->value = (u64)ttm_resource_manager_usage(vram_mgr) << 
PAGE_SHIFT;
+   getparam->value = (u64)ttm_resource_manager_usage(vram_mgr);
break;
}
default:
-- 
2.43.2



ttm usage inconsistency

2024-02-25 Thread Dave Airlie
This is probably something I knew about and forgot, but I'll ask if
anyone has considered cleaning it up (or maybe I should fix nouveau).

nouveau sets up the resource manager using vram_size >> PAGE_SHIFT as
the bounds, but the bo sizes are in bytes, hence usage ends up being
accounted in bytes, so we have usage > size which looks wierd and also
caused me to screw up adding an ioctl for userspace.

Should I just make nouveau use vram_size instead?

Dave.


[PATCH v2] drm/lcdif: Do not disable clocks on already suspended hardware

2024-02-25 Thread Marek Vasut
In case the LCDIF is enabled in DT but unused, the clocks used by the
LCDIF are not enabled. Those clocks may even have a use count of 0 in
case there are no other users of those clocks. This can happen e.g. in
case the LCDIF drives HDMI bridge which has no panel plugged into the
HDMI connector.

Do not attempt to disable clocks in the suspend callback and re-enable
clocks in the resume callback unless the LCDIF is enabled and was in
use before the system entered suspend, otherwise the driver might end
up trying to disable clocks which are already disabled with use count
0, and would trigger a warning from clocks core about this condition.

Note that the lcdif_rpm_suspend() and lcdif_rpm_resume() functions
internally perform the clocks disable and enable operations and act
as runtime PM hooks too.

Reviewed-by: Liu Ying 
Fixes: 9db35bb349a0 ("drm: lcdif: Add support for i.MX8MP LCDIF variant")
Signed-off-by: Marek Vasut 
---
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Fabio Estevam 
Cc: Liu Ying 
Cc: Maarten Lankhorst 
Cc: Maxime Ripard 
Cc: NXP Linux Team 
Cc: Pengutronix Kernel Team 
Cc: Sascha Hauer 
Cc: Shawn Guo 
Cc: Stefan Agner 
Cc: Thomas Zimmermann 
Cc: dri-devel@lists.freedesktop.org
Cc: linux-arm-ker...@lists.infradead.org
---
V2: - s@clock@clocks@g in commit message
- Add RB from Liu
---
 drivers/gpu/drm/mxsfb/lcdif_drv.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mxsfb/lcdif_drv.c 
b/drivers/gpu/drm/mxsfb/lcdif_drv.c
index 18de2f17e2491..6494e82707569 100644
--- a/drivers/gpu/drm/mxsfb/lcdif_drv.c
+++ b/drivers/gpu/drm/mxsfb/lcdif_drv.c
@@ -340,6 +340,9 @@ static int __maybe_unused lcdif_suspend(struct device *dev)
if (ret)
return ret;
 
+   if (pm_runtime_suspended(dev))
+   return 0;
+
return lcdif_rpm_suspend(dev);
 }
 
@@ -347,7 +350,8 @@ static int __maybe_unused lcdif_resume(struct device *dev)
 {
struct drm_device *drm = dev_get_drvdata(dev);
 
-   lcdif_rpm_resume(dev);
+   if (!pm_runtime_suspended(dev))
+   lcdif_rpm_resume(dev);
 
return drm_mode_config_helper_resume(drm);
 }
-- 
2.43.0



Re: [PATCH v2 0/6] Pinephone video out fixes (flipping between two frames)

2024-02-25 Thread Frank Oltmanns
Hi Jernej,
hi Maxime,
hi Ondřej,

On 2024-02-19 at 10:41:19 +0100, Frank Oltmanns  wrote:
> Hi Ondřej,
>
> On 2024-02-11 at 20:25:29 +0100, Ondřej Jirman  wrote:
>> Hi Frank,
>>
>> On Sun, Feb 11, 2024 at 04:09:16PM +0100, Frank Oltmanns wrote:
>>> Hi Ondřej,
>>>
>>> On 2024-02-05 at 17:02:00 +0100, Ondřej Jirman  wrote:
>>> > On Mon, Feb 05, 2024 at 04:54:07PM +0100, Ondřej Jirman wrote:
>>> >> On Mon, Feb 05, 2024 at 04:22:23PM +0100, Frank Oltmanns wrote:
>>> >>
>>> >> [...]
>>> >>
>>> >> Also sunxi-ng clk driver does apply NM factors at once to PLL_GPU clock,
>>> >> which can cause sudden frequency increase beyond intended output 
>>> >> frequency,
>>> >> because division is applied immediately while multiplication is reflected
>>> >> slowly.
>>> >>
>>> >> Eg. if you're changing divider from 7 to 1, you can get a sudden 7x 
>>> >> output
>>> >> frequency spike, before PLL VCO manages to lower the frequency through N 
>>> >> clk
>>> >> divider feedback loop and lock on again. This can mess up whatever's 
>>> >> connected
>>> >> to the output quite badly.
>>> >>
>>> >> You'd have to put logging on kernel writes to PLL_GPU register to see 
>>> >> what
>>> >> is written in there and if divider is lowered significantly on some GPU
>>> >> devfreq frequency transitions.
>>>
>>> By looking at the clocks in clk_summary in debugfs, the rate of PLL-GPU
>>> always matches the rate of the GPU (at least at 120, 312, and 432 MHz).
>>> This is further underlined by the fact, that none of the rates can be
>>> achieved by integer dividing one of the other rates. sunxi-ng would
>>> only favor a different rate for pll-gpu than the one that is requested
>>> for the gpu, if pll-gpu is already running at a rate such that there
>>> exists an M ∈ {1, 2, 3, 4, 5, 6, 7, 8}, where
>>>   rate of pll-gpu / M = requested gpu rate
>>> or if the requested rate could not be reached directly by pll-gpu. Both
>>> is not the case for the rates in question (120, 192, 312, and 432 MHz).
>>>
>>> This means that the following divisor/multipliers are used by sunxi-ng's
>>> ccu_nm:
>>> N =  5, M = 1 for 120 MHz (min value without PATCH 6)
>>> N =  8, M = 1 for 192 MHz (min value after applying PATCH 6)
>>> N = 13, M = 1 for 312 MHz
>>> N = 18, M = 1 for 432 MHz
>>>
>>> So, with or without PATCH 6, the divider stays constant and it's only
>>> the multiplier that changes. This means, there should be no unexpected
>>> frequency spikes, right?
>>
>> Maybe. Thanks for giving it a try. There may still be other kinds of glitches
>> even if the divisor stays the same. It all depends how the register update is
>> implemented in the PLL block. It's hard to say. I guess, unless Allwinner
>> guarantees glitchless output from a given PLL when changing its parameters,
>> you can't rely on the output being clean during changes.
>>
>>> >> It's also unclear what happens when FRAC_CLK_OUT or PLL_MODE_SEL changes.
>>>
>>> Those are not changed once the clock is initialized. The bug however
>>> occurs hours or days after booting. IMO, this makes it unlikely that this
>>> could be the culprit.
>>>
>>> >> Maybe not much because M is supposed to be set to 1, but you still need 
>>> >> to
>>> >> care when enabling fractional mode, and setting M to 1 because that's 
>>> >> exactly
>>> >> the bad scenario if M was previously higher than 1.
>>> >>
>>> >> It's tricky.
>>> >>
>>> >> Having GPU module clock gated during PLL config changes may help! You can
>>> >> do that without locking yourself out, unlike with the CPU PLL.
>>> >>
>>> >> There's a gate enable bit for it at GPU_CLK_REG.SCLK_GATING. (page 122)
>>>
>>> The GPU should already be properly gated:
>>> https://elixir.bootlin.com/linux/v6.7.4/source/drivers/clk/sunxi-ng/ccu-sun50i-a64.c#L599
>>
>> How so? That's just clock declaration. How does it guarantee the clock to the
>> module is gated during parent PLL configuration changes?
>>
>
> You're of course right.
>
> I now tried using a similar approach like the one for changes for on
> PLL-CPU. It's using a notifier to connect the CPU to the 24 MHz
> oscillator and, after PLL-CPU is at its new rate, connecting it back to
> PLL-CPU.
>
> For the GPU my approach was to disable the GPU prior to changing
> PLL-GPU's rate and then re-enabling it, once the rate change is
> complete. I think, that's what you were proposing, right?
>
> Unfortunately, this results in a frozen phone even more quickly.
>
> Below is my code. Again, it doesn't solve the problem, but maybe
> somebody can spot what I'm doing wrong.

It seems to me that all options for changing the GPU's rate in a stable
manner have been exhausted. There seems to be no common interpretation
what the phrase "Clock output of PLL_GPU can be used for GPU;and dynamic
frequency scaling is not supported" in the Allwinner A64 manual (chapter
3.3.3) means.

The BSP uses a fixed rate of 432 MHz. Unless one of you has a clever
idea, I suggest to remove the OPPs from the device tree and set the GPU
to 432 MHz.

What are your 

Re: [PATCH RFC 01/12] kbuild: create destination directory for _shipped handling

2024-02-25 Thread Masahiro Yamada
On Mon, Feb 26, 2024 at 11:11 AM Dmitry Baryshkov
 wrote:
>
> The driver might decide to put the _shipped files to the subdir.



Please stop this sentence.

This sounds like we are not learning.

https://lore.kernel.org/all/CAHk-=wgSEi_ZrHdqr=20xv+d6dr5G895CbOAi8ok+7-CQUN=f...@mail.gmail.com/




> In such
> case the cmd_copy might fail because the destination directory is not
> present. Call mkdir -p to make sure that the destination directory is
> present.


There is no justification for this.

If you need a single generated directory
(drivers/gpu/drm/msm/registers/, divers/gpu/drm/msm/generated/ or whatever)
that should be super simple.

Why does scripts/Makefile.lib need the modification?









>
> Signed-off-by: Dmitry Baryshkov 
> ---
>  scripts/Makefile.lib | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
> index cd5b181060f1..94373eeac420 100644
> --- a/scripts/Makefile.lib
> +++ b/scripts/Makefile.lib
> @@ -297,7 +297,7 @@ endef
>  # the copy would be read-only as well, leading to an error when executing the
>  # rule next time. Use 'cat' instead in order to generate a writable file.
>  quiet_cmd_copy = COPY$@
> -  cmd_copy = cat $< > $@
> +  cmd_copy = mkdir -p $(shell dirname $@) && cat $< > $@
>
>  $(obj)/%: $(src)/%_shipped
> $(call cmd,copy)
>
> --
> 2.39.2
>


--
Best Regards

Masahiro Yamada


Re: [PATCH RFC 00/12] drm/msm: add support for regenerating shipped xml.h headers

2024-02-25 Thread Masahiro Yamada
 don't output full file paths
>   drm/msm/headergen: generate _shipped files
>   drm/msm: import XML registers database
>   drm/msm: tie regeneration of shipped headers
>   drm/msm: sync shipped headers database
>
>  drivers/gpu/drm/msm/Makefile   |   80 +-
>  drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.h   |   11 +
>  drivers/gpu/drm/msm/disp/mdp_common.xml.h  |  111 --
>  drivers/gpu/drm/msm/dsi/mmss_cc.xml.h  |  131 --
>  drivers/gpu/drm/msm/dsi/sfpb.xml.h |   70 -
>  drivers/gpu/drm/msm/hdmi/qfprom.xml.h  |   61 -
>  drivers/gpu/drm/msm/headergen2/colors.c|   61 +
>  drivers/gpu/drm/msm/headergen2/colors.h|   49 +
>  drivers/gpu/drm/msm/headergen2/headergen2.c|  514 
>  drivers/gpu/drm/msm/headergen2/path.c  |   64 +
>  drivers/gpu/drm/msm/headergen2/rnn.c   | 1363 
> 
>  drivers/gpu/drm/msm/headergen2/rnn.h   |  243 
>  drivers/gpu/drm/msm/headergen2/rnndec.c|  550 
>  drivers/gpu/drm/msm/headergen2/rnndec.h|   59 +
>  drivers/gpu/drm/msm/headergen2/util.h  |  113 ++
>  drivers/gpu/drm/msm/headergen2/util/u_debug.h  |   12 +
>  drivers/gpu/drm/msm/registers/.gitignore   |5 +
>  .../{dsi/dsi.xml.h => registers/dsi.xml.h_shipped} |   38 +-
>  .../dsi_phy_10nm.xml.h_shipped}|   37 +-
>  .../dsi_phy_14nm.xml.h_shipped}|   37 +-
>  .../dsi_phy_20nm.xml.h_shipped}|   37 +-
>  .../dsi_phy_28nm.xml.h_shipped}|   37 +-
>  .../dsi_phy_28nm_8960.xml.h_shipped}   |   37 +-
>  .../dsi_phy_7nm.xml.h_shipped} |   37 +-
>  .../hdmi.xml.h => registers/hdmi.xml.h_shipped}|  111 +-
>  .../mdp4.xml.h => registers/mdp4.xml.h_shipped}|   37 +-
>  .../mdp5.xml.h => registers/mdp5.xml.h_shipped}|   39 +-
>  .../gpu/drm/msm/registers/mdp_common.xml.h_shipped |  114 ++
>  drivers/gpu/drm/msm/registers/sfpb.xml.h_shipped   |   67 +
>  drivers/gpu/drm/msm/registers/xml/dsi.xml  |  390 ++
>  drivers/gpu/drm/msm/registers/xml/dsi_phy_10nm.xml |  102 ++
>  drivers/gpu/drm/msm/registers/xml/dsi_phy_14nm.xml |  135 ++
>  drivers/gpu/drm/msm/registers/xml/dsi_phy_20nm.xml |  100 ++
>  drivers/gpu/drm/msm/registers/xml/dsi_phy_28nm.xml |  180 +++
>  .../drm/msm/registers/xml/dsi_phy_28nm_8960.xml|  134 ++
>  drivers/gpu/drm/msm/registers/xml/dsi_phy_7nm.xml  |  230 
>  drivers/gpu/drm/msm/registers/xml/edp.xml  |  239 
>  .../drm/msm/registers/xml/freedreno_copyright.xml  |   40 +
>  drivers/gpu/drm/msm/registers/xml/hdmi.xml | 1015 +++
>  drivers/gpu/drm/msm/registers/xml/mdp4.xml |  480 +++
>  drivers/gpu/drm/msm/registers/xml/mdp5.xml |  806 
>  drivers/gpu/drm/msm/registers/xml/mdp_common.xml   |   89 ++
>  drivers/gpu/drm/msm/registers/xml/mmss_cc.xml  |   48 +
>  drivers/gpu/drm/msm/registers/xml/msm.xml  |   32 +
>  drivers/gpu/drm/msm/registers/xml/rules-ng.xsd |  457 +++
>  drivers/gpu/drm/msm/registers/xml/sfpb.xml |   17 +
>  scripts/Makefile.lib   |2 +-
>  47 files changed, 8034 insertions(+), 587 deletions(-)
> ---
> base-commit: ffa0c87f172bf7a0132aa960db412f8d63b2f533
> change-id: 20240225-fd-xml-shipped-ba9a321cdedf
>
> Best regards,
> --
> Dmitry Baryshkov 
>


-- 
Best Regards
Masahiro Yamada


RE: [PATCH] drm/lcdif: Do not disable clock on already suspended hardware

2024-02-25 Thread Ying Liu
On Friday, January 19, 2024 2:39 AM, Marek Vasut  wrote:
> In case the LCDIF is enabled in DT but unused, the clock used by the

Nit: s/clock/clocks/

> LCDIF are not enabled. Those clock may even have a use count of 0 in

Ditto.

> case there are no other users of those clock. This can happen e.g. in

Ditto.

> case the LCDIF drives HDMI bridge which has no panel plugged into the
> HDMI connector.
> 
> Do not attempt to disable clock in the suspend callback and re-enable
> clock in the resume callback unless the LCDIF is enabled and was in
> use before the system entered suspend, otherwise the driver might end
> up trying to disable clock which are already disabled with use count

Ditto.

With the nitpicks addressed:
Reviewed-by: Liu Ying 

Regards,
Liu Ying

> 0, and would trigger a warning from clock core about this condition.
> 
> Note that the lcdif_rpm_suspend() and lcdif_rpm_resume() functions
> internally perform the clock disable and enable operations and act
> as runtime PM hooks too.
> 
> Fixes: 9db35bb349a0 ("drm: lcdif: Add support for i.MX8MP LCDIF variant")
> Signed-off-by: Marek Vasut 
> ---
> Cc: Daniel Vetter 
> Cc: David Airlie 
> Cc: Fabio Estevam 
> Cc: Liu Ying 
> Cc: Maarten Lankhorst 
> Cc: Maxime Ripard 
> Cc: NXP Linux Team 
> Cc: Pengutronix Kernel Team 
> Cc: Sascha Hauer 
> Cc: Shawn Guo 
> Cc: Stefan Agner 
> Cc: Thomas Zimmermann 
> Cc: dri-devel@lists.freedesktop.org
> Cc: linux-arm-ker...@lists.infradead.org
> ---
>  drivers/gpu/drm/mxsfb/lcdif_drv.c | 6 +-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mxsfb/lcdif_drv.c
> b/drivers/gpu/drm/mxsfb/lcdif_drv.c
> index ea10bf81582e9..0f895b8a99d62 100644
> --- a/drivers/gpu/drm/mxsfb/lcdif_drv.c
> +++ b/drivers/gpu/drm/mxsfb/lcdif_drv.c
> @@ -343,6 +343,9 @@ static int __maybe_unused lcdif_suspend(struct
> device *dev)
>   if (ret)
>   return ret;
> 
> + if (pm_runtime_suspended(dev))
> + return 0;
> +
>   return lcdif_rpm_suspend(dev);
>  }
> 
> @@ -350,7 +353,8 @@ static int __maybe_unused lcdif_resume(struct
> device *dev)
>  {
>   struct drm_device *drm = dev_get_drvdata(dev);
> 
> - lcdif_rpm_resume(dev);
> + if (!pm_runtime_suspended(dev))
> + lcdif_rpm_resume(dev);
> 
>   return drm_mode_config_helper_resume(drm);
>  }
> --
> 2.43.0



Re: [PATCH v2 5/6] drm/panel: st7703: Drive XBD599 panel at higher clock rate

2024-02-25 Thread Icenowy Zheng
在 2024-02-25星期日的 17:46 +0100,Frank Oltmanns写道:
> Hi Maxime,
> 
> On 2024-02-22 at 11:29:51 +0100, Maxime Ripard 
> wrote:
> > [[PGP Signed Part:Undecided]]
> > On Sun, Feb 11, 2024 at 04:42:43PM +0100, Frank Oltmanns wrote:
> > > 
> > > On 2024-02-08 at 20:05:08 +0100, Maxime Ripard
> > >  wrote:
> > > > [[PGP Signed Part:Undecided]]
> > > > Hi Frank,
> > > > 
> > > > On Mon, Feb 05, 2024 at 04:22:28PM +0100, Frank Oltmanns wrote:
> > > > > This panel is used in the pinephone that runs on a Allwinner
> > > > > A64 SOC.
> > > > > The SOC requires pll-mipi to run at more than 500 MHz.
> > > > > 
> > > > > This is the relevant clock tree:
> > > > >  pll-mipi
> > > > >     tcon0
> > > > >    tcon-data-clock
> > > > > 
> > > > > tcon-data-clock has to run at 1/4 the DSI per-lane bit rate.
> > > > > The XBD599
> > > > > has 24 bpp and 4 lanes. Therefore, the resulting requested
> > > > > tcon-data-clock rate is:
> > > > >     crtc_clock * 1000 * (24 / 4) / 4
> > > > > 
> > > > > tcon-data-clock runs at tcon0 / 4 (fixed divisor), so it
> > > > > requests a
> > > > > parent rate of
> > > > >     4 * (crtc_clock * 1000 * (24 / 4) / 4)
> > > > > 
> > > > > Since tcon0 is a ccu_mux, the rate of tcon0 equals the rate
> > > > > of pll-mipi.
> > > > > 
> > > > > pll-mipi's constraint to run at 500MHz or higher forces us to
> > > > > have a
> > > > > crtc_clock >= 8 kHz if we want a 60 Hz vertical refresh
> > > > > rate.
> > > > > 
> > > > > Change [hv]sync_(start|end) so that we reach a clock rate of
> > > > > 83502 kHz
> > > > > so that it is high enough to align with pll-pipi limits.
> > > > > 
> > > > > Signed-off-by: Frank Oltmanns 
> > > > 
> > > > That commit log is great, but it's kind of off-topic. It's a
> > > > panel
> > > > driver, it can be used on any MIPI-DSI controller, the only
> > > > relevant
> > > > information there should be the panel timings required in the
> > > > datasheet.
> > > > 
> > > > The PLL setup is something for the MIPI-DSI driver to adjust,
> > > > not for
> > > > the panel to care for.
> > > > 
> > > 
> > > I absolutely agree. It even was the reason for my submission of a
> > > sunxi-ng patch series last year that was accepted, to make pll-
> > > mipi more
> > > flexible. :)
> > > 
> > > The only remaining option I currently see for adjusting the
> > > sunxi-ng
> > > driver to further accomodate the panel, is trying to use a higher
> > > divisor than 4 for calculating tcon-data-clock from tcon0. I
> > > remember
> > > reading a discussion about this, but as far as I remember that
> > > proposal
> > > was rejected (by you, IIRC).
> > > 
> > > While I appreciate other suggestion as well, I'll look into
> > > options for
> > > using a different divisor than 4.
> > 
> > Like I said, I'm not against the patch at all, it looks great to me
> > on
> > principle. I just think you should completely rephrase the commit
> > log
> > using the datasheet as the only reliable source of the display
> > timings.
> > Whether sun4i can work around the panel requirements is something
> > completely orthogonal to the discussion, and thus the commit log.
> > 
> 
> I was trying to follow the guidelines [1] for describing the reason
> behind my changes to the panel. My original commit message was a lot
> shorter, which, understandably, resulted in follow up questions [2].
> With the current commit log, I'm trying to address those questions.
> According to the device tree, the panel is only used in the
> pinephone.
> The only reason for the change is that the SoC used by the only user
> of
> this panel can not provide the rate the panel requests with the
> current
> values. I think this information is relevant.
> 
> Unfortunately, as described in [2], I cannot back these values with
> any
> datasheets because I couldn't find any. I could only find hints that
> they are not publicly available. Icenowy (added to CC) submitted the
> original values.

Sorry but this kind of things are just magic from the vendor that I
could hardly explain...

> 
> Best regards,
>   Frank
> 
> [1]:
> https://www.kernel.org/doc/html/v6.7/process/submitting-patches.html#describe-your-changes
> [2]: https://lore.kernel.org/lkml/87wmsvo0fh@oltmanns.dev/
> 
> > 
> > Maxime
> > 
> > [[End of PGP Signed Part]]
> 



Re: [PATCH v4 2/4] drm/bridge: add lvds controller support for sam9x7

2024-02-25 Thread Dharma.B

Hi Folks,

Your feedback is valuable, and I'm eager to address any concerns or make
improvements as needed. Thank you for your consideration.

On 09/02/24 8:37 pm, Dharma B - I70843 wrote:
> Add a new LVDS controller driver for sam9x7 which does the following:
> - Prepares and enables the LVDS Peripheral clock
> - Defines its connector type as DRM_MODE_CONNECTOR_LVDS and adds itself
> to the global bridge list.
> - Identifies its output endpoint as panel and adds it to the encoder
> display pipeline
> - Enables the LVDS serializer
> 
> Signed-off-by: Manikandan Muralidharan 
> Signed-off-by: Dharma Balasubiramani 
> ---
> Changelog
> v3 -> v4
> - No changes.
> v2 ->v3
> - Correct Typo error "serializer".
> - Consolidate get() and prepare() functions and use devm_clk_get_prepared().
> - Remove unused variable 'ret' in probe().
> - Use devm_pm_runtime_enable() and drop the mchp_lvds_remove().
> v1 -> v2
> - Drop 'res' variable and combine two lines into one.
> - Handle deferred probe properly, use dev_err_probe().
> - Don't print anything on deferred probe. Dropped print.
> - Remove the MODULE_ALIAS and add MODULE_DEVICE_TABLE().
> - symbol 'mchp_lvds_driver' was not declared. It should be static.
> ---
>   drivers/gpu/drm/bridge/Kconfig  |   7 +
>   drivers/gpu/drm/bridge/Makefile |   1 +
>   drivers/gpu/drm/bridge/microchip-lvds.c | 228 
>   3 files changed, 236 insertions(+)
>   create mode 100644 drivers/gpu/drm/bridge/microchip-lvds.c
> 
> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> index 3e6a4e2044c0..74ca0edb4e0d 100644
> --- a/drivers/gpu/drm/bridge/Kconfig
> +++ b/drivers/gpu/drm/bridge/Kconfig
> @@ -173,6 +173,13 @@ config DRM_MEGACHIPS_STDP_GE_B850V3_FW
> to DP++. This is used with the i.MX6 imx-ldb
> driver. You are likely to say N here.
>   
> +config DRM_MICROCHIP_LVDS_SERIALIZER
> + tristate "Microchip LVDS serializer support"
> + depends on OF
> + depends on DRM_ATMEL_HLCDC
> + help
> +   Support for Microchip's LVDS serializer.
> +
>   config DRM_NWL_MIPI_DSI
>   tristate "Northwest Logic MIPI DSI Host controller"
>   depends on DRM
> diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
> index 2b892b7ed59e..e3804e93d324 100644
> --- a/drivers/gpu/drm/bridge/Makefile
> +++ b/drivers/gpu/drm/bridge/Makefile
> @@ -11,6 +11,7 @@ obj-$(CONFIG_DRM_LONTIUM_LT9611) += lontium-lt9611.o
>   obj-$(CONFIG_DRM_LONTIUM_LT9611UXC) += lontium-lt9611uxc.o
>   obj-$(CONFIG_DRM_LVDS_CODEC) += lvds-codec.o
>   obj-$(CONFIG_DRM_MEGACHIPS_STDP_GE_B850V3_FW) += 
> megachips-stdp-ge-b850v3-fw.o
> +obj-$(CONFIG_DRM_MICROCHIP_LVDS_SERIALIZER) += microchip-lvds.o
>   obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
>   obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
>   obj-$(CONFIG_DRM_PARADE_PS8640) += parade-ps8640.o
> diff --git a/drivers/gpu/drm/bridge/microchip-lvds.c 
> b/drivers/gpu/drm/bridge/microchip-lvds.c
> new file mode 100644
> index ..d3fd9d722e36
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/microchip-lvds.c
> @@ -0,0 +1,228 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2023 Microchip Technology Inc. and its subsidiaries
> + *
> + * Author: Manikandan Muralidharan 
> + * Author: Dharma Balasubiramani 
> + *
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define LVDS_POLL_TIMEOUT_MS 1000
> +
> +/* LVDSC register offsets */
> +#define LVDSC_CR 0x00
> +#define LVDSC_CFGR   0x04
> +#define LVDSC_SR 0x0C
> +#define LVDSC_WPMR   0xE4
> +
> +/* Bitfields in LVDSC_CR (Control Register) */
> +#define LVDSC_CR_SER_EN  BIT(0)
> +
> +/* Bitfields in LVDSC_CFGR (Configuration Register) */
> +#define LVDSC_CFGR_PIXSIZE_24BITS0
> +#define LVDSC_CFGR_DEN_POL_HIGH  0
> +#define LVDSC_CFGR_DC_UNBALANCED 0
> +#define LVDSC_CFGR_MAPPING_JEIDA BIT(6)
> +
> +/*Bitfields in LVDSC_SR */
> +#define LVDSC_SR_CS  BIT(0)
> +
> +/* Bitfields in LVDSC_WPMR (Write Protection Mode Register) */
> +#define LVDSC_WPMR_WPKEY_MASKGENMASK(31, 8)
> +#define LVDSC_WPMR_WPKEY_PSSWD   0x4C5644
> +
> +struct mchp_lvds {
> + struct device *dev;
> + void __iomem *regs;
> + struct clk *pclk;
> + int format; /* vesa or jeida format */
> + struct drm_panel *panel;
> + struct drm_bridge bridge;
> + struct drm_bridge *panel_bridge;
> +};
> +
> +static inline struct mchp_lvds *bridge_to_lvds(struct drm_bridge *bridge)
> +{
> + return container_of(bridge, struct mchp_lvds, bridge);
> +}
> +
> +static inline u32 lvds_readl(struct mchp_lvds *lvds, u32 offset)
> +{
> + return readl_relaxed(lvds->regs + offset);
> +}
> +
> +static inline void lvds_writel(struc

[PATCH] drm/qxl: remove redundant code

2024-02-25 Thread Jiapeng Chong
Variable num_relocs is not effectively used, so delete it. Having two
labels seems somewhat redundant; the 'out_free_release' can be removed,
leaving 'out_free_bos'.

drivers/gpu/drm/qxl/qxl_ioctl.c:148:14: warning: variable 'num_relocs' set but 
not used.

Reported-by: Abaci Robot 
Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=8316
Signed-off-by: Jiapeng Chong 
---
 drivers/gpu/drm/qxl/qxl_ioctl.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c
index dd0f834d881c..c1dd5709d37a 100644
--- a/drivers/gpu/drm/qxl/qxl_ioctl.c
+++ b/drivers/gpu/drm/qxl/qxl_ioctl.c
@@ -145,7 +145,7 @@ static int qxl_process_single_command(struct qxl_device 
*qdev,
struct qxl_release *release;
struct qxl_bo *cmd_bo;
void *fb_cmd;
-   int i, ret, num_relocs;
+   int i, ret;
int unwritten;
 
switch (cmd->type) {
@@ -196,11 +196,10 @@ static int qxl_process_single_command(struct qxl_device 
*qdev,
if (unwritten) {
DRM_ERROR("got unwritten %d\n", unwritten);
ret = -EFAULT;
-   goto out_free_release;
+   goto out_free_bos;
}
 
/* fill out reloc info structs */
-   num_relocs = 0;
for (i = 0; i < cmd->relocs_num; ++i) {
struct drm_qxl_reloc reloc;
struct drm_qxl_reloc __user *u = u64_to_user_ptr(cmd->relocs);
@@ -230,7 +229,6 @@ static int qxl_process_single_command(struct qxl_device 
*qdev,
reloc_info[i].dst_bo = cmd_bo;
reloc_info[i].dst_offset = reloc.dst_offset + 
release->release_offset;
}
-   num_relocs++;
 
/* reserve and validate the reloc dst bo */
if (reloc.reloc_type == QXL_RELOC_TYPE_BO || reloc.src_handle) {
@@ -261,7 +259,6 @@ static int qxl_process_single_command(struct qxl_device 
*qdev,
ret = qxl_push_command_ring_release(qdev, release, cmd->type, true);
 
 out_free_bos:
-out_free_release:
if (ret)
qxl_release_free(qdev, release);
 out_free_reloc:
-- 
2.20.1.7.g153144c



Re: [PATCH 3/3] drm/xe/xe2: fix 64-bit division in pte_update_size

2024-02-25 Thread Lucas De Marchi

On Sat, Feb 24, 2024 at 01:15:01PM +0100, Arnd Bergmann wrote:

From: Arnd Bergmann 

This function does not build on 32-bit targets when the compiler
fails to reduce DIV_ROUND_UP() into a shift:

ld.lld: error: undefined symbol: __aeabi_uldivmod

referenced by xe_migrate.c
  drivers/gpu/drm/xe/xe_migrate.o:(pte_update_size) in archive 
vmlinux.a


There are two instances in this function. Change the first to
use an open-coded shift with the same behavior, and the second
one to a 32-bit calculation, which is sufficient here as the size
is never more than 2^32 pages (16TB).

Fixes: ea97a66a2218 ("drm/xe: Disable 32bits build")


same comment as in patch 2... should rather be the commit *enabling* 32b
builds?

Should this be something to be dealt with at the DIV_ROUND_UP() layer?
Why did the compiler fail to reduce it here but didn't in the other
11 uses in the xe driver?

thanks
Lucas De Marchi


Signed-off-by: Arnd Bergmann 
---
drivers/gpu/drm/xe/xe_migrate.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/xe/xe_migrate.c b/drivers/gpu/drm/xe/xe_migrate.c
index a66fdf2d2991..ee1bb938c493 100644
--- a/drivers/gpu/drm/xe/xe_migrate.c
+++ b/drivers/gpu/drm/xe/xe_migrate.c
@@ -462,7 +462,7 @@ static u32 pte_update_size(struct xe_migrate *m,
} else {
/* Clip L0 to available size */
u64 size = min(*L0, (u64)avail_pts * SZ_2M);
-   u64 num_4k_pages = DIV_ROUND_UP(size, XE_PAGE_SIZE);
+   u32 num_4k_pages = (size + XE_PAGE_SIZE - 1) >> XE_PTE_SHIFT;

*L0 = size;
*L0_ofs = xe_migrate_vm_addr(pt_ofs, 0);
--
2.39.2



Re: [PATCH 2/3] drm/xe/mmio: fix build warning for BAR resize on 32-bit

2024-02-25 Thread Lucas De Marchi

On Sat, Feb 24, 2024 at 01:15:00PM +0100, Arnd Bergmann wrote:

From: Arnd Bergmann 

clang complains about a nonsensical test on builds with a 32-bit phys_addr_t,
which means resizing will always fail:

drivers/gpu/drm/xe/xe_mmio.c:109:23: error: result of comparison of constant 
4294967296 with expression of type 'resource_size_t' (aka 'unsigned int') is 
always false [-Werror,-Wtautological-constant-out-of-range-compare]
 109 | root_res->start > 0x1ull)
 | ~~~ ^ ~~

Previously, BAR resize was always disallowed on 32-bit kernels, but
this apparently changed recently. Since 32-bit machines can in theory
support PAE/LPAE for large address spaces, this may end up useful,
so change the driver to shut up the warning but still work when
phys_addr_t/resource_size_t is 64 bit wide.

Fixes: 9a6e6c14bfde ("drm/xe/mmio: Use non-atomic writeq/readq variant for 32b")
Fixes: ea97a66a2218 ("drm/xe: Disable 32bits build")


this second Fixes should not be here? How would "disabling 32bits build"
break 32bits build? I think just the first one is enough, otherwise
237412e45390 ("drm/xe: Enable 32bits build") is your next good
candidate.


Acked-by: Lucas De Marchi 

Lucas De Marchi


Signed-off-by: Arnd Bergmann 
---
drivers/gpu/drm/xe/xe_mmio.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c
index e3db3a178760..7ba2477452d7 100644
--- a/drivers/gpu/drm/xe/xe_mmio.c
+++ b/drivers/gpu/drm/xe/xe_mmio.c
@@ -106,7 +106,7 @@ static void xe_resize_vram_bar(struct xe_device *xe)

pci_bus_for_each_resource(root, root_res, i) {
if (root_res && root_res->flags & (IORESOURCE_MEM | IORESOURCE_MEM_64) 
&&
-   root_res->start > 0x1ull)
+   (u64)root_res->start > 0x1ul)
break;
}

--
2.39.2



Re: [PATCH 1/3] drm/xe/kunit: fix link failure with built-in xe

2024-02-25 Thread Lucas De Marchi

On Sat, Feb 24, 2024 at 01:14:59PM +0100, Arnd Bergmann wrote:

From: Arnd Bergmann 

When the driver is built-in but the tests are in loadable modules,
the helpers don't actually get put into the driver:

ERROR: modpost: "xe_kunit_helper_alloc_xe_device" 
[drivers/gpu/drm/xe/tests/xe_test.ko] undefined!

Change the Makefile to ensure they are always part of the driver
even when the rest of the kunit tests are in loadable modules.

The tests/xe_kunit_helpers.c file depends on DRM_KUNIT_TEST_HELPERS,
so this has to always be selected by the main XE module now, rather
than the actual tests. In turn, the "depends on (m || (y && KUNIT=y))"
doesn't really do what it tried and can just be removed.


it actually did, which was to workaround issues prior to the commit you
are pointing out.  What it did  was to make sure xe.ko is m, or if it's
built-in, kunit is also built-in. Apparently the problem here is that
the xe_test.ko is missing the symbols.

See commit 08987a8b6820 ("drm/xe: Fix build with KUNIT=m").

I'm happy to remove it though if it's indeed not needed anymore.

Lucas De Marchi



Fixes: 5095d13d758b ("drm/xe/kunit: Define helper functions to allocate fake xe 
device")
Signed-off-by: Arnd Bergmann 
---
drivers/gpu/drm/xe/Kconfig   | 3 ++-
drivers/gpu/drm/xe/Kconfig.debug | 1 -
drivers/gpu/drm/xe/Makefile  | 6 --
3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/xe/Kconfig b/drivers/gpu/drm/xe/Kconfig
index 6d4428b19a4c..2948650680e1 100644
--- a/drivers/gpu/drm/xe/Kconfig
+++ b/drivers/gpu/drm/xe/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
config DRM_XE
tristate "Intel Xe Graphics"
-   depends on DRM && PCI && MMU && (m || (y && KUNIT=y))
+   depends on DRM && PCI && MMU
depends on ACPI_VIDEO || !ACPI
select INTERVAL_TREE
# we need shmfs for the swappable backing store, and in particular
@@ -11,6 +11,7 @@ config DRM_XE
select DRM_BUDDY
select DRM_EXEC
select DRM_KMS_HELPER
+   select DRM_KUNIT_TEST_HELPERS if DRM_XE_KUNIT_TEST != n
select DRM_PANEL
select DRM_SUBALLOC_HELPER
select DRM_DISPLAY_DP_HELPER
diff --git a/drivers/gpu/drm/xe/Kconfig.debug b/drivers/gpu/drm/xe/Kconfig.debug
index 549065f57a78..df02e5d17d26 100644
--- a/drivers/gpu/drm/xe/Kconfig.debug
+++ b/drivers/gpu/drm/xe/Kconfig.debug
@@ -76,7 +76,6 @@ config DRM_XE_KUNIT_TEST
depends on DRM_XE && KUNIT && DEBUG_FS
default KUNIT_ALL_TESTS
select DRM_EXPORT_FOR_TESTS if m
-   select DRM_KUNIT_TEST_HELPERS
help
  Choose this option to allow the driver to perform selftests under
  the kunit framework
diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile
index 4c6ffe4b2172..b596e4482a9b 100644
--- a/drivers/gpu/drm/xe/Makefile
+++ b/drivers/gpu/drm/xe/Makefile
@@ -158,8 +158,10 @@ xe-$(CONFIG_PCI_IOV) += \
xe_lmtt_2l.o \
xe_lmtt_ml.o

-xe-$(CONFIG_DRM_XE_KUNIT_TEST) += \
-   tests/xe_kunit_helpers.o
+# include helpers for tests even when XE is built-in
+ifdef CONFIG_DRM_XE_KUNIT_TEST
+xe-y += tests/xe_kunit_helpers.o
+endif

# i915 Display compat #defines and #includes
subdir-ccflags-$(CONFIG_DRM_XE_DISPLAY) += \
--
2.39.2



[PULL] drm-xe-next

2024-02-25 Thread Lucas De Marchi

Hi Dave and Sima,

Here's the PR for drm-xe-next for Linux v6.9. It's a big list of
changes, but it contains several fixes for things noticed throughout the
v6.8 cycle after being merged upstream, added to the linux-next, etc.
Approximately 30% are fixes already sent or on its way to v6.8.

First, the bad part: this still shows some issues of not being properly
integrated with our tooling, with this one being the worst:
https://lore.kernel.org/all/20240221173645.225a9...@canb.auug.org.au/.
Some of the committers didn't add their s-o-b while applying patches.  I
checked that all the affected patches do contain the s-o-b by the author
and come from the same company (Intel).

Also due to the same reason, some commits are missing a Link trailer to
the mailing list discussion. Often these patches were applied with bare
git-am or b4.

All of this should be fixed by now: dim is used for applying and pushing
patches, which has additional checks so that doesn't happen again. Still
pending confirmation from Daniel Stone if the git server hooks are ready
in gitlab so we properly forbid pushes without dim, like we do with the
git.fd.o infra.

Finally, we enabled again building for 32b, but on Friday we received
bug reports that it still fails with clang. There are some fixes being
reviewed and we should have them ready next week.

Summary of the changes are below.

drm-xe-next-2024-02-25:
drm/xe feature pull for v6.9: 


UAPI Changes:

- New query to the GuC firmware submission version. (José Roberto de Souza)
- Remove unused persistent exec_queues (Thomas Hellström)
- Add vram frequency sysfs attributes (Sujaritha Sundaresan, Rodrigo Vivi)
- Add the flag XE_VM_BIND_FLAG_DUMPABLE to notify devcoredump that mapping
  should be dumped (Maarten Lankhorst)

Cross-drivers Changes:

- Make sure intel_wakeref_t is treated as opaque type on i915-display
  and fix its type on xe

Driver Changes:

- Drop pre-production workarounds (Matt Roper)
- Drop kunit tests for unsuported platforms: PVC and pre-production DG2 (Lucas 
De Marchi)
- Start pumbling SR-IOV support with memory based interrupts
  for VF (Michal Wajdeczko)
- Allow to map BO in GGTT with PAT index corresponding to
  XE_CACHE_UC to work with memory based interrupts (Michal Wajdeczko)
- Improve logging with GT-oriented drm_printers (Michal Wajdeczko)
- Add GuC Doorbells Manager as prep work SR-IOV during
  VF provisioning ((Michal Wajdeczko)
- Refactor fake device handling in kunit integration ((Michal Wajdeczko)
- Implement additional workarounds for xe2 and MTL (Tejas Upadhyay,
  Lucas De Marchi, Shekhar Chauhan, Karthik Poosa)
- Program a few registers according to perfomance guide spec for Xe2 (Shekhar 
Chauhan)
- Add error handling for non-blocking communication with GuC (Daniele Ceraolo 
Spurio)
- Fix remaining 32b build issues and enable it back (Lucas De  Marchi)
- Fix build with CONFIG_DEBUG_FS=n (Jani Nikula)
- Fix warnings from GuC ABI headers (Matthew Brost)
- Introduce Relay Communication for SR-IOV for VF <-> GuC <-> PF (Michal 
Wajdeczko)
- Add mocs reset kunit (Ruthuvikas Ravikumar)
- Fix spellings (Colin Ian King)
- Disable mid-thread preemption when not properly supported by hardware (Nirmoy 
Das)
- Release mmap mappings on rpm suspend (Badal Nilawar)
- Fix BUG_ON on xe_exec by moving fence reservation to the validate stage 
(Matthew Auld)
- Fix xe_exec by reserving extra fence slot for CPU bind (Matthew Brost)
- Fix xe_exec with full long running exec queue, now returning
  -EWOULDBLOCK to userspace (Matthew Brost)
- Fix CT irq handler when CT is disabled (Matthew Brost)
- Fix VM_BIND_OP_UNMAP_ALL without any bound vmas (Thomas Hellström)
- Fix missing __iomem annotations (Thomas Hellström)
- Fix exec queue priority handling with GuC (Brian Welty)
- Fix setting SLPC flag to GuC when it's not supported (Vinay Belgaumkar)
- Fix C6 disabling without SLPC (Matt Roper)
- Drop -Wstringop-overflow to fix build with GCC11 (Paul E. McKenney)
- Circumvent bogus -Wstringop-overflow in one case (Arnd Bergmann)
- Refactor exec_queue user extensions handling and fix USM attributes
  being applied too late (Brian Welty)
- Use circ_buf head/tail convention (Matthew Brost)
- Fail build if circ_buf-related defines are modified with incompatible values
  (Matthew Brost)
- Fix several error paths (Dan Carpenter)
- Fix CCS copy for small VRAM copy chunks (Thomas Hellström)
- Rework driver initialization order and paths to account for driver running
  in VF mode (Michal Wajdeczko)
- Initialize GuC earlier during probe to handle driver in VF mode (Michał 
Winiarski)
- Fix migration use of MI_STORE_DATA_IMM to write PTEs (Matt Roper)
- Fix bounds checking in __xe_bo_placement_for_flags (Brian Welty)
- Drop display dependency on CONFIG_EXPERT (Jani Nikula)
- Do not hand-roll kstrdup when creating snapshot (Michal Wajdeczko)
- Stop creating one kunit module per kunit suite (Lucas De Marchi)
- Reduce scope and constify variables (Thomas Hellström, Jani Nikula, Michal 
Wajde

[PATCH v4 2/3] drm/msm/dpu: split dpu_encoder_wait_for_event into two functions

2024-02-25 Thread Dmitry Baryshkov
Stop multiplexing several events via the dpu_encoder_wait_for_event()
function. Split it into two distinct functions two allow separate
handling of those events.

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 70 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 22 ++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c |  2 +-
 drivers/gpu/drm/msm/msm_drv.h   | 10 -
 4 files changed, 55 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 194dbb08331d..c99c7fd770f6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1282,7 +1282,7 @@ static void dpu_encoder_virt_atomic_disable(struct 
drm_encoder *drm_enc,
trace_dpu_enc_disable(DRMID(drm_enc));
 
/* wait for idle */
-   dpu_encoder_wait_for_event(drm_enc, MSM_ENC_TX_COMPLETE);
+   dpu_encoder_wait_for_tx_complete(drm_enc);
 
dpu_encoder_resource_control(drm_enc, DPU_ENC_RC_EVENT_PRE_STOP);
 
@@ -2402,10 +2402,18 @@ struct drm_encoder *dpu_encoder_init(struct drm_device 
*dev,
return &dpu_enc->base;
 }
 
-int dpu_encoder_wait_for_event(struct drm_encoder *drm_enc,
-   enum msm_event_wait event)
+/**
+ * dpu_encoder_wait_for_commit_done() - Wait for encoder to flush pending state
+ * @drm_enc:   encoder pointer
+ *
+ * Wait for hardware to have flushed the current pending changes to hardware at
+ * a vblank or CTL_START. Physical encoders will map this differently depending
+ * on the type: vid mode -> vsync_irq, cmd mode -> CTL_START.
+ *
+ * Return: 0 on success, -EWOULDBLOCK if already signaled, error otherwise
+ */
+int dpu_encoder_wait_for_commit_done(struct drm_encoder *drm_enc)
 {
-   int (*fn_wait)(struct dpu_encoder_phys *phys_enc) = NULL;
struct dpu_encoder_virt *dpu_enc = NULL;
int i, ret = 0;
 
@@ -2419,23 +2427,47 @@ int dpu_encoder_wait_for_event(struct drm_encoder 
*drm_enc,
for (i = 0; i < dpu_enc->num_phys_encs; i++) {
struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
 
-   switch (event) {
-   case MSM_ENC_COMMIT_DONE:
-   fn_wait = phys->ops.wait_for_commit_done;
-   break;
-   case MSM_ENC_TX_COMPLETE:
-   fn_wait = phys->ops.wait_for_tx_complete;
-   break;
-   default:
-   DPU_ERROR_ENC(dpu_enc, "unknown wait event %d\n",
-   event);
-   return -EINVAL;
+   if (phys->ops.wait_for_commit_done) {
+   DPU_ATRACE_BEGIN("wait_for_commit_done");
+   ret = phys->ops.wait_for_commit_done(phys);
+   DPU_ATRACE_END("wait_for_commit_done");
+   if (ret)
+   return ret;
}
+   }
+
+   return ret;
+}
+
+/**
+ * dpu_encoder_wait_for_tx_complete() - Wait for encoder to transfer pixels to 
panel
+ * @drm_enc:   encoder pointer
+ *
+ * Wait for the hardware to transfer all the pixels to the panel. Physical
+ * encoders will map this differently depending on the type: vid mode -> 
vsync_irq,
+ * cmd mode -> pp_done.
+ *
+ * Return: 0 on success, -EWOULDBLOCK if already signaled, error otherwise
+ */
+int dpu_encoder_wait_for_tx_complete(struct drm_encoder *drm_enc)
+{
+   struct dpu_encoder_virt *dpu_enc = NULL;
+   int i, ret = 0;
+
+   if (!drm_enc) {
+   DPU_ERROR("invalid encoder\n");
+   return -EINVAL;
+   }
+   dpu_enc = to_dpu_encoder_virt(drm_enc);
+   DPU_DEBUG_ENC(dpu_enc, "\n");
+
+   for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+   struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
 
-   if (fn_wait) {
-   DPU_ATRACE_BEGIN("wait_for_completion_event");
-   ret = fn_wait(phys);
-   DPU_ATRACE_END("wait_for_completion_event");
+   if (phys->ops.wait_for_tx_complete) {
+   DPU_ATRACE_BEGIN("wait_for_tx_complete");
+   ret = phys->ops.wait_for_tx_complete(phys);
+   DPU_ATRACE_END("wait_for_tx_complete");
if (ret)
return ret;
}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
index fe6b1d312a74..0c928d1876e4 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
@@ -93,25 +93,9 @@ void dpu_encoder_kickoff(struct drm_encoder *encoder);
  */
 int dpu_encoder_vsync_time(struct drm_encoder *drm_enc, ktime_t *wakeup_time);
 
-/**
- * dpu_encoder_wait_for_event - Waits for encoder ev

[PATCH v4 1/3] drm/msm/dpu: make "vblank timeout" more useful

2024-02-25 Thread Dmitry Baryshkov
We have several reports of vblank timeout messages. However after some
debugging it was found that there might be different causes to that.
To allow us to identify the DPU block that gets stuck, include the
actual CTL_FLUSH value into the timeout message.

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
index 2aa72b578764..6058706f03e4 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
@@ -480,7 +480,7 @@ static int dpu_encoder_phys_vid_wait_for_commit_done(
(hw_ctl->ops.get_flush_register(hw_ctl) == 0),
msecs_to_jiffies(50));
if (ret <= 0) {
-   DPU_ERROR("vblank timeout\n");
+   DPU_ERROR("vblank timeout: %x\n", 
hw_ctl->ops.get_flush_register(hw_ctl));
return -ETIMEDOUT;
}
 

-- 
2.39.2



[PATCH v4 3/3] drm/msm/dpu: capture snapshot on the first commit_done timeout

2024-02-25 Thread Dmitry Baryshkov
In order to debug commit_done timeouts, capture the devcoredump state
when the first timeout occurs after the encoder has been enabled.

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index c99c7fd770f6..c45edcde7ebc 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -126,6 +126,8 @@ enum dpu_enc_rc_states {
  * @base:  drm_encoder base class for registration with DRM
  * @enc_spinlock:  Virtual-Encoder-Wide Spin Lock for IRQ purposes
  * @enabled:   True if the encoder is active, protected by enc_lock
+ * @commit_done_timedout: True if there has been a timeout on commit after
+ * enabling the encoder.
  * @num_phys_encs: Actual number of physical encoders contained.
  * @phys_encs: Container of physical encoders managed.
  * @cur_master:Pointer to the current master in this mode. 
Optimization
@@ -172,6 +174,7 @@ struct dpu_encoder_virt {
spinlock_t enc_spinlock;
 
bool enabled;
+   bool commit_done_timedout;
 
unsigned int num_phys_encs;
struct dpu_encoder_phys *phys_encs[MAX_PHYS_ENCODERS_PER_VIRTUAL];
@@ -1226,6 +1229,8 @@ static void dpu_encoder_virt_atomic_enable(struct 
drm_encoder *drm_enc,
else if (disp_info->intf_type == INTF_DSI)
dpu_enc->wide_bus_en = 
msm_dsi_wide_bus_enabled(priv->dsi[index]);
 
+   dpu_enc->commit_done_timedout = false;
+
mutex_lock(&dpu_enc->enc_lock);
cur_mode = &dpu_enc->base.crtc->state->adjusted_mode;
 
@@ -2431,6 +2436,10 @@ int dpu_encoder_wait_for_commit_done(struct drm_encoder 
*drm_enc)
DPU_ATRACE_BEGIN("wait_for_commit_done");
ret = phys->ops.wait_for_commit_done(phys);
DPU_ATRACE_END("wait_for_commit_done");
+   if (ret == -ETIMEDOUT && 
!dpu_enc->commit_done_timedout) {
+   dpu_enc->commit_done_timedout = true;
+   msm_disp_snapshot_state(drm_enc->dev);
+   }
if (ret)
return ret;
}

-- 
2.39.2



[PATCH v4 0/3] drm/msm/dpu: debug commit_done timeouts

2024-02-25 Thread Dmitry Baryshkov
In order to debug commit_done timeouts ([1]) display the sticky bits of
the CTL_FLUSH register and capture the devcore dump when the first such
timeout occurs.

[1] https://gitlab.freedesktop.org/drm/msm/-/issues/33

Signed-off-by: Dmitry Baryshkov 
---
Changes in v4:
- Reworded documentation for new funcsions (Abhinav)
- Link to v3: 
https://lore.kernel.org/r/20240225-fd-dpu-debug-timeout-v3-0-252f2b21c...@linaro.org

Changes in v3:
- Capture the snapshot only on the first comit_done timeout (Abhinav)
- Link to v2: 
https://lore.kernel.org/r/20240208-fd-dpu-debug-timeout-v2-1-9f907f1bd...@linaro.org

Changes in v2:
- Added a call to msm_disp_snapshot_state() to trigger devcore dump
  (Abhinav)
- Link to v1: 
https://lore.kernel.org/r/20240106-fd-dpu-debug-timeout-v1-1-6d9762884...@linaro.org

---
Dmitry Baryshkov (3):
  drm/msm/dpu: make "vblank timeout" more useful
  drm/msm/dpu: split dpu_encoder_wait_for_event into two functions
  drm/msm/dpu: capture snapshot on the first commit_done timeout

 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c| 79 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h| 22 +-
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c   |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c|  2 +-
 drivers/gpu/drm/msm/msm_drv.h  | 10 ---
 5 files changed, 65 insertions(+), 50 deletions(-)
---
base-commit: 33e1d31873f87d119e5120b88cd350efa68ef276
change-id: 20240106-fd-dpu-debug-timeout-e917f0bc8063

Best regards,
-- 
Dmitry Baryshkov 



Re: [PATCH] drm/nouveau: use dedicated wq for fence uevents work

2024-02-25 Thread Dave Airlie
On Sat, 24 Feb 2024 at 03:01, Danilo Krummrich  wrote:
>
> On Fri, Feb 23, 2024 at 10:14:53AM +1000, Dave Airlie wrote:
> > On Fri, 23 Feb 2024 at 00:45, Danilo Krummrich  wrote:
> > >
> > > Using the kernel global workqueue to signal fences can lead to
> > > unexpected deadlocks. Some other work (e.g. from a different driver)
> > > could directly or indirectly depend on this fence to be signaled.
> > > However, if the WQ_MAX_ACTIVE limit is reached by waiters, this can
> > > prevent the work signaling the fence from running.
> > >
> > > While this seems fairly unlikely, it's potentially exploitable.
> >
> > LGTM
> >
> > Reviewed-by: Dave Airlie 
> >
> > probably should go into drm-misc-fixes?
>
> Yes, however, 39126abc5e20 went in through drm-fixes directly it seems, since
> it's not in drm-misc-fixes.
>
> Guess you want me to cherry-pick 39126abc5e20 to drm-misc-fixes rather than 
> take
> this one through drm-fixes as well?

Nah don't ever cherry-pick, backmerge would be the correct thing, but
I'll just take it in through drm-fixes.

Dave.

>
> >
> > >
> > > Fixes: 39126abc5e20 ("nouveau: offload fence uevents work to workqueue")
> > > Signed-off-by: Danilo Krummrich 
> > > ---
> > >  drivers/gpu/drm/nouveau/nouveau_drm.c   | 13 +++--
> > >  drivers/gpu/drm/nouveau/nouveau_drv.h   |  3 +++
> > >  drivers/gpu/drm/nouveau/nouveau_fence.c |  3 ++-
> > >  drivers/gpu/drm/nouveau/nouveau_fence.h |  2 ++
> > >  4 files changed, 18 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c 
> > > b/drivers/gpu/drm/nouveau/nouveau_drm.c
> > > index 6f6c31a9937b..6be202081077 100644
> > > --- a/drivers/gpu/drm/nouveau/nouveau_drm.c
> > > +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
> > > @@ -598,9 +598,15 @@ nouveau_drm_device_init(struct drm_device *dev)
> > > goto fail_alloc;
> > > }
> > >
> > > +   drm->fence_wq = alloc_workqueue("nouveau_fence_wq", 0, 
> > > WQ_MAX_ACTIVE);
> > > +   if (!drm->fence_wq) {
> > > +   ret = -ENOMEM;
> > > +   goto fail_sched_wq;
> > > +   }
> > > +
> > > ret = nouveau_cli_init(drm, "DRM-master", &drm->master);
> > > if (ret)
> > > -   goto fail_wq;
> > > +   goto fail_fence_wq;
> > >
> > > ret = nouveau_cli_init(drm, "DRM", &drm->client);
> > > if (ret)
> > > @@ -670,7 +676,9 @@ nouveau_drm_device_init(struct drm_device *dev)
> > > nouveau_cli_fini(&drm->client);
> > >  fail_master:
> > > nouveau_cli_fini(&drm->master);
> > > -fail_wq:
> > > +fail_fence_wq:
> > > +   destroy_workqueue(drm->fence_wq);
> > > +fail_sched_wq:
> > > destroy_workqueue(drm->sched_wq);
> > >  fail_alloc:
> > > nvif_parent_dtor(&drm->parent);
> > > @@ -725,6 +733,7 @@ nouveau_drm_device_fini(struct drm_device *dev)
> > >
> > > nouveau_cli_fini(&drm->client);
> > > nouveau_cli_fini(&drm->master);
> > > +   destroy_workqueue(drm->fence_wq);
> > > destroy_workqueue(drm->sched_wq);
> > > nvif_parent_dtor(&drm->parent);
> > > mutex_destroy(&drm->clients_lock);
> > > diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h 
> > > b/drivers/gpu/drm/nouveau/nouveau_drv.h
> > > index 8a6d94c8b163..b43619a213a4 100644
> > > --- a/drivers/gpu/drm/nouveau/nouveau_drv.h
> > > +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
> > > @@ -261,6 +261,9 @@ struct nouveau_drm {
> > > /* Workqueue used for channel schedulers. */
> > > struct workqueue_struct *sched_wq;
> > >
> > > +   /* Workqueue used to signal fences. */
> > > +   struct workqueue_struct *fence_wq;
> > > +
> > > /* context for accelerated drm-internal operations */
> > > struct nouveau_channel *cechan;
> > > struct nouveau_channel *channel;
> > > diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c 
> > > b/drivers/gpu/drm/nouveau/nouveau_fence.c
> > > index 93f08f9479d8..c3ea3cd933cd 100644
> > > --- a/drivers/gpu/drm/nouveau/nouveau_fence.c
> > > +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
> > > @@ -174,7 +174,7 @@ static int
> > >  nouveau_fence_wait_uevent_handler(struct nvif_event *event, void *repv, 
> > > u32 repc)
> > >  {
> > > struct nouveau_fence_chan *fctx = container_of(event, 
> > > typeof(*fctx), event);
> > > -   schedule_work(&fctx->uevent_work);
> > > +   queue_work(fctx->wq, &fctx->uevent_work);
> > > return NVIF_EVENT_KEEP;
> > >  }
> > >
> > > @@ -194,6 +194,7 @@ nouveau_fence_context_new(struct nouveau_channel 
> > > *chan, struct nouveau_fence_cha
> > > INIT_LIST_HEAD(&fctx->pending);
> > > spin_lock_init(&fctx->lock);
> > > fctx->context = chan->drm->runl[chan->runlist].context_base + 
> > > chan->chid;
> > > +   fctx->wq = chan->drm->fence_wq;
> > >
> > > if (chan == chan->drm->cechan)
> > > strcpy(fctx->name, "copy engine channel");
> > > diff --git a/drivers/gpu/drm/nouveau/nouveau_fe

[PATCH] drm/exynos: use KMEM_CACHE() to create g2d_runqueue_node cache

2024-02-25 Thread Kunwu Chan
Use the KMEM_CACHE() macro instead of kmem_cache_create() to simplify
the creation of SLAB caches when the default values are used.

Signed-off-by: Kunwu Chan 
---
 drivers/gpu/drm/exynos/exynos_drm_g2d.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c 
b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index f3138423612e..a5818ed6a6f7 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -1456,8 +1456,7 @@ static int g2d_probe(struct platform_device *pdev)
if (!g2d)
return -ENOMEM;
 
-   g2d->runqueue_slab = kmem_cache_create("g2d_runqueue_slab",
-   sizeof(struct g2d_runqueue_node), 0, 0, NULL);
+   g2d->runqueue_slab = KMEM_CACHE(g2d_runqueue_node, 0);
if (!g2d->runqueue_slab)
return -ENOMEM;
 
-- 
2.39.2



[PATCH] drm/xe: use KMEM_CACHE() to create xe_hw_fence cache

2024-02-25 Thread Kunwu Chan
Use the KMEM_CACHE() macro instead of kmem_cache_create() to simplify
the creation of SLAB caches when the default values are used.

Signed-off-by: Kunwu Chan 
---
 drivers/gpu/drm/xe/xe_hw_fence.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/xe/xe_hw_fence.c b/drivers/gpu/drm/xe/xe_hw_fence.c
index a6094c81f2ad..cd258e0ccdf3 100644
--- a/drivers/gpu/drm/xe/xe_hw_fence.c
+++ b/drivers/gpu/drm/xe/xe_hw_fence.c
@@ -20,9 +20,7 @@ static struct kmem_cache *xe_hw_fence_slab;
 
 int __init xe_hw_fence_module_init(void)
 {
-   xe_hw_fence_slab = kmem_cache_create("xe_hw_fence",
-sizeof(struct xe_hw_fence), 0,
-SLAB_HWCACHE_ALIGN, NULL);
+   xe_hw_fence_slab = KMEM_CACHE(xe_hw_fence, SLAB_HWCACHE_ALIGN);
if (!xe_hw_fence_slab)
return -ENOMEM;
 
-- 
2.39.2



[PATCH RFC 12/12] drm/msm: sync shipped headers database

2024-02-25 Thread Dmitry Baryshkov
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/registers/dsi.xml.h_shipped|  38 ---
 .../drm/msm/registers/dsi_phy_10nm.xml.h_shipped   |  37 ---
 .../drm/msm/registers/dsi_phy_14nm.xml.h_shipped   |  37 ---
 .../drm/msm/registers/dsi_phy_20nm.xml.h_shipped   |  37 ---
 .../drm/msm/registers/dsi_phy_28nm.xml.h_shipped   |  37 ---
 .../msm/registers/dsi_phy_28nm_8960.xml.h_shipped  |  37 ---
 .../drm/msm/registers/dsi_phy_7nm.xml.h_shipped|  37 ---
 drivers/gpu/drm/msm/registers/hdmi.xml.h_shipped   | 111 +
 drivers/gpu/drm/msm/registers/mdp4.xml.h_shipped   |  37 ---
 drivers/gpu/drm/msm/registers/mdp5.xml.h_shipped   |  39 
 .../gpu/drm/msm/registers/mdp_common.xml.h_shipped |  45 +
 drivers/gpu/drm/msm/registers/sfpb.xml.h_shipped   |  35 +++
 12 files changed, 284 insertions(+), 243 deletions(-)

diff --git a/drivers/gpu/drm/msm/registers/dsi.xml.h_shipped 
b/drivers/gpu/drm/msm/registers/dsi.xml.h_shipped
index 2a7d980e12c3..d02fefe0d7ad 100644
--- a/drivers/gpu/drm/msm/registers/dsi.xml.h_shipped
+++ b/drivers/gpu/drm/msm/registers/dsi.xml.h_shipped
@@ -8,26 +8,23 @@ http://github.com/freedreno/envytools/
 git clone https://github.com/freedreno/envytools.git
 
 The rules-ng-ng source files this header was generated from are:
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/msm.xml 
  (944 bytes, from 2022-07-23 20:21:46)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml 
  (   1572 bytes, from 2022-07-23 20:21:46)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp4.xml
  (  20912 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp_common.xml  
  (   2849 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp5.xml
  (  37461 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi.xml 
  (  18746 bytes, from 2022-04-28 17:29:36)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml  
  (   3236 bytes, from 2022-03-08 17:40:42)
-- 
/home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml 
(   4935 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml
  (   7004 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml
  (   3712 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml
  (   5381 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml
  (   4499 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml 
  (  11007 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/sfpb.xml
  (602 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/mmss_cc.xml 
  (   1686 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/qfprom.xml 
  (600 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/hdmi.xml   
  (  42350 bytes, from 2022-09-20 17:45:56)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/edp/edp.xml 
  (  10416 bytes, from 2022-03-08 17:40:42)
-
-Copyright (C) 2013-2022 by the following authors:
+- msm.xml (802 bytes, from 2024-02-26 02:06:53)
+- freedreno_copyright.xml (   1572 bytes, from 2024-02-26 02:05:48)
+- mdp4.xml(  20908 bytes, from 2024-02-26 02:05:48)
+- mdp_common.xml  (   3056 bytes, from 2024-02-26 02:05:48)
+- mdp5.xml(  37457 bytes, from 2024-02-26 02:05:48)
+- dsi.xml (  18864 bytes, from 2024-02-26 02:05:48)
+- dsi_phy_28nm_8960.xml   (   4935 bytes, from 2024-02-26 02:05:48)
+- dsi_phy_28nm.xml(   7004 bytes, from 2024-02-26 02:05:48)
+- dsi_phy_20nm.xml(   3712 bytes, from 2024-02-26 02:05:48)
+- dsi_phy_14nm.xml(   5381 bytes, from 2024-02-26 02:05:48)
+- dsi_phy_10nm.xml(   4499 bytes, from 2024-02-26 02:05:48)
+- dsi_phy_7nm.xml (  11007 bytes, from 2024-02-26 02:05:48)
+- sfpb.xml(602 bytes, from 2024-02-26 02:05:48)
+- hdmi.xml(  44030 bytes, from 2024-02-26 02:05:48)
+- edp.xml (  10416 bytes, from 2024-02-26 02:05:48)
+
+Copyright (C) 2013-2024 by the following authors:
 - Rob Clark  (robclark)
 - Ilia Mirkin  (imirkin)
 
@@ -231,6 +228,7 @@ static inline uint32_t DSI_VID_CFG0_TRAFFIC_MODE(enum 
dsi_traffic_mode val)
 #define DSI_VID_CFG0_HSA_POWER_STOP0x0001
 #define DSI_VID_CFG0_HBP_POWER_STOP 

[PATCH RFC 11/12] drm/msm: tie regeneration of shipped headers

2024-02-25 Thread Dmitry Baryshkov
Finally add support for regeneration of the shipped autogenerated
register headers. Pass DRM_MSM_GENERATE_HEADERS=1 to make to force
regeneration.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/Makefile | 27 +++
 drivers/gpu/drm/msm/registers/.gitignore |  5 +
 2 files changed, 32 insertions(+)

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 89c9f5f93b85..a19ad02bd701 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -180,3 +180,30 @@ msm-$(CONFIG_DRM_MSM_DSI) += $(msm-dsi) $(msm-dsi-y)
 $(addprefix $(obj)/,$(msm-dsi) $(msm-dsi-y)): $(obj)/registers/dsi.xml.h
 
 obj-$(CONFIG_DRM_MSM)  += msm.o
+
+ifdef DRM_MSM_GENERATE_HEADERS
+
+hostprogs += hg2
+
+hg2-objs = \
+   headergen2/colors.o \
+   headergen2/path.o \
+   headergen2/rnn.o \
+   headergen2/rnndec.o \
+   headergen2/headergen2.o
+
+HOST_EXTRACFLAGS += -D_GNU_SOURCE $(shell pkg-config --cflags libxml-2.0) 
-DRNN_DEF_PATH='"$(srctree)/$(src)/registers/xml"'
+HOSTLDLIBS_hg2 = $(shell pkg-config --libs libxml-2.0)
+
+HEADERGEN = $(objtree)/$(obj)/hg2
+
+quiet_cmd_headergen = HG2 $@
+  cmd_headergen = $(HEADERGEN) $(shell basename $<) 
$(srctree)/$(src)/registers/
+
+$(src)/registers/%.xml.h_shipped: msm.xml.h
+   $(Q):
+
+msm.xml.h: $(src)/registers/xml/msm.xml $(HEADERGEN) FORCE
+   $(call cmd,headergen)
+
+endif
diff --git a/drivers/gpu/drm/msm/registers/.gitignore 
b/drivers/gpu/drm/msm/registers/.gitignore
new file mode 100644
index ..2e422e71e590
--- /dev/null
+++ b/drivers/gpu/drm/msm/registers/.gitignore
@@ -0,0 +1,5 @@
+# ignore empty files
+msm.xml.h_shipped
+freedreno_copyright.xml.h_shipped
+# unused files
+edp.xml.h_shipped

-- 
2.39.2



[PATCH RFC 07/12] drm/msm/headergen: use asprintf instead of custom aprintf

2024-02-25 Thread Dmitry Baryshkov
Replace custom aprintf() function with the standard asprintf().

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/headergen2/aprintf.c | 38 
 drivers/gpu/drm/msm/headergen2/rnn.c |  5 -
 drivers/gpu/drm/msm/headergen2/util.h|  2 --
 3 files changed, 4 insertions(+), 41 deletions(-)

diff --git a/drivers/gpu/drm/msm/headergen2/aprintf.c 
b/drivers/gpu/drm/msm/headergen2/aprintf.c
deleted file mode 100644
index b3d924f59413..
--- a/drivers/gpu/drm/msm/headergen2/aprintf.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2009-2011 Marcin Kościelnicki 
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "util.h"
-#include 
-
-char *aprintf(const char *format, ...) {
-   va_list va;
-   va_start(va, format);
-   size_t sz = vsnprintf(0, 0, format, va);
-   va_end(va);
-   char *res = malloc(sz + 1);
-   va_start(va, format);
-   vsnprintf(res, sz + 1, format, va);
-   va_end(va);
-   return res;
-}
diff --git a/drivers/gpu/drm/msm/headergen2/rnn.c 
b/drivers/gpu/drm/msm/headergen2/rnn.c
index d82d2a561b02..6cf3c54954bd 100644
--- a/drivers/gpu/drm/msm/headergen2/rnn.c
+++ b/drivers/gpu/drm/msm/headergen2/rnn.c
@@ -44,9 +44,12 @@
 #include "util/u_debug.h"
 
 static char *catstr (char *a, char *b) {
+   char *res;
+
if (!a)
return b;
-   return aprintf("%s_%s", a, b);
+
+   return asprintf(&res, "%s_%s", a, b) < 0 ? NULL : res;
 }
 
 static int strdiff (const char *a, const char *b) {
diff --git a/drivers/gpu/drm/msm/headergen2/util.h 
b/drivers/gpu/drm/msm/headergen2/util.h
index 98a32a34d076..07ad637e4521 100644
--- a/drivers/gpu/drm/msm/headergen2/util.h
+++ b/drivers/gpu/drm/msm/headergen2/util.h
@@ -110,6 +110,4 @@ struct astr {
 
 void print_escaped_astr(FILE *out, struct astr *astr);
 
-char *aprintf(const char *format, ...);
-
 #endif

-- 
2.39.2



[PATCH RFC 09/12] drm/msm/headergen: generate _shipped files

2024-02-25 Thread Dmitry Baryshkov
Change headergen semantics to generate the .xml.h_shipped files instead
of just generating headers.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/headergen2/headergen2.c | 33 +++--
 1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/msm/headergen2/headergen2.c 
b/drivers/gpu/drm/msm/headergen2/headergen2.c
index 2e5c4593d865..7d884fa547b2 100644
--- a/drivers/gpu/drm/msm/headergen2/headergen2.c
+++ b/drivers/gpu/drm/msm/headergen2/headergen2.c
@@ -417,30 +417,41 @@ static void printhead(struct fout f, struct rnndb *db) {
 
 int main(int argc, char **argv) {
char *file;
+   char *out_dir;
struct rnndb *db;
int i, j;
 
-   if (argc < 2) {
-   fprintf(stderr, "Usage:\n\theadergen database-file\n");
-   exit(1);
+   if (argv[1] && !strcmp(argv[1], "--no-asserts")) {
+   no_asserts = true;
+   argv++;
+   argc--;
}
 
-   if ((argc >= 3) && !strcmp(argv[1], "--no-asserts")) {
-   no_asserts = true;
-   file = argv[2];
-   } else {
-   file = argv[1];
+   if (argc != 3) {
+   fprintf(stderr, "Usage:\n\theadergen database-file out-dir\n");
+   exit(1);
}
 
+   file = argv[1];
+   out_dir = argv[2];
+
rnn_init();
db = rnn_newdb();
rnn_parsefile (db, file);
rnn_prepdb (db);
for(i = 0; i < db->filesnum; ++i) {
-   char *dstname = malloc(strlen(db->files[i]) + 3);
+   char *curfile = basename(db->files[i]);
+   char *dstname;
char *pretty;
-   strcpy(dstname, db->files[i]);
-   strcat(dstname, ".h");
+   int ret;
+
+   ret = asprintf(&dstname, "%s/%s.h_shipped",
+  out_dir, curfile);
+   if (ret < 0) {
+   perror("asprintf");
+   exit(1);
+   }
+
struct fout f = { db->files[i], fopen(dstname, "w") };
if (!f.file) {
perror(dstname);

-- 
2.39.2



[PATCH RFC 02/12] drm/msm/mdp5: add writeback block bases

2024-02-25 Thread Dmitry Baryshkov
In order to stop patching the mdp5 headers, import definitions for the
writeback blocks. This part is extracted from the old Rob's patch.

Co-developed-by: Rob Clark 
Signed-off-by: Rob Clark 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.h | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.h 
b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.h
index 26c5d8b4ab46..4b988e69fbfc 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.h
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.h
@@ -69,6 +69,16 @@ struct mdp5_mdp_block {
uint32_t caps;  /* MDP capabilities: MDP_CAP_xxx bits */
 };
 
+struct mdp5_wb_instance {
+   int id;
+   int lm;
+};
+
+struct mdp5_wb_block {
+   MDP5_SUB_BLOCK_DEFINITION;
+   struct mdp5_wb_instance instances[MAX_BASES];
+};
+
 #define MDP5_INTF_NUM_MAX  5
 
 struct mdp5_intf_block {
@@ -98,6 +108,7 @@ struct mdp5_cfg_hw {
struct mdp5_sub_block pp;
struct mdp5_sub_block dsc;
struct mdp5_sub_block cdm;
+   struct mdp5_wb_block wb;
struct mdp5_intf_block intf;
struct mdp5_perf_block perf;
 

-- 
2.39.2



[PATCH RFC 08/12] drm/msm/headergen: don't output full file paths

2024-02-25 Thread Dmitry Baryshkov
In order to reduce noise, include just the file name into the generated
file headers.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/headergen2/headergen2.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/headergen2/headergen2.c 
b/drivers/gpu/drm/msm/headergen2/headergen2.c
index d5a3eb7562ee..2e5c4593d865 100644
--- a/drivers/gpu/drm/msm/headergen2/headergen2.c
+++ b/drivers/gpu/drm/msm/headergen2/headergen2.c
@@ -377,13 +377,14 @@ static void printhead(struct fout f, struct rnndb *db) {
"The rules-ng-ng source files this header was generated from 
are:\n");
unsigned maxlen = 0;
for(i = 0; i < db->filesnum; ++i) {
-   unsigned len = strlen(db->files[i]);
+   unsigned len = strlen(basename(db->files[i]));
if(len > maxlen)
maxlen = len;
}
for(i = 0; i < db->filesnum; ++i) {
-   unsigned len = strlen(db->files[i]);
-   fprintf(f.file, "- %s%*s ", db->files[i], maxlen - len, "");
+   char *name = basename(db->files[i]);
+   unsigned len = strlen(name);
+   fprintf(f.file, "- %s%*s ", name, maxlen - len, "");
print_file_info(f.file, db->files[i]);
}
fprintf(f.file,

-- 
2.39.2



[PATCH RFC 05/12] drm/msm: use _shipped suffix for all xml.h files

2024-02-25 Thread Dmitry Baryshkov
Move non-GPU xml.h files into the ./registers subdir and add the
_shipped suffix. The GPU files are left intact for now, since they
require processing via a gen_headers.py, while display headers are
regenerated using headergen2

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/Makefile   | 53 ++
 .../{dsi/dsi.xml.h => registers/dsi.xml.h_shipped} |  0
 .../dsi_phy_10nm.xml.h_shipped}|  0
 .../dsi_phy_14nm.xml.h_shipped}|  0
 .../dsi_phy_20nm.xml.h_shipped}|  0
 .../dsi_phy_28nm.xml.h_shipped}|  0
 .../dsi_phy_28nm_8960.xml.h_shipped}   |  0
 .../dsi_phy_7nm.xml.h_shipped} |  0
 .../hdmi.xml.h => registers/hdmi.xml.h_shipped}|  0
 .../mdp4.xml.h => registers/mdp4.xml.h_shipped}|  0
 .../mdp5.xml.h => registers/mdp5.xml.h_shipped}|  0
 .../mdp_common.xml.h_shipped}  |  0
 .../sfpb.xml.h => registers/sfpb.xml.h_shipped}|  0
 13 files changed, 43 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 543e04fa72e3..89c9f5f93b85 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 ccflags-y := -I $(srctree)/$(src)
+ccflags-y := -I $(obj)/registers
 ccflags-y += -I $(srctree)/$(src)/disp/dpu1
 ccflags-$(CONFIG_DRM_MSM_DSI) += -I $(srctree)/$(src)/dsi
 ccflags-$(CONFIG_DRM_MSM_DP) += -I $(srctree)/$(src)/dp
@@ -17,7 +18,7 @@ msm-y := \
adreno/a6xx_gmu.o \
adreno/a6xx_hfi.o \
 
-msm-$(CONFIG_DRM_MSM_HDMI) += \
+msm-hdmi += \
hdmi/hdmi.o \
hdmi/hdmi_audio.o \
hdmi/hdmi_bridge.o \
@@ -30,7 +31,11 @@ msm-$(CONFIG_DRM_MSM_HDMI) += \
hdmi/hdmi_phy_8x74.o \
hdmi/hdmi_pll_8960.o \
 
-msm-$(CONFIG_DRM_MSM_MDP4) += \
+msm-$(CONFIG_DRM_MSM_HDMI) += $(msm-hdmi)
+
+$(addprefix $(obj)/,$(msm-hdmi)): $(obj)/registers/hdmi.xml.h
+
+msm-mdp4 += \
disp/mdp4/mdp4_crtc.o \
disp/mdp4/mdp4_dsi_encoder.o \
disp/mdp4/mdp4_dtv_encoder.o \
@@ -41,7 +46,12 @@ msm-$(CONFIG_DRM_MSM_MDP4) += \
disp/mdp4/mdp4_kms.o \
disp/mdp4/mdp4_plane.o \
 
-msm-$(CONFIG_DRM_MSM_MDP5) += \
+msm-$(CONFIG_DRM_MSM_MDP4) += $(msm-mdp4)
+
+$(addprefix $(obj)/,$(msm-mdp4)): $(obj)/registers/mdp4.xml.h
+$(addprefix $(obj)/,$(msm-mdp4)): $(obj)/registers/mdp_common.xml.h
+
+msm-mdp5 += \
disp/mdp5/mdp5_cfg.o \
disp/mdp5/mdp5_cmd_encoder.o \
disp/mdp5/mdp5_ctl.o \
@@ -54,6 +64,10 @@ msm-$(CONFIG_DRM_MSM_MDP5) += \
disp/mdp5/mdp5_plane.o \
disp/mdp5/mdp5_smp.o \
 
+msm-$(CONFIG_DRM_MSM_MDP5) += $(msm-mdp5)
+$(addprefix $(obj)/,$(msm-mdp5)): $(obj)/registers/mdp5.xml.h
+$(addprefix $(obj)/,$(msm-mdp5)): $(obj)/registers/mdp_common.xml.h
+
 msm-$(CONFIG_DRM_MSM_DPU) += \
disp/dpu1/dpu_core_perf.o \
disp/dpu1/dpu_crtc.o \
@@ -115,6 +129,9 @@ msm-y += \
msm_gpu_tracepoints.o \
msm_gpummu.o
 
+$(obj)/disp/mdp_format.o: $(obj)/registers/mdp_common.xml.h
+$(obj)/disp/mdp_kms.o: $(obj)/registers/mdp_common.xml.h
+
 msm-$(CONFIG_DEBUG_FS) += adreno/a5xx_debugfs.o \
dp/dp_debug.o
 
@@ -133,17 +150,33 @@ msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o
 
 msm-$(CONFIG_DRM_MSM_HDMI_HDCP) += hdmi/hdmi_hdcp.o
 
-msm-$(CONFIG_DRM_MSM_DSI) += dsi/dsi.o \
+msm-dsi += dsi/dsi.o \
dsi/dsi_cfg.o \
dsi/dsi_host.o \
dsi/dsi_manager.o \
dsi/phy/dsi_phy.o
 
-msm-$(CONFIG_DRM_MSM_DSI_28NM_PHY) += dsi/phy/dsi_phy_28nm.o
-msm-$(CONFIG_DRM_MSM_DSI_20NM_PHY) += dsi/phy/dsi_phy_20nm.o
-msm-$(CONFIG_DRM_MSM_DSI_28NM_8960_PHY) += dsi/phy/dsi_phy_28nm_8960.o
-msm-$(CONFIG_DRM_MSM_DSI_14NM_PHY) += dsi/phy/dsi_phy_14nm.o
-msm-$(CONFIG_DRM_MSM_DSI_10NM_PHY) += dsi/phy/dsi_phy_10nm.o
-msm-$(CONFIG_DRM_MSM_DSI_7NM_PHY) += dsi/phy/dsi_phy_7nm.o
+$(obj)/dsi/dsi_host.o: $(obj)/registers/sfpb.xml.h
+
+msm-dsi-$(CONFIG_DRM_MSM_DSI_28NM_PHY) += dsi/phy/dsi_phy_28nm.o
+$(obj)/dsi/phy/dsi_phy_28nm.o: $(obj)/registers/dsi_phy_28nm.xml.h
+
+msm-dsi-$(CONFIG_DRM_MSM_DSI_20NM_PHY) += dsi/phy/dsi_phy_20nm.o
+$(obj)/dsi/phy/dsi_phy_20nm.o: $(obj)/registers/dsi_phy_20nm.xml.h
+
+msm-dsi-$(CONFIG_DRM_MSM_DSI_28NM_8960_PHY) += dsi/phy/dsi_phy_28nm_8960.o
+$(obj)/dsi/phy/dsi_phy_28nm_8960.o: $(obj)/registers/dsi_phy_28nm_8960.xml.h
+
+msm-dsi-$(CONFIG_DRM_MSM_DSI_14NM_PHY) += dsi/phy/dsi_phy_14nm.o
+$(obj)/dsi/phy/dsi_phy_14nm.o: $(obj)/registers/dsi_phy_14nm.xml.h
+
+msm-dsi-$(CONFIG_DRM_MSM_DSI_10NM_PHY) += dsi/phy/dsi_phy_10nm.o
+$(obj)/dsi/phy/dsi_phy_10nm.o: $(obj)/registers/dsi_phy_10nm.xml.h
+
+msm-dsi-$(CONFIG_DRM_MSM_DSI_7NM_PHY) += dsi/phy/dsi_phy_7nm.o
+$(obj)/dsi/phy/dsi_phy_7nm.o: $(obj)/registers/dsi_phy_7nm.xml.h
+
+msm-$(CONFIG_DRM_MSM_DSI) += $(msm-dsi) $(msm-dsi-y)
+$(addprefix $(obj)/,$(msm-dsi) $(msm-dsi-y)): $(o

[PATCH RFC 06/12] drm/msm/headergen: import source files from freedreno/envytools

2024-02-25 Thread Dmitry Baryshkov
Import headergen2 sources at the commit d88cafa3ac3e ("freedreno/decode:
try harder to not crash in disasm") from
https://gitlab.freedesktop.org/freedreno/envytools. This tool has been
used to generate drm/msm header files from the corresponding XML files.
This required committing changes to the Mesa3D project, then manually
generating and synchronizing resulting files. Instead import the hg2
tool to be later included into the build process.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/headergen2/aprintf.c  |   38 +
 drivers/gpu/drm/msm/headergen2/colors.c   |   61 ++
 drivers/gpu/drm/msm/headergen2/colors.h   |   49 +
 drivers/gpu/drm/msm/headergen2/headergen2.c   |  502 +
 drivers/gpu/drm/msm/headergen2/path.c |   64 ++
 drivers/gpu/drm/msm/headergen2/rnn.c  | 1360 +
 drivers/gpu/drm/msm/headergen2/rnn.h  |  243 +
 drivers/gpu/drm/msm/headergen2/rnndec.c   |  550 ++
 drivers/gpu/drm/msm/headergen2/rnndec.h   |   59 ++
 drivers/gpu/drm/msm/headergen2/util.h |  115 +++
 drivers/gpu/drm/msm/headergen2/util/u_debug.h |   12 +
 11 files changed, 3053 insertions(+)

diff --git a/drivers/gpu/drm/msm/headergen2/aprintf.c 
b/drivers/gpu/drm/msm/headergen2/aprintf.c
new file mode 100644
index ..b3d924f59413
--- /dev/null
+++ b/drivers/gpu/drm/msm/headergen2/aprintf.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2009-2011 Marcin Kościelnicki 
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "util.h"
+#include 
+
+char *aprintf(const char *format, ...) {
+   va_list va;
+   va_start(va, format);
+   size_t sz = vsnprintf(0, 0, format, va);
+   va_end(va);
+   char *res = malloc(sz + 1);
+   va_start(va, format);
+   vsnprintf(res, sz + 1, format, va);
+   va_end(va);
+   return res;
+}
diff --git a/drivers/gpu/drm/msm/headergen2/colors.c 
b/drivers/gpu/drm/msm/headergen2/colors.c
new file mode 100644
index ..192c57dd18bb
--- /dev/null
+++ b/drivers/gpu/drm/msm/headergen2/colors.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2012 Marcin Kościelnicki 
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "colors.h"
+
+const struct envy_colors envy_null_colors = {
+   .reset  = "",
+   .iname  = "",
+   .rname  = "",
+   .mod= "",
+   .sym= "",
+   .reg= "",
+   .regsp  = "",
+   .num= "",
+   .mem= "",
+   .btarg  = "",
+   .ctarg  = "",
+   .bctarg = "",
+   .eval   = "",
+   .comm   = "",
+   .err= "",
+};
+
+const struct envy_colors envy_def_colors = {
+   .reset  = "\x1b[0m",
+   .iname  = "\x1b[0;32m",
+   .rname  = "\x1b[0;32m",
+   .mod= "\x1b[0;36m",
+  

[PATCH RFC 03/12] drm/msm/hdmi: drop qfprom.xml.h

2024-02-25 Thread Dmitry Baryshkov
The qfprom.xml.h contains definitions for the nvmem code. They are not
used in the existing code. Also if we were to use them later, we should
have used nvmem cell API instead of using these defs. Drop the file.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/hdmi/qfprom.xml.h | 61 ---
 1 file changed, 61 deletions(-)

diff --git a/drivers/gpu/drm/msm/hdmi/qfprom.xml.h 
b/drivers/gpu/drm/msm/hdmi/qfprom.xml.h
deleted file mode 100644
index 498801526695..
--- a/drivers/gpu/drm/msm/hdmi/qfprom.xml.h
+++ /dev/null
@@ -1,61 +0,0 @@
-#ifndef QFPROM_XML
-#define QFPROM_XML
-
-/* Autogenerated file, DO NOT EDIT manually!
-
-This file was generated by the rules-ng-ng headergen tool in this git 
repository:
-http://github.com/freedreno/envytools/
-git clone https://github.com/freedreno/envytools.git
-
-The rules-ng-ng source files this header was generated from are:
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/msm.xml 
  (944 bytes, from 2022-07-23 20:21:46)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml 
  (   1572 bytes, from 2022-07-23 20:21:46)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp4.xml
  (  20912 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp_common.xml  
  (   2849 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp5.xml
  (  37461 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi.xml 
  (  18746 bytes, from 2022-04-28 17:29:36)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml  
  (   3236 bytes, from 2022-03-08 17:40:42)
-- 
/home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml 
(   4935 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml
  (   7004 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml
  (   3712 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml
  (   5381 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml
  (   4499 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml 
  (  11007 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/sfpb.xml
  (602 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/mmss_cc.xml 
  (   1686 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/qfprom.xml 
  (600 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/hdmi.xml   
  (  42350 bytes, from 2022-09-20 17:45:56)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/edp/edp.xml 
  (  10416 bytes, from 2022-03-08 17:40:42)
-
-Copyright (C) 2013-2022 by the following authors:
-- Rob Clark  (robclark)
-- Ilia Mirkin  (imirkin)
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial
-portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-
-#define REG_QFPROM_CONFIG_ROW0_LSB 0x0238
-#define QFPROM_CONFIG_ROW0_LSB_HDMI_DISABLE0x0020
-#define QFPROM_CONFIG_ROW0_LSB_HDCP_DISABLE0x0040
-
-
-#endif /* QFPROM_XML */

-- 
2.39.2



[PATCH RFC 04/12] drm/msm/dsi: drop mmss_cc.xml.h

2024-02-25 Thread Dmitry Baryshkov
The mmss_cc.xml.h file describes bits of the MMSS clock controller on
APQ8064 / MSM8960 platforms. They are not used by the driver and do not
belong to the DRM MSM driver. Drop the file.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/dsi/mmss_cc.xml.h | 131 --
 1 file changed, 131 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h 
b/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h
deleted file mode 100644
index 7062f7164216..
--- a/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h
+++ /dev/null
@@ -1,131 +0,0 @@
-#ifndef MMSS_CC_XML
-#define MMSS_CC_XML
-
-/* Autogenerated file, DO NOT EDIT manually!
-
-This file was generated by the rules-ng-ng headergen tool in this git 
repository:
-http://github.com/freedreno/envytools/
-git clone https://github.com/freedreno/envytools.git
-
-The rules-ng-ng source files this header was generated from are:
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/msm.xml 
  (944 bytes, from 2022-07-23 20:21:46)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml 
  (   1572 bytes, from 2022-07-23 20:21:46)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp4.xml
  (  20912 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp_common.xml  
  (   2849 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp5.xml
  (  37461 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi.xml 
  (  18746 bytes, from 2022-04-28 17:29:36)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml  
  (   3236 bytes, from 2022-03-08 17:40:42)
-- 
/home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml 
(   4935 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml
  (   7004 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml
  (   3712 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml
  (   5381 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml
  (   4499 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml 
  (  11007 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/sfpb.xml
  (602 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/mmss_cc.xml 
  (   1686 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/qfprom.xml 
  (600 bytes, from 2022-03-08 17:40:42)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/hdmi.xml   
  (  42350 bytes, from 2022-09-20 17:45:56)
-- /home/robclark/src/mesa/mesa/src/freedreno/registers/edp/edp.xml 
  (  10416 bytes, from 2022-03-08 17:40:42)
-
-Copyright (C) 2013-2022 by the following authors:
-- Rob Clark  (robclark)
-- Ilia Mirkin  (imirkin)
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial
-portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-
-enum mmss_cc_clk {
-   CLK = 0,
-   PCLK = 1,
-};
-
-#define REG_MMSS_CC_AHB
0x0008
-
-static inline uint32_t __offset_CLK(enum mmss_cc_clk idx)
-{
-   switch (idx) {
-   case CLK: return 0x004c;
-   case PCLK: return 0x0130;
-   default: return INVALID_IDX(idx);
-   }
-}
-static inline uint32_t REG_MMSS_CC_CLK(enum mmss_cc_clk i0) { return 
0x + __offset_CLK(i0); }
-
-static inline uint32_t REG_MMSS_CC_CLK_CC(enum mmss_cc_clk i0) { return 
0x + __offset_CLK(i0); }
-#define MMSS_CC_CLK_CC_CLK_EN 

[PATCH RFC 00/12] drm/msm: add support for regenerating shipped xml.h headers

2024-02-25 Thread Dmitry Baryshkov
Currently display-related register headers are generated from XML files
shipped withing Mesa source tree. This is not fully optimal: it requires
multi-stage process of the changes first being landed to Mesa and only
then synced to the kernel tree.

Move original XML files to the kernel tree and generate header files if
required.

Signed-off-by: Dmitry Baryshkov 
---
Dmitry Baryshkov (12):
  kbuild: create destination directory for _shipped handling
  drm/msm/mdp5: add writeback block bases
  drm/msm/hdmi: drop qfprom.xml.h
  drm/msm/dsi: drop mmss_cc.xml.h
  drm/msm: use _shipped suffix for all xml.h files
  drm/msm/headergen: import source files from freedreno/envytools
  drm/msm/headergen: use asprintf instead of custom aprintf
  drm/msm/headergen: don't output full file paths
  drm/msm/headergen: generate _shipped files
  drm/msm: import XML registers database
  drm/msm: tie regeneration of shipped headers
  drm/msm: sync shipped headers database

 drivers/gpu/drm/msm/Makefile   |   80 +-
 drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.h   |   11 +
 drivers/gpu/drm/msm/disp/mdp_common.xml.h  |  111 --
 drivers/gpu/drm/msm/dsi/mmss_cc.xml.h  |  131 --
 drivers/gpu/drm/msm/dsi/sfpb.xml.h |   70 -
 drivers/gpu/drm/msm/hdmi/qfprom.xml.h  |   61 -
 drivers/gpu/drm/msm/headergen2/colors.c|   61 +
 drivers/gpu/drm/msm/headergen2/colors.h|   49 +
 drivers/gpu/drm/msm/headergen2/headergen2.c|  514 
 drivers/gpu/drm/msm/headergen2/path.c  |   64 +
 drivers/gpu/drm/msm/headergen2/rnn.c   | 1363 
 drivers/gpu/drm/msm/headergen2/rnn.h   |  243 
 drivers/gpu/drm/msm/headergen2/rnndec.c|  550 
 drivers/gpu/drm/msm/headergen2/rnndec.h|   59 +
 drivers/gpu/drm/msm/headergen2/util.h  |  113 ++
 drivers/gpu/drm/msm/headergen2/util/u_debug.h  |   12 +
 drivers/gpu/drm/msm/registers/.gitignore   |5 +
 .../{dsi/dsi.xml.h => registers/dsi.xml.h_shipped} |   38 +-
 .../dsi_phy_10nm.xml.h_shipped}|   37 +-
 .../dsi_phy_14nm.xml.h_shipped}|   37 +-
 .../dsi_phy_20nm.xml.h_shipped}|   37 +-
 .../dsi_phy_28nm.xml.h_shipped}|   37 +-
 .../dsi_phy_28nm_8960.xml.h_shipped}   |   37 +-
 .../dsi_phy_7nm.xml.h_shipped} |   37 +-
 .../hdmi.xml.h => registers/hdmi.xml.h_shipped}|  111 +-
 .../mdp4.xml.h => registers/mdp4.xml.h_shipped}|   37 +-
 .../mdp5.xml.h => registers/mdp5.xml.h_shipped}|   39 +-
 .../gpu/drm/msm/registers/mdp_common.xml.h_shipped |  114 ++
 drivers/gpu/drm/msm/registers/sfpb.xml.h_shipped   |   67 +
 drivers/gpu/drm/msm/registers/xml/dsi.xml  |  390 ++
 drivers/gpu/drm/msm/registers/xml/dsi_phy_10nm.xml |  102 ++
 drivers/gpu/drm/msm/registers/xml/dsi_phy_14nm.xml |  135 ++
 drivers/gpu/drm/msm/registers/xml/dsi_phy_20nm.xml |  100 ++
 drivers/gpu/drm/msm/registers/xml/dsi_phy_28nm.xml |  180 +++
 .../drm/msm/registers/xml/dsi_phy_28nm_8960.xml|  134 ++
 drivers/gpu/drm/msm/registers/xml/dsi_phy_7nm.xml  |  230 
 drivers/gpu/drm/msm/registers/xml/edp.xml  |  239 
 .../drm/msm/registers/xml/freedreno_copyright.xml  |   40 +
 drivers/gpu/drm/msm/registers/xml/hdmi.xml | 1015 +++
 drivers/gpu/drm/msm/registers/xml/mdp4.xml |  480 +++
 drivers/gpu/drm/msm/registers/xml/mdp5.xml |  806 
 drivers/gpu/drm/msm/registers/xml/mdp_common.xml   |   89 ++
 drivers/gpu/drm/msm/registers/xml/mmss_cc.xml  |   48 +
 drivers/gpu/drm/msm/registers/xml/msm.xml  |   32 +
 drivers/gpu/drm/msm/registers/xml/rules-ng.xsd |  457 +++
 drivers/gpu/drm/msm/registers/xml/sfpb.xml |   17 +
 scripts/Makefile.lib   |2 +-
 47 files changed, 8034 insertions(+), 587 deletions(-)
---
base-commit: ffa0c87f172bf7a0132aa960db412f8d63b2f533
change-id: 20240225-fd-xml-shipped-ba9a321cdedf

Best regards,
-- 
Dmitry Baryshkov 



[PATCH RFC 01/12] kbuild: create destination directory for _shipped handling

2024-02-25 Thread Dmitry Baryshkov
The driver might decide to put the _shipped files to the subdir. In such
case the cmd_copy might fail because the destination directory is not
present. Call mkdir -p to make sure that the destination directory is
present.

Signed-off-by: Dmitry Baryshkov 
---
 scripts/Makefile.lib | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index cd5b181060f1..94373eeac420 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -297,7 +297,7 @@ endef
 # the copy would be read-only as well, leading to an error when executing the
 # rule next time. Use 'cat' instead in order to generate a writable file.
 quiet_cmd_copy = COPY$@
-  cmd_copy = cat $< > $@
+  cmd_copy = mkdir -p $(shell dirname $@) && cat $< > $@
 
 $(obj)/%: $(src)/%_shipped
$(call cmd,copy)

-- 
2.39.2



Re: [PATCH v3 3/3] drm/msm/dpu: capture snapshot on the first commit_done timeout

2024-02-25 Thread Abhinav Kumar




On 2/25/2024 11:57 AM, Abhinav Kumar wrote:



On 2/25/2024 6:12 AM, Dmitry Baryshkov wrote:

In order to debug commit_done timeouts, capture the devcoredump state
when the first timeout occurs after the encoder has been enabled.

Signed-off-by: Dmitry Baryshkov 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 9 +
  1 file changed, 9 insertions(+)



This looks fine now. Once we discuss patch 2, I can ack this.



Not entirely onboard with patch 2, but lets see how that code evolves

Reviewed-by: Abhinav Kumar 

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c

index 30f349c8a1e5..3cae07bf0b9b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -126,6 +126,8 @@ enum dpu_enc_rc_states {
   * @base:    drm_encoder base class for registration with DRM
   * @enc_spinlock:    Virtual-Encoder-Wide Spin Lock for IRQ purposes
   * @enabled:    True if the encoder is active, protected by 
enc_lock
+ * @commit_done_timedout: True if there has been a timeout on commit 
after

+ *    enabling the encoder.
   * @num_phys_encs:    Actual number of physical encoders contained.
   * @phys_encs:    Container of physical encoders managed.
   * @cur_master:    Pointer to the current master in this mode. 
Optimization

@@ -172,6 +174,7 @@ struct dpu_encoder_virt {
  spinlock_t enc_spinlock;
  bool enabled;
+    bool commit_done_timedout;
  unsigned int num_phys_encs;
  struct dpu_encoder_phys *phys_encs[MAX_PHYS_ENCODERS_PER_VIRTUAL];
@@ -1226,6 +1229,8 @@ static void 
dpu_encoder_virt_atomic_enable(struct drm_encoder *drm_enc,

  else if (disp_info->intf_type == INTF_DSI)
  dpu_enc->wide_bus_en = 
msm_dsi_wide_bus_enabled(priv->dsi[index]);

+    dpu_enc->commit_done_timedout = false;
+
  mutex_lock(&dpu_enc->enc_lock);
  cur_mode = &dpu_enc->base.crtc->state->adjusted_mode;
@@ -2436,6 +2441,10 @@ int dpu_encoder_wait_for_commit_done(struct 
drm_encoder *drm_enc)

  DPU_ATRACE_BEGIN("wait_for_commit_done");
  ret = phys->ops.wait_for_commit_done(phys);
  DPU_ATRACE_END("wait_for_commit_done");
+    if (ret == -ETIMEDOUT && !dpu_enc->commit_done_timedout) {
+    dpu_enc->commit_done_timedout = true;
+    msm_disp_snapshot_state(drm_enc->dev);
+    }
  if (ret)
  return ret;
  }



Re: [PATCH v3 2/3] drm/msm/dpu: split dpu_encoder_wait_for_event into two functions

2024-02-25 Thread Abhinav Kumar




On 2/25/2024 12:52 PM, Dmitry Baryshkov wrote:

On Sun, 25 Feb 2024 at 21:49, Abhinav Kumar  wrote:




On 2/25/2024 6:12 AM, Dmitry Baryshkov wrote:

Stop multiplexing several events via the dpu_encoder_wait_for_event()
function. Split it into two distinct functions two allow separate
handling of those events.



I understand the idea but would handling of those events be really distinct?


We are interested in capturing the state after the first
wait_for_commit_done() timeout. The wait_for_tx_complete doesn't need
such handling. Even if we were to handle it in some way, it would be a
different conditional.



wait_for_tx_complete timeout also needs similar handling.

the timeout mechanisms need to be unified at some point, that time I 
will re-visit the need to have a common wait_timeout handler.


Lets see how this code evolves.

So with that nit about the kernel doc addressed,

Reviewed-by: Abhinav Kumar 


Last but not least, I don't like multiplexing just for the sake of it.
There is nearly no common behaviour.



the multiplexing allows us to have one common timeout path which I think 
will eventually happen. So i dont think its true that there is no common 
behavior.




Like if wait_for_commit_done timedout or wait_for_tx_complete timedout,
the handling will be similar from my PoV.


Signed-off-by: Dmitry Baryshkov 
---
   drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 74 
+
   drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 22 ++---
   drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c |  2 +-
   drivers/gpu/drm/msm/msm_drv.h   | 10 
   4 files changed, 59 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 194dbb08331d..30f349c8a1e5 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1282,7 +1282,7 @@ static void dpu_encoder_virt_atomic_disable(struct 
drm_encoder *drm_enc,
   trace_dpu_enc_disable(DRMID(drm_enc));

   /* wait for idle */
- dpu_encoder_wait_for_event(drm_enc, MSM_ENC_TX_COMPLETE);
+ dpu_encoder_wait_for_tx_complete(drm_enc);

   dpu_encoder_resource_control(drm_enc, DPU_ENC_RC_EVENT_PRE_STOP);

@@ -2402,10 +2402,23 @@ struct drm_encoder *dpu_encoder_init(struct drm_device 
*dev,
   return &dpu_enc->base;
   }

-int dpu_encoder_wait_for_event(struct drm_encoder *drm_enc,
- enum msm_event_wait event)
+/**
+ * dpu_encoder_wait_for_commit_done() - Wait for encoder to flush pending state
+ * @drm_enc: encoder pointer
+ *
+ * Wait for hardware to have flushed the current pending frames to hardware at
+ * a vblank or ctl_start Encoders will map this differently depending on the
+ * panel type.
+ *


Missing a '.' between ctl_start and Encoder?


Ack. Also I should drop the leftovers afterwards.




+ * MSM_ENC_TX_COMPLETE -  Wait for the hardware to transfer all the pixels to
+ *the panel. Encoders will map this differently
+ *depending on the panel type.
+ *vid mode -> vsync_irq
+ *cmd mode -> pp_done
+ * Return: 0 on success, -EWOULDBLOCK if already signaled, error otherwise
+ */
+int dpu_encoder_wait_for_commit_done(struct drm_encoder *drm_enc)
   {
- int (*fn_wait)(struct dpu_encoder_phys *phys_enc) = NULL;
   struct dpu_encoder_virt *dpu_enc = NULL;
   int i, ret = 0;

@@ -2419,23 +2432,46 @@ int dpu_encoder_wait_for_event(struct drm_encoder 
*drm_enc,
   for (i = 0; i < dpu_enc->num_phys_encs; i++) {
   struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];

- switch (event) {
- case MSM_ENC_COMMIT_DONE:
- fn_wait = phys->ops.wait_for_commit_done;
- break;
- case MSM_ENC_TX_COMPLETE:
- fn_wait = phys->ops.wait_for_tx_complete;
- break;
- default:
- DPU_ERROR_ENC(dpu_enc, "unknown wait event %d\n",
- event);
- return -EINVAL;
+ if (phys->ops.wait_for_commit_done) {
+ DPU_ATRACE_BEGIN("wait_for_commit_done");
+ ret = phys->ops.wait_for_commit_done(phys);
+ DPU_ATRACE_END("wait_for_commit_done");
+ if (ret)
+ return ret;
   }
+ }
+
+ return ret;
+}
+
+/**
+ * dpu_encoder_wait_for_tx_complete() - Wait for encoder to transfer pixels to 
panel
+ * @drm_enc: encoder pointer
+ *
+ * Wait for the hardware to transfer all the pixels to the panel. Encoders will
+ * map this differently depending on the panel type.
+ *
+ * Return: 0 on success, -EWOULDBLOCK if already signaled, error otherwise
+ */
+int dpu_encoder_wait_for_tx_complete(struct drm_encoder *drm_enc)
+{
+ struct dpu_encoder_virt *dpu_enc = NULL;
+   

Re: [PATCH next v2 08/11] minmax: Add min_const() and max_const()

2024-02-25 Thread Dave Airlie
On Mon, 26 Feb 2024 at 07:26, David Laight  wrote:
>
> ...
> > Yes, yes, that may end up requiring getting rid of some current users of
> >
> >   #define MIN(a,b) ((a)<(b) ? (a):(b))
> >
> > but dammit, we don't actually have _that_ many of them, and why should
> > we have random drivers doing that anyway?
>
> They look like they could be changed to min().
> It is even likely the header gets pulled in somewhere.
>
> I'm not sure about the ones in drivers/gpu/drm/amd/display/*..*/*.c, but it
> wouldn't surprise me if that code doesn't use any standard kernel headers.
> Isn't that also the code that manages to pass 42 integer parameters
> to functions?

They are all separate in C files, I think we could get rid of them
pretty easily in favour of the standard ones,

Adding Harry to cc.

Dave.


Re: linux-next: build failure after merge of the drm-misc tree

2024-02-25 Thread Stephen Rothwell
Hi all,

On Mon, 26 Feb 2024 08:41:16 +1100 Stephen Rothwell  
wrote:
> 
> On Tue, 20 Feb 2024 08:48:21 +1100 Stephen Rothwell  
> wrote:
> > 
> > On Mon, 12 Feb 2024 15:15:54 +0200 Jani Nikula 
> >  wrote:  
> > >
> > > On Tue, 06 Feb 2024, Stephen Rothwell  wrote:
> > > >
> > > > After merging the drm-misc tree, today's linux-next build (i386 
> > > > defconfig)
> > > > failed like this:
> > > >
> > > > In function 'i915_ttm_placement_from_obj',
> > > > inlined from 'i915_ttm_get_pages' at 
> > > > drivers/gpu/drm/i915/gem/i915_gem_ttm.c:847:2:
> > > > drivers/gpu/drm/i915/gem/i915_gem_ttm.c:165:18: error: 
> > > > 'places[0].flags' is used uninitialized [-Werror=uninitialized]
> > > >   165 | places[0].flags |= TTM_PL_FLAG_DESIRED;
> > > >   | ~^~
> > > > drivers/gpu/drm/i915/gem/i915_gem_ttm.c: In function 
> > > > 'i915_ttm_get_pages':
> > > > drivers/gpu/drm/i915/gem/i915_gem_ttm.c:837:26: note: 'places' declared 
> > > > here
> > > >   837 | struct ttm_place places[I915_TTM_MAX_PLACEMENTS + 1];
> > > >   |  ^~
> > > >
> > > > Caused by commit
> > > >
> > > >   a78a8da51b36 ("drm/ttm: replace busy placement with flags v6")  
> > > 
> > > Cc: more people.
> > > 
> > > >
> > > > I applied the following hack for today:
> > > >
> > > > From: Stephen Rothwell 
> > > > Date: Tue, 6 Feb 2024 15:17:54 +1100
> > > > Subject: [PATCH] drm/ttm: initialise places
> > > >
> > > > Signed-off-by: Stephen Rothwell 
> > > > ---
> > > >  drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 2 +-
> > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c 
> > > > b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> > > > index 80c6cafc8887..34e699e67c25 100644
> > > > --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> > > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> > > > @@ -834,7 +834,7 @@ static int __i915_ttm_get_pages(struct 
> > > > drm_i915_gem_object *obj,
> > > >  
> > > >  static int i915_ttm_get_pages(struct drm_i915_gem_object *obj)
> > > >  {
> > > > -   struct ttm_place places[I915_TTM_MAX_PLACEMENTS + 1];
> > > > +   struct ttm_place places[I915_TTM_MAX_PLACEMENTS + 1] = {};
> > > > struct ttm_placement placement;
> > > >  
> > > > /* restricted by sg_alloc_table */
> > > > -- 
> > > > 2.43.0  
> > 
> > I am still applying the above patch ...  
> 
> Any progress?

And this commit is now in the drm tree.
-- 
Cheers,
Stephen Rothwell


pgpydYZSdnc_h.pgp
Description: OpenPGP digital signature


Re: linux-next: build failure after merge of the drm-misc tree

2024-02-25 Thread Stephen Rothwell
Hi all,

On Tue, 20 Feb 2024 08:48:21 +1100 Stephen Rothwell  
wrote:
> 
> On Mon, 12 Feb 2024 15:15:54 +0200 Jani Nikula  
> wrote:
> >
> > On Tue, 06 Feb 2024, Stephen Rothwell  wrote:  
> > >
> > > After merging the drm-misc tree, today's linux-next build (i386 defconfig)
> > > failed like this:
> > >
> > > In function 'i915_ttm_placement_from_obj',
> > > inlined from 'i915_ttm_get_pages' at 
> > > drivers/gpu/drm/i915/gem/i915_gem_ttm.c:847:2:
> > > drivers/gpu/drm/i915/gem/i915_gem_ttm.c:165:18: error: 'places[0].flags' 
> > > is used uninitialized [-Werror=uninitialized]
> > >   165 | places[0].flags |= TTM_PL_FLAG_DESIRED;
> > >   | ~^~
> > > drivers/gpu/drm/i915/gem/i915_gem_ttm.c: In function 'i915_ttm_get_pages':
> > > drivers/gpu/drm/i915/gem/i915_gem_ttm.c:837:26: note: 'places' declared 
> > > here
> > >   837 | struct ttm_place places[I915_TTM_MAX_PLACEMENTS + 1];
> > >   |  ^~
> > >
> > > Caused by commit
> > >
> > >   a78a8da51b36 ("drm/ttm: replace busy placement with flags v6")
> > 
> > Cc: more people.
> >   
> > >
> > > I applied the following hack for today:
> > >
> > > From: Stephen Rothwell 
> > > Date: Tue, 6 Feb 2024 15:17:54 +1100
> > > Subject: [PATCH] drm/ttm: initialise places
> > >
> > > Signed-off-by: Stephen Rothwell 
> > > ---
> > >  drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c 
> > > b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> > > index 80c6cafc8887..34e699e67c25 100644
> > > --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> > > @@ -834,7 +834,7 @@ static int __i915_ttm_get_pages(struct 
> > > drm_i915_gem_object *obj,
> > >  
> > >  static int i915_ttm_get_pages(struct drm_i915_gem_object *obj)
> > >  {
> > > - struct ttm_place places[I915_TTM_MAX_PLACEMENTS + 1];
> > > + struct ttm_place places[I915_TTM_MAX_PLACEMENTS + 1] = {};
> > >   struct ttm_placement placement;
> > >  
> > >   /* restricted by sg_alloc_table */
> > > -- 
> > > 2.43.0
> 
> I am still applying the above patch ...

Any progress?

-- 
Cheers,
Stephen Rothwell


pgpCHGv9EFzpd.pgp
Description: OpenPGP digital signature


RE: [PATCH next v2 08/11] minmax: Add min_const() and max_const()

2024-02-25 Thread David Laight
...
> Yes, yes, that may end up requiring getting rid of some current users of
> 
>   #define MIN(a,b) ((a)<(b) ? (a):(b))
> 
> but dammit, we don't actually have _that_ many of them, and why should
> we have random drivers doing that anyway?

They look like they could be changed to min().
It is even likely the header gets pulled in somewhere.

I'm not sure about the ones in drivers/gpu/drm/amd/display/*..*/*.c, but it
wouldn't surprise me if that code doesn't use any standard kernel headers.
Isn't that also the code that manages to pass 42 integer parameters
to functions?

David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, 
UK
Registration No: 1397386 (Wales)


RE: [PATCH next v2 08/11] minmax: Add min_const() and max_const()

2024-02-25 Thread David Laight
From: Linus Torvalds
> Sent: 25 February 2024 17:14
> 
> On Sun, 25 Feb 2024 at 08:53, David Laight  wrote:
> >
> > The expansions of min() and max() contain statement expressions so are
> > not valid for static intialisers.
> > min_const() and max_const() are expressions so can be used for static
> > initialisers.
> 
> I hate the name.

Picking name is always hard...

> Naming shouldn't be about an implementation detail, particularly not
> an esoteric one like the "C constant expression" rule. That can be
> useful for some internal helper functions or macros, but not for
> something that random people are supposed to USE.
> 
> Telling some random developer that inside an array size declaration or
> a static initializer you need to use "max_const()" because it needs to
> syntactically be a constant expression, and our regular "max()"
> function isn't that, is just *horrid*.
> 
> No, please just use the traditional C model of just using ALL CAPS for
> macro names that don't act like a function.
> 
> Yes, yes, that may end up requiring getting rid of some current users of
> 
>   #define MIN(a,b) ((a)<(b) ? (a):(b))
> 
> but dammit, we don't actually have _that_ many of them, and why should
> we have random drivers doing that anyway?

I'll have a look at what is there.
It might take a three part patch though.
Unless you apply it as a tree-wide patch?

One option is to add as max_const(), then change any existing MAX()
to be max() or max_const() and then finally rename to MAX()?

David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, 
UK
Registration No: 1397386 (Wales)


Re: [PATCH v3 1/3] drm/msm/dpu: make "vblank timeout" more useful

2024-02-25 Thread Abhinav Kumar




On 2/25/2024 12:57 PM, Dmitry Baryshkov wrote:

On Sun, 25 Feb 2024 at 21:44, Abhinav Kumar  wrote:




On 2/25/2024 6:12 AM, Dmitry Baryshkov wrote:

We have several reports of vblank timeout messages. However after some
debugging it was found that there might be different causes to that.
To allow us to identify the DPU block that gets stuck, include the
actual CTL_FLUSH value into the timeout message.



the flush register shall also be part of the coredump in patch 3. so why
is this needed?


I'd prefer to keep it. The devcoredump captures all registers, while
CTL_FLUSH points to the actual bit without the need to analyze the
coredump. At the very least, it allows us to analyze whether the issue
is the same or not (compare SSPP_DMA2 on c630 vs LM_1 on sdm660)
without looking into the dump.



Ok, sg


Reviewed-by: Abhinav Kumar 




Signed-off-by: Dmitry Baryshkov 
---
   drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 2 +-
   1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
index 2aa72b578764..6058706f03e4 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
@@ -480,7 +480,7 @@ static int dpu_encoder_phys_vid_wait_for_commit_done(
   (hw_ctl->ops.get_flush_register(hw_ctl) == 0),
   msecs_to_jiffies(50));
   if (ret <= 0) {
- DPU_ERROR("vblank timeout\n");
+ DPU_ERROR("vblank timeout: %x\n", 
hw_ctl->ops.get_flush_register(hw_ctl));
   return -ETIMEDOUT;
   }








Re: [PATCH v3 1/3] drm/msm/dpu: make "vblank timeout" more useful

2024-02-25 Thread Dmitry Baryshkov
On Sun, 25 Feb 2024 at 21:44, Abhinav Kumar  wrote:
>
>
>
> On 2/25/2024 6:12 AM, Dmitry Baryshkov wrote:
> > We have several reports of vblank timeout messages. However after some
> > debugging it was found that there might be different causes to that.
> > To allow us to identify the DPU block that gets stuck, include the
> > actual CTL_FLUSH value into the timeout message.
> >
>
> the flush register shall also be part of the coredump in patch 3. so why
> is this needed?

I'd prefer to keep it. The devcoredump captures all registers, while
CTL_FLUSH points to the actual bit without the need to analyze the
coredump. At the very least, it allows us to analyze whether the issue
is the same or not (compare SSPP_DMA2 on c630 vs LM_1 on sdm660)
without looking into the dump.

>
> > Signed-off-by: Dmitry Baryshkov 
> > ---
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 2 +-
> >   1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c 
> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
> > index 2aa72b578764..6058706f03e4 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
> > @@ -480,7 +480,7 @@ static int dpu_encoder_phys_vid_wait_for_commit_done(
> >   (hw_ctl->ops.get_flush_register(hw_ctl) == 0),
> >   msecs_to_jiffies(50));
> >   if (ret <= 0) {
> > - DPU_ERROR("vblank timeout\n");
> > + DPU_ERROR("vblank timeout: %x\n", 
> > hw_ctl->ops.get_flush_register(hw_ctl));
> >   return -ETIMEDOUT;
> >   }
> >
> >



-- 
With best wishes
Dmitry


Re: [PATCH v3 2/3] drm/msm/dpu: split dpu_encoder_wait_for_event into two functions

2024-02-25 Thread Dmitry Baryshkov
On Sun, 25 Feb 2024 at 21:49, Abhinav Kumar  wrote:
>
>
>
> On 2/25/2024 6:12 AM, Dmitry Baryshkov wrote:
> > Stop multiplexing several events via the dpu_encoder_wait_for_event()
> > function. Split it into two distinct functions two allow separate
> > handling of those events.
> >
>
> I understand the idea but would handling of those events be really distinct?

We are interested in capturing the state after the first
wait_for_commit_done() timeout. The wait_for_tx_complete doesn't need
such handling. Even if we were to handle it in some way, it would be a
different conditional.

Last but not least, I don't like multiplexing just for the sake of it.
There is nearly no common behaviour.

>
> Like if wait_for_commit_done timedout or wait_for_tx_complete timedout,
> the handling will be similar from my PoV.
>
> > Signed-off-by: Dmitry Baryshkov 
> > ---
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 74 
> > +
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 22 ++---
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c |  2 +-
> >   drivers/gpu/drm/msm/msm_drv.h   | 10 
> >   4 files changed, 59 insertions(+), 49 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > index 194dbb08331d..30f349c8a1e5 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > @@ -1282,7 +1282,7 @@ static void dpu_encoder_virt_atomic_disable(struct 
> > drm_encoder *drm_enc,
> >   trace_dpu_enc_disable(DRMID(drm_enc));
> >
> >   /* wait for idle */
> > - dpu_encoder_wait_for_event(drm_enc, MSM_ENC_TX_COMPLETE);
> > + dpu_encoder_wait_for_tx_complete(drm_enc);
> >
> >   dpu_encoder_resource_control(drm_enc, DPU_ENC_RC_EVENT_PRE_STOP);
> >
> > @@ -2402,10 +2402,23 @@ struct drm_encoder *dpu_encoder_init(struct 
> > drm_device *dev,
> >   return &dpu_enc->base;
> >   }
> >
> > -int dpu_encoder_wait_for_event(struct drm_encoder *drm_enc,
> > - enum msm_event_wait event)
> > +/**
> > + * dpu_encoder_wait_for_commit_done() - Wait for encoder to flush pending 
> > state
> > + * @drm_enc: encoder pointer
> > + *
> > + * Wait for hardware to have flushed the current pending frames to 
> > hardware at
> > + * a vblank or ctl_start Encoders will map this differently depending on 
> > the
> > + * panel type.
> > + *
>
> Missing a '.' between ctl_start and Encoder?

Ack. Also I should drop the leftovers afterwards.

>
> > + * MSM_ENC_TX_COMPLETE -  Wait for the hardware to transfer all the pixels 
> > to
> > + *the panel. Encoders will map this differently
> > + *depending on the panel type.
> > + *vid mode -> vsync_irq
> > + *cmd mode -> pp_done
> > + * Return: 0 on success, -EWOULDBLOCK if already signaled, error otherwise
> > + */
> > +int dpu_encoder_wait_for_commit_done(struct drm_encoder *drm_enc)
> >   {
> > - int (*fn_wait)(struct dpu_encoder_phys *phys_enc) = NULL;
> >   struct dpu_encoder_virt *dpu_enc = NULL;
> >   int i, ret = 0;
> >
> > @@ -2419,23 +2432,46 @@ int dpu_encoder_wait_for_event(struct drm_encoder 
> > *drm_enc,
> >   for (i = 0; i < dpu_enc->num_phys_encs; i++) {
> >   struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
> >
> > - switch (event) {
> > - case MSM_ENC_COMMIT_DONE:
> > - fn_wait = phys->ops.wait_for_commit_done;
> > - break;
> > - case MSM_ENC_TX_COMPLETE:
> > - fn_wait = phys->ops.wait_for_tx_complete;
> > - break;
> > - default:
> > - DPU_ERROR_ENC(dpu_enc, "unknown wait event %d\n",
> > - event);
> > - return -EINVAL;
> > + if (phys->ops.wait_for_commit_done) {
> > + DPU_ATRACE_BEGIN("wait_for_commit_done");
> > + ret = phys->ops.wait_for_commit_done(phys);
> > + DPU_ATRACE_END("wait_for_commit_done");
> > + if (ret)
> > + return ret;
> >   }
> > + }
> > +
> > + return ret;
> > +}
> > +
> > +/**
> > + * dpu_encoder_wait_for_tx_complete() - Wait for encoder to transfer 
> > pixels to panel
> > + * @drm_enc: encoder pointer
> > + *
> > + * Wait for the hardware to transfer all the pixels to the panel. Encoders 
> > will
> > + * map this differently depending on the panel type.
> > + *
> > + * Return: 0 on success, -EWOULDBLOCK if already signaled, error otherwise
> > + */
> > +int dpu_encoder_wait_for_tx_complete(struct drm_encoder *drm_enc)
> > +{
> > + struct dpu_encoder_virt *dpu_enc = NULL;
> > + int i, ret = 0;
> > +
> > + if (!drm_enc) {
> > + DPU_ERROR("invalid encoder\n");
> > + ret

Re: [PATCH v3 3/3] drm/msm/dpu: capture snapshot on the first commit_done timeout

2024-02-25 Thread Abhinav Kumar




On 2/25/2024 6:12 AM, Dmitry Baryshkov wrote:

In order to debug commit_done timeouts, capture the devcoredump state
when the first timeout occurs after the encoder has been enabled.

Signed-off-by: Dmitry Baryshkov 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 9 +
  1 file changed, 9 insertions(+)



This looks fine now. Once we discuss patch 2, I can ack this.


diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 30f349c8a1e5..3cae07bf0b9b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -126,6 +126,8 @@ enum dpu_enc_rc_states {
   * @base: drm_encoder base class for registration with DRM
   * @enc_spinlock: Virtual-Encoder-Wide Spin Lock for IRQ purposes
   * @enabled:  True if the encoder is active, protected by enc_lock
+ * @commit_done_timedout: True if there has been a timeout on commit after
+ * enabling the encoder.
   * @num_phys_encs:Actual number of physical encoders contained.
   * @phys_encs:Container of physical encoders managed.
   * @cur_master:   Pointer to the current master in this mode. 
Optimization
@@ -172,6 +174,7 @@ struct dpu_encoder_virt {
spinlock_t enc_spinlock;
  
  	bool enabled;

+   bool commit_done_timedout;
  
  	unsigned int num_phys_encs;

struct dpu_encoder_phys *phys_encs[MAX_PHYS_ENCODERS_PER_VIRTUAL];
@@ -1226,6 +1229,8 @@ static void dpu_encoder_virt_atomic_enable(struct 
drm_encoder *drm_enc,
else if (disp_info->intf_type == INTF_DSI)
dpu_enc->wide_bus_en = 
msm_dsi_wide_bus_enabled(priv->dsi[index]);
  
+	dpu_enc->commit_done_timedout = false;

+
mutex_lock(&dpu_enc->enc_lock);
cur_mode = &dpu_enc->base.crtc->state->adjusted_mode;
  
@@ -2436,6 +2441,10 @@ int dpu_encoder_wait_for_commit_done(struct drm_encoder *drm_enc)

DPU_ATRACE_BEGIN("wait_for_commit_done");
ret = phys->ops.wait_for_commit_done(phys);
DPU_ATRACE_END("wait_for_commit_done");
+   if (ret == -ETIMEDOUT && 
!dpu_enc->commit_done_timedout) {
+   dpu_enc->commit_done_timedout = true;
+   msm_disp_snapshot_state(drm_enc->dev);
+   }
if (ret)
return ret;
}



Re: [PATCH v3 2/3] drm/msm/dpu: split dpu_encoder_wait_for_event into two functions

2024-02-25 Thread Abhinav Kumar




On 2/25/2024 6:12 AM, Dmitry Baryshkov wrote:

Stop multiplexing several events via the dpu_encoder_wait_for_event()
function. Split it into two distinct functions two allow separate
handling of those events.



I understand the idea but would handling of those events be really distinct?

Like if wait_for_commit_done timedout or wait_for_tx_complete timedout, 
the handling will be similar from my PoV.



Signed-off-by: Dmitry Baryshkov 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 74 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 22 ++---
  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c |  2 +-
  drivers/gpu/drm/msm/msm_drv.h   | 10 
  4 files changed, 59 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 194dbb08331d..30f349c8a1e5 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1282,7 +1282,7 @@ static void dpu_encoder_virt_atomic_disable(struct 
drm_encoder *drm_enc,
trace_dpu_enc_disable(DRMID(drm_enc));
  
  	/* wait for idle */

-   dpu_encoder_wait_for_event(drm_enc, MSM_ENC_TX_COMPLETE);
+   dpu_encoder_wait_for_tx_complete(drm_enc);
  
  	dpu_encoder_resource_control(drm_enc, DPU_ENC_RC_EVENT_PRE_STOP);
  
@@ -2402,10 +2402,23 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev,

return &dpu_enc->base;
  }
  
-int dpu_encoder_wait_for_event(struct drm_encoder *drm_enc,

-   enum msm_event_wait event)
+/**
+ * dpu_encoder_wait_for_commit_done() - Wait for encoder to flush pending state
+ * @drm_enc:   encoder pointer
+ *
+ * Wait for hardware to have flushed the current pending frames to hardware at
+ * a vblank or ctl_start Encoders will map this differently depending on the
+ * panel type.
+ *


Missing a '.' between ctl_start and Encoder?


+ * MSM_ENC_TX_COMPLETE -  Wait for the hardware to transfer all the pixels to
+ *the panel. Encoders will map this differently
+ *depending on the panel type.
+ *vid mode -> vsync_irq
+ *cmd mode -> pp_done
+ * Return: 0 on success, -EWOULDBLOCK if already signaled, error otherwise
+ */
+int dpu_encoder_wait_for_commit_done(struct drm_encoder *drm_enc)
  {
-   int (*fn_wait)(struct dpu_encoder_phys *phys_enc) = NULL;
struct dpu_encoder_virt *dpu_enc = NULL;
int i, ret = 0;
  
@@ -2419,23 +2432,46 @@ int dpu_encoder_wait_for_event(struct drm_encoder *drm_enc,

for (i = 0; i < dpu_enc->num_phys_encs; i++) {
struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
  
-		switch (event) {

-   case MSM_ENC_COMMIT_DONE:
-   fn_wait = phys->ops.wait_for_commit_done;
-   break;
-   case MSM_ENC_TX_COMPLETE:
-   fn_wait = phys->ops.wait_for_tx_complete;
-   break;
-   default:
-   DPU_ERROR_ENC(dpu_enc, "unknown wait event %d\n",
-   event);
-   return -EINVAL;
+   if (phys->ops.wait_for_commit_done) {
+   DPU_ATRACE_BEGIN("wait_for_commit_done");
+   ret = phys->ops.wait_for_commit_done(phys);
+   DPU_ATRACE_END("wait_for_commit_done");
+   if (ret)
+   return ret;
}
+   }
+
+   return ret;
+}
+
+/**
+ * dpu_encoder_wait_for_tx_complete() - Wait for encoder to transfer pixels to 
panel
+ * @drm_enc:   encoder pointer
+ *
+ * Wait for the hardware to transfer all the pixels to the panel. Encoders will
+ * map this differently depending on the panel type.
+ *
+ * Return: 0 on success, -EWOULDBLOCK if already signaled, error otherwise
+ */
+int dpu_encoder_wait_for_tx_complete(struct drm_encoder *drm_enc)
+{
+   struct dpu_encoder_virt *dpu_enc = NULL;
+   int i, ret = 0;
+
+   if (!drm_enc) {
+   DPU_ERROR("invalid encoder\n");
+   return -EINVAL;
+   }
+   dpu_enc = to_dpu_encoder_virt(drm_enc);
+   DPU_DEBUG_ENC(dpu_enc, "\n");
+
+   for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+   struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
  
-		if (fn_wait) {

-   DPU_ATRACE_BEGIN("wait_for_completion_event");
-   ret = fn_wait(phys);
-   DPU_ATRACE_END("wait_for_completion_event");
+   if (phys->ops.wait_for_tx_complete) {
+   DPU_ATRACE_BEGIN("wait_for_tx_complete");
+   ret = phys->ops.wait_for_tx_complete(phys);
+   DPU_ATRACE_END("wait_for_tx_complete");
if (ret)
return ret;
}
diff --git 

Re: [PATCH v3 1/3] drm/msm/dpu: make "vblank timeout" more useful

2024-02-25 Thread Abhinav Kumar




On 2/25/2024 6:12 AM, Dmitry Baryshkov wrote:

We have several reports of vblank timeout messages. However after some
debugging it was found that there might be different causes to that.
To allow us to identify the DPU block that gets stuck, include the
actual CTL_FLUSH value into the timeout message.



the flush register shall also be part of the coredump in patch 3. so why 
is this needed?



Signed-off-by: Dmitry Baryshkov 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
index 2aa72b578764..6058706f03e4 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
@@ -480,7 +480,7 @@ static int dpu_encoder_phys_vid_wait_for_commit_done(
(hw_ctl->ops.get_flush_register(hw_ctl) == 0),
msecs_to_jiffies(50));
if (ret <= 0) {
-   DPU_ERROR("vblank timeout\n");
+   DPU_ERROR("vblank timeout: %x\n", 
hw_ctl->ops.get_flush_register(hw_ctl));
return -ETIMEDOUT;
}
  



[drm-misc:drm-misc-next 1/3] drivers/gpu/drm/i915/display/intel_dp.c:4233:8: error: call to undeclared function 'intel_dp_vsc_sdp_pack'; ISO C99 and later do not support implicit function declarations

2024-02-25 Thread kernel test robot
tree:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
head:   de8de2c8acb931ce6197a04376a7078ccf50e821
commit: 47f419e07111acecab3b529d4ae31a28985f5b61 [1/3] drm/dp: move 
intel_dp_vsc_sdp_pack() to generic helper
config: i386-buildonly-randconfig-003-20240225 
(https://download.01.org/0day-ci/archive/20240226/202402260120.ebo7ntye-...@intel.com/config)
compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 
6009708b4367171ccdbf4b5905cb6a803753fe18)
reproduce (this is a W=1 build): 
(https://download.01.org/0day-ci/archive/20240226/202402260120.ebo7ntye-...@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot 
| Closes: 
https://lore.kernel.org/oe-kbuild-all/202402260120.ebo7ntye-...@intel.com/

Note: the drm-misc/drm-misc-next HEAD de8de2c8acb931ce6197a04376a7078ccf50e821 
builds fine.
  It only hurts bisectability.

All errors (new ones prefixed by >>):

>> drivers/gpu/drm/i915/display/intel_dp.c:4233:8: error: call to undeclared 
>> function 'intel_dp_vsc_sdp_pack'; ISO C99 and later do not support implicit 
>> function declarations [-Wimplicit-function-declaration]
4233 | len = intel_dp_vsc_sdp_pack(vsc, &sdp, sizeof(sdp));
 |   ^
   drivers/gpu/drm/i915/display/intel_dp.c:4233:8: note: did you mean 
'drm_dp_vsc_sdp_pack'?
   include/drm/display/drm_dp_helper.h:815:9: note: 'drm_dp_vsc_sdp_pack' 
declared here
 815 | ssize_t drm_dp_vsc_sdp_pack(const struct drm_dp_vsc_sdp *vsc,
 | ^
   1 error generated.


vim +/intel_dp_vsc_sdp_pack +4233 drivers/gpu/drm/i915/display/intel_dp.c

03c761b00c87d6 Gwan-gyeong Mun   2020-02-11  4223  
cafac5a9836199 Gwan-gyeong Mun   2020-05-14  4224  void 
intel_write_dp_vsc_sdp(struct intel_encoder *encoder,
cafac5a9836199 Gwan-gyeong Mun   2020-05-14  4225   
const struct intel_crtc_state *crtc_state,
9ce5884e513903 José Roberto de Souza 2021-09-22  4226   
const struct drm_dp_vsc_sdp *vsc)
cafac5a9836199 Gwan-gyeong Mun   2020-05-14  4227  {
7801f3b792b0fd Lucas De Marchi   2020-06-30  4228   struct 
intel_digital_port *dig_port = enc_to_dig_port(encoder);
cafac5a9836199 Gwan-gyeong Mun   2020-05-14  4229   struct drm_i915_private 
*dev_priv = to_i915(encoder->base.dev);
cafac5a9836199 Gwan-gyeong Mun   2020-05-14  4230   struct dp_sdp sdp = {};
cafac5a9836199 Gwan-gyeong Mun   2020-05-14  4231   ssize_t len;
cafac5a9836199 Gwan-gyeong Mun   2020-05-14  4232  
cafac5a9836199 Gwan-gyeong Mun   2020-05-14 @4233   len = 
intel_dp_vsc_sdp_pack(vsc, &sdp, sizeof(sdp));
cafac5a9836199 Gwan-gyeong Mun   2020-05-14  4234  
cafac5a9836199 Gwan-gyeong Mun   2020-05-14  4235   if 
(drm_WARN_ON(&dev_priv->drm, len < 0))
cafac5a9836199 Gwan-gyeong Mun   2020-05-14  4236   return;
cafac5a9836199 Gwan-gyeong Mun   2020-05-14  4237  
7801f3b792b0fd Lucas De Marchi   2020-06-30  4238   
dig_port->write_infoframe(encoder, crtc_state, DP_SDP_VSC,
cafac5a9836199 Gwan-gyeong Mun   2020-05-14  4239   
&sdp, len);
cafac5a9836199 Gwan-gyeong Mun   2020-05-14  4240  }
cafac5a9836199 Gwan-gyeong Mun   2020-05-14  4241  

:: The code at line 4233 was first introduced by commit
:: cafac5a983619944afa639c53f0d5d885616a3d2 drm/i915/dp: Add compute 
routine for DP PSR VSC SDP

:: TO: Gwan-gyeong Mun 
:: CC: Jani Nikula 

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


Re: [PATCH next v2 08/11] minmax: Add min_const() and max_const()

2024-02-25 Thread Linus Torvalds
On Sun, 25 Feb 2024 at 08:53, David Laight  wrote:
>
> The expansions of min() and max() contain statement expressions so are
> not valid for static intialisers.
> min_const() and max_const() are expressions so can be used for static
> initialisers.

I hate the name.

Naming shouldn't be about an implementation detail, particularly not
an esoteric one like the "C constant expression" rule. That can be
useful for some internal helper functions or macros, but not for
something that random people are supposed to USE.

Telling some random developer that inside an array size declaration or
a static initializer you need to use "max_const()" because it needs to
syntactically be a constant expression, and our regular "max()"
function isn't that, is just *horrid*.

No, please just use the traditional C model of just using ALL CAPS for
macro names that don't act like a function.

Yes, yes, that may end up requiring getting rid of some current users of

  #define MIN(a,b) ((a)<(b) ? (a):(b))

but dammit, we don't actually have _that_ many of them, and why should
we have random drivers doing that anyway?

  Linus


[PATCH next v2 11/11] minmax: min() and max() don't need to return constant expressions

2024-02-25 Thread David Laight
After changing the handful of places max() was used to size an on-stack
array to use max_const() it is no longer necessary for min() and max()
to return constant expressions from constant inputs.
Remove the associated logic to reduce the expanded text.

Remove the 'hack' that allowed max(bool, bool).

Fixup the initial block comment to match current reality.

Signed-off-by: David Laight 
---
 include/linux/minmax.h | 23 ---
 1 file changed, 12 insertions(+), 11 deletions(-)

Changes for v2:
- Typographical and spelling corrections to the commit messages.
  Patches unchanged.

diff --git a/include/linux/minmax.h b/include/linux/minmax.h
index c08916588425..5e65c98ff256 100644
--- a/include/linux/minmax.h
+++ b/include/linux/minmax.h
@@ -8,13 +8,10 @@
 #include 
 
 /*
- * min()/max()/clamp() macros must accomplish three things:
+ * min()/max()/clamp() macros must accomplish several things:
  *
  * - Avoid multiple evaluations of the arguments (so side-effects like
  *   "x++" happen only once) when non-constant.
- * - Retain result as a constant expressions when called with only
- *   constant expressions (to avoid tripping VLA warnings in stack
- *   allocation usage).
  * - Perform signed v unsigned type-checking (to generate compile
  *   errors instead of nasty runtime surprises).
  * - Unsigned char/short are always promoted to signed int and can be
@@ -22,13 +19,19 @@
  * - Unsigned arguments can be compared against non-negative signed constants.
  * - Comparison of a signed argument against an unsigned constant fails
  *   even if the constant is below __INT_MAX__ and could be cast to int.
+ *
+ * The return value of min()/max() is not a constant expression for
+ * constant parameters - so will trigger a VLA warging if used to size
+ * an on-stack array.
+ * Instead use min_const() or max_const() which do generate constant
+ * expressions and are also valid for static initialisers.
  */
 #define __typecheck(x, y) \
(!!(sizeof((typeof(x) *)1 == (typeof(y) *)1)))
 
 /* Allow unsigned compares against non-negative signed constants. */
 #define __is_ok_unsigned(x) \
-   (is_unsigned_type(typeof(x)) || (__is_constexpr(x) ? (x) + 0 >= 0 : 0))
+   (is_unsigned_type(typeof(x)) || (__is_constexpr(x) ? (x) >= 0 : 0))
 
 /* Check for signed after promoting unsigned char/short to int */
 #define __is_ok_signed(x) is_signed_type(typeof((x) + 0))
@@ -53,12 +56,10 @@
typeof(y) __y_##uniq = (y); \
__cmp(op, __x_##uniq, __y_##uniq); })
 
-#define __careful_cmp(op, x, y, uniq)  \
-   __builtin_choose_expr(__is_constexpr((x) - (y)),\
-   __cmp(op, x, y),\
-   ({ _Static_assert(__types_ok(x, y), \
-   #op "(" #x ", " #y ") signedness error, fix types or 
consider u" #op "() before " #op "_t()"); \
-   __cmp_once(op, x, y, uniq); }))
+#define __careful_cmp(op, x, y, uniq) ({   \
+   _Static_assert(__types_ok(x, y),\
+   #op "(" #x ", " #y ") signedness error, fix types or consider 
u" #op "() before " #op "_t()"); \
+   __cmp_once(op, x, y, uniq); })
 
 #define __careful_cmp_const(op, x, y)  \
(BUILD_BUG_ON_ZERO(!__is_constexpr((x) - (y))) +\
-- 
2.17.1

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, 
UK
Registration No: 1397386 (Wales)



[PATCH next v2 10/11] block: Use a boolean expression instead of max() on booleans

2024-02-25 Thread David Laight
blk_stack_limits() contains:
t->zoned = max(t->zoned, b->zoned);
These are bool, so can be replaced by bitwise or.
However it generates:
error: comparison of constant '0' with boolean expression is always true 
[-Werror=bool-compare]
inside the signedness check that max() does unless a '+ 0' is added.
It is a shame the compiler generates this warning for code that will
be optimised away.

Change so that the extra '+ 0' can be removed.

Signed-off-by: David Laight 
---
 block/blk-settings.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Changes for v2:
- Typographical and spelling corrections to the commit messages.
  Patches unchanged.

diff --git a/block/blk-settings.c b/block/blk-settings.c
index 06ea91e51b8b..9ca21fea039d 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -688,7 +688,7 @@ int blk_stack_limits(struct queue_limits *t, struct 
queue_limits *b,
   b->max_secure_erase_sectors);
t->zone_write_granularity = max(t->zone_write_granularity,
b->zone_write_granularity);
-   t->zoned = max(t->zoned, b->zoned);
+   t->zoned = t->zoned | b->zoned;
return ret;
 }
 EXPORT_SYMBOL(blk_stack_limits);
-- 
2.17.1

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, 
UK
Registration No: 1397386 (Wales)



[PATCH next v2 09/11] tree-wide: minmax: Replace all the uses of max() for array sizes with max_const()

2024-02-25 Thread David Laight
These are the only uses of max() that require a constant value
from constant parameters.
There don't seem to be any similar uses of min().

Replacing the max() by max_const() lets min()/max() be simplified
speeding up compilation.

max_const() will convert enums to int (or unsigned int) so that the
casts added by max_t() are no longer needed.

Signed-off-by: David Laight 
---
 drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c | 2 +-
 drivers/gpu/drm/drm_color_mgmt.c   | 4 ++--
 drivers/input/touchscreen/cyttsp4_core.c   | 2 +-
 drivers/net/can/usb/etas_es58x/es58x_devlink.c | 2 +-
 fs/btrfs/tree-checker.c| 2 +-
 lib/vsprintf.c | 4 ++--
 net/ipv4/proc.c| 2 +-
 net/ipv6/proc.c| 2 +-
 8 files changed, 10 insertions(+), 10 deletions(-)

Changes for v2:
- Typographical and spelling corrections to the commit messages.
  Patches unchanged.

diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
index 00cd615bbcdc..935fb4014f7c 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
@@ -708,7 +708,7 @@ static const char *smu_get_feature_name(struct smu_context 
*smu,
 size_t smu_cmn_get_pp_feature_mask(struct smu_context *smu,
   char *buf)
 {
-   int8_t sort_feature[max(SMU_FEATURE_COUNT, SMU_FEATURE_MAX)];
+   int8_t sort_feature[max_const(SMU_FEATURE_COUNT, SMU_FEATURE_MAX)];
uint64_t feature_mask;
int i, feature_index;
uint32_t count = 0;
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index d021497841b8..43a6bd0ca960 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -532,8 +532,8 @@ int drm_plane_create_color_properties(struct drm_plane 
*plane,
 {
struct drm_device *dev = plane->dev;
struct drm_property *prop;
-   struct drm_prop_enum_list enum_list[max_t(int, DRM_COLOR_ENCODING_MAX,
-  DRM_COLOR_RANGE_MAX)];
+   struct drm_prop_enum_list enum_list[max_const(DRM_COLOR_ENCODING_MAX,
+ DRM_COLOR_RANGE_MAX)];
int i, len;
 
if (WARN_ON(supported_encodings == 0 ||
diff --git a/drivers/input/touchscreen/cyttsp4_core.c 
b/drivers/input/touchscreen/cyttsp4_core.c
index 7cb26929dc73..c6884c3c3fca 100644
--- a/drivers/input/touchscreen/cyttsp4_core.c
+++ b/drivers/input/touchscreen/cyttsp4_core.c
@@ -871,7 +871,7 @@ static void cyttsp4_get_mt_touches(struct cyttsp4_mt_data 
*md, int num_cur_tch)
struct cyttsp4_touch tch;
int sig;
int i, j, t = 0;
-   int ids[max(CY_TMA1036_MAX_TCH, CY_TMA4XX_MAX_TCH)];
+   int ids[max_const(CY_TMA1036_MAX_TCH, CY_TMA4XX_MAX_TCH)];
 
memset(ids, 0, si->si_ofs.tch_abs[CY_TCH_T].max * sizeof(int));
for (i = 0; i < num_cur_tch; i++) {
diff --git a/drivers/net/can/usb/etas_es58x/es58x_devlink.c 
b/drivers/net/can/usb/etas_es58x/es58x_devlink.c
index 635edeb8f68c..28fa87668bf8 100644
--- a/drivers/net/can/usb/etas_es58x/es58x_devlink.c
+++ b/drivers/net/can/usb/etas_es58x/es58x_devlink.c
@@ -215,7 +215,7 @@ static int es58x_devlink_info_get(struct devlink *devlink,
struct es58x_sw_version *fw_ver = &es58x_dev->firmware_version;
struct es58x_sw_version *bl_ver = &es58x_dev->bootloader_version;
struct es58x_hw_revision *hw_rev = &es58x_dev->hardware_revision;
-   char buf[max(sizeof("xx.xx.xx"), sizeof("axxx/xxx"))];
+   char buf[max_const(sizeof("xx.xx.xx"), sizeof("axxx/xxx"))];
int ret = 0;
 
if (es58x_sw_version_is_valid(fw_ver)) {
diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c
index 6eccf8496486..aec4729a9a82 100644
--- a/fs/btrfs/tree-checker.c
+++ b/fs/btrfs/tree-checker.c
@@ -615,7 +615,7 @@ static int check_dir_item(struct extent_buffer *leaf,
 */
if (key->type == BTRFS_DIR_ITEM_KEY ||
key->type == BTRFS_XATTR_ITEM_KEY) {
-   char namebuf[max(BTRFS_NAME_LEN, XATTR_NAME_MAX)];
+   char namebuf[max_const(BTRFS_NAME_LEN, XATTR_NAME_MAX)];
 
read_extent_buffer(leaf, namebuf,
(unsigned long)(di + 1), name_len);
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 552738f14275..6c3c319afd86 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -1080,8 +1080,8 @@ char *resource_string(char *buf, char *end, struct 
resource *res,
 #define FLAG_BUF_SIZE  (2 * sizeof(res->flags))
 #define DECODED_BUF_SIZE   sizeof("[mem - 64bit pref window disabled]")
 #define RAW_BUF_SIZE   sizeof("[mem - flags 0x]")
-   char sym[max(2*RSRC_BUF_SIZE + DECODED_BUF_SIZE,
-2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)];
+

[PATCH next v2 08/11] minmax: Add min_const() and max_const()

2024-02-25 Thread David Laight
The expansions of min() and max() contain statement expressions so are
not valid for static intialisers.
min_const() and max_const() are expressions so can be used for static
initialisers.
The arguments are checked for being constant and for negative signed
values being converted to large unsigned values.

Using these to size on-stack arrays lets min/max be simplified.
Zero is added before the compare to convert enum values to integers
avoinding the need for casts when enums have been used for constants.

Signed-off-by: David Laight 
---
 include/linux/minmax.h | 15 +++
 1 file changed, 15 insertions(+)

Changes for v2:
- Typographical and spelling corrections to the commit messages.
  Patches unchanged.

diff --git a/include/linux/minmax.h b/include/linux/minmax.h
index 278a390b8a4c..c08916588425 100644
--- a/include/linux/minmax.h
+++ b/include/linux/minmax.h
@@ -60,19 +60,34 @@
#op "(" #x ", " #y ") signedness error, fix types or 
consider u" #op "() before " #op "_t()"); \
__cmp_once(op, x, y, uniq); }))
 
+#define __careful_cmp_const(op, x, y)  \
+   (BUILD_BUG_ON_ZERO(!__is_constexpr((x) - (y))) +\
+   BUILD_BUG_ON_ZERO(!__types_ok(x, y)) +  \
+   __cmp(op, (x) + 0, (y) + 0))
+
 /**
  * min - return minimum of two values of the same or compatible types
  * @x: first value
  * @y: second value
+ *
+ * If @x and @y are constants the return value is constant, but not 'constant
+ * enough' for things like static initialisers.
+ * min_const(@x, @y) is a constant expression for constant inputs.
  */
 #define min(x, y)  __careful_cmp(min, x, y, __COUNTER__)
+#define min_const(x, y)__careful_cmp_const(min, x, y)
 
 /**
  * max - return maximum of two values of the same or compatible types
  * @x: first value
  * @y: second value
+ *
+ * If @x and @y are constants the return value is constant, but not 'constant
+ * enough' for things like static initialisers.
+ * max_const(@x, @y) is a constant expression for constant inputs.
  */
 #define max(x, y)  __careful_cmp(max, x, y, __COUNTER__)
+#define max_const(x, y)__careful_cmp_const(max, x, y)
 
 /**
  * umin - return minimum of two non-negative values
-- 
2.17.1

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, 
UK
Registration No: 1397386 (Wales)



[PATCH next v2 07/11] minmax: minmax: Add __types_ok3() and optimise defines with 3 arguments

2024-02-25 Thread David Laight
min3() and max3() were added to optimise nested min(x, min(y, z))
sequences, but only moved where the expansion was requiested.

Add a separate implementation for 3 argument calls.
These are never required to generate constant expressions to
remove that logic.

Signed-off-by: David Laight 
---
 include/linux/minmax.h | 23 +++
 1 file changed, 19 insertions(+), 4 deletions(-)

Changes for v2:
- Typographical and spelling corrections to the commit messages.
  Patches unchanged.

diff --git a/include/linux/minmax.h b/include/linux/minmax.h
index 5c7fce76abe5..278a390b8a4c 100644
--- a/include/linux/minmax.h
+++ b/include/linux/minmax.h
@@ -38,6 +38,11 @@
((__is_ok_signed(x) && __is_ok_signed(y)) ||\
 (__is_ok_unsigned(x) && __is_ok_unsigned(y)))
 
+/* Check three values for min3(), max3() and clamp() */
+#define __types_ok3(x, y, z)   
\
+   ((__is_ok_signed(x) && __is_ok_signed(y) && __is_ok_signed(z)) ||   
\
+(__is_ok_unsigned(x) && __is_ok_unsigned(y) && __is_ok_unsigned(z)))
+
 #define __cmp_op_min <
 #define __cmp_op_max >
 
@@ -87,13 +92,24 @@
 #define umax(x, y) \
__careful_cmp(max, __zero_extend(x), _zero_extend(y), __COUNTER__)
 
+#define __cmp_once3(op, x, y, z, uniq) ({  \
+   typeof(x) __x_##uniq = (x); \
+   typeof(x) __y_##uniq = (y); \
+   typeof(x) __z_##uniq = (z); \
+   __cmp(op, __cmp(op, __x_##uniq, __y_##uniq), __z_##uniq); })
+
+#define __careful_cmp3(op, x, y, z, uniq) ({   \
+   static_assert(__types_ok3(x, y, z), \
+   #op "3(" #x ", " #y ", " #z ") signedness error");  \
+   __cmp_once3(op, x, y, z, uniq); })
+
 /**
  * min3 - return minimum of three values
  * @x: first value
  * @y: second value
  * @z: third value
  */
-#define min3(x, y, z) min((typeof(x))min(x, y), z)
+#define min3(x, y, z) __careful_cmp3(min, x, y, z, __COUNTER__)
 
 /**
  * max3 - return maximum of three values
@@ -101,7 +117,7 @@
  * @y: second value
  * @z: third value
  */
-#define max3(x, y, z) max((typeof(x))max(x, y), z)
+#define max3(x, y, z) __careful_cmp3(max, x, y, z, __COUNTER__)
 
 /**
  * min_t - return minimum of two values, using the specified type
@@ -142,8 +158,7 @@
__clamp(__val_##uniq, __lo_##uniq, __hi_##uniq); })
 
 #define __careful_clamp(val, lo, hi, uniq) ({  
\
-   _Static_assert(__types_ok(val, lo), "clamp() 'lo' signedness error");   
\
-   _Static_assert(__types_ok(val, hi), "clamp() 'hi' signedness error");   
\
+   _Static_assert(__types_ok3(val, lo, hi), "clamp() signedness error");   
\
__clamp_once(val, lo, hi, uniq); })
 
 /**
-- 
2.17.1

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, 
UK
Registration No: 1397386 (Wales)



[PATCH next v2 06/11] minmax: Remove 'constexpr' check from __careful_clamp()

2024-02-25 Thread David Laight
Nothing requires that clamp() return a constant expression.
The logic to do so significantly increases the .i file.
Remove the check and directly expand __clamp_once() from clamp_t()
since the type check can't fail.

Signed-off-by: David Laight 
---
 include/linux/minmax.h | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

Changes for v2:
- Typographical and spelling corrections to the commit messages.
  Patches unchanged.

diff --git a/include/linux/minmax.h b/include/linux/minmax.h
index 111c52a14fe5..5c7fce76abe5 100644
--- a/include/linux/minmax.h
+++ b/include/linux/minmax.h
@@ -141,12 +141,10 @@
"clamp() low limit " #lo " greater than high limit " #hi);  
\
__clamp(__val_##uniq, __lo_##uniq, __hi_##uniq); })
 
-#define __careful_clamp(val, lo, hi, uniq) \
-   __builtin_choose_expr(__is_constexpr((val) - (lo) + (hi)),  \
-   __clamp(val, lo, hi),   \
-   ({ _Static_assert(__types_ok(val, lo), "clamp() 'lo' signedness 
error");\
-   _Static_assert(__types_ok(val, hi), "clamp() 'hi' signedness 
error");   \
-   __clamp_once(val, lo, hi, uniq); }))
+#define __careful_clamp(val, lo, hi, uniq) ({  
\
+   _Static_assert(__types_ok(val, lo), "clamp() 'lo' signedness error");   
\
+   _Static_assert(__types_ok(val, hi), "clamp() 'hi' signedness error");   
\
+   __clamp_once(val, lo, hi, uniq); })
 
 /**
  * clamp - return a value clamped to a given range with strict typechecking
@@ -168,7 +166,9 @@
  * This macro does no typechecking and uses temporary variables of type
  * @type to make all the comparisons.
  */
-#define clamp_t(type, val, lo, hi) clamp((type)(val), (type)(lo), (type)(hi))
+#define __clamp_t(type, val, lo, hi, uniq) \
+   __clamp_once((type)(val), (type)(lo), (type)(hi), uniq)
+#define clamp_t(type, val, lo, hi) __clamp_t(type, val, lo, hi, __COUNTER__)
 
 /**
  * clamp_val - return a value clamped to a given range using val's type
-- 
2.17.1

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, 
UK
Registration No: 1397386 (Wales)



[PATCH next v2 05/11] minmax: Move the signedness check out of __cmp_once() and __clamp_once()

2024-02-25 Thread David Laight
There is no need to do the signedness/type check when the arguments
are being cast to a fixed type.
So move the check out of __xxx_once() into __careful_xxx().

Signed-off-by: David Laight 
---
 include/linux/minmax.h | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

Changes for v2:
- Typographical and spelling corrections to the commit messages.
  Patches unchanged.

diff --git a/include/linux/minmax.h b/include/linux/minmax.h
index 8ee003d8abaf..111c52a14fe5 100644
--- a/include/linux/minmax.h
+++ b/include/linux/minmax.h
@@ -46,14 +46,14 @@
 #define __cmp_once(op, x, y, uniq) ({  \
typeof(x) __x_##uniq = (x); \
typeof(y) __y_##uniq = (y); \
-   _Static_assert(__types_ok(x, y),\
-   #op "(" #x ", " #y ") signedness error, fix types or consider 
u" #op "() before " #op "_t()"); \
__cmp(op, __x_##uniq, __y_##uniq); })
 
 #define __careful_cmp(op, x, y, uniq)  \
__builtin_choose_expr(__is_constexpr((x) - (y)),\
__cmp(op, x, y),\
-   __cmp_once(op, x, y, uniq))
+   ({ _Static_assert(__types_ok(x, y), \
+   #op "(" #x ", " #y ") signedness error, fix types or 
consider u" #op "() before " #op "_t()"); \
+   __cmp_once(op, x, y, uniq); }))
 
 /**
  * min - return minimum of two values of the same or compatible types
@@ -139,14 +139,14 @@
_Static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)),   
\
(lo) <= (hi), true),
\
"clamp() low limit " #lo " greater than high limit " #hi);  
\
-   _Static_assert(__types_ok(val, lo), "clamp() 'lo' signedness error");   
\
-   _Static_assert(__types_ok(val, hi), "clamp() 'hi' signedness error");   
\
__clamp(__val_##uniq, __lo_##uniq, __hi_##uniq); })
 
-#define __careful_clamp(val, lo, hi, uniq) ({  \
+#define __careful_clamp(val, lo, hi, uniq) \
__builtin_choose_expr(__is_constexpr((val) - (lo) + (hi)),  \
__clamp(val, lo, hi),   \
-   __clamp_once(val, lo, hi, uniq)); })
+   ({ _Static_assert(__types_ok(val, lo), "clamp() 'lo' signedness 
error");\
+   _Static_assert(__types_ok(val, hi), "clamp() 'hi' signedness 
error");   \
+   __clamp_once(val, lo, hi, uniq); }))
 
 /**
  * clamp - return a value clamped to a given range with strict typechecking
-- 
2.17.1

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, 
UK
Registration No: 1397386 (Wales)



[PATCH next v2 04/11] minmax: Replace multiple __UNIQUE_ID() by directly using __COUNTER__

2024-02-25 Thread David Laight
Provided __COUNTER__ is passed through an extra #define it can be pasted
onto multiple local variables to give unique names.
This saves having 3 __UNIQUE_ID() for #defines with three locals and
look less messy in general.

Stop the umin()/umax() lines being overlong by factoring out the
zero-extension logic.

Signed-off-by: David Laight 
---
 include/linux/minmax.h | 48 +-
 1 file changed, 24 insertions(+), 24 deletions(-)

Changes for v2:
- Typographical and spelling corrections to the commit messages.
  Patches unchanged.

diff --git a/include/linux/minmax.h b/include/linux/minmax.h
index c32b4b40ce01..8ee003d8abaf 100644
--- a/include/linux/minmax.h
+++ b/include/linux/minmax.h
@@ -8,7 +8,7 @@
 #include 
 
 /*
- * min()/max()/clamp() macros must accomplish several things:
+ * min()/max()/clamp() macros must accomplish three things:
  *
  * - Avoid multiple evaluations of the arguments (so side-effects like
  *   "x++" happen only once) when non-constant.
@@ -43,31 +43,31 @@
 
 #define __cmp(op, x, y)((x) __cmp_op_##op (y) ? (x) : (y))
 
-#define __cmp_once(op, x, y, unique_x, unique_y) ({\
-   typeof(x) unique_x = (x);   \
-   typeof(y) unique_y = (y);   \
-   _Static_assert(__types_ok(x, y),\
+#define __cmp_once(op, x, y, uniq) ({  \
+   typeof(x) __x_##uniq = (x); \
+   typeof(y) __y_##uniq = (y); \
+   _Static_assert(__types_ok(x, y),\
#op "(" #x ", " #y ") signedness error, fix types or consider 
u" #op "() before " #op "_t()"); \
-   __cmp(op, unique_x, unique_y); })
+   __cmp(op, __x_##uniq, __y_##uniq); })
 
-#define __careful_cmp(op, x, y)\
+#define __careful_cmp(op, x, y, uniq)  \
__builtin_choose_expr(__is_constexpr((x) - (y)),\
__cmp(op, x, y),\
-   __cmp_once(op, x, y, __UNIQUE_ID(__x), __UNIQUE_ID(__y)))
+   __cmp_once(op, x, y, uniq))
 
 /**
  * min - return minimum of two values of the same or compatible types
  * @x: first value
  * @y: second value
  */
-#define min(x, y)  __careful_cmp(min, x, y)
+#define min(x, y)  __careful_cmp(min, x, y, __COUNTER__)
 
 /**
  * max - return maximum of two values of the same or compatible types
  * @x: first value
  * @y: second value
  */
-#define max(x, y)  __careful_cmp(max, x, y)
+#define max(x, y)  __careful_cmp(max, x, y, __COUNTER__)
 
 /**
  * umin - return minimum of two non-negative values
@@ -75,8 +75,9 @@
  * @x: first value
  * @y: second value
  */
+#define __zero_extend(x) ((x) + 0u + 0ul + 0ull)
 #define umin(x, y) \
-   __careful_cmp(min, (x) + 0u + 0ul + 0ull, (y) + 0u + 0ul + 0ull)
+   __careful_cmp(min, __zero_extend(x), _zero_extend(y), __COUNTER__)
 
 /**
  * umax - return maximum of two non-negative values
@@ -84,7 +85,7 @@
  * @y: second value
  */
 #define umax(x, y) \
-   __careful_cmp(max, (x) + 0u + 0ul + 0ull, (y) + 0u + 0ul + 0ull)
+   __careful_cmp(max, __zero_extend(x), _zero_extend(y), __COUNTER__)
 
 /**
  * min3 - return minimum of three values
@@ -108,7 +109,7 @@
  * @x: first value
  * @y: second value
  */
-#define min_t(type, x, y)  __careful_cmp(min, (type)(x), (type)(y))
+#define min_t(type, x, y)  __careful_cmp(min, (type)(x), (type)(y), 
__COUNTER__)
 
 /**
  * max_t - return maximum of two values, using the specified type
@@ -116,7 +117,7 @@
  * @x: first value
  * @y: second value
  */
-#define max_t(type, x, y)  __careful_cmp(max, (type)(x), (type)(y))
+#define max_t(type, x, y)  __careful_cmp(max, (type)(x), (type)(y), 
__COUNTER__)
 
 /**
  * min_not_zero - return the minimum that is _not_ zero, unless both are zero
@@ -131,22 +132,21 @@
 #define __clamp(val, lo, hi)   \
((val) >= (hi) ? (hi) : ((val) <= (lo) ? (lo) : (val)))
 
-#define __clamp_once(val, lo, hi, unique_val, unique_lo, unique_hi) ({ 
\
-   typeof(val) unique_val = (val); 
\
-   typeof(lo) unique_lo = (lo);
\
-   typeof(hi) unique_hi = (hi);
\
+#define __clamp_once(val, lo, hi, uniq) ({ 
\
+   typeof(val) __val_##uniq = (val);   
\
+   typeof(lo) __lo_##uniq = (lo);  
\
+   typeof(hi) __hi_##uniq = (hi);  
\
_Static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)),   
\
(lo) <= (hi), true),
\
"clamp() low limit " #lo " greater than high limit " #hi);  
\
_Static_assert(__types_ok(val, lo), "clamp() 'lo' signedness 

[PATCH next v2 03/11] minmax: Simplify signedness check

2024-02-25 Thread David Laight
It is enough to check that both 'x' and 'y' are valid for either
a signed compare or an unsigned compare.
For unsigned they must be an unsigned type or a positive constant.
For signed they must be signed after unsigned char/short are promoted.

The predicate for _Static_assert() only needs to be a compile-time
constant not a constant integeger expression.
In particular the short-circuit evaluation of || && ?: can be used
to avoid the non-constantness of (pointer_type)1 in is_signed_type().

The '+ 0' in '(x) + 0 > = 0' is there to convert 'bool' to 'int'
and avoid a compiler warning because max() gets used for 'bool'
in one place (a very expensive 'or').
(The code is optimised away by two earlier checks - but the compiler
still bleats.)

Signed-off-by: David Laight 
---
 include/linux/minmax.h | 22 ++
 1 file changed, 10 insertions(+), 12 deletions(-)

Changes for v2:
- Typographical and spelling corrections to the commit messages.
  Patches unchanged.

diff --git a/include/linux/minmax.h b/include/linux/minmax.h
index 900eec7a28e5..c32b4b40ce01 100644
--- a/include/linux/minmax.h
+++ b/include/linux/minmax.h
@@ -8,7 +8,7 @@
 #include 
 
 /*
- * min()/max()/clamp() macros must accomplish three things:
+ * min()/max()/clamp() macros must accomplish several things:
  *
  * - Avoid multiple evaluations of the arguments (so side-effects like
  *   "x++" happen only once) when non-constant.
@@ -26,19 +26,17 @@
 #define __typecheck(x, y) \
(!!(sizeof((typeof(x) *)1 == (typeof(y) *)1)))
 
-/* is_signed_type() isn't a constexpr for pointer types */
-#define __is_signed(x) 
\
-   __builtin_choose_expr(__is_constexpr(is_signed_type(typeof(x))),
\
-   is_signed_type(typeof(x)), 0)
+/* Allow unsigned compares against non-negative signed constants. */
+#define __is_ok_unsigned(x) \
+   (is_unsigned_type(typeof(x)) || (__is_constexpr(x) ? (x) + 0 >= 0 : 0))
 
-/* True for a non-negative signed int constant */
-#define __is_noneg_int(x)  \
-   (__builtin_choose_expr(__is_constexpr(x) && __is_signed(x), x, -1) >= 0)
+/* Check for signed after promoting unsigned char/short to int */
+#define __is_ok_signed(x) is_signed_type(typeof((x) + 0))
 
-#define __types_ok(x, y)   \
-   (__is_signed(x) == __is_signed(y) ||\
-   __is_signed((x) + 0) == __is_signed((y) + 0) || \
-   __is_noneg_int(x) || __is_noneg_int(y))
+/* Allow if both x and y are valid for either signed or unsigned compares. */
+#define __types_ok(x, y)   \
+   ((__is_ok_signed(x) && __is_ok_signed(y)) ||\
+(__is_ok_unsigned(x) && __is_ok_unsigned(y)))
 
 #define __cmp_op_min <
 #define __cmp_op_max >
-- 
2.17.1

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, 
UK
Registration No: 1397386 (Wales)



[PATCH next v2 02/11] minmax: Use _Static_assert() instead of static_assert()

2024-02-25 Thread David Laight
The wrapper just adds two more lines of error output when the test fails.

Signed-off-by: David Laight 
---
 include/linux/minmax.h | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

Changes for v2:
- Typographical and spelling corrections to the commit messages.
  Patches unchanged.

diff --git a/include/linux/minmax.h b/include/linux/minmax.h
index 63c45865b48a..900eec7a28e5 100644
--- a/include/linux/minmax.h
+++ b/include/linux/minmax.h
@@ -48,7 +48,7 @@
 #define __cmp_once(op, x, y, unique_x, unique_y) ({\
typeof(x) unique_x = (x);   \
typeof(y) unique_y = (y);   \
-   static_assert(__types_ok(x, y), \
+   _Static_assert(__types_ok(x, y),\
#op "(" #x ", " #y ") signedness error, fix types or consider 
u" #op "() before " #op "_t()"); \
__cmp(op, unique_x, unique_y); })
 
@@ -137,11 +137,11 @@
typeof(val) unique_val = (val); 
\
typeof(lo) unique_lo = (lo);
\
typeof(hi) unique_hi = (hi);
\
-   static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)),
\
+   _Static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)),   
\
(lo) <= (hi), true),
\
"clamp() low limit " #lo " greater than high limit " #hi);  
\
-   static_assert(__types_ok(val, lo), "clamp() 'lo' signedness error");
\
-   static_assert(__types_ok(val, hi), "clamp() 'hi' signedness error");
\
+   _Static_assert(__types_ok(val, lo), "clamp() 'lo' signedness error");   
\
+   _Static_assert(__types_ok(val, hi), "clamp() 'hi' signedness error");   
\
__clamp(unique_val, unique_lo, unique_hi); })
 
 #define __careful_clamp(val, lo, hi) ({
\
-- 
2.17.1

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, 
UK
Registration No: 1397386 (Wales)



[PATCH next v2 01/11] minmax: Put all the clamp() definitions together

2024-02-25 Thread David Laight
The defines for clamp() have got separated, move togther for readability.
Update description of signedness check.

Signed-off-by: David Laight 
---
 include/linux/minmax.h | 120 +++--
 1 file changed, 56 insertions(+), 64 deletions(-)

Changes for v2:
- Typographical and spelling corrections to the commit messages.
  Patches unchanged.

diff --git a/include/linux/minmax.h b/include/linux/minmax.h
index 2ec559284a9f..63c45865b48a 100644
--- a/include/linux/minmax.h
+++ b/include/linux/minmax.h
@@ -57,26 +57,6 @@
__cmp(op, x, y),\
__cmp_once(op, x, y, __UNIQUE_ID(__x), __UNIQUE_ID(__y)))
 
-#define __clamp(val, lo, hi)   \
-   ((val) >= (hi) ? (hi) : ((val) <= (lo) ? (lo) : (val)))
-
-#define __clamp_once(val, lo, hi, unique_val, unique_lo, unique_hi) ({ 
\
-   typeof(val) unique_val = (val); 
\
-   typeof(lo) unique_lo = (lo);
\
-   typeof(hi) unique_hi = (hi);
\
-   static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)),
\
-   (lo) <= (hi), true),
\
-   "clamp() low limit " #lo " greater than high limit " #hi);  
\
-   static_assert(__types_ok(val, lo), "clamp() 'lo' signedness error");
\
-   static_assert(__types_ok(val, hi), "clamp() 'hi' signedness error");
\
-   __clamp(unique_val, unique_lo, unique_hi); })
-
-#define __careful_clamp(val, lo, hi) ({
\
-   __builtin_choose_expr(__is_constexpr((val) - (lo) + (hi)),  \
-   __clamp(val, lo, hi),   \
-   __clamp_once(val, lo, hi, __UNIQUE_ID(__val),   \
-__UNIQUE_ID(__lo), __UNIQUE_ID(__hi))); })
-
 /**
  * min - return minimum of two values of the same or compatible types
  * @x: first value
@@ -124,6 +104,22 @@
  */
 #define max3(x, y, z) max((typeof(x))max(x, y), z)
 
+/**
+ * min_t - return minimum of two values, using the specified type
+ * @type: data type to use
+ * @x: first value
+ * @y: second value
+ */
+#define min_t(type, x, y)  __careful_cmp(min, (type)(x), (type)(y))
+
+/**
+ * max_t - return maximum of two values, using the specified type
+ * @type: data type to use
+ * @x: first value
+ * @y: second value
+ */
+#define max_t(type, x, y)  __careful_cmp(max, (type)(x), (type)(y))
+
 /**
  * min_not_zero - return the minimum that is _not_ zero, unless both are zero
  * @x: value1
@@ -134,39 +130,60 @@
typeof(y) __y = (y);\
__x == 0 ? __y : ((__y == 0) ? __x : min(__x, __y)); })
 
+#define __clamp(val, lo, hi)   \
+   ((val) >= (hi) ? (hi) : ((val) <= (lo) ? (lo) : (val)))
+
+#define __clamp_once(val, lo, hi, unique_val, unique_lo, unique_hi) ({ 
\
+   typeof(val) unique_val = (val); 
\
+   typeof(lo) unique_lo = (lo);
\
+   typeof(hi) unique_hi = (hi);
\
+   static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)),
\
+   (lo) <= (hi), true),
\
+   "clamp() low limit " #lo " greater than high limit " #hi);  
\
+   static_assert(__types_ok(val, lo), "clamp() 'lo' signedness error");
\
+   static_assert(__types_ok(val, hi), "clamp() 'hi' signedness error");
\
+   __clamp(unique_val, unique_lo, unique_hi); })
+
+#define __careful_clamp(val, lo, hi) ({
\
+   __builtin_choose_expr(__is_constexpr((val) - (lo) + (hi)),  \
+   __clamp(val, lo, hi),   \
+   __clamp_once(val, lo, hi, __UNIQUE_ID(__val),   \
+__UNIQUE_ID(__lo), __UNIQUE_ID(__hi))); })
+
 /**
  * clamp - return a value clamped to a given range with strict typechecking
  * @val: current value
  * @lo: lowest allowable value
  * @hi: highest allowable value
  *
- * This macro does strict typechecking of @lo/@hi to make sure they are of the
- * same type as @val.  See the unnecessary pointer comparisons.
+ * This macro checks that @val, @lo and @hi have the same signedness.
  */
 #define clamp(val, lo, hi) __careful_clamp(val, lo, hi)
 
-/*
- * ..and if you can't take the strict
- * types, you can specify one yourself.
- *
- * Or not use min/max/clamp at all, of course.
- */
-
 /**
- * min_t - return minimum of two values, using the specified type
- * @type: data type to use
- * @x: first value
- * @y: second value
+ * clamp_t - return a value clamped to a given range using a given type
+ * @type: the type of variable to use
+ * @val: current value
+ * @lo: m

Re: [PATCH v2 5/6] drm/panel: st7703: Drive XBD599 panel at higher clock rate

2024-02-25 Thread Frank Oltmanns
Hi Maxime,

On 2024-02-22 at 11:29:51 +0100, Maxime Ripard  wrote:
> [[PGP Signed Part:Undecided]]
> On Sun, Feb 11, 2024 at 04:42:43PM +0100, Frank Oltmanns wrote:
>>
>> On 2024-02-08 at 20:05:08 +0100, Maxime Ripard  wrote:
>> > [[PGP Signed Part:Undecided]]
>> > Hi Frank,
>> >
>> > On Mon, Feb 05, 2024 at 04:22:28PM +0100, Frank Oltmanns wrote:
>> >> This panel is used in the pinephone that runs on a Allwinner A64 SOC.
>> >> The SOC requires pll-mipi to run at more than 500 MHz.
>> >>
>> >> This is the relevant clock tree:
>> >>  pll-mipi
>> >> tcon0
>> >>tcon-data-clock
>> >>
>> >> tcon-data-clock has to run at 1/4 the DSI per-lane bit rate. The XBD599
>> >> has 24 bpp and 4 lanes. Therefore, the resulting requested
>> >> tcon-data-clock rate is:
>> >> crtc_clock * 1000 * (24 / 4) / 4
>> >>
>> >> tcon-data-clock runs at tcon0 / 4 (fixed divisor), so it requests a
>> >> parent rate of
>> >> 4 * (crtc_clock * 1000 * (24 / 4) / 4)
>> >>
>> >> Since tcon0 is a ccu_mux, the rate of tcon0 equals the rate of pll-mipi.
>> >>
>> >> pll-mipi's constraint to run at 500MHz or higher forces us to have a
>> >> crtc_clock >= 8 kHz if we want a 60 Hz vertical refresh rate.
>> >>
>> >> Change [hv]sync_(start|end) so that we reach a clock rate of 83502 kHz
>> >> so that it is high enough to align with pll-pipi limits.
>> >>
>> >> Signed-off-by: Frank Oltmanns 
>> >
>> > That commit log is great, but it's kind of off-topic. It's a panel
>> > driver, it can be used on any MIPI-DSI controller, the only relevant
>> > information there should be the panel timings required in the datasheet.
>> >
>> > The PLL setup is something for the MIPI-DSI driver to adjust, not for
>> > the panel to care for.
>> >
>>
>> I absolutely agree. It even was the reason for my submission of a
>> sunxi-ng patch series last year that was accepted, to make pll-mipi more
>> flexible. :)
>>
>> The only remaining option I currently see for adjusting the sunxi-ng
>> driver to further accomodate the panel, is trying to use a higher
>> divisor than 4 for calculating tcon-data-clock from tcon0. I remember
>> reading a discussion about this, but as far as I remember that proposal
>> was rejected (by you, IIRC).
>>
>> While I appreciate other suggestion as well, I'll look into options for
>> using a different divisor than 4.
>
> Like I said, I'm not against the patch at all, it looks great to me on
> principle. I just think you should completely rephrase the commit log
> using the datasheet as the only reliable source of the display timings.
> Whether sun4i can work around the panel requirements is something
> completely orthogonal to the discussion, and thus the commit log.
>

I was trying to follow the guidelines [1] for describing the reason
behind my changes to the panel. My original commit message was a lot
shorter, which, understandably, resulted in follow up questions [2].
With the current commit log, I'm trying to address those questions.
According to the device tree, the panel is only used in the pinephone.
The only reason for the change is that the SoC used by the only user of
this panel can not provide the rate the panel requests with the current
values. I think this information is relevant.

Unfortunately, as described in [2], I cannot back these values with any
datasheets because I couldn't find any. I could only find hints that
they are not publicly available. Icenowy (added to CC) submitted the
original values.

Best regards,
  Frank

[1]: 
https://www.kernel.org/doc/html/v6.7/process/submitting-patches.html#describe-your-changes
[2]: https://lore.kernel.org/lkml/87wmsvo0fh@oltmanns.dev/

>
> Maxime
>
> [[End of PGP Signed Part]]


[PATCH next v2 00/11] minmax: Optimise to reduce .i line length

2024-02-25 Thread David Laight
The changes to minmax.h that changed the type check to a signedness
check significantly increased the length of the expansion.
In some cases it has also significantly increased compile type.
This is particularly noticable for nested expansions.

The fact that _Static_assert() only requires a compile time constant
not a constant expression allows a lot of simplification.

The other thing that compilicates the expansion is the necessity of
returning a constant expression from constant arguments (for VLA).
I can only find a handful of places this is done.
Penalising most of the code for these few cases seems 'suboptimal'.
Instead I've added min_const() and max_const() for VLA and static
initialisers, these check the arguments are constant to avoid misuse.

Patch [9] is dependant on the earlier patches.
Patch [10] isn't dependant on them.
Patch [11] depends on both 9 and 10.

Changes for v2:
- Typographical and spelling corrections to the commit messages.
  Patches unchanged.

David Laight (11):
  [1] minmax: Put all the clamp() definitions together
  [2] minmax: Use _Static_assert() instead of static_assert()
  [3] minmax: Simplify signedness check
  [4] minmax: Replace multiple __UNIQUE_ID() by directly using __COUNTER__
  [5] minmax: Move the signedness check out of __cmp_once() and
__clamp_once()
  [6] minmax: Remove 'constexpr' check from __careful_clamp()
  [7] minmax: minmax: Add __types_ok3() and optimise defines with 3
arguments
  [8] minmax: Add min_const() and max_const()
  [9] tree-wide: minmax: Replace all the uses of max() for array sizes with
max_const().
  [10] block: Use a boolean expression instead of max() on booleans
  [11] minmax: min() and max() don't need to return constant expressions

 block/blk-settings.c  |   2 +-
 drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c|   2 +-
 drivers/gpu/drm/drm_color_mgmt.c  |   4 +-
 drivers/input/touchscreen/cyttsp4_core.c  |   2 +-
 .../net/can/usb/etas_es58x/es58x_devlink.c|   2 +-
 fs/btrfs/tree-checker.c   |   2 +-
 include/linux/minmax.h| 211 ++
 lib/vsprintf.c|   4 +-
 net/ipv4/proc.c   |   2 +-
 net/ipv6/proc.c   |   2 +-
 10 files changed, 127 insertions(+), 106 deletions(-)

-- 
2.17.1

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, 
UK
Registration No: 1397386 (Wales)



Re: [PATCH v7 25/36] drm/connector: hdmi: Add Infoframes generation

2024-02-25 Thread Dmitry Baryshkov
On Thu, 22 Feb 2024 at 20:16, Maxime Ripard  wrote:
>
> Infoframes in KMS is usually handled by a bunch of low-level helpers
> that require quite some boilerplate for drivers. This leads to
> discrepancies with how drivers generate them, and which are actually
> sent.
>
> Now that we have everything needed to generate them in the HDMI
> connector state, we can generate them in our common logic so that
> drivers can simply reuse what we precomputed.
>
> Signed-off-by: Maxime Ripard 
> ---
>  drivers/gpu/drm/Kconfig|   1 +
>  drivers/gpu/drm/drm_atomic_state_helper.c  | 327 
> +
>  drivers/gpu/drm/drm_connector.c|  16 +
>  .../gpu/drm/tests/drm_atomic_state_helper_test.c   |   1 +
>  drivers/gpu/drm/tests/drm_connector_test.c |  12 +
>  include/drm/drm_atomic_state_helper.h  |   8 +
>  include/drm/drm_connector.h| 133 +
>  7 files changed, 498 insertions(+)
>
> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> index 872edb47bb53..ad9c467e20ce 100644
> --- a/drivers/gpu/drm/Kconfig
> +++ b/drivers/gpu/drm/Kconfig
> @@ -99,6 +99,7 @@ config DRM_KUNIT_TEST
>  config DRM_KMS_HELPER
> tristate
> depends on DRM
> +   select DRM_DISPLAY_HDMI_HELPER
> help
>   CRTC helpers for KMS drivers.
>
> diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
> b/drivers/gpu/drm/drm_atomic_state_helper.c
> index e66272c0d006..46d9fd2ea8fa 100644
> --- a/drivers/gpu/drm/drm_atomic_state_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_state_helper.c
> @@ -38,6 +38,8 @@
>  #include 
>  #include 
>
> +#include 
> +
>  #include 
>  #include 
>
> @@ -914,6 +916,142 @@ hdmi_compute_config(const struct drm_connector 
> *connector,
> return -EINVAL;
>  }
>
> +static int hdmi_generate_avi_infoframe(const struct drm_connector *connector,
> +  struct drm_connector_state *state)
> +{
> +   const struct drm_display_mode *mode =
> +   connector_state_get_mode(state);
> +   struct drm_connector_hdmi_infoframe *infoframe =
> +   &state->hdmi.infoframes.avi;
> +   struct hdmi_avi_infoframe *frame =
> +   &infoframe->data.avi;
> +   bool is_full_range = state->hdmi.is_full_range;
> +   enum hdmi_quantization_range rgb_quant_range =
> +   is_full_range ? HDMI_QUANTIZATION_RANGE_FULL : 
> HDMI_QUANTIZATION_RANGE_LIMITED;
> +   int ret;
> +
> +   ret = drm_hdmi_avi_infoframe_from_display_mode(frame, connector, 
> mode);
> +   if (ret)
> +   return ret;
> +
> +   frame->colorspace = state->hdmi.output_format;
> +
> +   drm_hdmi_avi_infoframe_quant_range(frame, connector, mode, 
> rgb_quant_range);
> +   drm_hdmi_avi_infoframe_colorimetry(frame, state);
> +   drm_hdmi_avi_infoframe_bars(frame, state);
> +
> +   infoframe->set = true;
> +
> +   return 0;
> +}
> +
> +static int hdmi_generate_spd_infoframe(const struct drm_connector *connector,
> +  struct drm_connector_state *state)
> +{
> +   struct drm_connector_hdmi_infoframe *infoframe =
> +   &state->hdmi.infoframes.spd;
> +   struct hdmi_spd_infoframe *frame =
> +   &infoframe->data.spd;
> +   int ret;
> +
> +   ret = hdmi_spd_infoframe_init(frame,
> + connector->hdmi.vendor,
> + connector->hdmi.product);
> +   if (ret)
> +   return ret;
> +
> +   frame->sdi = HDMI_SPD_SDI_PC;
> +
> +   infoframe->set = true;
> +
> +   return 0;
> +}
> +
> +static int hdmi_generate_hdr_infoframe(const struct drm_connector *connector,
> +  struct drm_connector_state *state)
> +{
> +   struct drm_connector_hdmi_infoframe *infoframe =
> +   &state->hdmi.infoframes.hdr_drm;
> +   struct hdmi_drm_infoframe *frame =
> +   &infoframe->data.drm;
> +   int ret;
> +
> +   if (connector->max_bpc < 10)
> +   return 0;
> +
> +   if (!state->hdr_output_metadata)
> +   return 0;
> +
> +   ret = drm_hdmi_infoframe_set_hdr_metadata(frame, state);
> +   if (ret)
> +   return ret;
> +
> +   infoframe->set = true;
> +
> +   return 0;
> +}
> +
> +static int hdmi_generate_hdmi_vendor_infoframe(const struct drm_connector 
> *connector,
> +  struct drm_connector_state 
> *state)
> +{
> +   const struct drm_display_mode *mode =
> +   connector_state_get_mode(state);
> +   struct drm_connector_hdmi_infoframe *infoframe =
> +   &state->hdmi.infoframes.hdmi;
> +   struct hdmi_vendor_infoframe *frame =
> +   &infoframe->data.vendor.hdmi;
> +   int ret;
> +
> +   ret = drm_hdmi_vendor_infoframe_from_display_mode(f

Re: [PATCH v7 00/36] drm/connector: Create HDMI Connector infrastructure

2024-02-25 Thread Dmitry Baryshkov
Hi Maxime,

On Thu, 22 Feb 2024 at 20:14, Maxime Ripard  wrote:
>
> Hi,
>
> Here's a series that creates some extra infrastructure specifically
> targeted at HDMI controllers.
>
> The idea behind this series came from a recent discussion on IRC during
> which we discussed infoframes generation of i915 vs everything else.
>
> Infoframes generation code still requires some decent boilerplate, with
> each driver doing some variation of it.
>
> In parallel, while working on vc4, we ended up converting a lot of i915
> logic (mostly around format / bpc selection, and scrambler setup) to
> apply on top of a driver that relies only on helpers.
>
> While currently sitting in the vc4 driver, none of that logic actually
> relies on any driver or hardware-specific behaviour.
>
> The only missing piece to make it shareable are a bunch of extra
> variables stored in a state (current bpc, format, RGB range selection,
> etc.).
>
> The initial implementation was relying on some generic subclass of
> drm_connector to address HDMI connectors, with a bunch of helpers that
> will take care of all the "HDMI Spec" related code. Scrambler setup is
> missing at the moment but can easily be plugged in.
>
> The feedback was that creating a connector subclass like was done for
> writeback would prevent the adoption of those helpers since it couldn't
> be used in all situations (like when the connector driver can implement
> multiple output) and required more churn to cast between the
> drm_connector and its subclass. The decision was thus to provide a set
> of helper and to store the required variables in drm_connector and
> drm_connector_state. This what has been implemented now.
>
> Hans Verkuil also expressed interest in implementing a mechanism in v4l2
> to retrieve infoframes from HDMI receiver and implementing a tool to
> decode (and eventually check) infoframes. His current work on
> edid-decode to enable that based on that series can be found here:
> https://git.linuxtv.org/hverkuil/edid-decode.git/log/?h=hverkuil
>
> And some more context here:
> https://lore.kernel.org/dri-devel/50db7366-cd3d-4675-aaad-b85720223...@xs4all.nl/
>
> This series thus leverages the infoframe generation code to expose it
> through debugfs.

[...]

>
> Let me know what you think,
> Maxime

The overall idea looks great. I've started checking how I can use that
for our msm devices family, which makes use of bridges and
drm_bridge_connector.
My current idea is to extend the drm_bridge_funcs with the new
callback to be called once the drm_connector has been instantiated.
This way all the bridges can influence new connector.
Another possibility is to follow drm_bridge_connector design closely
and let it call into drm_connector_hdmi code if it detects that the
last bridge is the HDMI one.
WDYT?

Some context, older MSM devices have an on-die HDMI encoder,
implemented as drm_bridge at drivers/gpu/drm/msm/hdmi. Newer
generation of devices has dropped the on-die HDMI implementation in
favour of using external DSI-to-HDMI bridges, like Lontium LT9611 or
LT9611UXC. I'm looking at enabling new HDMI infrastructure for both
cases.

-- 
With best wishes
Dmitry


[PATCH v3 3/3] drm/msm/dpu: capture snapshot on the first commit_done timeout

2024-02-25 Thread Dmitry Baryshkov
In order to debug commit_done timeouts, capture the devcoredump state
when the first timeout occurs after the encoder has been enabled.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 30f349c8a1e5..3cae07bf0b9b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -126,6 +126,8 @@ enum dpu_enc_rc_states {
  * @base:  drm_encoder base class for registration with DRM
  * @enc_spinlock:  Virtual-Encoder-Wide Spin Lock for IRQ purposes
  * @enabled:   True if the encoder is active, protected by enc_lock
+ * @commit_done_timedout: True if there has been a timeout on commit after
+ * enabling the encoder.
  * @num_phys_encs: Actual number of physical encoders contained.
  * @phys_encs: Container of physical encoders managed.
  * @cur_master:Pointer to the current master in this mode. 
Optimization
@@ -172,6 +174,7 @@ struct dpu_encoder_virt {
spinlock_t enc_spinlock;
 
bool enabled;
+   bool commit_done_timedout;
 
unsigned int num_phys_encs;
struct dpu_encoder_phys *phys_encs[MAX_PHYS_ENCODERS_PER_VIRTUAL];
@@ -1226,6 +1229,8 @@ static void dpu_encoder_virt_atomic_enable(struct 
drm_encoder *drm_enc,
else if (disp_info->intf_type == INTF_DSI)
dpu_enc->wide_bus_en = 
msm_dsi_wide_bus_enabled(priv->dsi[index]);
 
+   dpu_enc->commit_done_timedout = false;
+
mutex_lock(&dpu_enc->enc_lock);
cur_mode = &dpu_enc->base.crtc->state->adjusted_mode;
 
@@ -2436,6 +2441,10 @@ int dpu_encoder_wait_for_commit_done(struct drm_encoder 
*drm_enc)
DPU_ATRACE_BEGIN("wait_for_commit_done");
ret = phys->ops.wait_for_commit_done(phys);
DPU_ATRACE_END("wait_for_commit_done");
+   if (ret == -ETIMEDOUT && 
!dpu_enc->commit_done_timedout) {
+   dpu_enc->commit_done_timedout = true;
+   msm_disp_snapshot_state(drm_enc->dev);
+   }
if (ret)
return ret;
}

-- 
2.39.2



[PATCH v3 1/3] drm/msm/dpu: make "vblank timeout" more useful

2024-02-25 Thread Dmitry Baryshkov
We have several reports of vblank timeout messages. However after some
debugging it was found that there might be different causes to that.
To allow us to identify the DPU block that gets stuck, include the
actual CTL_FLUSH value into the timeout message.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
index 2aa72b578764..6058706f03e4 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
@@ -480,7 +480,7 @@ static int dpu_encoder_phys_vid_wait_for_commit_done(
(hw_ctl->ops.get_flush_register(hw_ctl) == 0),
msecs_to_jiffies(50));
if (ret <= 0) {
-   DPU_ERROR("vblank timeout\n");
+   DPU_ERROR("vblank timeout: %x\n", 
hw_ctl->ops.get_flush_register(hw_ctl));
return -ETIMEDOUT;
}
 

-- 
2.39.2



[PATCH v3 2/3] drm/msm/dpu: split dpu_encoder_wait_for_event into two functions

2024-02-25 Thread Dmitry Baryshkov
Stop multiplexing several events via the dpu_encoder_wait_for_event()
function. Split it into two distinct functions two allow separate
handling of those events.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 74 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 22 ++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c |  2 +-
 drivers/gpu/drm/msm/msm_drv.h   | 10 
 4 files changed, 59 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 194dbb08331d..30f349c8a1e5 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1282,7 +1282,7 @@ static void dpu_encoder_virt_atomic_disable(struct 
drm_encoder *drm_enc,
trace_dpu_enc_disable(DRMID(drm_enc));
 
/* wait for idle */
-   dpu_encoder_wait_for_event(drm_enc, MSM_ENC_TX_COMPLETE);
+   dpu_encoder_wait_for_tx_complete(drm_enc);
 
dpu_encoder_resource_control(drm_enc, DPU_ENC_RC_EVENT_PRE_STOP);
 
@@ -2402,10 +2402,23 @@ struct drm_encoder *dpu_encoder_init(struct drm_device 
*dev,
return &dpu_enc->base;
 }
 
-int dpu_encoder_wait_for_event(struct drm_encoder *drm_enc,
-   enum msm_event_wait event)
+/**
+ * dpu_encoder_wait_for_commit_done() - Wait for encoder to flush pending state
+ * @drm_enc:   encoder pointer
+ *
+ * Wait for hardware to have flushed the current pending frames to hardware at
+ * a vblank or ctl_start Encoders will map this differently depending on the
+ * panel type.
+ *
+ * MSM_ENC_TX_COMPLETE -  Wait for the hardware to transfer all the pixels to
+ *the panel. Encoders will map this differently
+ *depending on the panel type.
+ *vid mode -> vsync_irq
+ *cmd mode -> pp_done
+ * Return: 0 on success, -EWOULDBLOCK if already signaled, error otherwise
+ */
+int dpu_encoder_wait_for_commit_done(struct drm_encoder *drm_enc)
 {
-   int (*fn_wait)(struct dpu_encoder_phys *phys_enc) = NULL;
struct dpu_encoder_virt *dpu_enc = NULL;
int i, ret = 0;
 
@@ -2419,23 +2432,46 @@ int dpu_encoder_wait_for_event(struct drm_encoder 
*drm_enc,
for (i = 0; i < dpu_enc->num_phys_encs; i++) {
struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
 
-   switch (event) {
-   case MSM_ENC_COMMIT_DONE:
-   fn_wait = phys->ops.wait_for_commit_done;
-   break;
-   case MSM_ENC_TX_COMPLETE:
-   fn_wait = phys->ops.wait_for_tx_complete;
-   break;
-   default:
-   DPU_ERROR_ENC(dpu_enc, "unknown wait event %d\n",
-   event);
-   return -EINVAL;
+   if (phys->ops.wait_for_commit_done) {
+   DPU_ATRACE_BEGIN("wait_for_commit_done");
+   ret = phys->ops.wait_for_commit_done(phys);
+   DPU_ATRACE_END("wait_for_commit_done");
+   if (ret)
+   return ret;
}
+   }
+
+   return ret;
+}
+
+/**
+ * dpu_encoder_wait_for_tx_complete() - Wait for encoder to transfer pixels to 
panel
+ * @drm_enc:   encoder pointer
+ *
+ * Wait for the hardware to transfer all the pixels to the panel. Encoders will
+ * map this differently depending on the panel type.
+ *
+ * Return: 0 on success, -EWOULDBLOCK if already signaled, error otherwise
+ */
+int dpu_encoder_wait_for_tx_complete(struct drm_encoder *drm_enc)
+{
+   struct dpu_encoder_virt *dpu_enc = NULL;
+   int i, ret = 0;
+
+   if (!drm_enc) {
+   DPU_ERROR("invalid encoder\n");
+   return -EINVAL;
+   }
+   dpu_enc = to_dpu_encoder_virt(drm_enc);
+   DPU_DEBUG_ENC(dpu_enc, "\n");
+
+   for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+   struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
 
-   if (fn_wait) {
-   DPU_ATRACE_BEGIN("wait_for_completion_event");
-   ret = fn_wait(phys);
-   DPU_ATRACE_END("wait_for_completion_event");
+   if (phys->ops.wait_for_tx_complete) {
+   DPU_ATRACE_BEGIN("wait_for_tx_complete");
+   ret = phys->ops.wait_for_tx_complete(phys);
+   DPU_ATRACE_END("wait_for_tx_complete");
if (ret)
return ret;
}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
index fe6b1d312a74..0c928d1876e4 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
@@ -93,25 +93,9 @@ void dpu_encoder_kickoff(str

[PATCH v3 0/3] drm/msm/dpu: debug commit_done timeouts

2024-02-25 Thread Dmitry Baryshkov
In order to debug commit_done timeouts ([1]) display the sticky bits of
the CTL_FLUSH register and capture the devcore dump when the first such
timeout occurs.

[1] https://gitlab.freedesktop.org/drm/msm/-/issues/33

Signed-off-by: Dmitry Baryshkov 
---
Changes in v3:
- Capture the snapshot only on the first comit_done timeout (Abhinav)
- Link to v2: 
https://lore.kernel.org/r/20240208-fd-dpu-debug-timeout-v2-1-9f907f1bd...@linaro.org

Changes in v2:
- Added a call to msm_disp_snapshot_state() to trigger devcore dump
  (Abhinav)
- Link to v1: 
https://lore.kernel.org/r/20240106-fd-dpu-debug-timeout-v1-1-6d9762884...@linaro.org

---
Dmitry Baryshkov (3):
  drm/msm/dpu: make "vblank timeout" more useful
  drm/msm/dpu: split dpu_encoder_wait_for_event into two functions
  drm/msm/dpu: capture snapshot on the first commit_done timeout

 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c| 83 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h| 22 +-
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c   |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c|  2 +-
 drivers/gpu/drm/msm/msm_drv.h  | 10 ---
 5 files changed, 69 insertions(+), 50 deletions(-)
---
base-commit: 33e1d31873f87d119e5120b88cd350efa68ef276
change-id: 20240106-fd-dpu-debug-timeout-e917f0bc8063

Best regards,
-- 
Dmitry Baryshkov 



Re: [PATCH v7 19/36] drm/connector: hdmi: Compute bpc and format automatically

2024-02-25 Thread Alex Bee

Hi Maxime,

Am 22.02.24 um 19:14 schrieb Maxime Ripard:

Now that we have all the infrastructure needed, we can add some code
that will, for a given connector state and mode, compute the best output
format and bpc.

The algorithm is equivalent to the one already found in i915 and vc4.

Signed-off-by: Maxime Ripard 
---
  drivers/gpu/drm/drm_atomic_state_helper.c  | 184 -
  .../gpu/drm/tests/drm_atomic_state_helper_test.c   |  25 ++-
  2 files changed, 197 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
b/drivers/gpu/drm/drm_atomic_state_helper.c
index 448b4a73d1c8..9f517599f117 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -31,6 +31,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
@@ -662,6 +663,96 @@ connector_state_get_mode(const struct drm_connector_state 
*conn_state)
return &crtc_state->mode;
  }
  
+static bool

+sink_supports_format_bpc(const struct drm_connector *connector,
+const struct drm_display_info *info,
+const struct drm_display_mode *mode,
+unsigned int format, unsigned int bpc)
+{
+   struct drm_device *dev = connector->dev;
+   u8 vic = drm_match_cea_mode(mode);
+
+   if (vic == 1 && bpc != 8) {
+   drm_dbg(dev, "VIC1 requires a bpc of 8, got %u\n", bpc);
+   return false;
+   }
+
+   if (!info->is_hdmi &&
+   (format != HDMI_COLORSPACE_RGB || bpc != 8)) {
+   drm_dbg(dev, "DVI Monitors require an RGB output at 8 bpc\n");
+   return false;
+   }
+
+   if (!(connector->hdmi.supported_formats & BIT(format))) {
+   drm_dbg(dev, "%s format unsupported by the connector.\n",
+   drm_hdmi_connector_get_output_format_name(format));
+   return false;
+   }
+
+   switch (format) {
+   case HDMI_COLORSPACE_RGB:
+   drm_dbg(dev, "RGB Format, checking the constraints.\n");
+
+   if (!(info->color_formats & DRM_COLOR_FORMAT_RGB444))
+   return false;
+
+   if (bpc == 10 && !(info->edid_hdmi_rgb444_dc_modes & 
DRM_EDID_HDMI_DC_30)) {
+   drm_dbg(dev, "10 BPC but sink doesn't support Deep Color 
30.\n");
+   return false;
+   }
+
+   if (bpc == 12 && !(info->edid_hdmi_rgb444_dc_modes & 
DRM_EDID_HDMI_DC_36)) {
+   drm_dbg(dev, "12 BPC but sink doesn't support Deep Color 
36.\n");
+   return false;
+   }
+
+   drm_dbg(dev, "RGB format supported in that configuration.\n");
+
+   return true;
+
+   case HDMI_COLORSPACE_YUV422:
+   drm_dbg(dev, "YUV422 format, checking the constraints.\n");
+
+   if (!(info->color_formats & DRM_COLOR_FORMAT_YCBCR422)) {
+   drm_dbg(dev, "Sink doesn't support YUV422.\n");
+   return false;
+   }
+
+   if (bpc != 12) {
+   drm_dbg(dev, "YUV422 only supports 12 bpc.\n");
+   return false;
+   }
+

I'm not sure this check is really necessary/helpful.
In [0] you are quoting HDMI specs which are saying that YUV422 is just
always 12 bpc - which I guess is correct. The problem I'm seeing here:
There are HDMI 1.4 controllers, like Rockchip Inno HDMI, that support
YUV422 but do not support any other color depth than 8 bpc for RGB or
YUV444. In drmm_connector_hdmi_init you are expecting to give the max bpc
as parameter and (if I'm getting it correctly) I'd had to set it to 12 to
also get YUV422 modes, but I'd also get RGB/YUV444 with bpc > 8 modes which
are not supported by this controller. I guess the same applies to other
HDMI 1.4 controllers that support YUV422. Or would I have to filter it out
myself?
So I guess the easiest way around is to drop the above check since it is
just always 12 bpc for YUV422 and there is no need to filter out anything.
(Same applies to the similar check in [0]).

Regards,
Alex

[0] 
https://lore.kernel.org/lkml/20240222-kms-hdmi-connector-state-v7-13-8f4af575f...@kernel.org/

+   drm_dbg(dev, "YUV422 format supported in that 
configuration.\n");
+
+   return true;
+
+   case HDMI_COLORSPACE_YUV444:
+   drm_dbg(dev, "YUV444 format, checking the constraints.\n");
+
+   if (!(info->color_formats & DRM_COLOR_FORMAT_YCBCR444)) {
+   drm_dbg(dev, "Sink doesn't support YUV444.\n");
+   return false;
+   }
+
+   if (bpc == 10 && !(info->edid_hdmi_ycbcr444_dc_modes & 
DRM_EDID_HDMI_DC_30)) {
+   drm_dbg(dev, "10 BPC but sink doesn't support Deep Color 
30.\n");
+   return false;
+   

Re: [PATCH 01/13] accel/habanalabs/gaudi2: use single function to compare FW versions

2024-02-25 Thread Ohad Sharabi
On 24/02/2024 0:38, Carl Vanderlip wrote:
> [You don't often get email from quic_ca...@quicinc.com. Learn why this 
> is important at https://aka.ms/LearnAboutSenderIdentification ]
>
> On 2/20/2024 8:01 AM, Oded Gabbay wrote:> From: Ohad Sharabi
> 
> >
> > Currently, the code contains 2 types of FW version comparison 
> functions:
> > - hl_is_fw_sw_ver_[below/equal_or_greater]()
> > - gaudi2 specific function of the type
> >    gaudi2_is_fw_ver_[below/above]x_y_z()
> >
> > Moreover, some functions use the inner FW version which should be only
> > stage during development but not version dependencies.
> >
> > Finally, some tests are done to deprecated FW version to which LKD
> > should hold no compatibility.
> >
> > This commit aligns all APIs to a single function that just compares the
> > version and return an integers indicator (similar in some way to
> > strcmp()).
> >
> > In addition, this generic function now considers also the sub-minor FW
> > version and also remove dead code resulting in deprecated FW versions
> > compatibility.
> >
> > Signed-off-by: Ohad Sharabi 
> > Reviewed-by: Oded Gabbay 
> > Signed-off-by: Oded Gabbay 
> > ---
> >   drivers/accel/habanalabs/common/firmware_if.c | 25 
> >   drivers/accel/habanalabs/common/habanalabs.h  | 20 +--
> >   drivers/accel/habanalabs/gaudi2/gaudi2.c  | 57 
> +++
> >   3 files changed, 34 insertions(+), 68 deletions(-)
> >
> ...
> > diff --git a/drivers/accel/habanalabs/gaudi2/gaudi2.c
> b/drivers/accel/habanalabs/gaudi2/gaudi2.c
> > index 1f061209ae21..4a0917aa4dd7 100644
> > --- a/drivers/accel/habanalabs/gaudi2/gaudi2.c
> > +++ b/drivers/accel/habanalabs/gaudi2/gaudi2.c
> > @@ -2601,6 +2601,8 @@ static int gaudi2_set_fixed_properties(struct
> hl_device *hdev)
> >
> >  prop->hbw_flush_reg = mmPCIE_WRAP_SPECIAL_GLBL_SPARE_0;
> >
> > +    prop->supports_advanced_cpucp_rc = true;
> > +
> >  return 0;
> >
> >   free_qprops:
> > @@ -3308,8 +3310,6 @@ static int gaudi2_late_init(struct hl_device 
> *hdev)
> >  struct gaudi2_device *gaudi2 = hdev->asic_specific;
> >  int rc;
> >
> > -    hdev->asic_prop.supports_advanced_cpucp_rc = true;
> > -
> >  rc = hl_fw_send_pci_access_msg(hdev, 
> CPUCP_PACKET_ENABLE_PCI_ACCESS,
> > gaudi2->virt_msix_db_dma_addr);
> >  if (rc) {

Carl,

Sure, we'll split the patches

Ohad

>
> Is this change in support of the others in this patch? Feels like this
> should be more than one patch (adding new version_cmp, removing old 
> checks).
>
> -Carl V.




Re: [drm-drm-misc:drm-misc-next v2] dt-bindings: nt35510: document 'port' property

2024-02-25 Thread Dario Binacchi
Hi,

On Wed, Feb 14, 2024 at 10:47 AM Alexandre TORGUE
 wrote:
>
> Hi Heiko
>
> On 1/31/24 16:53, Conor Dooley wrote:
> > On Wed, Jan 31, 2024 at 10:28:44AM +0100, Dario Binacchi wrote:
> >> Allow 'port' property (coming from panel-common.yaml) to be used in DTS:
> >>
> >>st/stm32f769-disco-mb1166-reva09.dtb: panel@0: 'port' does not match 
> >> any of the regexes: 'pinctrl-[0-9]+'
> >>
> >> Signed-off-by: Dario Binacchi 
> >> Cc: Alexandre Torgue 
> >
> > Acked-by: Conor Dooley 
> >
> >
> >>
> >> ---
> >>
> >> Changes in v2:
> >> - Rework the patch to drop errors found by command
> >>'make DT_CHECKER_FLAGS=-m dt_binding_check'.
> >>
> >>   .../devicetree/bindings/display/panel/novatek,nt35510.yaml   | 1 +
> >>   1 file changed, 1 insertion(+)
> >>
> >> diff --git 
> >> a/Documentation/devicetree/bindings/display/panel/novatek,nt35510.yaml 
> >> b/Documentation/devicetree/bindings/display/panel/novatek,nt35510.yaml
> >> index a4afaff483b7..91921f4b0e5f 100644
> >> --- a/Documentation/devicetree/bindings/display/panel/novatek,nt35510.yaml
> >> +++ b/Documentation/devicetree/bindings/display/panel/novatek,nt35510.yaml
> >> @@ -31,6 +31,7 @@ properties:
> >> vddi-supply:
> >>   description: regulator that supplies the vddi voltage
> >> backlight: true
> >> +  port: true
> >>
> >>   required:
> >> - compatible
> >> --
> >> 2.43.0
> >>
>
> Do you plan to take this patch in drm-misc next branch ? As I have a
> dependency with it to merge a DT patch I can take in my tree
> (stm32-next) if you prefer. Let me know.
>
> Cheers
> Alex

It's been some weeks, so a gentle ping seems in order :)

Thanks and regards,
Dario

-- 

Dario Binacchi

Senior Embedded Linux Developer

dario.binac...@amarulasolutions.com

__


Amarula Solutions SRL

Via Le Canevare 30, 31100 Treviso, Veneto, IT

T. +39 042 243 5310
i...@amarulasolutions.com

www.amarulasolutions.com


Re: [FYI][PATCH] tracing/treewide: Remove second parameter of __assign_str()

2024-02-25 Thread Kent Overstreet
On Fri, Feb 23, 2024 at 01:46:53PM -0500, Steven Rostedt wrote:
> On Fri, 23 Feb 2024 10:30:45 -0800
> Jeff Johnson  wrote:
> 
> > On 2/23/2024 9:56 AM, Steven Rostedt wrote:
> > > From: "Steven Rostedt (Google)" 
> > > 
> > > [
> > >This is a treewide change. I will likely re-create this patch again in
> > >the second week of the merge window of v6.9 and submit it then. Hoping
> > >to keep the conflicts that it will cause to a minimum.
> > > ]
> > > 
> > > With the rework of how the __string() handles dynamic strings where it
> > > saves off the source string in field in the helper structure[1], the
> > > assignment of that value to the trace event field is stored in the helper
> > > value and does not need to be passed in again.  
> > 
> > Just curious if this could be done piecemeal by first changing the
> > macros to be variadic macros which allows you to ignore the extra
> > argument. The callers could then be modified in their separate trees.
> > And then once all the callers have be merged, the macros could be
> > changed to no longer be variadic.
> 
> I weighed doing that, but I think ripping off the band-aid is a better
> approach. One thing I found is that leaving unused parameters in the macros
> can cause bugs itself. I found one case doing my clean up, where an unused
> parameter in one of the macros was bogus, and when I made it a used
> parameter, it broke the build.
> 
> I think for tree-wide changes, the preferred approach is to do one big
> patch at once. And since this only affects TRACE_EVENT() macros, it
> hopefully would not be too much of a burden (although out of tree users may
> suffer from this, but do we care?)

Agreed on doing it all at once, it'll be way less spam for people to
deal with.

Tangentially related though, what would make me really happy is if we
could create the string with in the TP__fast_assign() section. I have to
have a bunch of annoying wrappers right now because the string length
has to be known when we invoke the tracepoint.


[PATCH 0/3] panel-simple: add support for Crystal Clear CMT430B19N00

2024-02-25 Thread Jérémie Dautheribes
This patch series add support for the Crystal Clear Technology
CMT430B19N00 4.3" 480x272 TFT-LCD panel.
It also adds Crystal Clear Technology to vendor-prefixes.yaml.

Please note that unfortunately there is no public datasheet available
for this panel.

Jérémie Dautheribes (3):
  dt-bindings: Add Crystal Clear Technology vendor prefix
  dt-bindings: display: simple: add support for Crystal Clear
CMT430B19N00
  drm/panel: simple: add CMT430B19N00 LCD panel support

 .../bindings/display/panel/panel-simple.yaml  |  2 ++
 .../devicetree/bindings/vendor-prefixes.yaml  |  2 ++
 drivers/gpu/drm/panel/panel-simple.c  | 29 +++
 3 files changed, 33 insertions(+)

-- 
2.34.1



[PATCH 3/3] drm/panel: simple: add CMT430B19N00 LCD panel support

2024-02-25 Thread Jérémie Dautheribes
Add support for Crystal Clear Technology CMT430B19N00 4.3" 480x272
TFT-LCD panel.

Signed-off-by: Jérémie Dautheribes 
---
 drivers/gpu/drm/panel/panel-simple.c | 29 
 1 file changed, 29 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-simple.c 
b/drivers/gpu/drm/panel/panel-simple.c
index 20e3df1c59d4..b940220f56e2 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -1457,6 +1457,32 @@ static const struct panel_desc boe_hv070wsa = {
.connector_type = DRM_MODE_CONNECTOR_LVDS,
 };
 
+static const struct drm_display_mode cct_cmt430b19n00_mode = {
+   .clock = 9000,
+   .hdisplay = 480,
+   .hsync_start = 480 + 43,
+   .hsync_end = 480 + 43 + 8,
+   .htotal = 480 + 43 + 8 + 4,
+   .vdisplay = 272,
+   .vsync_start = 272 + 12,
+   .vsync_end = 272 + 12 + 8,
+   .vtotal = 272 + 12 + 8 + 4,
+   .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
+};
+
+static const struct panel_desc cct_cmt430b19n00 = {
+   .modes = &cct_cmt430b19n00_mode,
+   .num_modes = 1,
+   .bpc = 8,
+   .size = {
+   .width = 95,
+   .height = 53,
+   },
+   .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
+   .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE,
+   .connector_type = DRM_MODE_CONNECTOR_DPI,
+};
+
 static const struct drm_display_mode cdtech_s043wq26h_ct7_mode = {
.clock = 9000,
.hdisplay = 480,
@@ -4402,6 +4428,9 @@ static const struct of_device_id platform_of_match[] = {
}, {
.compatible = "boe,hv070wsa-100",
.data = &boe_hv070wsa
+   }, {
+   .compatible = "cct,cmt430b19n00",
+   .data = &cct_cmt430b19n00,
}, {
.compatible = "cdtech,s043wq26h-ct7",
.data = &cdtech_s043wq26h_ct7,
-- 
2.34.1



Re: [PATCH v2 2/7] clk: qcom: clk-alpha-pll: Add HUAYRA_2290 support

2024-02-25 Thread Trilok Soni
On 2/23/2024 1:21 PM, Konrad Dybcio wrote:
> + /* Wait 50us for PLL_LOCK_DET bit to go high */
> + usleep_range(50, 55);
> +
> + /* Enable PLL output */
> + regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, PLL_OUTCTRL);
> +}
> +EXPORT_SYMBOL(clk_huayra_2290_pll_configure);

Please use EXPORT_SYMBOL_GPL. 

-- 
---Trilok Soni



[PATCH 1/3] dt-bindings: Add Crystal Clear Technology vendor prefix

2024-02-25 Thread Jérémie Dautheribes
Update Documentation/devicetree/bindings/vendor-prefixes.yaml to
include "cct" as a vendor prefix for "Crystal Clear Technology". CCT is
the vendor of the CMT430B19N00 TFT-LCD panel.

Signed-off-by: Jérémie Dautheribes 
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml 
b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index fef2e12b504e..96e47742e250 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -248,6 +248,8 @@ patternProperties:
 description: Catalyst Semiconductor, Inc.
   "^cavium,.*":
 description: Cavium, Inc.
+  "^cct,.*":
+description: Crystal Clear Technology Sdn. Bhd.
   "^cdns,.*":
 description: Cadence Design Systems Inc.
   "^cdtech,.*":
-- 
2.34.1



[PATCH 2/3] dt-bindings: display: simple: add support for Crystal Clear CMT430B19N00

2024-02-25 Thread Jérémie Dautheribes
Add Crystal Clear Technology CMT430B19N00 4.3" 480x272 TFT-LCD panel
compatible string.

Signed-off-by: Jérémie Dautheribes 
---
 .../devicetree/bindings/display/panel/panel-simple.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml 
b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
index a95445f40870..c575f7c4b745 100644
--- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
+++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
@@ -91,6 +91,8 @@ properties:
   - boe,nv133fhm-n62
 # BOE NV140FHM-N49 14.0" FHD a-Si FT panel
   - boe,nv140fhmn49
+# Crystal Clear Technology CMT430B19N00 4.3" 480x272 TFT-LCD panel
+  - cct,cmt430b19n00
 # CDTech(H.K.) Electronics Limited 4.3" 480x272 color TFT-LCD panel
   - cdtech,s043wq26h-ct7
 # CDTech(H.K.) Electronics Limited 7" WSVGA (1024x600) TFT LCD Panel
-- 
2.34.1



Re: [PATCH 2/2] drm/tiny: Add driver for the sharp LS027B7DH01 Memory LCD

2024-02-25 Thread Mehdi Djait
Hi Thomas, 

Thank you for the review.

On Wed, Nov 29, 2023 at 05:21:19PM +0100, Thomas Zimmermann wrote:
> Hi,
> 
> thanks for the patches.
> 
> Am 29.11.23 um 15:29 schrieb Mehdi Djait:
> > Introduce a DRM driver for the sharp LS027B7DH01 Memory LCD.
> > 
> > LS027B7DH01 is a 2.7" 400x240 monochrome display connected to a SPI bus.
> > The drivers implements the Multiple Lines Data Update Mode.
> > External COM inversion is enabled using a PWM signal as input.
> > 
> > Signed-off-by: Mehdi Djait 
> > ---
> >   MAINTAINERS  |   7 +
> >   drivers/gpu/drm/tiny/Kconfig |   8 +
> >   drivers/gpu/drm/tiny/Makefile|   1 +
> >   drivers/gpu/drm/tiny/sharp-ls027b7dh01.c | 411 +++
> >   4 files changed, 427 insertions(+)
> >   create mode 100644 drivers/gpu/drm/tiny/sharp-ls027b7dh01.c
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 012df8ccf34e..fb859698bd3d 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -6832,6 +6832,13 @@ S:   Maintained
> >   F:
> > Documentation/devicetree/bindings/display/panel/samsung,s6d7aa0.yaml
> >   F:drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c
> > +DRM DRIVER FOR SHARP LS027B7DH01 Memory LCD
> > +M: Mehdi Djait 
> > +S: Maintained
> > +T: git git://anongit.freedesktop.org/drm/drm-misc
> > +F: Documentation/devicetree/bindings/display/sharp,ls027b7dh01.yaml
> > +F: drivers/gpu/drm/tiny/sharp-ls027b7dh01.c
> > +
> >   DRM DRIVER FOR SITRONIX ST7586 PANELS
> >   M:David Lechner 
> >   S:Maintained
> > diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig
> > index f6889f649bc1..a2ade06403ca 100644
> > --- a/drivers/gpu/drm/tiny/Kconfig
> > +++ b/drivers/gpu/drm/tiny/Kconfig
> > @@ -186,6 +186,14 @@ config TINYDRM_REPAPER
> >   If M is selected the module will be called repaper.
> > +config TINYDRM_SHARP_LS027B7DH01
> > +   tristate "DRM support for SHARP LS027B7DH01 display"
> > +   depends on DRM && SPI
> > +   select DRM_KMS_HELPER
> > +   select DRM_GEM_DMA_HELPER
> > +   help
> > + DRM driver for the SHARP LS027B7DD01 LCD display.
> > +
> >   config TINYDRM_ST7586
> > tristate "DRM support for Sitronix ST7586 display panels"
> > depends on DRM && SPI
> > diff --git a/drivers/gpu/drm/tiny/Makefile b/drivers/gpu/drm/tiny/Makefile
> > index 76dde89a044b..b05df3afb231 100644
> > --- a/drivers/gpu/drm/tiny/Makefile
> > +++ b/drivers/gpu/drm/tiny/Makefile
> > @@ -14,5 +14,6 @@ obj-$(CONFIG_TINYDRM_ILI9341) += ili9341.o
> >   obj-$(CONFIG_TINYDRM_ILI9486) += ili9486.o
> >   obj-$(CONFIG_TINYDRM_MI0283QT)+= mi0283qt.o
> >   obj-$(CONFIG_TINYDRM_REPAPER) += repaper.o
> > +obj-$(CONFIG_TINYDRM_SHARP_LS027B7DH01)+= sharp-ls027b7dh01.o
> >   obj-$(CONFIG_TINYDRM_ST7586)  += st7586.o
> >   obj-$(CONFIG_TINYDRM_ST7735R) += st7735r.o
> > diff --git a/drivers/gpu/drm/tiny/sharp-ls027b7dh01.c 
> > b/drivers/gpu/drm/tiny/sharp-ls027b7dh01.c
> > new file mode 100644
> > index ..2f58865a5c78
> > --- /dev/null
> > +++ b/drivers/gpu/drm/tiny/sharp-ls027b7dh01.c
> > @@ -0,0 +1,411 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Sharp LS027B7DH01 Memory Display Driver
> > + *
> > + * Copyright (C) 2023 Andrew D'Angelo
> > + * Copyright (C) 2023 Mehdi Djait 
> > + *
> > + * The Sharp Memory LCD requires an alternating signal to prevent the 
> > buildup of
> > + * a DC bias that would result in a Display that no longer can be updated. 
> > Two
> > + * modes for the generation of this signal are supported:
> > + *
> > + * Software, EXTMODE = Low: toggling the BIT(1) of the Command and writing 
> > it at
> > + * least once a second to the display.
> > + *
> > + * Hardware, EXTMODE = High: the alternating signal should be supplied on 
> > the
> > + * EXTCOMIN pin.
> > + *
> > + * In this driver the Hardware mode is implemented with a PWM signal.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define CMD_WRITE BIT(0)
> > +#define CMD_CLEAR BIT(2)
> > +
> > +struct sharp_ls027b7dh01 {
> > +   struct spi_device *spi;
> > +
> > +   struct drm_device drm;
> > +   struct drm_connector connector;
> > +   struct drm_simple_display_pipe pipe;
> 
> Could you please replace the simple pipe and its helpers with regular
> DRMhelpers. It should no tbe used in new drivers. It's an unnecessary
> indirection. Replacing is simple: copy the content of the data structure and
> its helpers into the driver. Maybe clean up the result, if necessary.


Could you please further explain where to copy the helper functions or give me
an example driver ? This is my first DRM driver and grepping did not help me 
much.

(Sorry for the delayed response)

[PATCH v12 6/8] udmabuf: Convert udmabuf driver to use folios

2024-02-25 Thread Vivek Kasireddy
This is mainly a preparatory patch to use memfd_pin_folios() API
for pinning folios. Using folios instead of pages makes sense as
the udmabuf driver needs to handle both shmem and hugetlb cases.
However, the function vmap_udmabuf() still needs a list of pages;
so, we collect all the head pages into a local array in this case.

Other changes in this patch include the addition of helpers for
checking the memfd seals and exporting dmabuf. Moving code from
udmabuf_create() into these helpers improves readability given
that udmabuf_create() is a bit long.

Cc: David Hildenbrand 
Cc: Matthew Wilcox 
Cc: Daniel Vetter 
Cc: Mike Kravetz 
Cc: Hugh Dickins 
Cc: Peter Xu 
Cc: Jason Gunthorpe 
Cc: Gerd Hoffmann 
Cc: Dongwon Kim 
Cc: Junxiao Chang 
Signed-off-by: Vivek Kasireddy 
---
 drivers/dma-buf/udmabuf.c | 140 ++
 1 file changed, 83 insertions(+), 57 deletions(-)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index 274defd3fa3e..a8f3af61f7f2 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -26,7 +26,7 @@ MODULE_PARM_DESC(size_limit_mb, "Max size of a dmabuf, in 
megabytes. Default is
 
 struct udmabuf {
pgoff_t pagecount;
-   struct page **pages;
+   struct folio **folios;
struct sg_table *sg;
struct miscdevice *device;
pgoff_t *offsets;
@@ -42,7 +42,7 @@ static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf)
if (pgoff >= ubuf->pagecount)
return VM_FAULT_SIGBUS;
 
-   pfn = page_to_pfn(ubuf->pages[pgoff]);
+   pfn = folio_pfn(ubuf->folios[pgoff]);
pfn += ubuf->offsets[pgoff] >> PAGE_SHIFT;
 
return vmf_insert_pfn(vma, vmf->address, pfn);
@@ -68,11 +68,21 @@ static int mmap_udmabuf(struct dma_buf *buf, struct 
vm_area_struct *vma)
 static int vmap_udmabuf(struct dma_buf *buf, struct iosys_map *map)
 {
struct udmabuf *ubuf = buf->priv;
+   struct page **pages;
void *vaddr;
+   pgoff_t pg;
 
dma_resv_assert_held(buf->resv);
 
-   vaddr = vm_map_ram(ubuf->pages, ubuf->pagecount, -1);
+   pages = kmalloc_array(ubuf->pagecount, sizeof(*pages), GFP_KERNEL);
+   if (!pages)
+   return -ENOMEM;
+
+   for (pg = 0; pg < ubuf->pagecount; pg++)
+   pages[pg] = &ubuf->folios[pg]->page;
+
+   vaddr = vm_map_ram(pages, ubuf->pagecount, -1);
+   kfree(pages);
if (!vaddr)
return -EINVAL;
 
@@ -107,7 +117,8 @@ static struct sg_table *get_sg_table(struct device *dev, 
struct dma_buf *buf,
goto err_alloc;
 
for_each_sg(sg->sgl, sgl, ubuf->pagecount, i)
-   sg_set_page(sgl, ubuf->pages[i], PAGE_SIZE, ubuf->offsets[i]);
+   sg_set_folio(sgl, ubuf->folios[i], PAGE_SIZE,
+ubuf->offsets[i]);
 
ret = dma_map_sgtable(dev, sg, direction, 0);
if (ret < 0)
@@ -152,9 +163,9 @@ static void release_udmabuf(struct dma_buf *buf)
put_sg_table(dev, ubuf->sg, DMA_BIDIRECTIONAL);
 
for (pg = 0; pg < ubuf->pagecount; pg++)
-   put_page(ubuf->pages[pg]);
+   folio_put(ubuf->folios[pg]);
kfree(ubuf->offsets);
-   kfree(ubuf->pages);
+   kfree(ubuf->folios);
kfree(ubuf);
 }
 
@@ -215,36 +226,33 @@ static int handle_hugetlb_pages(struct udmabuf *ubuf, 
struct file *memfd,
pgoff_t mapidx = offset >> huge_page_shift(hpstate);
pgoff_t subpgoff = (offset & ~huge_page_mask(hpstate)) >> PAGE_SHIFT;
pgoff_t maxsubpgs = huge_page_size(hpstate) >> PAGE_SHIFT;
-   struct page *hpage = NULL;
-   struct folio *folio;
+   struct folio *folio = NULL;
pgoff_t pgidx;
 
mapidx <<= huge_page_order(hpstate);
for (pgidx = 0; pgidx < pgcnt; pgidx++) {
-   if (!hpage) {
+   if (!folio) {
folio = __filemap_get_folio(memfd->f_mapping,
mapidx,
FGP_ACCESSED, 0);
if (IS_ERR(folio))
return PTR_ERR(folio);
-
-   hpage = &folio->page;
}
 
-   get_page(hpage);
-   ubuf->pages[*pgbuf] = hpage;
+   folio_get(folio);
+   ubuf->folios[*pgbuf] = folio;
ubuf->offsets[*pgbuf] = subpgoff << PAGE_SHIFT;
(*pgbuf)++;
if (++subpgoff == maxsubpgs) {
-   put_page(hpage);
-   hpage = NULL;
+   folio_put(folio);
+   folio = NULL;
subpgoff = 0;
mapidx += pages_per_huge_page(hpstate);
}
}
 
-   if (hpage)
-   put_page(hpage);
+   if (folio)
+   folio_put(folio);
 
return 0;
 }
@@ -254,31 +262,

[PATCH v12 7/8] udmabuf: Pin the pages using memfd_pin_folios() API

2024-02-25 Thread Vivek Kasireddy
Using memfd_pin_folios() will ensure that the pages are pinned
correctly using FOLL_PIN. And, this also ensures that we don't
accidentally break features such as memory hotunplug as it would
not allow pinning pages in the movable zone.

Using this new API also simplifies the code as we no longer have
to deal with extracting individual pages from their mappings or
handle shmem and hugetlb cases separately.

Cc: David Hildenbrand 
Cc: Matthew Wilcox 
Cc: Daniel Vetter 
Cc: Mike Kravetz 
Cc: Hugh Dickins 
Cc: Peter Xu 
Cc: Jason Gunthorpe 
Cc: Gerd Hoffmann 
Cc: Dongwon Kim 
Cc: Junxiao Chang 
Signed-off-by: Vivek Kasireddy 
---
 drivers/dma-buf/udmabuf.c | 153 +++---
 1 file changed, 78 insertions(+), 75 deletions(-)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index a8f3af61f7f2..afa8bfd2a2a9 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -30,6 +30,12 @@ struct udmabuf {
struct sg_table *sg;
struct miscdevice *device;
pgoff_t *offsets;
+   struct list_head unpin_list;
+};
+
+struct udmabuf_folio {
+   struct folio *folio;
+   struct list_head list;
 };
 
 static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf)
@@ -153,17 +159,43 @@ static void unmap_udmabuf(struct dma_buf_attachment *at,
return put_sg_table(at->dev, sg, direction);
 }
 
+static void unpin_all_folios(struct list_head *unpin_list)
+{
+   struct udmabuf_folio *ubuf_folio;
+
+   while (!list_empty(unpin_list)) {
+   ubuf_folio = list_first_entry(unpin_list,
+ struct udmabuf_folio, list);
+   unpin_folio(ubuf_folio->folio);
+
+   list_del(&ubuf_folio->list);
+   kfree(ubuf_folio);
+   }
+}
+
+static int add_to_unpin_list(struct list_head *unpin_list,
+struct folio *folio)
+{
+   struct udmabuf_folio *ubuf_folio;
+
+   ubuf_folio = kzalloc(sizeof(*ubuf_folio), GFP_KERNEL);
+   if (!ubuf_folio)
+   return -ENOMEM;
+
+   ubuf_folio->folio = folio;
+   list_add_tail(&ubuf_folio->list, unpin_list);
+   return 0;
+}
+
 static void release_udmabuf(struct dma_buf *buf)
 {
struct udmabuf *ubuf = buf->priv;
struct device *dev = ubuf->device->this_device;
-   pgoff_t pg;
 
if (ubuf->sg)
put_sg_table(dev, ubuf->sg, DMA_BIDIRECTIONAL);
 
-   for (pg = 0; pg < ubuf->pagecount; pg++)
-   folio_put(ubuf->folios[pg]);
+   unpin_all_folios(&ubuf->unpin_list);
kfree(ubuf->offsets);
kfree(ubuf->folios);
kfree(ubuf);
@@ -218,64 +250,6 @@ static const struct dma_buf_ops udmabuf_ops = {
 #define SEALS_WANTED (F_SEAL_SHRINK)
 #define SEALS_DENIED (F_SEAL_WRITE)
 
-static int handle_hugetlb_pages(struct udmabuf *ubuf, struct file *memfd,
-   pgoff_t offset, pgoff_t pgcnt,
-   pgoff_t *pgbuf)
-{
-   struct hstate *hpstate = hstate_file(memfd);
-   pgoff_t mapidx = offset >> huge_page_shift(hpstate);
-   pgoff_t subpgoff = (offset & ~huge_page_mask(hpstate)) >> PAGE_SHIFT;
-   pgoff_t maxsubpgs = huge_page_size(hpstate) >> PAGE_SHIFT;
-   struct folio *folio = NULL;
-   pgoff_t pgidx;
-
-   mapidx <<= huge_page_order(hpstate);
-   for (pgidx = 0; pgidx < pgcnt; pgidx++) {
-   if (!folio) {
-   folio = __filemap_get_folio(memfd->f_mapping,
-   mapidx,
-   FGP_ACCESSED, 0);
-   if (IS_ERR(folio))
-   return PTR_ERR(folio);
-   }
-
-   folio_get(folio);
-   ubuf->folios[*pgbuf] = folio;
-   ubuf->offsets[*pgbuf] = subpgoff << PAGE_SHIFT;
-   (*pgbuf)++;
-   if (++subpgoff == maxsubpgs) {
-   folio_put(folio);
-   folio = NULL;
-   subpgoff = 0;
-   mapidx += pages_per_huge_page(hpstate);
-   }
-   }
-
-   if (folio)
-   folio_put(folio);
-
-   return 0;
-}
-
-static int handle_shmem_pages(struct udmabuf *ubuf, struct file *memfd,
- pgoff_t offset, pgoff_t pgcnt,
- pgoff_t *pgbuf)
-{
-   pgoff_t pgidx, pgoff = offset >> PAGE_SHIFT;
-   struct folio *folio = NULL;
-
-   for (pgidx = 0; pgidx < pgcnt; pgidx++) {
-   folio = shmem_read_folio(memfd->f_mapping, pgoff + pgidx);
-   if (IS_ERR(folio))
-   return PTR_ERR(folio);
-
-   ubuf->folios[*pgbuf] = folio;
-   (*pgbuf)++;
-   }
-
-   return 0;
-}
-
 static int check_memfd_seals(struct file *memfd)
 {
int seals;
@@ -321,16 +295,19 @@ static long udmabuf_creat

[PATCH v12 8/8] selftests/udmabuf: Add tests to verify data after page migration

2024-02-25 Thread Vivek Kasireddy
Since the memfd pages associated with a udmabuf may be migrated
as part of udmabuf create, we need to verify the data coherency
after successful migration. The new tests added in this patch try
to do just that using 4k sized pages and also 2 MB sized huge
pages for the memfd.

Successful completion of the tests would mean that there is no
disconnect between the memfd pages and the ones associated with
a udmabuf. And, these tests can also be augmented in the future
to test newer udmabuf features (such as handling memfd hole punch).

The idea for these tests comes from a patch by Mike Kravetz.

Cc: Shuah Khan 
Cc: David Hildenbrand 
Cc: Daniel Vetter 
Cc: Mike Kravetz 
Cc: Hugh Dickins 
Cc: Peter Xu 
Cc: Jason Gunthorpe 
Cc: Gerd Hoffmann 
Cc: Dongwon Kim 
Cc: Junxiao Chang 
Signed-off-by: Vivek Kasireddy 
---
 .../selftests/drivers/dma-buf/udmabuf.c   | 151 +-
 1 file changed, 147 insertions(+), 4 deletions(-)

diff --git a/tools/testing/selftests/drivers/dma-buf/udmabuf.c 
b/tools/testing/selftests/drivers/dma-buf/udmabuf.c
index c812080e304e..d76c813fe652 100644
--- a/tools/testing/selftests/drivers/dma-buf/udmabuf.c
+++ b/tools/testing/selftests/drivers/dma-buf/udmabuf.c
@@ -9,26 +9,132 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
+#include 
 #include 
 #include 
 
 #define TEST_PREFIX"drivers/dma-buf/udmabuf"
 #define NUM_PAGES   4
+#define NUM_ENTRIES 4
+#define MEMFD_SIZE  1024 /* in pages */
 
-static int memfd_create(const char *name, unsigned int flags)
+static unsigned int page_size;
+
+static int create_memfd_with_seals(off64_t size, bool hpage)
+{
+   int memfd, ret;
+   unsigned int flags = MFD_ALLOW_SEALING;
+
+   if (hpage)
+   flags |= MFD_HUGETLB;
+
+   memfd = memfd_create("udmabuf-test", flags);
+   if (memfd < 0) {
+   printf("%s: [skip,no-memfd]\n", TEST_PREFIX);
+   exit(77);
+   }
+
+   ret = fcntl(memfd, F_ADD_SEALS, F_SEAL_SHRINK);
+   if (ret < 0) {
+   printf("%s: [skip,fcntl-add-seals]\n", TEST_PREFIX);
+   exit(77);
+   }
+
+   ret = ftruncate(memfd, size);
+   if (ret == -1) {
+   printf("%s: [FAIL,memfd-truncate]\n", TEST_PREFIX);
+   exit(1);
+   }
+
+   return memfd;
+}
+
+static int create_udmabuf_list(int devfd, int memfd, off64_t memfd_size)
+{
+   struct udmabuf_create_list *list;
+   int ubuf_fd, i;
+
+   list = malloc(sizeof(struct udmabuf_create_list) +
+ sizeof(struct udmabuf_create_item) * NUM_ENTRIES);
+   if (!list) {
+   printf("%s: [FAIL, udmabuf-malloc]\n", TEST_PREFIX);
+   exit(1);
+   }
+
+   for (i = 0; i < NUM_ENTRIES; i++) {
+   list->list[i].memfd  = memfd;
+   list->list[i].offset = i * (memfd_size / NUM_ENTRIES);
+   list->list[i].size   = getpagesize() * NUM_PAGES;
+   }
+
+   list->count = NUM_ENTRIES;
+   list->flags = UDMABUF_FLAGS_CLOEXEC;
+   ubuf_fd = ioctl(devfd, UDMABUF_CREATE_LIST, list);
+   free(list);
+   if (ubuf_fd < 0) {
+   printf("%s: [FAIL, udmabuf-create]\n", TEST_PREFIX);
+   exit(1);
+   }
+
+   return ubuf_fd;
+}
+
+static void write_to_memfd(void *addr, off64_t size, char chr)
+{
+   int i;
+
+   for (i = 0; i < size / page_size; i++) {
+   *((char *)addr + (i * page_size)) = chr;
+   }
+}
+
+static void *mmap_fd(int fd, off64_t size)
 {
-   return syscall(__NR_memfd_create, name, flags);
+   void *addr;
+
+   addr = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+   if (addr == MAP_FAILED) {
+   printf("%s: ubuf_fd mmap fail\n", TEST_PREFIX);
+   exit(1);
+   }
+
+   return addr;
+}
+
+static int compare_chunks(void *addr1, void *addr2, off64_t memfd_size)
+{
+   off64_t off;
+   int i = 0, j, k = 0, ret = 0;
+   char char1, char2;
+
+   while (i < NUM_ENTRIES) {
+   off = i * (memfd_size / NUM_ENTRIES);
+   for (j = 0; j < NUM_PAGES; j++, k++) {
+   char1 = *((char *)addr1 + off + (j * getpagesize()));
+   char2 = *((char *)addr2 + (k * getpagesize()));
+   if (char1 != char2) {
+   ret = -1;
+   goto err;
+   }
+   }
+   i++;
+   }
+err:
+   munmap(addr1, memfd_size);
+   munmap(addr2, NUM_ENTRIES * NUM_PAGES * getpagesize());
+   return ret;
 }
 
 int main(int argc, char *argv[])
 {
struct udmabuf_create create;
int devfd, memfd, buf, ret;
-   off_t size;
-   void *mem;
+   off64_t size;
+   void *addr1, *addr2;
 
devfd = open("/dev/udmabuf", O_RDWR);
if (devfd < 0) {
@@ -90,6 +196,9 @@ int main(int argc, char *argv[])
}
 
 

[PATCH v12 4/8] udmabuf: Use vmf_insert_pfn and VM_PFNMAP for handling mmap

2024-02-25 Thread Vivek Kasireddy
Add VM_PFNMAP to vm_flags in the mmap handler to ensure that
the mappings would be managed without using struct page.

And, in the vm_fault handler, use vmf_insert_pfn to share the
page's pfn to userspace instead of directly sharing the page
(via struct page *).

Cc: David Hildenbrand 
Cc: Daniel Vetter 
Cc: Mike Kravetz 
Cc: Hugh Dickins 
Cc: Peter Xu 
Cc: Jason Gunthorpe 
Cc: Gerd Hoffmann 
Cc: Dongwon Kim 
Cc: Junxiao Chang 
Suggested-by: David Hildenbrand 
Acked-by: David Hildenbrand 
Signed-off-by: Vivek Kasireddy 
---
 drivers/dma-buf/udmabuf.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index c40645999648..820c993c8659 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -35,12 +35,13 @@ static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf)
struct vm_area_struct *vma = vmf->vma;
struct udmabuf *ubuf = vma->vm_private_data;
pgoff_t pgoff = vmf->pgoff;
+   unsigned long pfn;
 
if (pgoff >= ubuf->pagecount)
return VM_FAULT_SIGBUS;
-   vmf->page = ubuf->pages[pgoff];
-   get_page(vmf->page);
-   return 0;
+
+   pfn = page_to_pfn(ubuf->pages[pgoff]);
+   return vmf_insert_pfn(vma, vmf->address, pfn);
 }
 
 static const struct vm_operations_struct udmabuf_vm_ops = {
@@ -56,6 +57,7 @@ static int mmap_udmabuf(struct dma_buf *buf, struct 
vm_area_struct *vma)
 
vma->vm_ops = &udmabuf_vm_ops;
vma->vm_private_data = ubuf;
+   vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
return 0;
 }
 
-- 
2.43.0



[PATCH v12 0/8] mm/gup: Introduce memfd_pin_folios() for pinning memfd folios

2024-02-25 Thread Vivek Kasireddy
Currently, some drivers (e.g, Udmabuf) that want to longterm-pin
the pages/folios associated with a memfd, do so by simply taking a
reference on them. This is not desirable because the pages/folios
may reside in Movable zone or CMA block.

Therefore, having drivers use memfd_pin_folios() API ensures that
the folios are appropriately pinned via FOLL_PIN for longterm DMA.

This patchset also introduces a few helpers and converts the Udmabuf
driver to use folios and memfd_pin_folios() API to longterm-pin
the folios for DMA. Two new Udmabuf selftests are also included to
test the driver and the new API.

---

Patchset overview:

Patch 1-2:GUP helpers to migrate and unpin one or more folios
Patch 3:  Introduce memfd_pin_folios() API
Patch 4-5:Udmabuf driver bug fixes for Qemu + hugetlb=on, blob=true case
Patch 6-8:Convert Udmabuf to use memfd_pin_folios() and add sefltests

This series is tested using the following methods:
- Run the subtests added in Patch 8
- Run Qemu (master) with the following options and a few additional
  patches to Spice:
  qemu-system-x86_64 -m 4096m
  -device virtio-gpu-pci,max_outputs=1,blob=true,xres=1920,yres=1080
  -spice port=3001,gl=on,disable-ticketing=on,preferred-codec=gstreamer:h264
  -object memory-backend-memfd,hugetlb=on,id=mem1,size=4096M
  -machine memory-backend=mem1
- Run source ./run_vmtests.sh -t gup_test -a to check GUP regressions

Changelog:

v11 -> v12:
- Rebased and tested on mm-unstable

v10 -> v11:
- Remove the version string from the patch subject (Andrew)
- Move the changelog from the patches into the cover letter
- Rearrange the patchset to have GUP patches at the beginning

v9 -> v10:
- Introduce and use unpin_folio(), unpin_folios() and
  check_and_migrate_movable_folios() helpers
- Use a list to track the folios that need to be unpinned in udmabuf

v8 -> v9: (suggestions from Matthew)
- Drop the extern while declaring memfd_alloc_folio()
- Fix memfd_alloc_folio() declaration to have it return struct folio *
  instead of struct page * when CONFIG_MEMFD_CREATE is not defined
- Use folio_pfn() on the folio instead of page_to_pfn() on head page
  in udmabuf
- Don't split the arguments to shmem_read_folio() on multiple lines
  in udmabuf

v7 -> v8: (suggestions from David)
- Have caller pass [start, end], max_folios instead of start, nr_pages
- Replace offsets array with just offset into the first page
- Add comments explaning the need for next_idx
- Pin (and return) the folio (via FOLL_PIN) only once

v6 -> v7:
- Rename this API to memfd_pin_folios() and make it return folios
  and offsets instead of pages (David)
- Don't continue processing the folios in the batch returned by
  filemap_get_folios_contig() if they do not have correct next_idx
- Add the R-b tag from Christoph

v5 -> v6: (suggestions from Christoph)
- Rename this API to memfd_pin_user_pages() to make it clear that it
  is intended for memfds
- Move the memfd page allocation helper from gup.c to memfd.c
- Fix indentation errors in memfd_pin_user_pages()
- For contiguous ranges of folios, use a helper such as
  filemap_get_folios_contig() to lookup the page cache in batches
- Split the processing of hugetlb or shmem pages into helpers to
  simplify the code in udmabuf_create()

v4 -> v5: (suggestions from David)
- For hugetlb case, ensure that we only obtain head pages from the
  mapping by using __filemap_get_folio() instead of find_get_page_flags()
- Handle -EEXIST when two or more potential users try to simultaneously
  add a huge page to the mapping by forcing them to retry on failure

v3 -> v4:
- Remove the local variable "page" and instead use 3 return statements
  in alloc_file_page() (David)
- Add the R-b tag from David

v2 -> v3: (suggestions from David)
- Enclose the huge page allocation code with #ifdef CONFIG_HUGETLB_PAGE
  (Build error reported by kernel test robot )
- Don't forget memalloc_pin_restore() on non-migration related errors
- Improve the readability of the cleanup code associated with
  non-migration related errors
- Augment the comments by describing FOLL_LONGTERM like behavior
- Include the R-b tag from Jason

v1 -> v2:
- Drop gup_flags and improve comments and commit message (David)
- Allocate a page if we cannot find in page cache for the hugetlbfs
  case as well (David)
- Don't unpin pages if there is a migration related failure (David)
- Drop the unnecessary nr_pages <= 0 check (Jason)
- Have the caller of the API pass in file * instead of fd (Jason)

Cc: David Hildenbrand 
Cc: Matthew Wilcox (Oracle) 
Cc: Christoph Hellwig 
Cc: Andrew Morton 
Cc: Daniel Vetter 
Cc: Mike Kravetz 
Cc: Hugh Dickins 
Cc: Peter Xu 
Cc: Jason Gunthorpe 
Cc: Gerd Hoffmann 
Cc: Dongwon Kim 
Cc: Junxiao Chang 

Vivek Kasireddy (8):
  mm/gup: Introduce unpin_folio/unpin_folios helpers
  mm/gup: Introduce check_and_migrate_movable_folios()
  mm/gup: Introduce memfd_pin_folios() for pinning memfd folios
  udmabuf: Use vmf_insert_pfn and VM_PFNMAP for handling mmap
  udmabu

[PATCH v12 2/8] mm/gup: Introduce check_and_migrate_movable_folios()

2024-02-25 Thread Vivek Kasireddy
This helper is the folio equivalent of check_and_migrate_movable_pages().
Therefore, all the rules that apply to check_and_migrate_movable_pages()
also apply to this one as well. Currently, this helper is only used by
memfd_pin_folios().

This patch also includes changes to rename and convert the internal
functions collect_longterm_unpinnable_pages() and
migrate_longterm_unpinnable_pages() to work on folios. Since they
are also used by check_and_migrate_movable_pages(), a temporary
array is used to collect and share the folios with these functions.

Cc: David Hildenbrand 
Cc: Matthew Wilcox 
Cc: Christoph Hellwig 
Cc: Jason Gunthorpe 
Cc: Peter Xu 
Suggested-by: David Hildenbrand 
Signed-off-by: Vivek Kasireddy 
---
 mm/gup.c | 129 +++
 1 file changed, 92 insertions(+), 37 deletions(-)

diff --git a/mm/gup.c b/mm/gup.c
index 0a45eda6aaeb..1410af954a4e 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -2099,20 +2099,24 @@ struct page *get_dump_page(unsigned long addr)
 
 #ifdef CONFIG_MIGRATION
 /*
- * Returns the number of collected pages. Return value is always >= 0.
+ * Returns the number of collected folios. Return value is always >= 0.
  */
-static unsigned long collect_longterm_unpinnable_pages(
-   struct list_head *movable_page_list,
-   unsigned long nr_pages,
+static unsigned long collect_longterm_unpinnable_folios(
+   struct list_head *movable_folio_list,
+   unsigned long nr_folios,
+   struct folio **folios,
struct page **pages)
 {
unsigned long i, collected = 0;
struct folio *prev_folio = NULL;
bool drain_allow = true;
+   struct folio *folio;
 
-   for (i = 0; i < nr_pages; i++) {
-   struct folio *folio = page_folio(pages[i]);
+   for (i = 0; i < nr_folios; i++) {
+   if (pages)
+   folios[i] = page_folio(pages[i]);
 
+   folio = folios[i];
if (folio == prev_folio)
continue;
prev_folio = folio;
@@ -2126,7 +2130,7 @@ static unsigned long collect_longterm_unpinnable_pages(
continue;
 
if (folio_test_hugetlb(folio)) {
-   isolate_hugetlb(folio, movable_page_list);
+   isolate_hugetlb(folio, movable_folio_list);
continue;
}
 
@@ -2138,7 +2142,7 @@ static unsigned long collect_longterm_unpinnable_pages(
if (!folio_isolate_lru(folio))
continue;
 
-   list_add_tail(&folio->lru, movable_page_list);
+   list_add_tail(&folio->lru, movable_folio_list);
node_stat_mod_folio(folio,
NR_ISOLATED_ANON + folio_is_file_lru(folio),
folio_nr_pages(folio));
@@ -2148,27 +2152,28 @@ static unsigned long collect_longterm_unpinnable_pages(
 }
 
 /*
- * Unpins all pages and migrates device coherent pages and movable_page_list.
- * Returns -EAGAIN if all pages were successfully migrated or -errno for 
failure
- * (or partial success).
+ * Unpins all folios and migrates device coherent folios and 
movable_folio_list.
+ * Returns -EAGAIN if all folios were successfully migrated or -errno for
+ * failure (or partial success).
  */
-static int migrate_longterm_unpinnable_pages(
-   struct list_head *movable_page_list,
-   unsigned long nr_pages,
-   struct page **pages)
+static int migrate_longterm_unpinnable_folios(
+   struct list_head *movable_folio_list,
+   unsigned long nr_folios,
+   struct folio **folios)
 {
int ret;
unsigned long i;
 
-   for (i = 0; i < nr_pages; i++) {
-   struct folio *folio = page_folio(pages[i]);
+   for (i = 0; i < nr_folios; i++) {
+   struct folio *folio = folios[i];
 
if (folio_is_device_coherent(folio)) {
/*
-* Migration will fail if the page is pinned, so convert
-* the pin on the source page to a normal reference.
+* Migration will fail if the folio is pinned, so
+* convert the pin on the source folio to a normal
+* reference.
 */
-   pages[i] = NULL;
+   folios[i] = NULL;
folio_get(folio);
gup_put_folio(folio, 1, FOLL_PIN);
 
@@ -2181,23 +2186,23 @@ static int migrate_longterm_unpinnable_p

[PATCH v12 5/8] udmabuf: Add back support for mapping hugetlb pages

2024-02-25 Thread Vivek Kasireddy
A user or admin can configure a VMM (Qemu) Guest's memory to be
backed by hugetlb pages for various reasons. However, a Guest OS
would still allocate (and pin) buffers that are backed by regular
4k sized pages. In order to map these buffers and create dma-bufs
for them on the Host, we first need to find the hugetlb pages where
the buffer allocations are located and then determine the offsets
of individual chunks (within those pages) and use this information
to eventually populate a scatterlist.

Testcase: default_hugepagesz=2M hugepagesz=2M hugepages=2500 options
were passed to the Host kernel and Qemu was launched with these
relevant options: qemu-system-x86_64 -m 4096m
-device virtio-gpu-pci,max_outputs=1,blob=true,xres=1920,yres=1080
-display gtk,gl=on
-object memory-backend-memfd,hugetlb=on,id=mem1,size=4096M
-machine memory-backend=mem1

Replacing -display gtk,gl=on with -display gtk,gl=off above would
exercise the mmap handler.

Cc: David Hildenbrand 
Cc: Daniel Vetter 
Cc: Mike Kravetz 
Cc: Hugh Dickins 
Cc: Peter Xu 
Cc: Jason Gunthorpe 
Cc: Gerd Hoffmann 
Cc: Dongwon Kim 
Cc: Junxiao Chang 
Acked-by: Mike Kravetz  (v2)
Signed-off-by: Vivek Kasireddy 
---
 drivers/dma-buf/udmabuf.c | 122 +++---
 1 file changed, 101 insertions(+), 21 deletions(-)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index 820c993c8659..274defd3fa3e 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -28,6 +29,7 @@ struct udmabuf {
struct page **pages;
struct sg_table *sg;
struct miscdevice *device;
+   pgoff_t *offsets;
 };
 
 static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf)
@@ -41,6 +43,8 @@ static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf)
return VM_FAULT_SIGBUS;
 
pfn = page_to_pfn(ubuf->pages[pgoff]);
+   pfn += ubuf->offsets[pgoff] >> PAGE_SHIFT;
+
return vmf_insert_pfn(vma, vmf->address, pfn);
 }
 
@@ -90,23 +94,29 @@ static struct sg_table *get_sg_table(struct device *dev, 
struct dma_buf *buf,
 {
struct udmabuf *ubuf = buf->priv;
struct sg_table *sg;
+   struct scatterlist *sgl;
+   unsigned int i = 0;
int ret;
 
sg = kzalloc(sizeof(*sg), GFP_KERNEL);
if (!sg)
return ERR_PTR(-ENOMEM);
-   ret = sg_alloc_table_from_pages(sg, ubuf->pages, ubuf->pagecount,
-   0, ubuf->pagecount << PAGE_SHIFT,
-   GFP_KERNEL);
+
+   ret = sg_alloc_table(sg, ubuf->pagecount, GFP_KERNEL);
if (ret < 0)
-   goto err;
+   goto err_alloc;
+
+   for_each_sg(sg->sgl, sgl, ubuf->pagecount, i)
+   sg_set_page(sgl, ubuf->pages[i], PAGE_SIZE, ubuf->offsets[i]);
+
ret = dma_map_sgtable(dev, sg, direction, 0);
if (ret < 0)
-   goto err;
+   goto err_map;
return sg;
 
-err:
+err_map:
sg_free_table(sg);
+err_alloc:
kfree(sg);
return ERR_PTR(ret);
 }
@@ -143,6 +153,7 @@ static void release_udmabuf(struct dma_buf *buf)
 
for (pg = 0; pg < ubuf->pagecount; pg++)
put_page(ubuf->pages[pg]);
+   kfree(ubuf->offsets);
kfree(ubuf->pages);
kfree(ubuf);
 }
@@ -196,17 +207,77 @@ static const struct dma_buf_ops udmabuf_ops = {
 #define SEALS_WANTED (F_SEAL_SHRINK)
 #define SEALS_DENIED (F_SEAL_WRITE)
 
+static int handle_hugetlb_pages(struct udmabuf *ubuf, struct file *memfd,
+   pgoff_t offset, pgoff_t pgcnt,
+   pgoff_t *pgbuf)
+{
+   struct hstate *hpstate = hstate_file(memfd);
+   pgoff_t mapidx = offset >> huge_page_shift(hpstate);
+   pgoff_t subpgoff = (offset & ~huge_page_mask(hpstate)) >> PAGE_SHIFT;
+   pgoff_t maxsubpgs = huge_page_size(hpstate) >> PAGE_SHIFT;
+   struct page *hpage = NULL;
+   struct folio *folio;
+   pgoff_t pgidx;
+
+   mapidx <<= huge_page_order(hpstate);
+   for (pgidx = 0; pgidx < pgcnt; pgidx++) {
+   if (!hpage) {
+   folio = __filemap_get_folio(memfd->f_mapping,
+   mapidx,
+   FGP_ACCESSED, 0);
+   if (IS_ERR(folio))
+   return PTR_ERR(folio);
+
+   hpage = &folio->page;
+   }
+
+   get_page(hpage);
+   ubuf->pages[*pgbuf] = hpage;
+   ubuf->offsets[*pgbuf] = subpgoff << PAGE_SHIFT;
+   (*pgbuf)++;
+   if (++subpgoff == maxsubpgs) {
+   put_page(hpage);
+   hpage = NULL;
+   subpgoff = 0;
+   mapidx += pages_per_huge_page(hpstate);
+  

[PATCH v12 1/8] mm/gup: Introduce unpin_folio/unpin_folios helpers

2024-02-25 Thread Vivek Kasireddy
These helpers are the folio versions of unpin_user_page/unpin_user_pages.
They are currently only useful for unpinning folios pinned by
memfd_pin_folios() or other associated routines. However, they could
find new uses in the future, when more and more folio-only helpers
are added to GUP.

Cc: David Hildenbrand 
Cc: Matthew Wilcox 
Cc: Christoph Hellwig 
Cc: Jason Gunthorpe 
Cc: Peter Xu 
Suggested-by: David Hildenbrand 
Signed-off-by: Vivek Kasireddy 
---
 include/linux/mm.h |  2 ++
 mm/gup.c   | 81 --
 2 files changed, 74 insertions(+), 9 deletions(-)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index 6f4825d82965..36e4c2b22600 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1601,11 +1601,13 @@ static inline void put_page(struct page *page)
 #define GUP_PIN_COUNTING_BIAS (1U << 10)
 
 void unpin_user_page(struct page *page);
+void unpin_folio(struct folio *folio);
 void unpin_user_pages_dirty_lock(struct page **pages, unsigned long npages,
 bool make_dirty);
 void unpin_user_page_range_dirty_lock(struct page *page, unsigned long npages,
  bool make_dirty);
 void unpin_user_pages(struct page **pages, unsigned long npages);
+void unpin_folios(struct folio **folios, unsigned long nfolios);
 
 static inline bool is_cow_mapping(vm_flags_t flags)
 {
diff --git a/mm/gup.c b/mm/gup.c
index df83182ec72d..0a45eda6aaeb 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -30,6 +30,23 @@ struct follow_page_context {
unsigned int page_mask;
 };
 
+static inline void sanity_check_pinned_folios(struct folio **folios,
+ unsigned long nfolios)
+{
+   if (!IS_ENABLED(CONFIG_DEBUG_VM))
+   return;
+
+   for (; nfolios; nfolios--, folios++) {
+   struct folio *folio = *folios;
+
+   if (is_zero_folio(folio) ||
+   !folio_test_anon(folio))
+   continue;
+
+   VM_BUG_ON_FOLIO(!PageAnonExclusive(&folio->page), folio);
+   }
+}
+
 static inline void sanity_check_pinned_pages(struct page **pages,
 unsigned long npages)
 {
@@ -52,15 +69,11 @@ static inline void sanity_check_pinned_pages(struct page 
**pages,
struct page *page = *pages;
struct folio *folio = page_folio(page);
 
-   if (is_zero_page(page) ||
-   !folio_test_anon(folio))
-   continue;
-   if (!folio_test_large(folio) || folio_test_hugetlb(folio))
-   VM_BUG_ON_PAGE(!PageAnonExclusive(&folio->page), page);
-   else
-   /* Either a PTE-mapped or a PMD-mapped THP. */
-   VM_BUG_ON_PAGE(!PageAnonExclusive(&folio->page) &&
-  !PageAnonExclusive(page), page);
+   sanity_check_pinned_folios(&folio, 1);
+
+   /* Either a PTE-mapped or a PMD-mapped THP. */
+   if (folio_test_large(folio) && !folio_test_hugetlb(folio))
+   VM_BUG_ON_PAGE(!PageAnonExclusive(page), page);
}
 }
 
@@ -276,6 +289,21 @@ void unpin_user_page(struct page *page)
 }
 EXPORT_SYMBOL(unpin_user_page);
 
+/**
+ * unpin_folio() - release a dma-pinned folio
+ * @folio: pointer to folio to be released
+ *
+ * Folios that were pinned via memfd_pin_folios() or other similar routines
+ * must be released either using unpin_folio() or unpin_folios(). This is so
+ * that such folios can be separately tracked and uniquely handled.
+ */
+void unpin_folio(struct folio *folio)
+{
+   sanity_check_pinned_folios(&folio, 1);
+   gup_put_folio(folio, 1, FOLL_PIN);
+}
+EXPORT_SYMBOL(unpin_folio);
+
 /**
  * folio_add_pin - Try to get an additional pin on a pinned folio
  * @folio: The folio to be pinned
@@ -488,6 +516,41 @@ void unpin_user_pages(struct page **pages, unsigned long 
npages)
 }
 EXPORT_SYMBOL(unpin_user_pages);
 
+/**
+ * unpin_folios() - release an array of gup-pinned folios.
+ * @folios:  array of folios to be marked dirty and released.
+ * @nfolios: number of folios in the @folios array.
+ *
+ * For each folio in the @folios array, release the folio using unpin_folio().
+ *
+ * Please see the unpin_folio() documentation for details.
+ */
+void unpin_folios(struct folio **folios, unsigned long nfolios)
+{
+   unsigned long i = 0, j;
+
+   /*
+* If this WARN_ON() fires, then the system *might* be leaking folios
+* (by leaving them pinned), but probably not. More likely, gup/pup
+* returned a hard -ERRNO error to the caller, who erroneously passed
+* it here.
+*/
+   if (WARN_ON(IS_ERR_VALUE(nfolios)))
+   return;
+
+   sanity_check_pinned_folios(folios, nfolios);
+   while (i < nfolios) {
+   for (j = i + 1; j < nfolios; j++)
+ 

[PATCH v12 3/8] mm/gup: Introduce memfd_pin_folios() for pinning memfd folios

2024-02-25 Thread Vivek Kasireddy
For drivers that would like to longterm-pin the folios associated
with a memfd, the memfd_pin_folios() API provides an option to
not only pin the folios via FOLL_PIN but also to check and migrate
them if they reside in movable zone or CMA block. This API
currently works with memfds but it should work with any files
that belong to either shmemfs or hugetlbfs. Files belonging to
other filesystems are rejected for now.

The folios need to be located first before pinning them via FOLL_PIN.
If they are found in the page cache, they can be immediately pinned.
Otherwise, they need to be allocated using the filesystem specific
APIs and then pinned.

Cc: David Hildenbrand 
Cc: Matthew Wilcox (Oracle) 
Cc: Christoph Hellwig 
Cc: Daniel Vetter 
Cc: Mike Kravetz 
Cc: Hugh Dickins 
Cc: Peter Xu 
Cc: Gerd Hoffmann 
Cc: Dongwon Kim 
Cc: Junxiao Chang 
Suggested-by: Jason Gunthorpe 
Reviewed-by: Jason Gunthorpe  (v2)
Reviewed-by: David Hildenbrand  (v3)
Reviewed-by: Christoph Hellwig  (v6)
Signed-off-by: Vivek Kasireddy 
---
 include/linux/memfd.h |   5 ++
 include/linux/mm.h|   3 +
 mm/gup.c  | 136 ++
 mm/memfd.c|  34 +++
 4 files changed, 178 insertions(+)

diff --git a/include/linux/memfd.h b/include/linux/memfd.h
index e7abf6fa4c52..3f2cf339ceaf 100644
--- a/include/linux/memfd.h
+++ b/include/linux/memfd.h
@@ -6,11 +6,16 @@
 
 #ifdef CONFIG_MEMFD_CREATE
 extern long memfd_fcntl(struct file *file, unsigned int cmd, unsigned int arg);
+struct folio *memfd_alloc_folio(struct file *memfd, pgoff_t idx);
 #else
 static inline long memfd_fcntl(struct file *f, unsigned int c, unsigned int a)
 {
return -EINVAL;
 }
+static inline struct folio *memfd_alloc_folio(struct file *memfd, pgoff_t idx)
+{
+   return ERR_PTR(-EINVAL);
+}
 #endif
 
 #endif /* __LINUX_MEMFD_H */
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 36e4c2b22600..54e2775f89be 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2491,6 +2491,9 @@ long get_user_pages_unlocked(unsigned long start, 
unsigned long nr_pages,
struct page **pages, unsigned int gup_flags);
 long pin_user_pages_unlocked(unsigned long start, unsigned long nr_pages,
struct page **pages, unsigned int gup_flags);
+long memfd_pin_folios(struct file *memfd, loff_t start, loff_t end,
+ struct folio **folios, unsigned int max_folios,
+ pgoff_t *offset);
 
 int get_user_pages_fast(unsigned long start, int nr_pages,
unsigned int gup_flags, struct page **pages);
diff --git a/mm/gup.c b/mm/gup.c
index 1410af954a4e..a72bff363d0c 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -5,6 +5,7 @@
 #include 
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -17,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -3530,3 +3532,137 @@ long pin_user_pages_unlocked(unsigned long start, 
unsigned long nr_pages,
 &locked, gup_flags);
 }
 EXPORT_SYMBOL(pin_user_pages_unlocked);
+
+/**
+ * memfd_pin_folios() - pin folios associated with a memfd
+ * @memfd:  the memfd whose folios are to be pinned
+ * @start:  the first memfd offset
+ * @end:the last memfd offset (inclusive)
+ * @folios: array that receives pointers to the folios pinned
+ * @max_folios: maximum number of entries in @folios
+ * @offset: the offset into the first folio
+ *
+ * Attempt to pin folios associated with a memfd in the contiguous range
+ * [start, end]. Given that a memfd is either backed by shmem or hugetlb,
+ * the folios can either be found in the page cache or need to be allocated
+ * if necessary. Once the folios are located, they are all pinned via
+ * FOLL_PIN and @offset is populatedwith the offset into the first folio.
+ * And, eventually, these pinned folios must be released either using
+ * unpin_folios() or unpin_folio().
+ *
+ * It must be noted that the folios may be pinned for an indefinite amount
+ * of time. And, in most cases, the duration of time they may stay pinned
+ * would be controlled by the userspace. This behavior is effectively the
+ * same as using FOLL_LONGTERM with other GUP APIs.
+ *
+ * Returns number of folios pinned, which could be less than @max_folios
+ * as it depends on the folio sizes that cover the range [start, end].
+ * If no folios were pinned, it returns -errno.
+ */
+long memfd_pin_folios(struct file *memfd, loff_t start, loff_t end,
+ struct folio **folios, unsigned int max_folios,
+ pgoff_t *offset)
+{
+   unsigned int flags, nr_folios, nr_found;
+   unsigned int i, pgshift = PAGE_SHIFT;
+   pgoff_t start_idx, end_idx, next_idx;
+   struct folio *folio = NULL;
+   struct folio_batch fbatch;
+   struct hstate *h;
+   long ret;
+
+   if (start > end || !max_folios)
+   return -EINVAL;
+
+   if (!memfd)
+