Re: [PATCH RFC v6 07/21] dept: Apply Dept to seqlock
On Sat, May 21, 2022 at 02:25:35PM +0900, Hyeonggon Yoo wrote: > Hello I got new report from dept, related to seqlock. > I applied dept 1.20 series on v5.18-rc7. > > Below is what DEPT reported. > I think this is bogus because reader of p->alloc_lock cannot block > its writer. Or please kindly tell me if I'm missing something ;) Hi, Yes, it should've been silent. I will fix it. Thank you! Just FYI, a reader of seq-reader is a wait blocking the following event e.i. spin_unlock(&host->lock) in here, not its writer. This report tells the writer is blocked by __raw_spin_lock(&dentry->d_lock), not by its reader. I've explained it just for your information. (: Thank you! Byungchul > > Thanks. > > [8.032674] === > [8.032676] DEPT: Circular dependency has been detected. > [8.032677] 5.18.0-rc7-dept+ #10 Tainted: GE > [8.032677] --- > [8.032678] summary > [8.032678] --- > [8.032679] *** DEADLOCK *** > > [8.032679] context A > [8.032679] [S] __raw_spin_lock_irqsave(&host->lock:0) > [8.032681] [W] __seqprop_spinlock_wait(&p->alloc_lock:0) > [8.032681] [E] spin_unlock(&host->lock:0) > > [8.032682] context B > [8.032682] [S] __raw_spin_lock(&dentry->d_lock:0) > [8.032683] [W] __raw_spin_lock(&host->lock:0) > [8.032684] [E] spin_unlock(&dentry->d_lock:0) > > [8.032684] context C > [8.032685] [S] __raw_spin_lock(&p->alloc_lock:0) > [8.032685] [W] __raw_spin_lock(&dentry->d_lock:0) > [8.032685] [E] spin_unlock(&p->alloc_lock:0) > > [8.032686] [S]: start of the event context > [8.032686] [W]: the wait blocked > [8.032687] [E]: the event not reachable > [8.032687] --- > [8.032687] context A's detail > [8.032688] --- > [8.032688] context A > [8.032688] [S] __raw_spin_lock_irqsave(&host->lock:0) > [8.032689] [W] __seqprop_spinlock_wait(&p->alloc_lock:0) > [8.032689] [E] spin_unlock(&host->lock:0) > > [8.032690] [S] __raw_spin_lock_irqsave(&host->lock:0): > [8.032690] ata_scsi_queuecmd (drivers/ata/libata-scsi.c:2734 > drivers/ata/libata-scsi.c:4017) > [8.032694] stacktrace: > [8.032694] ata_scsi_queuecmd (drivers/ata/libata-scsi.c:2734 > drivers/ata/libata-scsi.c:4017) > [8.032696] scsi_queue_rq (drivers/scsi/scsi_lib.c:1517 > drivers/scsi/scsi_lib.c:1745) > [8.032697] blk_mq_dispatch_rq_list (block/blk-mq.c:1858) > [8.032700] blk_mq_do_dispatch_sched (block/blk-mq-sched.c:173 > block/blk-mq-sched.c:187) > [8.032701] __blk_mq_sched_dispatch_requests (block/blk-mq-sched.c:313) > [8.032702] blk_mq_sched_dispatch_requests (block/blk-mq-sched.c:339) > [8.032703] __blk_mq_run_hw_queue (./include/linux/rcupdate.h:723 > block/blk-mq.c:1974) > [8.032704] __blk_mq_delay_run_hw_queue (block/blk-mq.c:2052) > [8.032705] blk_mq_run_hw_queue (block/blk-mq.c:2103) > [8.032706] blk_mq_sched_insert_requests (./include/linux/rcupdate.h:692 > ./include/linux/percpu-refcount.h:330 ./include/linux/percpu-refcount.h:351 > block/blk-mq-sched.c:495) > [8.032707] blk_mq_flush_plug_list (block/blk-mq.c:2640) > [8.032708] __blk_flush_plug (block/blk-core.c:1247) > [8.032709] blk_finish_plug (block/blk-core.c:1265 block/blk-core.c:1261) > [8.032710] read_pages (mm/readahead.c:181) > [8.032712] page_cache_ra_unbounded (./include/linux/fs.h:815 > mm/readahead.c:262) > [8.032713] page_cache_ra_order (mm/readahead.c:547) > > [8.032714] [W] __seqprop_spinlock_wait(&p->alloc_lock:0): > [8.032714] __slab_alloc.constprop.0 (mm/slub.c:3092) > [8.032717] stacktrace: > [8.032717] dept_wait (./arch/x86/include/asm/current.h:15 > kernel/dependency/dept.c:227 kernel/dependency/dept.c:1013 > kernel/dependency/dept.c:1057 kernel/dependency/dept.c:2216) > [8.032719] ___slab_alloc (./include/linux/seqlock.h:326 > ./include/linux/cpuset.h:151 mm/slub.c:2223 mm/slub.c:2266 mm/slub.c:3000) > [8.032720] __slab_alloc.constprop.0 (mm/slub.c:3092) > [8.032721] kmem_cache_alloc (mm/slub.c:3183 mm/slub.c:3225 mm/slub.c:3232 > mm/slub.c:3242) > [8.032722] alloc_iova (./include/linux/slab.h:704 > drivers/iommu/iova.c:240 drivers/iommu/iova.c:316) > [8.032724] alloc_iova_fast (drivers/iommu/iova.c:455) > [8.032725] iommu_dma_alloc_iova (drivers/iommu/dma-iommu.c:628) > [8.032726] iommu_dma_map_sg (drivers/iommu/dma-iommu.c:1201) > [8.032727] __dma_map_sg_attrs (kernel/dma/mapping.c:195) > [8.032729] dma_map_sg_attrs (kernel/dma/mapping.c:232) > [8.032730] ata_qc_issue (drivers/ata/libata-core.c:4530 > drivers/ata/libata-core.c:4876) > [8.032731] __ata_scsi_queuecmd (drivers/a
Re: [PATCH -next] drm/msm: DRM_DP_AUX_BUS depends on OF
On 5/23/22 15:23, Dmitry Baryshkov wrote: > Hi, > > On Mon, 23 May 2022 at 23:43, Randy Dunlap wrote: >> >> Fix a Kconfig warning for DRM_MSM by making it depend on OF, >> since 'select' does not follow any dependency chaings. >> >> WARNING: unmet direct dependencies detected for DRM_DP_AUX_BUS > > I think it was agreed that DRM_DP_AUX_BUS should depend on OF || > COMPILE_TEST (and the patch has been submitted by YueHaibing). See the > thread at > https://lore.kernel.org/dri-devel/9534934e-4c4a-ba2f-3bc3-d6d241e62...@linaro.org/T/ > I see. Thanks. > >> Depends on [n]: HAS_IOMEM [=y] && DRM [=m] && OF [=n] >> Selected by [m]: >> - DRM_MSM [=m] && HAS_IOMEM [=y] && DRM [=m] && (ARCH_QCOM || SOC_IMX5 || >> COMPILE_TEST [=y]) && COMMON_CLK [=y] && IOMMU_SUPPORT [=y] && (QCOM_OCMEM >> [=n] || QCOM_OCMEM [=n]=n) && (QCOM_LLCC [=y] || QCOM_LLCC [=y]=n) && >> (QCOM_COMMAND_DB [=n] || QCOM_COMMAND_DB [=n]=n) >> >> Fixes: f5d01644921b ("drm/msm: select DRM_DP_AUX_BUS for the AUX bus >> support") >> Signed-off-by: Randy Dunlap >> Cc: Rob Clark >> Cc: Abhinav Kumar >> Cc: Dmitry Baryshkov >> Cc: Sean Paul >> Cc: linux-arm-...@vger.kernel.org >> Cc: dri-devel@lists.freedesktop.org >> Cc: freedr...@lists.freedesktop.org >> Cc: David Airlie >> Cc: Daniel Vetter >> --- >> drivers/gpu/drm/msm/Kconfig |1 + >> 1 file changed, 1 insertion(+) >> >> --- a/drivers/gpu/drm/msm/Kconfig >> +++ b/drivers/gpu/drm/msm/Kconfig >> @@ -3,6 +3,7 @@ >> config DRM_MSM >> tristate "MSM DRM" >> depends on DRM >> + depends on OF >> depends on ARCH_QCOM || SOC_IMX5 || COMPILE_TEST >> depends on COMMON_CLK >> depends on IOMMU_SUPPORT > > > -- ~Randy
Re: [PATCH v2 10/11] drm/msm: Convert to drm_of_get_data_lanes_count
On 5/23/2022 6:05 PM, Marek Vasut wrote: Convert driver to use this new helper to standardize OF "data-lanes" parsing. Reviewed-by: Andrzej Hajda Reviewed-by: Dmitry Baryshkov Signed-off-by: Marek Vasut Reviewed-by: Abhinav Kumar Cc: Abhinav Kumar Cc: Andrzej Hajda Cc: Dmitry Baryshkov Cc: Laurent Pinchart Cc: Lucas Stach Cc: Maxime Ripard Cc: Rob Clark Cc: Robert Foss Cc: Sam Ravnborg Cc: Sean Paul To: dri-devel@lists.freedesktop.org --- V2: - Use drm/msm prefix - Rename drm_of_get_data_lanes{,_ep} to drm_of_get_data_lanes_count{,_ep} - Add RB from Andrzej and Dmitry --- drivers/gpu/drm/msm/dp/dp_parser.c | 6 ++ drivers/gpu/drm/msm/dsi/dsi_host.c | 7 +++ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c index 8f9fed9fdafc4..346556c5706d7 100644 --- a/drivers/gpu/drm/msm/dp/dp_parser.c +++ b/drivers/gpu/drm/msm/dp/dp_parser.c @@ -102,11 +102,9 @@ static int dp_parser_ctrl_res(struct dp_parser *parser) static int dp_parser_misc(struct dp_parser *parser) { struct device_node *of_node = parser->pdev->dev.of_node; - int len = 0; - const char *data_lane_property = "data-lanes"; + int len; - len = of_property_count_elems_of_size(of_node, -data_lane_property, sizeof(u32)); + len = drm_of_get_data_lanes_count(of_node, 1, DP_MAX_NUM_DP_LANES); if (len < 0) { DRM_WARN("Invalid property %s, default max DP lanes = %d\n", data_lane_property, DP_MAX_NUM_DP_LANES); diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index a95d5df52653c..90f9d3daa9a6d 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -1779,11 +1779,10 @@ static int dsi_host_parse_lane_data(struct msm_dsi_host *msm_host, return 0; } - num_lanes = len / sizeof(u32); - - if (num_lanes < 1 || num_lanes > 4) { + num_lanes = drm_of_get_data_lanes_count(ep, 1, 4); + if (num_lanes < 0) { DRM_DEV_ERROR(dev, "bad number of data lanes\n"); - return -EINVAL; + return num_lanes; } msm_host->num_data_lanes = num_lanes;
[PATCH v2 11/11] drm/bridge: rcar: Convert to drm_of_get_data_lanes_count_ep
Convert driver to use this new helper to standardize OF "data-lanes" parsing. Reviewed-by: Andrzej Hajda Signed-off-by: Marek Vasut Cc: Andrzej Hajda Cc: Laurent Pinchart Cc: Lucas Stach Cc: Maxime Ripard Cc: Robert Foss Cc: Sam Ravnborg To: dri-devel@lists.freedesktop.org --- V2: - Rename drm_of_get_data_lanes{,_ep} to drm_of_get_data_lanes_count{,_ep} - Add RB from Andrzej --- drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c | 13 ++--- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c index 891bb956fd61b..67dce337098a5 100644 --- a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c +++ b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c @@ -683,19 +683,10 @@ static int rcar_mipi_dsi_parse_dt(struct rcar_mipi_dsi *dsi) u32 data_lanes[4]; int ret; - ep = of_graph_get_endpoint_by_regs(dsi->dev->of_node, 1, 0); - if (!ep) { - dev_dbg(dsi->dev, "unconnected port@1\n"); - return -ENODEV; - } - - ret = of_property_read_variable_u32_array(ep, "data-lanes", data_lanes, - 1, 4); - of_node_put(ep); - + ret = drm_of_get_data_lanes_count_ep(dsi->dev->of_node, 1, 0, 1, 4); if (ret < 0) { dev_err(dsi->dev, "missing or invalid data-lanes property\n"); - return -ENODEV; + return ret; } dsi->num_data_lanes = ret; -- 2.35.1
[PATCH v2 08/11] drm/bridge: ti-sn65dsi83: Convert to drm_of_get_data_lanes_count
Convert driver to use this new helper to standardize OF "data-lanes" parsing. Reviewed-by: Andrzej Hajda Signed-off-by: Marek Vasut Cc: Andrzej Hajda Cc: Laurent Pinchart Cc: Lucas Stach Cc: Maxime Ripard Cc: Robert Foss Cc: Sam Ravnborg To: dri-devel@lists.freedesktop.org --- V2: - Rename drm_of_get_data_lanes{,_ep} to drm_of_get_data_lanes_count{,_ep} - Add RB from Andrzej --- drivers/gpu/drm/bridge/ti-sn65dsi83.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c index f5c1819857665..66693a8a53263 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c @@ -628,7 +628,7 @@ static int sn65dsi83_host_attach(struct sn65dsi83 *ctx) int dsi_lanes, ret; endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1); - dsi_lanes = of_property_count_u32_elems(endpoint, "data-lanes"); + dsi_lanes = drm_of_get_data_lanes_count(endpoint, 1, 4); host_node = of_graph_get_remote_port_parent(endpoint); host = of_find_mipi_dsi_host_by_node(host_node); of_node_put(host_node); -- 2.35.1
[PATCH v2 07/11] drm/bridge: tc358775: Convert to drm_of_get_data_lanes_count_ep
Convert driver to use this new helper to standardize OF "data-lanes" parsing. Reviewed-by: Andrzej Hajda Signed-off-by: Marek Vasut Cc: Andrzej Hajda Cc: Laurent Pinchart Cc: Lucas Stach Cc: Maxime Ripard Cc: Robert Foss Cc: Sam Ravnborg To: dri-devel@lists.freedesktop.org --- V2: - Rename drm_of_get_data_lanes{,_ep} to drm_of_get_data_lanes_count{,_ep} - Drop now unused prop and len local variables - Add RB from Andrzej --- drivers/gpu/drm/bridge/tc358775.c | 21 + 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/bridge/tc358775.c b/drivers/gpu/drm/bridge/tc358775.c index 62a7ef352daa5..5b1fb8e2f9a7d 100644 --- a/drivers/gpu/drm/bridge/tc358775.c +++ b/drivers/gpu/drm/bridge/tc358775.c @@ -529,8 +529,7 @@ static int tc358775_parse_dt(struct device_node *np, struct tc_data *tc) struct device_node *endpoint; struct device_node *parent; struct device_node *remote; - struct property *prop; - int len = 0; + int dsi_lanes; /* * To get the data-lanes of dsi, we need to access the dsi0_out of port1 @@ -544,25 +543,15 @@ static int tc358775_parse_dt(struct device_node *np, struct tc_data *tc) of_node_put(endpoint); if (parent) { /* dsi0 port 1 */ - endpoint = of_graph_get_endpoint_by_regs(parent, 1, -1); + dsi_lanes = drm_of_get_data_lanes_count_ep(parent, 1, -1, 1, 4); of_node_put(parent); - if (endpoint) { - prop = of_find_property(endpoint, "data-lanes", - &len); - of_node_put(endpoint); - if (!prop) { - dev_err(tc->dev, - "failed to find data lane\n"); - return -EPROBE_DEFER; - } - } } } - tc->num_dsi_lanes = len / sizeof(u32); + if (dsi_lanes < 0) + return dsi_lanes; - if (tc->num_dsi_lanes < 1 || tc->num_dsi_lanes > 4) - return -EINVAL; + tc->num_dsi_lanes = dsi_lanes; tc->host_node = of_graph_get_remote_node(np, 0, 0); if (!tc->host_node) -- 2.35.1
[PATCH v2 10/11] drm/msm: Convert to drm_of_get_data_lanes_count
Convert driver to use this new helper to standardize OF "data-lanes" parsing. Reviewed-by: Andrzej Hajda Reviewed-by: Dmitry Baryshkov Signed-off-by: Marek Vasut Cc: Abhinav Kumar Cc: Andrzej Hajda Cc: Dmitry Baryshkov Cc: Laurent Pinchart Cc: Lucas Stach Cc: Maxime Ripard Cc: Rob Clark Cc: Robert Foss Cc: Sam Ravnborg Cc: Sean Paul To: dri-devel@lists.freedesktop.org --- V2: - Use drm/msm prefix - Rename drm_of_get_data_lanes{,_ep} to drm_of_get_data_lanes_count{,_ep} - Add RB from Andrzej and Dmitry --- drivers/gpu/drm/msm/dp/dp_parser.c | 6 ++ drivers/gpu/drm/msm/dsi/dsi_host.c | 7 +++ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c index 8f9fed9fdafc4..346556c5706d7 100644 --- a/drivers/gpu/drm/msm/dp/dp_parser.c +++ b/drivers/gpu/drm/msm/dp/dp_parser.c @@ -102,11 +102,9 @@ static int dp_parser_ctrl_res(struct dp_parser *parser) static int dp_parser_misc(struct dp_parser *parser) { struct device_node *of_node = parser->pdev->dev.of_node; - int len = 0; - const char *data_lane_property = "data-lanes"; + int len; - len = of_property_count_elems_of_size(of_node, -data_lane_property, sizeof(u32)); + len = drm_of_get_data_lanes_count(of_node, 1, DP_MAX_NUM_DP_LANES); if (len < 0) { DRM_WARN("Invalid property %s, default max DP lanes = %d\n", data_lane_property, DP_MAX_NUM_DP_LANES); diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index a95d5df52653c..90f9d3daa9a6d 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -1779,11 +1779,10 @@ static int dsi_host_parse_lane_data(struct msm_dsi_host *msm_host, return 0; } - num_lanes = len / sizeof(u32); - - if (num_lanes < 1 || num_lanes > 4) { + num_lanes = drm_of_get_data_lanes_count(ep, 1, 4); + if (num_lanes < 0) { DRM_DEV_ERROR(dev, "bad number of data lanes\n"); - return -EINVAL; + return num_lanes; } msm_host->num_data_lanes = num_lanes; -- 2.35.1
[PATCH v2 09/11] drm/bridge: ti-sn65dsi86: Convert to drm_of_get_data_lanes_count
Convert driver to use this new helper to standardize OF "data-lanes" parsing. Reviewed-by: Andrzej Hajda Signed-off-by: Marek Vasut Cc: Andrzej Hajda Cc: Laurent Pinchart Cc: Lucas Stach Cc: Maxime Ripard Cc: Robert Foss Cc: Sam Ravnborg To: dri-devel@lists.freedesktop.org --- V2: - Rename drm_of_get_data_lanes{,_ep} to drm_of_get_data_lanes_count{,_ep} - Add RB from Andrzej --- drivers/gpu/drm/bridge/ti-sn65dsi86.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index 8cad662de9bb5..c2b9227f7042a 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -1142,8 +1142,8 @@ static void ti_sn_bridge_parse_lanes(struct ti_sn65dsi86 *pdata, * mappings that the hardware supports. */ endpoint = of_graph_get_endpoint_by_regs(np, 1, -1); - dp_lanes = of_property_count_u32_elems(endpoint, "data-lanes"); - if (dp_lanes > 0 && dp_lanes <= SN_MAX_DP_LANES) { + dp_lanes = drm_of_get_data_lanes_count(endpoint, 1, SN_MAX_DP_LANES); + if (dp_lanes > 0) { of_property_read_u32_array(endpoint, "data-lanes", lane_assignments, dp_lanes); of_property_read_u32_array(endpoint, "lane-polarities", -- 2.35.1
[PATCH v2 05/11] drm/bridge: lt9211: Convert to drm_of_get_data_lanes_count
Convert driver to use this new helper to standardize OF "data-lanes" parsing. Reviewed-by: Andrzej Hajda Signed-off-by: Marek Vasut Cc: Andrzej Hajda Cc: Laurent Pinchart Cc: Lucas Stach Cc: Maxime Ripard Cc: Robert Foss Cc: Sam Ravnborg To: dri-devel@lists.freedesktop.org --- V2: - Rename drm_of_get_data_lanes{,_ep} to drm_of_get_data_lanes_count{,_ep} - Add RB from Andrzej --- drivers/gpu/drm/bridge/lontium-lt9211.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/lontium-lt9211.c b/drivers/gpu/drm/bridge/lontium-lt9211.c index e92821fbc6393..84d764b4139bd 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9211.c +++ b/drivers/gpu/drm/bridge/lontium-lt9211.c @@ -686,7 +686,7 @@ static int lt9211_host_attach(struct lt9211 *ctx) int ret; endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1); - dsi_lanes = of_property_count_u32_elems(endpoint, "data-lanes"); + dsi_lanes = drm_of_get_data_lanes_count(endpoint, 1, 4); host_node = of_graph_get_remote_port_parent(endpoint); host = of_find_mipi_dsi_host_by_node(host_node); of_node_put(host_node); @@ -695,8 +695,8 @@ static int lt9211_host_attach(struct lt9211 *ctx) if (!host) return -EPROBE_DEFER; - if (dsi_lanes < 0 || dsi_lanes > 4) - return -EINVAL; + if (dsi_lanes < 0) + return dsi_lanes; dsi = devm_mipi_dsi_device_register_full(dev, host, &info); if (IS_ERR(dsi)) -- 2.35.1
[PATCH v2 03/11] drm/bridge: icn6211: Convert to drm_of_get_data_lanes_count_ep
Convert driver to use this new helper to standardize OF "data-lanes" parsing. Reviewed-by: Andrzej Hajda Signed-off-by: Marek Vasut Cc: Andrzej Hajda Cc: Jagan Teki Cc: Laurent Pinchart Cc: Lucas Stach Cc: Maxime Ripard Cc: Robert Foss Cc: Sam Ravnborg To: dri-devel@lists.freedesktop.org --- V2: - Rename drm_of_get_data_lanes{,_ep} to drm_of_get_data_lanes_count{,_ep} - Add RB from Andrzej --- drivers/gpu/drm/bridge/chipone-icn6211.c | 11 --- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c b/drivers/gpu/drm/bridge/chipone-icn6211.c index 45bb89ac3fff7..6214990354d8f 100644 --- a/drivers/gpu/drm/bridge/chipone-icn6211.c +++ b/drivers/gpu/drm/bridge/chipone-icn6211.c @@ -496,21 +496,18 @@ static int chipone_dsi_attach(struct chipone *icn) { struct mipi_dsi_device *dsi = icn->dsi; struct device *dev = icn->dev; - struct device_node *endpoint; int dsi_lanes, ret; - endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, 0); - dsi_lanes = of_property_count_u32_elems(endpoint, "data-lanes"); - of_node_put(endpoint); + dsi_lanes = drm_of_get_data_lanes_count_ep(dev->of_node, 0, 0, 1, 4); /* * If the 'data-lanes' property does not exist in DT or is invalid, * default to previously hard-coded behavior, which was 4 data lanes. */ - if (dsi_lanes >= 1 && dsi_lanes <= 4) - icn->dsi->lanes = dsi_lanes; - else + if (dsi_lanes < 0) icn->dsi->lanes = 4; + else + icn->dsi->lanes = dsi_lanes; dsi->format = MIPI_DSI_FMT_RGB888; dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | -- 2.35.1
[PATCH v2 06/11] drm/bridge: tc358767: Convert to drm_of_get_data_lanes_count
Convert driver to use this new helper to standardize OF "data-lanes" parsing. Reviewed-by: Andrzej Hajda Signed-off-by: Marek Vasut Cc: Andrzej Hajda Cc: Laurent Pinchart Cc: Lucas Stach Cc: Maxime Ripard Cc: Robert Foss Cc: Sam Ravnborg To: dri-devel@lists.freedesktop.org --- V2: - Rename drm_of_get_data_lanes{,_ep} to drm_of_get_data_lanes_count{,_ep} - Add RB from Andrzej --- drivers/gpu/drm/bridge/tc358767.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c index cec0f50f4874f..44f32bf483c51 100644 --- a/drivers/gpu/drm/bridge/tc358767.c +++ b/drivers/gpu/drm/bridge/tc358767.c @@ -1889,18 +1889,18 @@ static int tc_mipi_dsi_host_attach(struct tc_data *tc) int dsi_lanes, ret; endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1); - dsi_lanes = of_property_count_u32_elems(endpoint, "data-lanes"); + dsi_lanes = drm_of_get_data_lanes_count(endpoint, 1, 4); host_node = of_graph_get_remote_port_parent(endpoint); host = of_find_mipi_dsi_host_by_node(host_node); of_node_put(host_node); of_node_put(endpoint); - if (dsi_lanes <= 0 || dsi_lanes > 4) - return -EINVAL; - if (!host) return -EPROBE_DEFER; + if (dsi_lanes < 0) + return dsi_lanes; + dsi = mipi_dsi_device_register_full(host, &info); if (IS_ERR(dsi)) return dev_err_probe(dev, PTR_ERR(dsi), -- 2.35.1
[PATCH v2 04/11] drm/bridge: lt8912: Convert to drm_of_get_data_lanes_count_ep
Convert driver to use this new helper to standardize OF "data-lanes" parsing. Reviewed-by: Andrzej Hajda Signed-off-by: Marek Vasut Cc: Adrien Grassein Cc: Andrzej Hajda Cc: Laurent Pinchart Cc: Lucas Stach Cc: Maxime Ripard Cc: Robert Foss Cc: Sam Ravnborg To: dri-devel@lists.freedesktop.org --- V2: - Rename drm_of_get_data_lanes{,_ep} to drm_of_get_data_lanes_count{,_ep} - Add RB from Andrzej --- drivers/gpu/drm/bridge/lontium-lt8912b.c | 9 ++--- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c index c642d1e02b2f8..c92515834ff2d 100644 --- a/drivers/gpu/drm/bridge/lontium-lt8912b.c +++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c @@ -607,7 +607,6 @@ static int lt8912_parse_dt(struct lt8912 *lt) int ret; int data_lanes; struct device_node *port_node; - struct device_node *endpoint; gp_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(gp_reset)) { @@ -618,16 +617,12 @@ static int lt8912_parse_dt(struct lt8912 *lt) } lt->gp_reset = gp_reset; - endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1); - if (!endpoint) - return -ENODEV; - - data_lanes = of_property_count_u32_elems(endpoint, "data-lanes"); - of_node_put(endpoint); + data_lanes = drm_of_get_data_lanes_count_ep(dev->of_node, 0, -1, 1, 4); if (data_lanes < 0) { dev_err(lt->dev, "%s: Bad data-lanes property\n", __func__); return data_lanes; } + lt->data_lanes = data_lanes; lt->host_node = of_graph_get_remote_node(dev->of_node, 0, -1); -- 2.35.1
[PATCH v2 02/11] drm/bridge: anx7625: Convert to drm_of_get_data_lanes_count
Convert driver to use this new helper to standardize OF "data-lanes" parsing. Reviewed-by: Andrzej Hajda Signed-off-by: Marek Vasut Cc: Andrzej Hajda Cc: Laurent Pinchart Cc: Lucas Stach Cc: Maxime Ripard Cc: Robert Foss Cc: Sam Ravnborg Cc: Xin Ji To: dri-devel@lists.freedesktop.org --- V2: - Rename drm_of_get_data_lanes{,_ep} to drm_of_get_data_lanes_count{,_ep} - Add RB from Andrzej --- drivers/gpu/drm/bridge/analogix/anx7625.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index e92eb4a407452..bbdca16db0d67 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1637,16 +1637,16 @@ static int anx7625_parse_dt(struct device *dev, if (of_property_read_u32(ep0, "bus-type", &bus_type)) bus_type = 0; - mipi_lanes = of_property_count_u32_elems(ep0, "data-lanes"); + mipi_lanes = drm_of_get_data_lanes_count(ep0, 1, MAX_LANES_SUPPORT); of_node_put(ep0); } if (bus_type == V4L2_FWNODE_BUS_TYPE_PARALLEL) /* bus type is Parallel(DSI) */ pdata->is_dpi = 0; - pdata->mipi_lanes = mipi_lanes; - if (pdata->mipi_lanes > MAX_LANES_SUPPORT || pdata->mipi_lanes <= 0) - pdata->mipi_lanes = MAX_LANES_SUPPORT; + pdata->mipi_lanes = MAX_LANES_SUPPORT; + if (mipi_lanes > 0) + pdata->mipi_lanes = mipi_lanes; if (pdata->is_dpi) DRM_DEV_DEBUG_DRIVER(dev, "found MIPI DPI host node.\n"); -- 2.35.1
[PATCH v2 01/11] drm: of: Add drm_of_get_data_lanes_count and drm_of_get_data_lanes_ep
Add helper function to count and sanitize DT "data-lanes" property and return either error or the data-lanes count. This is useful for both DSI and (e)DP "data-lanes" property. The later version of the function is an extra wrapper which handles the endpoint look up by regs, that's what majority of the drivers duplicate too, but not all of them. Reviewed-by: Andrzej Hajda Signed-off-by: Marek Vasut Cc: Andrzej Hajda Cc: Laurent Pinchart Cc: Lucas Stach Cc: Maxime Ripard Cc: Robert Foss Cc: Sam Ravnborg To: dri-devel@lists.freedesktop.org --- V2: - Rename drm_of_get_data_lanes{,_ep} to drm_of_get_data_lanes_count{,_ep} - Add RB from Andrzej --- drivers/gpu/drm/drm_of.c | 61 include/drm/drm_of.h | 20 + 2 files changed, 81 insertions(+) diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c index 9a2cfab3a177f..2c1ee601f1d83 100644 --- a/drivers/gpu/drm/drm_of.c +++ b/drivers/gpu/drm/drm_of.c @@ -430,3 +430,64 @@ int drm_of_lvds_get_data_mapping(const struct device_node *port) return -EINVAL; } EXPORT_SYMBOL_GPL(drm_of_lvds_get_data_mapping); + +/** + * drm_of_get_data_lanes_count - Get DSI/(e)DP data lane count + * @endpoint: DT endpoint node of the DSI/(e)DP source or sink + * @min: minimum supported number of data lanes + * @max: maximum supported number of data lanes + * + * Count DT "data-lanes" property elements and check for validity. + * + * Return: + * * min..max - positive integer count of "data-lanes" elements + * * -ve - the "data-lanes" property is missing or invalid + * * -EINVAL - the "data-lanes" property is unsupported + */ +int drm_of_get_data_lanes_count(const struct device_node *endpoint, + const unsigned int min, const unsigned int max) +{ + int ret; + + ret = of_property_count_u32_elems(endpoint, "data-lanes"); + if (ret < 0) + return ret; + + if (ret < min || ret > max) + return -EINVAL; + + return ret; +} +EXPORT_SYMBOL_GPL(drm_of_get_data_lanes_count); + +/** + * drm_of_get_data_lanes_count_ep - Get DSI/(e)DP data lane count by endpoint + * @port: DT port node of the DSI/(e)DP source or sink + * @port_reg: identifier (value of reg property) of the parent port node + * @reg: identifier (value of reg property) of the endpoint node + * @min: minimum supported number of data lanes + * @max: maximum supported number of data lanes + * + * Count DT "data-lanes" property elements and check for validity. + * This variant uses endpoint specifier. + * + * Return: + * * min..max - positive integer count of "data-lanes" elements + * * -EINVAL - the "data-mapping" property is unsupported + * * -ENODEV - the "data-mapping" property is missing + */ +int drm_of_get_data_lanes_count_ep(const struct device_node *port, + int port_reg, int reg, + const unsigned int min, + const unsigned int max) +{ + struct device_node *endpoint; + int ret; + + endpoint = of_graph_get_endpoint_by_regs(port, port_reg, reg); + ret = drm_of_get_data_lanes_count(endpoint, min, max); + of_node_put(endpoint); + + return ret; +} +EXPORT_SYMBOL_GPL(drm_of_get_data_lanes_count_ep); diff --git a/include/drm/drm_of.h b/include/drm/drm_of.h index 99f79ac8b4cd7..92387eabcb6f0 100644 --- a/include/drm/drm_of.h +++ b/include/drm/drm_of.h @@ -50,6 +50,12 @@ int drm_of_find_panel_or_bridge(const struct device_node *np, int drm_of_lvds_get_dual_link_pixel_order(const struct device_node *port1, const struct device_node *port2); int drm_of_lvds_get_data_mapping(const struct device_node *port); +int drm_of_get_data_lanes_count(const struct device_node *endpoint, + const unsigned int min, const unsigned int max); +int drm_of_get_data_lanes_count_ep(const struct device_node *port, + int port_reg, int reg, + const unsigned int min, + const unsigned int max); #else static inline uint32_t drm_of_crtc_port_mask(struct drm_device *dev, struct device_node *port) @@ -105,6 +111,20 @@ drm_of_lvds_get_data_mapping(const struct device_node *port) { return -EINVAL; } + +int drm_of_get_data_lanes_count(const struct device_node *endpoint, + const unsigned int min, const unsigned int max) +{ + return -EINVAL; +} + +int drm_of_get_data_lanes_count_ep(const struct device_node *port, + int port_reg, int reg + const unsigned int min, + const unsigned int max) +{ + return -EINVAL; +} #endif /* -- 2.35.1
Re: [PATCH v3] drm/probe-helper: Make 640x480 first if no EDID
Hi, On Fri, May 20, 2022 at 5:01 PM Doug Anderson wrote: > > Hi, > > On Mon, May 16, 2022 at 3:28 AM Thomas Zimmermann wrote: > > > > Hi Douglas, > > > > I understand that you're trying to tell userspace that the modelist has > > been made up, but it's not something that should be done via fragile > > heuristics IMHO. > > > > I looked at the Chromium source code that you linked, but I cannot say > > whether it's doing the correct thing. It all depends on what your > > program needs. > > > > In that function, you could also search for 'DRM_MODE_TYPE_USERDEF'. > > It's the mode that the user specified on the kernel command line. If > > Chromium's automatic mode selection fails, you'd give your users direct > > control over it. > > That doesn't really work for Chrome OS. Certainly a kernel hacker > could do this, but it's not something I could imagine us exposing to > an average user of a Chromebook. > > > > When there's no flagged mode or if > > /sys/class/drm/card<...>/status contains "unconnected", you can assume > > that the modelist is artificial and try the modes in an appropriate order. > > So "no flagged" means that nothing is marked as preferred, correct? > > ...so I guess what you're suggesting is that the order that the kernel > is presenting the modes to userspace is not ABI. If there are no > preferred modes then userspace shouldn't necessarily assume that the > first mode returned is the best mode. Instead it should assume that if > there is no preferred mode then the mode list is made up and it should > make its own decisions about the best mode to start with. If this is > the ABI from the kernel then plausibly I could convince people to > change userspace to pick 640x480 first in this case. > > > If we really want the kernel to give additional guarantees, we should > > have a broader discussion about this topic IMHO. > > Sure. I've added Stéphane Marchesin to this thread in case he wants to > chime in about anything. > > Overall, my take on the matter: > > * Mostly I got involved because, apparently, a DP compliance test was > failing. The compliance test was upset that when it presented us with > no EDID that we didn't default to 640x480. There was a push to make a > fix for this in the Qualcomm specific driver but that didn't sit right > with me. > > * On all devices I'm currently working with (laptops), the DP is a > secondary display. If a user was trying to plug in a display with a > bad EDID and the max mode (1024x768) didn't work, they could just use > the primary display to choose a different resolution. It seems > unlikely a user would truly be upset and would probably be happy they > could get their broken display to work at all. Even if this is a > primary display, I believe there are documented key combos to change > the resolution of the primary display even if you can't see anything. > > * That all being said, defaulting to 640x480 when there's no EDID made > sense to me, especially since it's actually defined in the DP spec. So > I'm trying to do the right thing and solve this corner case. That > being said, if it's truly controversial I can just drop it. > > > So I guess my plan will be to give Stéphane a little while in case he > wants to chime in. If not then I guess I'll try a Chrome patch... > ...and if that doesn't work, I'll just drop it. OK, this userspace code seems to work: https://crrev.com/c/3662501 - ozone/drm: Try 640x480 before picking the first mode if no EDID ...so we'll see how review of that goes. :-)
[linux-next:master] BUILD REGRESSION cc63e8e92cb872081f249ea16e6c460642f3e4fb
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master branch HEAD: cc63e8e92cb872081f249ea16e6c460642f3e4fb Add linux-next specific files for 20220523 Error/Warning reports: https://lore.kernel.org/linux-mm/202204291924.vtgzmeri-...@intel.com https://lore.kernel.org/linux-mm/202205031017.4twman3l-...@intel.com https://lore.kernel.org/linux-mm/202205041248.wgcwpcev-...@intel.com https://lore.kernel.org/linux-mm/202205122113.ulkzd3sz-...@intel.com https://lore.kernel.org/linux-mm/202205150051.3rzuooag-...@intel.com https://lore.kernel.org/linux-mm/202205150117.sd6hzbvm-...@intel.com https://lore.kernel.org/linux-mm/202205211550.ifuenz5n-...@intel.com https://lore.kernel.org/lkml/202205100617.5uum3uet-...@intel.com https://lore.kernel.org/llvm/202205060132.uhqyux1l-...@intel.com https://lore.kernel.org/llvm/202205110148.mrgbbmtn-...@intel.com https://lore.kernel.org/llvm/202205221120.tt6uxepi-...@intel.com Error/Warning: (recently discovered and may have been fixed) : fatal error: ./include/generated/utsrelease.h: No such file or directory arch/m68k/q40/config.c:173: undefined reference to `mach_get_rtc_pll' config.c:(.init.text+0xf2): undefined reference to `mach_get_rtc_pll' drivers/gpu/drm/amd/amdgpu/../pm/swsmu/smu13/smu_v13_0_7_ppt.c:1407:12: warning: stack frame size (1040) exceeds limit (1024) in 'smu_v13_0_7_get_power_profile_mode' [-Wframe-larger-than] drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c:1364:5: warning: no previous prototype for 'amdgpu_discovery_get_mall_info' [-Wmissing-prototypes] drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c:1986:6: warning: no previous prototype for function 'gfx_v11_0_rlc_stop' [-Wmissing-prototypes] drivers/gpu/drm/amd/amdgpu/soc21.c:171:6: warning: no previous prototype for 'soc21_grbm_select' [-Wmissing-prototypes] drivers/gpu/drm/solomon/ssd130x-spi.c:154:35: warning: 'ssd130x_spi_table' defined but not used [-Wunused-const-variable=] drivers/rtc/rtc-rzn1.c:291:3: warning: variable 'val' is uninitialized when used here [-Wuninitialized] drivers/video/fbdev/omap/hwa742.c:492:5: warning: no previous prototype for 'hwa742_update_window_async' [-Wmissing-prototypes] fs/buffer.c:2254:5: warning: stack frame size (2144) exceeds limit (1024) in 'block_read_full_folio' [-Wframe-larger-than] fs/ntfs/aops.c:378:12: warning: stack frame size (2216) exceeds limit (1024) in 'ntfs_read_folio' [-Wframe-larger-than] llvm-objcopy: error: invalid output format: 'elf64-s390' m68k-linux-ld: arch/m68k/q40/config.c:174: undefined reference to `mach_set_rtc_pll' m68k-linux-ld: config.c:(.init.text+0xfc): undefined reference to `mach_set_rtc_pll' Unverified Error/Warning (likely false positive, please contact us if interested): Error: Section .bss not empty in prom_init.c Makefile:686: arch/h8300/Makefile: No such file or directory arch/Kconfig:10: can't open file "arch/h8300/Kconfig" drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c:1364:5: warning: no previous prototype for function 'amdgpu_discovery_get_mall_info' [-Wmissing-prototypes] drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c:129:6: warning: no previous prototype for function 'amdgpu_ucode_print_imu_hdr' [-Wmissing-prototypes] drivers/gpu/drm/amd/amdgpu/imu_v11_0.c:302:6: warning: no previous prototype for function 'program_imu_rlc_ram' [-Wmissing-prototypes] drivers/gpu/drm/amd/amdgpu/soc21.c:171:6: warning: no previous prototype for function 'soc21_grbm_select' [-Wmissing-prototypes] drivers/gpu/drm/bridge/adv7511/adv7511.h:229:17: warning: 'ADV7511_REG_CEC_RX_FRAME_HDR' defined but not used [-Wunused-const-variable=] drivers/gpu/drm/bridge/adv7511/adv7511.h:235:17: warning: 'ADV7511_REG_CEC_RX_FRAME_LEN' defined but not used [-Wunused-const-variable=] drivers/infiniband/hw/hns/hns_roce_hw_v2.c:309:9: sparse: sparse: dubious: x & !y drivers/staging/vt6655/card.c:758:16: sparse: sparse: cast to restricted __le64 drivers/ufs/host/ufs-exynos.c:1598:34: warning: unused variable 'exynos_ufs_of_match' [-Wunused-const-variable] kernel/bpf/verifier.c:5355 process_kptr_func() warn: passing zero to 'PTR_ERR' ld.lld: warning: call to __warn_flushing_systemwide_wq marked "dontcall-warn": Please avoid flushing system-wide workqueues. make[1]: *** No rule to make target 'arch/h8300/Makefile'. mm/shmem.c:1949 shmem_getpage_gfp() warn: should '(((1) << 12) / 512) << folio_order(folio)' be a 64 bit type? powerpc64-linux-ld: drivers/gpu/drm/vkms/vkms_crtc.o:(.bss+0x40): multiple definition of `cacheline_aligned'; drivers/gpu/drm/vkms/vkms_plane.o:(.bss+0x0): first defined here powerpc64-linux-ld: drivers/hid/hid-wiimote-modules.o:(.bss+0x40): multiple definition of `cacheline_aligned'; drivers/hid/hid-wiimote-co
Re: [PATCH 0/9] drm/msm/dsi_phy: Replace parent names with clk_hw pointers
Hi, On Tue, 24 May 2022 at 00:38, Marijn Suijten wrote: > > As stated in [1] I promised to tackle and send this series. > > parent_hw pointers are easier to manage and cheaper to use than > repeatedly formatting the parent name and subsequently leaving the clk > framework to perform lookups based on that name. > > This series starts out by adding extra constructors for divider, mux and > fixed-factor clocks that have parent_hw(s) pointer argument(s) instead > of some DT index or name. Followed by individual patches performing the > conversion, one DSI PHY at a time. > > dsi_phy_28nm_8960 includes an extra fixup to replace "eternal" > devm_kzalloc allocations (for the lifetime of the device) with > stack-local char arrays, like all the other DSI PHY drivers. > > I couldn't help but notice that clock names are wildly varying: > > - Some use underscores in the _clk suffix where others have nothing; > - Some have an _ after the %d, others have not; > - Some use a _pll suffix after dsi%d or even _phy_pll suffix. > > Are there any thoughts or feelings towards unifying these? > Theoretically no clock names are used anywhere in the kernel, and > everything is based on a phandle + index in DT (I have yet to validate > this). Obviously no .name/.fw_name will be updated to not break DT. I'd say, leave them as is. Even if they are historical, we don't have a strong pressure to change them. Significant number of older platforms still use names to identify the clock. And moreover apq8096/msm8960 uses dsi1/dsi2 instead of dsi0/dsi1. Probably we should call the next cycle "The Cycle of clocks cleaning". I can volunteer to take care of 8960/8064/8016/8996, as at least I can test them. But if you wish, you (or anybody else of course) can take any of these platforms too, just ping me, so that I won't spend time duplicating somebody's efforts. > Which, by the way, is there a particular reason for: > > #define DSI_BYTE_PLL_CLK 0 > #define DSI_PIXEL_PLL_CLK 1 > > To not be in the dt-bindings and used in the DT? Before my restructure of the DSI PHY subsys, each driver defined them separately. And the idea of moving them to a dt-bindings header didn't come to my mind. Feel free to do so, it looks like a good idea. Just as a note, DP PHY also uses 0 for the link clock and 1 for the pixel clock. What do you think about having a single header for these names? > > And with enough future improvements out of the way, let's round out this > patch-series by stating that it has been successfully tested on: > > - Sony Nile Discovery (Xperia XA2 Ultra): 14nm; > - Sony Seine PDX201 (Xperia 10II): 14nm; > - Sony Loire Suzu (Xperia X): 28nm. > > And no diff is observed in debugfs's clk_summary. > > Unfortunately all other devices in my collection with a 7/10nm DSI PHY > have a DSC panel which we have yet to get working. I will test it on RB3 (10nm) and RB5 (7nm) during one of the next few days. > > [1]: > https://lore.kernel.org/linux-arm-msm/20220502214235.s5plebunh4ttj...@somainline.org/ > > Marijn Suijten (9): > clk: divider: Introduce devm_clk_hw_register_divider_parent_hw() > clk: mux: Introduce devm_clk_hw_register_mux_parent_hws() > clk: fixed-factor: Introduce *clk_hw_register_fixed_factor_parent_hw() > drm/msm/dsi_phy_28nm: Replace parent names with clk_hw pointers > drm/msm/dsi_phy_28nm_8960: Replace parent names with clk_hw pointers > drm/msm/dsi_phy_28nm_8960: Use stack memory for temporary clock names > drm/msm/dsi_phy_14nm: Replace parent names with clk_hw pointers > drm/msm/dsi_phy_10nm: Replace parent names with clk_hw pointers > drm/msm/dsi_phy_7nm: Replace parent names with clk_hw pointers > > drivers/clk/clk-fixed-factor.c| 57 ++-- > drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c| 92 --- > drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c| 36 > drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c| 52 +-- > .../gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c | 26 ++ > drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 92 +-- > include/linux/clk-provider.h | 34 +++ > 7 files changed, 209 insertions(+), 180 deletions(-) > > -- > 2.36.1 -- With best wishes Dmitry
Re: [PATCH 09/14] ACPI: video: Make backlight class device registration a separate step
On 5/20/22 16:41, Daniel Dadap wrote: On 5/17/22 10:23, Hans de Goede wrote: On x86/ACPI boards the acpi_video driver will usually initializing before the kms driver (except i915). This causes /sys/class/backlight/acpi_video0 to show up and then the kms driver registers its own native backlight device after which the drivers/acpi/video_detect.c code unregisters the acpi_video0 device (when acpi_video_get_backlight_type()==native). This means that userspace briefly sees 2 devices and the disappearing of acpi_video0 after a brief time confuses the systemd backlight level save/restore code, see e.g.: https://bbs.archlinux.org/viewtopic.php?id=269920 To fix this make backlight class device registration a separate step done by a new acpi_video_register_backlight() function. The intend is for this to be called by the drm/kms driver *after* it is done setting up its own native backlight device. So that acpi_video_get_backlight_type() knows if a native backlight will be available or not at acpi_video backlight registration time, avoiding the add + remove dance. If I'm understanding this correctly, it seems we will want to call acpi_video_register_backlight() from the NVIDIA proprietary driver in a fallback path in case the driver's own GPU-controlled backlight handler either should not be used, or fails to register. That sounds reasonable enough, but I'm not sure what should be done about drivers like nvidia-wmi-ec-backlight, which are independent of the GPU hardware, and wouldn't be part of the acpi_video driver, either. There are a number of other similar vendor-y/platform-y type backlight drivers in drivers/video/backlight and drivers/platform/x86 that I think would be in a similar situation. From a quick skim of the ACPI video driver, it seems that perhaps nvidia-wmi-ec-backlight is missing a call to acpi_video_set_dmi_backlight_type(), perhaps with the acpi_backlight_vendor value? But I'm not familiar enough with this code to be sure that nobody will be checking acpi_video_get_backlight_type() before nvidia-wmi-ec-backlight loads. I'll take a closer look to try to convince myself that it makes sense. Note the new acpi_video_register_backlight() function is also called from a delayed work to ensure that the acpi_video backlight devices does get registered if necessary even if there is no drm/kms driver or when it is disabled. It sounds like maybe everything should be fine as long as nvidia-wmi-ec-backlight (and other vendor-y/platform-y type drivers) gets everything set up before the delayed work which calls acpi_video_register_backlight()? But then is it really necessary to explicitly call acpi_video_register_backlight() from the DRM drivers if it's going to be called later if no GPU driver registered a backlight handler, anyway? Then we'd just need to make sure that the iGPU and dGPU drivers won't attempt to register a backlight handler on systems where a vendor-y/platform-y driver is supposed to handle the backlight instead, which sounds like it has the potential to be quite messy. Ah, I see you addressed this concern in your RFC (sorry for missing that, earlier): The above only takes native vs acpi_video backlight issues into account, there are also a couple of other scenarios which may lead to multiple backlight-devices getting registered: 1) Apple laptops using the apple_gmux driver 2) Nvidia laptops using the (new) nvidia-wmi-ec-backlight driver 3) drivers/platform/x86 drivers calling acpi_video_set_dmi_backlight_type() to override the normal acpi_video_get_backlight_type() heuristics after the native/acpi_video drivers have already loaded The plan for 1) + 2) is to extend the acpi_backlight_type enum with acpi_backlight_gmux and acpi_backlight_nvidia_wmi_ec values and to add detection of these 2 to acpi_video_get_backlight_type(). Is there a reason these shouldn't have the same, generic, type, rather than separate, driver-specific ones? I don't foresee any situation where a system would need to use these two particular drivers simultaneously. Multiple DRM drivers can coexist on the same system, and even though the goal here is to remove the existing "multiple backlight interfaces for the same panel" situation, there shouldn't be any reason why more than one DRM driver couldn't register backlight handlers at the same time, so long as they are driving distinct panels. If we don't need separate backlight types for individual DRM drivers, why should we have them for apple_gmux and nvidia_wmi_ec_backlight? I still think that relying on the GPU drivers to correctly know whether they should register their backlight handlers when a platform-level device is supposed to register one instead might be easier said than done, especially on systems where the same panel could potentially be driven by more than one GPU (but not at the same time). Recall that on at least one system, both amdgpu and the NVIDIA proprietary driver regis
Re: [PATCH v4 12/13] drm/msm: Utilize gpu scheduler priorities
On Mon, May 23, 2022 at 7:45 AM Tvrtko Ursulin wrote: > > > Hi Rob, > > On 28/07/2021 02:06, Rob Clark wrote: > > From: Rob Clark > > > > The drm/scheduler provides additional prioritization on top of that > > provided by however many number of ringbuffers (each with their own > > priority level) is supported on a given generation. Expose the > > additional levels of priority to userspace and map the userspace > > priority back to ring (first level of priority) and schedular priority > > (additional priority levels within the ring). > > > > Signed-off-by: Rob Clark > > Acked-by: Christian König > > --- > > drivers/gpu/drm/msm/adreno/adreno_gpu.c | 4 +- > > drivers/gpu/drm/msm/msm_gem_submit.c| 4 +- > > drivers/gpu/drm/msm/msm_gpu.h | 58 - > > drivers/gpu/drm/msm/msm_submitqueue.c | 35 +++ > > include/uapi/drm/msm_drm.h | 14 +- > > 5 files changed, 88 insertions(+), 27 deletions(-) > > > > diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c > > b/drivers/gpu/drm/msm/adreno/adreno_gpu.c > > index bad4809b68ef..748665232d29 100644 > > --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c > > +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c > > @@ -261,8 +261,8 @@ int adreno_get_param(struct msm_gpu *gpu, uint32_t > > param, uint64_t *value) > > return ret; > > } > > return -EINVAL; > > - case MSM_PARAM_NR_RINGS: > > - *value = gpu->nr_rings; > > + case MSM_PARAM_PRIORITIES: > > + *value = gpu->nr_rings * NR_SCHED_PRIORITIES; > > return 0; > > case MSM_PARAM_PP_PGTABLE: > > *value = 0; > > diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c > > b/drivers/gpu/drm/msm/msm_gem_submit.c > > index 450efe59abb5..c2ecec5b11c4 100644 > > --- a/drivers/gpu/drm/msm/msm_gem_submit.c > > +++ b/drivers/gpu/drm/msm/msm_gem_submit.c > > @@ -59,7 +59,7 @@ static struct msm_gem_submit *submit_create(struct > > drm_device *dev, > > submit->gpu = gpu; > > submit->cmd = (void *)&submit->bos[nr_bos]; > > submit->queue = queue; > > - submit->ring = gpu->rb[queue->prio]; > > + submit->ring = gpu->rb[queue->ring_nr]; > > submit->fault_dumped = false; > > > > INIT_LIST_HEAD(&submit->node); > > @@ -749,7 +749,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void > > *data, > > /* Get a unique identifier for the submission for logging purposes */ > > submitid = atomic_inc_return(&ident) - 1; > > > > - ring = gpu->rb[queue->prio]; > > + ring = gpu->rb[queue->ring_nr]; > > trace_msm_gpu_submit(pid_nr(pid), ring->id, submitid, > > args->nr_bos, args->nr_cmds); > > > > diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h > > index b912cacaecc0..0e4b45bff2e6 100644 > > --- a/drivers/gpu/drm/msm/msm_gpu.h > > +++ b/drivers/gpu/drm/msm/msm_gpu.h > > @@ -250,6 +250,59 @@ struct msm_gpu_perfcntr { > > const char *name; > > }; > > > > +/* > > + * The number of priority levels provided by drm gpu scheduler. The > > + * DRM_SCHED_PRIORITY_KERNEL priority level is treated specially in some > > + * cases, so we don't use it (no need for kernel generated jobs). > > + */ > > +#define NR_SCHED_PRIORITIES (1 + DRM_SCHED_PRIORITY_HIGH - > > DRM_SCHED_PRIORITY_MIN) > > + > > +/** > > + * msm_gpu_convert_priority - Map userspace priority to ring # and sched > > priority > > + * > > + * @gpu:the gpu instance > > + * @prio: the userspace priority level > > + * @ring_nr:[out] the ringbuffer the userspace priority maps to > > + * @sched_prio: [out] the gpu scheduler priority level which the userspace > > + * priority maps to > > + * > > + * With drm/scheduler providing it's own level of prioritization, our total > > + * number of available priority levels is (nr_rings * NR_SCHED_PRIORITIES). > > + * Each ring is associated with it's own scheduler instance. However, our > > + * UABI is that lower numerical values are higher priority. So mapping the > > + * single userspace priority level into ring_nr and sched_prio takes some > > + * care. The userspace provided priority (when a submitqueue is created) > > + * is mapped to ring nr and scheduler priority as such: > > + * > > + * ring_nr= userspace_prio / NR_SCHED_PRIORITIES > > + * sched_prio = NR_SCHED_PRIORITIES - > > + *(userspace_prio % NR_SCHED_PRIORITIES) - 1 > > + * > > + * This allows generations without preemption (nr_rings==1) to have some > > + * amount of prioritization, and provides more priority levels for gens > > + * that do have preemption. > > I am exploring how different drivers handle priority levels and this > caught my eye. > > Is the implication of the last paragraphs that on hw with nr_rings > 1, > ring + 1 preempts ring? Other way around, at least from the uabi standpoint. Ie. ring[0] preempts ring[1] > If so I am wonderi
Re: [PATCH 9/9] drm/msm/dsi_phy_7nm: Replace parent names with clk_hw pointers
On Tue, 24 May 2022 at 00:39, Marijn Suijten wrote: > > parent_hw pointers are easier to manage and cheaper to use than > repeatedly formatting the parent name and subsequently leaving the clk > framework to perform lookups based on that name. > > Signed-off-by: Marijn Suijten Reviewed-by: Dmitry Baryshkov > --- > drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 92 +++ > 1 file changed, 42 insertions(+), 50 deletions(-) > -- With best wishes Dmitry
Re: [PATCH 8/9] drm/msm/dsi_phy_10nm: Replace parent names with clk_hw pointers
On Tue, 24 May 2022 at 00:38, Marijn Suijten wrote: > > parent_hw pointers are easier to manage and cheaper to use than > repeatedly formatting the parent name and subsequently leaving the clk > framework to perform lookups based on that name. > > Signed-off-by: Marijn Suijten Reviewed-by: Dmitry Baryshkov > --- > drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c | 92 ++ > 1 file changed, 40 insertions(+), 52 deletions(-) > -- With best wishes Dmitry
Re: [PATCH 7/9] drm/msm/dsi_phy_14nm: Replace parent names with clk_hw pointers
On Tue, 24 May 2022 at 00:38, Marijn Suijten wrote: > > parent_hw pointers are easier to manage and cheaper to use than > repeatedly formatting the parent name and subsequently leaving the clk > framework to perform lookups based on that name. > > Signed-off-by: Marijn Suijten Reviewed-by: Dmitry Baryshkov Nit: my rant regarding syntax changes applies here too. > --- > drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 36 ++ > 1 file changed, 17 insertions(+), 19 deletions(-) > > diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c > b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c > index 8199c53567f4..574f95ab2f22 100644 > --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c > +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c > @@ -764,14 +764,14 @@ static int dsi_14nm_set_usecase(struct msm_dsi_phy *phy) > > static struct clk_hw *pll_14nm_postdiv_register(struct dsi_pll_14nm > *pll_14nm, > const char *name, > - const char *parent_name, > + const struct clk_hw > *parent_hw, > unsigned long flags, > u8 shift) > { > struct dsi_pll_14nm_postdiv *pll_postdiv; > struct device *dev = &pll_14nm->phy->pdev->dev; > struct clk_init_data postdiv_init = { > - .parent_names = (const char *[]) { parent_name }, > + .parent_hws = (const struct clk_hw *[]) { parent_hw }, > .num_parents = 1, > .name = name, > .flags = flags, > @@ -800,7 +800,7 @@ static struct clk_hw *pll_14nm_postdiv_register(struct > dsi_pll_14nm *pll_14nm, > > static int pll_14nm_register(struct dsi_pll_14nm *pll_14nm, struct clk_hw > **provided_clocks) > { > - char clk_name[32], parent[32], vco_name[32]; > + char clk_name[32], vco_name[32]; > struct clk_init_data vco_init = { > .parent_data = &(const struct clk_parent_data) { > .fw_name = "ref", > @@ -811,7 +811,7 @@ static int pll_14nm_register(struct dsi_pll_14nm > *pll_14nm, struct clk_hw **prov > .ops = &clk_ops_dsi_pll_14nm_vco, > }; > struct device *dev = &pll_14nm->phy->pdev->dev; > - struct clk_hw *hw; > + struct clk_hw *hw, *n1_postdiv, *n1_postdivby2; > int ret; > > DBG("DSI%d", pll_14nm->phy->id); > @@ -824,48 +824,46 @@ static int pll_14nm_register(struct dsi_pll_14nm > *pll_14nm, struct clk_hw **prov > return ret; > > snprintf(clk_name, 32, "dsi%dn1_postdiv_clk", pll_14nm->phy->id); > - snprintf(parent, 32, "dsi%dvco_clk", pll_14nm->phy->id); > > /* N1 postdiv, bits 0-3 in REG_DSI_14nm_PHY_CMN_CLK_CFG0 */ > - hw = pll_14nm_postdiv_register(pll_14nm, clk_name, parent, > - CLK_SET_RATE_PARENT, 0); > - if (IS_ERR(hw)) > - return PTR_ERR(hw); > + n1_postdiv = pll_14nm_postdiv_register(pll_14nm, clk_name, > + &pll_14nm->clk_hw, CLK_SET_RATE_PARENT, 0); > + if (IS_ERR(n1_postdiv)) > + return PTR_ERR(n1_postdiv); > > snprintf(clk_name, 32, "dsi%dpllbyte", pll_14nm->phy->id); > - snprintf(parent, 32, "dsi%dn1_postdiv_clk", pll_14nm->phy->id); > > /* DSI Byte clock = VCO_CLK / N1 / 8 */ > - hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent, > - CLK_SET_RATE_PARENT, 1, 8); > + hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, clk_name, > + n1_postdiv, CLK_SET_RATE_PARENT, 1, 8); > if (IS_ERR(hw)) > return PTR_ERR(hw); > > provided_clocks[DSI_BYTE_PLL_CLK] = hw; > > snprintf(clk_name, 32, "dsi%dn1_postdivby2_clk", pll_14nm->phy->id); > - snprintf(parent, 32, "dsi%dn1_postdiv_clk", pll_14nm->phy->id); > > /* > * Skip the mux for now, force DSICLK_SEL to 1, Add a /2 divider > * on the way. Don't let it set parent. > */ > - hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent, 0, 1, > 2); > - if (IS_ERR(hw)) > - return PTR_ERR(hw); > + n1_postdivby2 = devm_clk_hw_register_fixed_factor_parent_hw(dev, > + clk_name, n1_postdiv, 0, 1, 2); > + if (IS_ERR(n1_postdivby2)) > + return PTR_ERR(n1_postdivby2); > > snprintf(clk_name, 32, "dsi%dpll", pll_14nm->phy->id); > - snprintf(parent, 32, "dsi%dn1_postdivby2_clk", pll_14nm->phy->id); > > /* DSI pixel clock = VCO_CLK / N1 / 2 / N2 > * This is the output of N2 post-divider, bits 4-7 in > * REG_DSI_14nm_PHY_CMN_CLK_CFG0. Don't let it set parent. > */ > - hw = pll_14nm_postdiv_register(pll_14nm, clk_name, parent, 0, 4);
Re: [PATCH 6/9] drm/msm/dsi_phy_28nm_8960: Use stack memory for temporary clock names
On Tue, 24 May 2022 at 00:38, Marijn Suijten wrote: > > The clock names formatted into the hw_clk's init structure are only used > for the duration of the registration function where they are kstrdup'ed, > making it unnecessary to keep the allocations alive for the duration of > the device (through devm). > > Just like the other DSI PHY PLL clock trees, use a stack-local char > array and save on memory outside of the pll_28nm_register function. > > Signed-off-by: Marijn Suijten Reviewed-by: Dmitry Baryshkov Nit: we can use clk_name instead of vco_name too. > --- > drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c | 10 +- > 1 file changed, 1 insertion(+), 9 deletions(-) > > diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c > b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c > index 943a7e847c90..554978fc434d 100644 > --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c > +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c > @@ -383,7 +383,7 @@ static int dsi_28nm_pll_restore_state(struct msm_dsi_phy > *phy) > > static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw > **provided_clocks) > { > - char *clk_name, *vco_name; > + char clk_name[32], vco_name[32]; > struct clk_init_data vco_init = { > .parent_data = &(const struct clk_parent_data) { > .fw_name = "ref", > @@ -404,14 +404,6 @@ static int pll_28nm_register(struct dsi_pll_28nm > *pll_28nm, struct clk_hw **prov > if (!bytediv) > return -ENOMEM; > > - vco_name = devm_kzalloc(dev, 32, GFP_KERNEL); > - if (!vco_name) > - return -ENOMEM; > - > - clk_name = devm_kzalloc(dev, 32, GFP_KERNEL); > - if (!clk_name) > - return -ENOMEM; > - > snprintf(vco_name, 32, "dsi%dvco_clk", pll_28nm->phy->id); > vco_init.name = vco_name; > > -- > 2.36.1 > -- With best wishes Dmitry
Re: [PATCH 5/9] drm/msm/dsi_phy_28nm_8960: Replace parent names with clk_hw pointers
On Tue, 24 May 2022 at 01:44, Dmitry Baryshkov wrote: > > On Tue, 24 May 2022 at 00:38, Marijn Suijten > wrote: > > > > parent_hw pointers are easier to manage and cheaper to use than > > repeatedly formatting the parent name and subsequently leaving the clk > > framework to perform lookups based on that name. > > Can you please add a followup patch (or a preface one) removing the > rest of devm_kzalloc()'ed clock names. Argh, stupid me, you did that in the next patch. Please ignore this. > > Reviewed-by: Dmitry Baryshkov -- With best wishes Dmitry
Re: [PATCH 5/9] drm/msm/dsi_phy_28nm_8960: Replace parent names with clk_hw pointers
On Tue, 24 May 2022 at 00:38, Marijn Suijten wrote: > > parent_hw pointers are easier to manage and cheaper to use than > repeatedly formatting the parent name and subsequently leaving the clk > framework to perform lookups based on that name. Can you please add a followup patch (or a preface one) removing the rest of devm_kzalloc()'ed clock names. Reviewed-by: Dmitry Baryshkov Minor nit below. > > Signed-off-by: Marijn Suijten > --- > .../gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c| 18 +++--- > 1 file changed, 7 insertions(+), 11 deletions(-) > > diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c > b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c > index fc56cdcc9ad6..943a7e847c90 100644 > --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c > +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c > @@ -383,7 +383,7 @@ static int dsi_28nm_pll_restore_state(struct msm_dsi_phy > *phy) > > static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw > **provided_clocks) > { > - char *clk_name, *parent_name, *vco_name; > + char *clk_name, *vco_name; > struct clk_init_data vco_init = { > .parent_data = &(const struct clk_parent_data) { > .fw_name = "ref", > @@ -408,10 +408,6 @@ static int pll_28nm_register(struct dsi_pll_28nm > *pll_28nm, struct clk_hw **prov > if (!vco_name) > return -ENOMEM; > > - parent_name = devm_kzalloc(dev, 32, GFP_KERNEL); > - if (!parent_name) > - return -ENOMEM; > - > clk_name = devm_kzalloc(dev, 32, GFP_KERNEL); > if (!clk_name) > return -ENOMEM; > @@ -429,13 +425,14 @@ static int pll_28nm_register(struct dsi_pll_28nm > *pll_28nm, struct clk_hw **prov > bytediv->hw.init = &bytediv_init; > bytediv->reg = pll_28nm->phy->pll_base + > REG_DSI_28nm_8960_PHY_PLL_CTRL_9; > > - snprintf(parent_name, 32, "dsi%dvco_clk", pll_28nm->phy->id); > snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->phy->id + 1); > > bytediv_init.name = clk_name; > bytediv_init.ops = &clk_bytediv_ops; > bytediv_init.flags = CLK_SET_RATE_PARENT; > - bytediv_init.parent_names = (const char * const *) &parent_name; > + bytediv_init.parent_hws = (const struct clk_hw*[]){ > + &pll_28nm->clk_hw, > + }; > bytediv_init.num_parents = 1; I wonder if we can express the bytediv clock with the standard ops. However it's definitely a separate topic. > > /* DIV2 */ > @@ -446,10 +443,9 @@ static int pll_28nm_register(struct dsi_pll_28nm > *pll_28nm, struct clk_hw **prov > > snprintf(clk_name, 32, "dsi%dpll", pll_28nm->phy->id + 1); > /* DIV3 */ > - hw = devm_clk_hw_register_divider(dev, clk_name, > - parent_name, 0, pll_28nm->phy->pll_base + > - REG_DSI_28nm_8960_PHY_PLL_CTRL_10, > - 0, 8, 0, NULL); > + hw = devm_clk_hw_register_divider_parent_hw(dev, clk_name, > + &pll_28nm->clk_hw, 0, pll_28nm->phy->pll_base + > + REG_DSI_28nm_8960_PHY_PLL_CTRL_10, 0, 8, 0, NULL); Again, could you please keep the linebreak in place? > if (IS_ERR(hw)) > return PTR_ERR(hw); > provided_clocks[DSI_PIXEL_PLL_CLK] = hw; > -- > 2.36.1 > -- With best wishes Dmitry
Re: [PATCH 4/9] drm/msm/dsi_phy_28nm: Replace parent names with clk_hw pointers
On Tue, 24 May 2022 at 00:38, Marijn Suijten wrote: > > parent_hw pointers are easier to manage and cheaper to use than > repeatedly formatting the parent name and subsequently leaving the clk > framework to perform lookups based on that name. > > Signed-off-by: Marijn Suijten > --- > drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c | 52 +- > 1 file changed, 22 insertions(+), 30 deletions(-) > > diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c > b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c > index 48eab80b548e..6926c8ff6255 100644 > --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c > +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c > @@ -519,7 +519,7 @@ static int dsi_28nm_pll_restore_state(struct msm_dsi_phy > *phy) > > static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw > **provided_clocks) > { > - char clk_name[32], parent1[32], parent2[32], vco_name[32]; > + char clk_name[32], vco_name[32]; While we are at it, we might also get rid of vco_name and use clk_name everywhere. > struct clk_init_data vco_init = { > .parent_data = &(const struct clk_parent_data) { > .fw_name = "ref", .name = "xo", > @@ -529,7 +529,7 @@ static int pll_28nm_register(struct dsi_pll_28nm > *pll_28nm, struct clk_hw **prov > .flags = CLK_IGNORE_UNUSED, > }; > struct device *dev = &pll_28nm->phy->pdev->dev; > - struct clk_hw *hw; > + struct clk_hw *hw, *analog_postdiv, *indirect_path_div2, *byte_mux; > int ret; > > DBG("%d", pll_28nm->phy->id); > @@ -546,48 +546,40 @@ static int pll_28nm_register(struct dsi_pll_28nm > *pll_28nm, struct clk_hw **prov > return ret; > > snprintf(clk_name, 32, "dsi%danalog_postdiv_clk", pll_28nm->phy->id); > - snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->phy->id); > - hw = devm_clk_hw_register_divider(dev, clk_name, > - parent1, CLK_SET_RATE_PARENT, > + analog_postdiv = devm_clk_hw_register_divider_parent_hw(dev, clk_name, > + &pll_28nm->clk_hw, CLK_SET_RATE_PARENT, > pll_28nm->phy->pll_base + > - REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG, > - 0, 4, 0, NULL); > - if (IS_ERR(hw)) > - return PTR_ERR(hw); > + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG, 0, 4, 0, NULL); The diff is already hard enough to read. Could you please drop syntax/whitespace/newline changes? > + if (IS_ERR(analog_postdiv)) > + return PTR_ERR(analog_postdiv); > > snprintf(clk_name, 32, "dsi%dindirect_path_div2_clk", > pll_28nm->phy->id); > - snprintf(parent1, 32, "dsi%danalog_postdiv_clk", pll_28nm->phy->id); > - hw = devm_clk_hw_register_fixed_factor(dev, clk_name, > - parent1, CLK_SET_RATE_PARENT, > - 1, 2); > - if (IS_ERR(hw)) > - return PTR_ERR(hw); > + indirect_path_div2 = devm_clk_hw_register_fixed_factor_parent_hw(dev, > + clk_name, analog_postdiv, CLK_SET_RATE_PARENT, 1, 2); > + if (IS_ERR(indirect_path_div2)) > + return PTR_ERR(indirect_path_div2); > > snprintf(clk_name, 32, "dsi%dpll", pll_28nm->phy->id); > - snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->phy->id); > - hw = devm_clk_hw_register_divider(dev, clk_name, > - parent1, 0, pll_28nm->phy->pll_base + > - REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG, > - 0, 8, 0, NULL); > + hw = devm_clk_hw_register_divider_parent_hw(dev, clk_name, > + &pll_28nm->clk_hw, 0, pll_28nm->phy->pll_base + > + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG, 0, 8, 0, NULL); > if (IS_ERR(hw)) > return PTR_ERR(hw); > provided_clocks[DSI_PIXEL_PLL_CLK] = hw; > > snprintf(clk_name, 32, "dsi%dbyte_mux", pll_28nm->phy->id); > - snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->phy->id); > - snprintf(parent2, 32, "dsi%dindirect_path_div2_clk", > pll_28nm->phy->id); > - hw = devm_clk_hw_register_mux(dev, clk_name, > - ((const char *[]){ > - parent1, parent2 > + byte_mux = devm_clk_hw_register_mux_parent_hws(dev, clk_name, > + ((const struct clk_hw *[]){ > + &pll_28nm->clk_hw, > + indirect_path_div2, > }), 2, CLK_SET_RATE_PARENT, pll_28nm->phy->pll_base + > REG_DSI_28nm_PHY_PLL_VREG_CFG, 1, 1, 0, NULL); > - if (IS_ERR(hw)) > - return PTR_ERR(hw); > + if (IS_ERR(byte_mux)) > + return PTR_ERR(byte_mux); > > snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->phy->id); > - s
Re: [PATCH -next] drm/msm: DRM_DP_AUX_BUS depends on OF
Hi, On Mon, 23 May 2022 at 23:43, Randy Dunlap wrote: > > Fix a Kconfig warning for DRM_MSM by making it depend on OF, > since 'select' does not follow any dependency chaings. > > WARNING: unmet direct dependencies detected for DRM_DP_AUX_BUS I think it was agreed that DRM_DP_AUX_BUS should depend on OF || COMPILE_TEST (and the patch has been submitted by YueHaibing). See the thread at https://lore.kernel.org/dri-devel/9534934e-4c4a-ba2f-3bc3-d6d241e62...@linaro.org/T/ > Depends on [n]: HAS_IOMEM [=y] && DRM [=m] && OF [=n] > Selected by [m]: > - DRM_MSM [=m] && HAS_IOMEM [=y] && DRM [=m] && (ARCH_QCOM || SOC_IMX5 || > COMPILE_TEST [=y]) && COMMON_CLK [=y] && IOMMU_SUPPORT [=y] && (QCOM_OCMEM > [=n] || QCOM_OCMEM [=n]=n) && (QCOM_LLCC [=y] || QCOM_LLCC [=y]=n) && > (QCOM_COMMAND_DB [=n] || QCOM_COMMAND_DB [=n]=n) > > Fixes: f5d01644921b ("drm/msm: select DRM_DP_AUX_BUS for the AUX bus support") > Signed-off-by: Randy Dunlap > Cc: Rob Clark > Cc: Abhinav Kumar > Cc: Dmitry Baryshkov > Cc: Sean Paul > Cc: linux-arm-...@vger.kernel.org > Cc: dri-devel@lists.freedesktop.org > Cc: freedr...@lists.freedesktop.org > Cc: David Airlie > Cc: Daniel Vetter > --- > drivers/gpu/drm/msm/Kconfig |1 + > 1 file changed, 1 insertion(+) > > --- a/drivers/gpu/drm/msm/Kconfig > +++ b/drivers/gpu/drm/msm/Kconfig > @@ -3,6 +3,7 @@ > config DRM_MSM > tristate "MSM DRM" > depends on DRM > + depends on OF > depends on ARCH_QCOM || SOC_IMX5 || COMPILE_TEST > depends on COMMON_CLK > depends on IOMMU_SUPPORT -- With best wishes Dmitry
Re: [PATCH v2 0/2] drm/bridge: analogix_dp: Self-refresh state machine fixes
On Thu, Mar 10, 2022 at 3:50 PM Brian Norris wrote: > On Mon, Feb 28, 2022 at 12:25 PM Brian Norris > wrote: > Ping for review? Sean, perhaps? (You already reviewed this on the > Chromium tracker.) Ping
Re: [PATCH] drm/msm/dsi: pll_7nm: remove unsupported dividers for DSI pixel clock
On 2022-05-03 01:02:42, Dmitry Baryshkov wrote: > On 03/05/2022 00:42, Marijn Suijten wrote: > > On 2022-05-02 13:47:51, Stephen Boyd wrote: > >> Quoting Dmitry Baryshkov (2022-05-01 12:56:20) > >>> Remove dividers that are not recommended for DSI DPHY mode when setting > >> > >> Is "DPHY" intentional or just "PHY" should be here? > >> > >>> up the clock tree for the DSI pixel clock. > >>> > >>> Signed-off-by: Dmitry Baryshkov > >>> --- > >> > >> Reviewed-by: Stephen Boyd > >> > >>> drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 10 -- > >>> 1 file changed, 4 insertions(+), 6 deletions(-) > >>> > >>> diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c > >>> b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c > >>> index 6e506feb111f..66ed1919a1db 100644 > >>> --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c > >>> +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c > >>> @@ -687,15 +687,13 @@ static int pll_7nm_register(struct dsi_pll_7nm > >>> *pll_7nm, struct clk_hw **provide > >>> snprintf(clk_name, 32, "dsi%d_pclk_mux", > >>> pll_7nm->phy->id); > >>> snprintf(parent, 32, "dsi%d_pll_bit_clk", > >>> pll_7nm->phy->id); > >>> snprintf(parent2, 32, "dsi%d_pll_by_2_bit_clk", > >>> pll_7nm->phy->id); > >>> - snprintf(parent3, 32, "dsi%d_pll_out_div_clk", > >>> pll_7nm->phy->id); > >>> - snprintf(parent4, 32, "dsi%d_pll_post_out_div_clk", > >>> pll_7nm->phy->id); > >>> > >>> hw = devm_clk_hw_register_mux(dev, clk_name, > >>> ((const char *[]){ > >>> - parent, parent2, parent3, parent4 > >>> - }), 4, 0, pll_7nm->phy->base + > >>> + parent, parent2, > >>> + }), 2, 0, pll_7nm->phy->base + > >>> REG_DSI_7nm_PHY_CMN_CLK_CFG1, > >>> - 0, 2, 0, NULL); > >>> + 0, 1, 0, NULL); > >> > >> Can you followup with a patch to move to clk_parent_data instead of > >> strings? > > > > Dmitry and I discussed this a while ago, and I actually have patches in > > progress converting this. Dmitry, if you haven't started on the > > conversion yet, perhaps it's efficient if I respin my efforts and submit > > them soon? > > Yes, please. I'm under the pile of other things. Your patches will be > appreciated. You don't have to convert all PHYs at once. Holding to my promise, the patches are now available on the lists: https://lore.kernel.org/linux-arm-msm/20220523213837.1016542-1-marijn.suij...@somainline.org/T/#t It was more convenient to convert the remaining PHYs on top of the 14/28nm I had already done, it's mostly trivial work anyway. - Marijn
[PATCH 4/9] drm/msm/dsi_phy_28nm: Replace parent names with clk_hw pointers
parent_hw pointers are easier to manage and cheaper to use than repeatedly formatting the parent name and subsequently leaving the clk framework to perform lookups based on that name. Signed-off-by: Marijn Suijten --- drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c | 52 +- 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c index 48eab80b548e..6926c8ff6255 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c @@ -519,7 +519,7 @@ static int dsi_28nm_pll_restore_state(struct msm_dsi_phy *phy) static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **provided_clocks) { - char clk_name[32], parent1[32], parent2[32], vco_name[32]; + char clk_name[32], vco_name[32]; struct clk_init_data vco_init = { .parent_data = &(const struct clk_parent_data) { .fw_name = "ref", .name = "xo", @@ -529,7 +529,7 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov .flags = CLK_IGNORE_UNUSED, }; struct device *dev = &pll_28nm->phy->pdev->dev; - struct clk_hw *hw; + struct clk_hw *hw, *analog_postdiv, *indirect_path_div2, *byte_mux; int ret; DBG("%d", pll_28nm->phy->id); @@ -546,48 +546,40 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov return ret; snprintf(clk_name, 32, "dsi%danalog_postdiv_clk", pll_28nm->phy->id); - snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->phy->id); - hw = devm_clk_hw_register_divider(dev, clk_name, - parent1, CLK_SET_RATE_PARENT, + analog_postdiv = devm_clk_hw_register_divider_parent_hw(dev, clk_name, + &pll_28nm->clk_hw, CLK_SET_RATE_PARENT, pll_28nm->phy->pll_base + - REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG, - 0, 4, 0, NULL); - if (IS_ERR(hw)) - return PTR_ERR(hw); + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG, 0, 4, 0, NULL); + if (IS_ERR(analog_postdiv)) + return PTR_ERR(analog_postdiv); snprintf(clk_name, 32, "dsi%dindirect_path_div2_clk", pll_28nm->phy->id); - snprintf(parent1, 32, "dsi%danalog_postdiv_clk", pll_28nm->phy->id); - hw = devm_clk_hw_register_fixed_factor(dev, clk_name, - parent1, CLK_SET_RATE_PARENT, - 1, 2); - if (IS_ERR(hw)) - return PTR_ERR(hw); + indirect_path_div2 = devm_clk_hw_register_fixed_factor_parent_hw(dev, + clk_name, analog_postdiv, CLK_SET_RATE_PARENT, 1, 2); + if (IS_ERR(indirect_path_div2)) + return PTR_ERR(indirect_path_div2); snprintf(clk_name, 32, "dsi%dpll", pll_28nm->phy->id); - snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->phy->id); - hw = devm_clk_hw_register_divider(dev, clk_name, - parent1, 0, pll_28nm->phy->pll_base + - REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG, - 0, 8, 0, NULL); + hw = devm_clk_hw_register_divider_parent_hw(dev, clk_name, + &pll_28nm->clk_hw, 0, pll_28nm->phy->pll_base + + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG, 0, 8, 0, NULL); if (IS_ERR(hw)) return PTR_ERR(hw); provided_clocks[DSI_PIXEL_PLL_CLK] = hw; snprintf(clk_name, 32, "dsi%dbyte_mux", pll_28nm->phy->id); - snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->phy->id); - snprintf(parent2, 32, "dsi%dindirect_path_div2_clk", pll_28nm->phy->id); - hw = devm_clk_hw_register_mux(dev, clk_name, - ((const char *[]){ - parent1, parent2 + byte_mux = devm_clk_hw_register_mux_parent_hws(dev, clk_name, + ((const struct clk_hw *[]){ + &pll_28nm->clk_hw, + indirect_path_div2, }), 2, CLK_SET_RATE_PARENT, pll_28nm->phy->pll_base + REG_DSI_28nm_PHY_PLL_VREG_CFG, 1, 1, 0, NULL); - if (IS_ERR(hw)) - return PTR_ERR(hw); + if (IS_ERR(byte_mux)) + return PTR_ERR(byte_mux); snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->phy->id); - snprintf(parent1, 32, "dsi%dbyte_mux", pll_28nm->phy->id); - hw = devm_clk_hw_register_fixed_factor(dev, clk_name, - parent1, CLK_SET_RATE_PARENT, 1, 4); + hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, clk_name, + byte_mux, CLK_SET_RATE_PARENT, 1, 4); if (IS_ERR(hw)) return PTR_ERR(hw); provided_clocks[DSI_BYTE_PLL_CLK] = hw; -- 2
[PATCH 6/9] drm/msm/dsi_phy_28nm_8960: Use stack memory for temporary clock names
The clock names formatted into the hw_clk's init structure are only used for the duration of the registration function where they are kstrdup'ed, making it unnecessary to keep the allocations alive for the duration of the device (through devm). Just like the other DSI PHY PLL clock trees, use a stack-local char array and save on memory outside of the pll_28nm_register function. Signed-off-by: Marijn Suijten --- drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c | 10 +- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c index 943a7e847c90..554978fc434d 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c @@ -383,7 +383,7 @@ static int dsi_28nm_pll_restore_state(struct msm_dsi_phy *phy) static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **provided_clocks) { - char *clk_name, *vco_name; + char clk_name[32], vco_name[32]; struct clk_init_data vco_init = { .parent_data = &(const struct clk_parent_data) { .fw_name = "ref", @@ -404,14 +404,6 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov if (!bytediv) return -ENOMEM; - vco_name = devm_kzalloc(dev, 32, GFP_KERNEL); - if (!vco_name) - return -ENOMEM; - - clk_name = devm_kzalloc(dev, 32, GFP_KERNEL); - if (!clk_name) - return -ENOMEM; - snprintf(vco_name, 32, "dsi%dvco_clk", pll_28nm->phy->id); vco_init.name = vco_name; -- 2.36.1
[PATCH 5/9] drm/msm/dsi_phy_28nm_8960: Replace parent names with clk_hw pointers
parent_hw pointers are easier to manage and cheaper to use than repeatedly formatting the parent name and subsequently leaving the clk framework to perform lookups based on that name. Signed-off-by: Marijn Suijten --- .../gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c| 18 +++--- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c index fc56cdcc9ad6..943a7e847c90 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c @@ -383,7 +383,7 @@ static int dsi_28nm_pll_restore_state(struct msm_dsi_phy *phy) static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **provided_clocks) { - char *clk_name, *parent_name, *vco_name; + char *clk_name, *vco_name; struct clk_init_data vco_init = { .parent_data = &(const struct clk_parent_data) { .fw_name = "ref", @@ -408,10 +408,6 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov if (!vco_name) return -ENOMEM; - parent_name = devm_kzalloc(dev, 32, GFP_KERNEL); - if (!parent_name) - return -ENOMEM; - clk_name = devm_kzalloc(dev, 32, GFP_KERNEL); if (!clk_name) return -ENOMEM; @@ -429,13 +425,14 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov bytediv->hw.init = &bytediv_init; bytediv->reg = pll_28nm->phy->pll_base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9; - snprintf(parent_name, 32, "dsi%dvco_clk", pll_28nm->phy->id); snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->phy->id + 1); bytediv_init.name = clk_name; bytediv_init.ops = &clk_bytediv_ops; bytediv_init.flags = CLK_SET_RATE_PARENT; - bytediv_init.parent_names = (const char * const *) &parent_name; + bytediv_init.parent_hws = (const struct clk_hw*[]){ + &pll_28nm->clk_hw, + }; bytediv_init.num_parents = 1; /* DIV2 */ @@ -446,10 +443,9 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov snprintf(clk_name, 32, "dsi%dpll", pll_28nm->phy->id + 1); /* DIV3 */ - hw = devm_clk_hw_register_divider(dev, clk_name, - parent_name, 0, pll_28nm->phy->pll_base + - REG_DSI_28nm_8960_PHY_PLL_CTRL_10, - 0, 8, 0, NULL); + hw = devm_clk_hw_register_divider_parent_hw(dev, clk_name, + &pll_28nm->clk_hw, 0, pll_28nm->phy->pll_base + + REG_DSI_28nm_8960_PHY_PLL_CTRL_10, 0, 8, 0, NULL); if (IS_ERR(hw)) return PTR_ERR(hw); provided_clocks[DSI_PIXEL_PLL_CLK] = hw; -- 2.36.1
[PATCH 8/9] drm/msm/dsi_phy_10nm: Replace parent names with clk_hw pointers
parent_hw pointers are easier to manage and cheaper to use than repeatedly formatting the parent name and subsequently leaving the clk framework to perform lookups based on that name. Signed-off-by: Marijn Suijten --- drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c | 92 ++ 1 file changed, 40 insertions(+), 52 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c index 08b015ea1b1e..178c3f70a7b2 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c @@ -571,8 +571,7 @@ static int dsi_10nm_set_usecase(struct msm_dsi_phy *phy) */ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm, struct clk_hw **provided_clocks) { - char clk_name[32], parent[32], vco_name[32]; - char parent2[32], parent3[32], parent4[32]; + char clk_name[32], vco_name[32]; struct clk_init_data vco_init = { .parent_data = &(const struct clk_parent_data) { .fw_name = "ref", @@ -583,7 +582,8 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm, struct clk_hw **prov .ops = &clk_ops_dsi_pll_10nm_vco, }; struct device *dev = &pll_10nm->phy->pdev->dev; - struct clk_hw *hw; + struct clk_hw *hw, *pll_out_div, *pll_bit, *pll_by_2_bit; + struct clk_hw *pll_post_out_div, *pclk_mux; int ret; DBG("DSI%d", pll_10nm->phy->id); @@ -596,39 +596,34 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm, struct clk_hw **prov return ret; snprintf(clk_name, 32, "dsi%d_pll_out_div_clk", pll_10nm->phy->id); - snprintf(parent, 32, "dsi%dvco_clk", pll_10nm->phy->id); - hw = devm_clk_hw_register_divider(dev, clk_name, -parent, CLK_SET_RATE_PARENT, -pll_10nm->phy->pll_base + -REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE, -0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL); - if (IS_ERR(hw)) { - ret = PTR_ERR(hw); + pll_out_div = devm_clk_hw_register_divider_parent_hw(dev, clk_name, + &pll_10nm->clk_hw, CLK_SET_RATE_PARENT, + pll_10nm->phy->pll_base + + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE, + 0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL); + if (IS_ERR(pll_out_div)) { + ret = PTR_ERR(pll_out_div); goto fail; } snprintf(clk_name, 32, "dsi%d_pll_bit_clk", pll_10nm->phy->id); - snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_10nm->phy->id); /* BIT CLK: DIV_CTRL_3_0 */ - hw = devm_clk_hw_register_divider(dev, clk_name, parent, -CLK_SET_RATE_PARENT, -pll_10nm->phy->base + -REG_DSI_10nm_PHY_CMN_CLK_CFG0, -0, 4, CLK_DIVIDER_ONE_BASED, -&pll_10nm->postdiv_lock); - if (IS_ERR(hw)) { - ret = PTR_ERR(hw); + pll_bit = devm_clk_hw_register_divider_parent_hw(dev, clk_name, + pll_out_div, CLK_SET_RATE_PARENT, + pll_10nm->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG0, + 0, 4, CLK_DIVIDER_ONE_BASED, &pll_10nm->postdiv_lock); + if (IS_ERR(pll_bit)) { + ret = PTR_ERR(pll_bit); goto fail; } snprintf(clk_name, 32, "dsi%d_phy_pll_out_byteclk", pll_10nm->phy->id); - snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_10nm->phy->id); /* DSI Byte clock = VCO_CLK / OUT_DIV / BIT_DIV / 8 */ - hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent, - CLK_SET_RATE_PARENT, 1, 8); + hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, clk_name, + pll_bit, CLK_SET_RATE_PARENT, 1, 8); if (IS_ERR(hw)) { ret = PTR_ERR(hw); goto fail; @@ -637,51 +632,44 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm, struct clk_hw **prov provided_clocks[DSI_BYTE_PLL_CLK] = hw; snprintf(clk_name, 32, "dsi%d_pll_by_2_bit_clk", pll_10nm->phy->id); - snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_10nm->phy->id); - hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent, - 0, 1, 2); - if (IS_ERR(hw)) { - ret = PTR_ERR(hw); + pll_by_2_bit = devm_clk_hw_register_fixed_factor_parent_hw(dev, + clk_name, pll_bit, 0, 1, 2); + if (IS_ERR(pll_by_2_bit)) { + ret = PTR_ERR(pll_by_2_bit); goto fail; } snprintf(clk_name, 32, "dsi%d_pll_post_out_div_clk", pll_10nm->phy->id); - sn
[PATCH 9/9] drm/msm/dsi_phy_7nm: Replace parent names with clk_hw pointers
parent_hw pointers are easier to manage and cheaper to use than repeatedly formatting the parent name and subsequently leaving the clk framework to perform lookups based on that name. Signed-off-by: Marijn Suijten --- drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 92 +++ 1 file changed, 42 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c index 66ed1919a1db..76a9d5094e1b 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c @@ -585,8 +585,7 @@ static int dsi_7nm_set_usecase(struct msm_dsi_phy *phy) */ static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provided_clocks) { - char clk_name[32], parent[32], vco_name[32]; - char parent2[32]; + char clk_name[32], vco_name[32]; struct clk_init_data vco_init = { .parent_data = &(const struct clk_parent_data) { .fw_name = "ref", @@ -597,7 +596,8 @@ static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provide .ops = &clk_ops_dsi_pll_7nm_vco, }; struct device *dev = &pll_7nm->phy->pdev->dev; - struct clk_hw *hw; + struct clk_hw *hw, *pll_out_div, *pll_bit, *pll_by_2_bit; + struct clk_hw *pll_post_out_div, *phy_pll_out_dsi_parent; int ret; DBG("DSI%d", pll_7nm->phy->id); @@ -610,40 +610,35 @@ static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provide return ret; snprintf(clk_name, 32, "dsi%d_pll_out_div_clk", pll_7nm->phy->id); - snprintf(parent, 32, "dsi%dvco_clk", pll_7nm->phy->id); - hw = devm_clk_hw_register_divider(dev, clk_name, -parent, CLK_SET_RATE_PARENT, -pll_7nm->phy->pll_base + -REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE, -0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL); - if (IS_ERR(hw)) { - ret = PTR_ERR(hw); + pll_out_div = devm_clk_hw_register_divider_parent_hw(dev, clk_name, + &pll_7nm->clk_hw, CLK_SET_RATE_PARENT, + pll_7nm->phy->pll_base + + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE, + 0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL); + if (IS_ERR(pll_out_div)) { + ret = PTR_ERR(pll_out_div); goto fail; } snprintf(clk_name, 32, "dsi%d_pll_bit_clk", pll_7nm->phy->id); - snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_7nm->phy->id); /* BIT CLK: DIV_CTRL_3_0 */ - hw = devm_clk_hw_register_divider(dev, clk_name, parent, -CLK_SET_RATE_PARENT, -pll_7nm->phy->base + -REG_DSI_7nm_PHY_CMN_CLK_CFG0, -0, 4, CLK_DIVIDER_ONE_BASED, -&pll_7nm->postdiv_lock); - if (IS_ERR(hw)) { - ret = PTR_ERR(hw); + pll_bit = devm_clk_hw_register_divider_parent_hw(dev, clk_name, + pll_out_div, CLK_SET_RATE_PARENT, + pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG0, + 0, 4, CLK_DIVIDER_ONE_BASED, &pll_7nm->postdiv_lock); + if (IS_ERR(pll_bit)) { + ret = PTR_ERR(pll_bit); goto fail; } snprintf(clk_name, 32, "dsi%d_phy_pll_out_byteclk", pll_7nm->phy->id); - snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->phy->id); /* DSI Byte clock = VCO_CLK / OUT_DIV / BIT_DIV / 8 */ - hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent, - CLK_SET_RATE_PARENT, 1, - pll_7nm->phy->cphy_mode ? 7 : 8); + hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, clk_name, + pll_bit, CLK_SET_RATE_PARENT, 1, + pll_7nm->phy->cphy_mode ? 7 : 8); if (IS_ERR(hw)) { ret = PTR_ERR(hw); goto fail; @@ -652,24 +647,24 @@ static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provide provided_clocks[DSI_BYTE_PLL_CLK] = hw; snprintf(clk_name, 32, "dsi%d_pll_by_2_bit_clk", pll_7nm->phy->id); - snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->phy->id); - hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent, - 0, 1, 2); - if (IS_ERR(hw)) { - ret = PTR_ERR(hw); + pll_by_2_bit = devm_clk_hw_register_fixed_factor_parent_hw(dev, + clk_name, pll_bit, 0, 1, 2); + if (IS_ERR(pll_by_2_bit)) { + ret = PTR_ERR(pll_by_2_bit); goto fail; }
[PATCH 7/9] drm/msm/dsi_phy_14nm: Replace parent names with clk_hw pointers
parent_hw pointers are easier to manage and cheaper to use than repeatedly formatting the parent name and subsequently leaving the clk framework to perform lookups based on that name. Signed-off-by: Marijn Suijten --- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 36 ++ 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c index 8199c53567f4..574f95ab2f22 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c @@ -764,14 +764,14 @@ static int dsi_14nm_set_usecase(struct msm_dsi_phy *phy) static struct clk_hw *pll_14nm_postdiv_register(struct dsi_pll_14nm *pll_14nm, const char *name, - const char *parent_name, + const struct clk_hw *parent_hw, unsigned long flags, u8 shift) { struct dsi_pll_14nm_postdiv *pll_postdiv; struct device *dev = &pll_14nm->phy->pdev->dev; struct clk_init_data postdiv_init = { - .parent_names = (const char *[]) { parent_name }, + .parent_hws = (const struct clk_hw *[]) { parent_hw }, .num_parents = 1, .name = name, .flags = flags, @@ -800,7 +800,7 @@ static struct clk_hw *pll_14nm_postdiv_register(struct dsi_pll_14nm *pll_14nm, static int pll_14nm_register(struct dsi_pll_14nm *pll_14nm, struct clk_hw **provided_clocks) { - char clk_name[32], parent[32], vco_name[32]; + char clk_name[32], vco_name[32]; struct clk_init_data vco_init = { .parent_data = &(const struct clk_parent_data) { .fw_name = "ref", @@ -811,7 +811,7 @@ static int pll_14nm_register(struct dsi_pll_14nm *pll_14nm, struct clk_hw **prov .ops = &clk_ops_dsi_pll_14nm_vco, }; struct device *dev = &pll_14nm->phy->pdev->dev; - struct clk_hw *hw; + struct clk_hw *hw, *n1_postdiv, *n1_postdivby2; int ret; DBG("DSI%d", pll_14nm->phy->id); @@ -824,48 +824,46 @@ static int pll_14nm_register(struct dsi_pll_14nm *pll_14nm, struct clk_hw **prov return ret; snprintf(clk_name, 32, "dsi%dn1_postdiv_clk", pll_14nm->phy->id); - snprintf(parent, 32, "dsi%dvco_clk", pll_14nm->phy->id); /* N1 postdiv, bits 0-3 in REG_DSI_14nm_PHY_CMN_CLK_CFG0 */ - hw = pll_14nm_postdiv_register(pll_14nm, clk_name, parent, - CLK_SET_RATE_PARENT, 0); - if (IS_ERR(hw)) - return PTR_ERR(hw); + n1_postdiv = pll_14nm_postdiv_register(pll_14nm, clk_name, + &pll_14nm->clk_hw, CLK_SET_RATE_PARENT, 0); + if (IS_ERR(n1_postdiv)) + return PTR_ERR(n1_postdiv); snprintf(clk_name, 32, "dsi%dpllbyte", pll_14nm->phy->id); - snprintf(parent, 32, "dsi%dn1_postdiv_clk", pll_14nm->phy->id); /* DSI Byte clock = VCO_CLK / N1 / 8 */ - hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent, - CLK_SET_RATE_PARENT, 1, 8); + hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, clk_name, + n1_postdiv, CLK_SET_RATE_PARENT, 1, 8); if (IS_ERR(hw)) return PTR_ERR(hw); provided_clocks[DSI_BYTE_PLL_CLK] = hw; snprintf(clk_name, 32, "dsi%dn1_postdivby2_clk", pll_14nm->phy->id); - snprintf(parent, 32, "dsi%dn1_postdiv_clk", pll_14nm->phy->id); /* * Skip the mux for now, force DSICLK_SEL to 1, Add a /2 divider * on the way. Don't let it set parent. */ - hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent, 0, 1, 2); - if (IS_ERR(hw)) - return PTR_ERR(hw); + n1_postdivby2 = devm_clk_hw_register_fixed_factor_parent_hw(dev, + clk_name, n1_postdiv, 0, 1, 2); + if (IS_ERR(n1_postdivby2)) + return PTR_ERR(n1_postdivby2); snprintf(clk_name, 32, "dsi%dpll", pll_14nm->phy->id); - snprintf(parent, 32, "dsi%dn1_postdivby2_clk", pll_14nm->phy->id); /* DSI pixel clock = VCO_CLK / N1 / 2 / N2 * This is the output of N2 post-divider, bits 4-7 in * REG_DSI_14nm_PHY_CMN_CLK_CFG0. Don't let it set parent. */ - hw = pll_14nm_postdiv_register(pll_14nm, clk_name, parent, 0, 4); + hw = pll_14nm_postdiv_register(pll_14nm, clk_name, n1_postdivby2, + 0, 4); if (IS_ERR(hw)) return PTR_ERR(hw); - provided_clocks[DSI_PIXEL_PLL_CLK] = hw; + provided_clocks[DSI_PIXEL_PLL_CLK] = hw; return 0; } -- 2.36.1
[PATCH 3/9] clk: fixed-factor: Introduce *clk_hw_register_fixed_factor_parent_hw()
Add the devres and non-devres variant of clk_hw_register_fixed_factor_parent_hw() for registering a fixed factor clock with clk_hw parent pointer instead of parent name. Signed-off-by: Marijn Suijten --- drivers/clk/clk-fixed-factor.c | 57 -- include/linux/clk-provider.h | 8 + 2 files changed, 55 insertions(+), 10 deletions(-) diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c index 54942d758ee6..fabb98d0cdb2 100644 --- a/drivers/clk/clk-fixed-factor.c +++ b/drivers/clk/clk-fixed-factor.c @@ -78,7 +78,8 @@ static void devm_clk_hw_register_fixed_factor_release(struct device *dev, void * static struct clk_hw * __clk_hw_register_fixed_factor(struct device *dev, struct device_node *np, - const char *name, const char *parent_name, int index, + const char *name, const char *parent_name, + const struct clk_hw *parent_hw, int index, unsigned long flags, unsigned int mult, unsigned int div, bool devm) { @@ -108,7 +109,9 @@ __clk_hw_register_fixed_factor(struct device *dev, struct device_node *np, init.name = name; init.ops = &clk_fixed_factor_ops; init.flags = flags; - if (parent_name) + if (parent_hw) + init.parent_hws = &parent_hw; + else if (parent_name) init.parent_names = &parent_name; else init.parent_data = &pdata; @@ -148,17 +151,50 @@ struct clk_hw *devm_clk_hw_register_fixed_factor_index(struct device *dev, const char *name, unsigned int index, unsigned long flags, unsigned int mult, unsigned int div) { - return __clk_hw_register_fixed_factor(dev, NULL, name, NULL, index, - flags, mult, div, true); + return __clk_hw_register_fixed_factor(dev, NULL, name, NULL, NULL, + index, flags, mult, div, true); } EXPORT_SYMBOL_GPL(devm_clk_hw_register_fixed_factor_index); +/** + * devm_clk_hw_register_fixed_factor_parent_hw - Register a fixed factor clock with + * pointer to parent clock + * @dev: device that is registering this clock + * @name: name of this clock + * @parent_hw: pointer to parent clk + * @flags: fixed factor flags + * @mult: multiplier + * @div: divider + * + * Return: Pointer to fixed factor clk_hw structure that was registered or + * an error pointer. + */ +struct clk_hw *devm_clk_hw_register_fixed_factor_parent_hw(struct device *dev, + const char *name, const struct clk_hw *parent_hw, + unsigned long flags, unsigned int mult, unsigned int div) +{ + return __clk_hw_register_fixed_factor(dev, NULL, name, NULL, parent_hw, + -1, flags, mult, div, true); +} +EXPORT_SYMBOL_GPL(devm_clk_hw_register_fixed_factor_parent_hw); + +struct clk_hw *clk_hw_register_fixed_factor_parent_hw(struct device *dev, + const char *name, const struct clk_hw *parent_hw, + unsigned long flags, unsigned int mult, unsigned int div) +{ + return __clk_hw_register_fixed_factor(dev, NULL, name, NULL, + parent_hw, -1, flags, mult, div, + false); +} +EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor_parent_hw); + struct clk_hw *clk_hw_register_fixed_factor(struct device *dev, const char *name, const char *parent_name, unsigned long flags, unsigned int mult, unsigned int div) { - return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, -1, - flags, mult, div, false); + return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, + NULL, -1, flags, mult, div, + false); } EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor); @@ -204,8 +240,9 @@ struct clk_hw *devm_clk_hw_register_fixed_factor(struct device *dev, const char *name, const char *parent_name, unsigned long flags, unsigned int mult, unsigned int div) { - return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, -1, - flags, mult, div, true); + return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, + NULL, -1, flags, mult, div, + true); } EXPORT_SYMBOL_GPL(devm_clk_hw_register_fixed_factor); @@ -240,8 +277,8 @@ static struct clk_hw *_of_fixed_factor_clk_setup(struct device_node *node) if (of_match_node(set_rate_parent_matches, node)) flags |= CLK_SET_RATE_PARENT; - hw = __clk_hw_register_fixed_factor(NULL, node, clk_name, NULL, 0, - flags, mult, div, false);
[PATCH 2/9] clk: mux: Introduce devm_clk_hw_register_mux_parent_hws()
Add the devres variant of clk_hw_register_mux_hws() for registering a mux clock with clk_hw parent pointers instead of parent names. Signed-off-by: Marijn Suijten --- include/linux/clk-provider.h | 7 +++ 1 file changed, 7 insertions(+) diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 4e07621849e6..316c7e082934 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -980,6 +980,13 @@ struct clk *clk_register_mux_table(struct device *dev, const char *name, (parent_names), NULL, NULL, (flags), (reg), \ (shift), BIT((width)) - 1, (clk_mux_flags), \ NULL, (lock)) +#define devm_clk_hw_register_mux_parent_hws(dev, name, parent_hws, \ + num_parents, flags, reg, shift, \ + width, clk_mux_flags, lock) \ + __devm_clk_hw_register_mux((dev), NULL, (name), (num_parents), NULL, \ + (parent_hws), NULL, (flags), (reg),\ + (shift), BIT((width)) - 1, \ + (clk_mux_flags), NULL, (lock)) int clk_mux_val_to_index(struct clk_hw *hw, const u32 *table, unsigned int flags, unsigned int val); -- 2.36.1
[PATCH 0/9] drm/msm/dsi_phy: Replace parent names with clk_hw pointers
As stated in [1] I promised to tackle and send this series. parent_hw pointers are easier to manage and cheaper to use than repeatedly formatting the parent name and subsequently leaving the clk framework to perform lookups based on that name. This series starts out by adding extra constructors for divider, mux and fixed-factor clocks that have parent_hw(s) pointer argument(s) instead of some DT index or name. Followed by individual patches performing the conversion, one DSI PHY at a time. dsi_phy_28nm_8960 includes an extra fixup to replace "eternal" devm_kzalloc allocations (for the lifetime of the device) with stack-local char arrays, like all the other DSI PHY drivers. I couldn't help but notice that clock names are wildly varying: - Some use underscores in the _clk suffix where others have nothing; - Some have an _ after the %d, others have not; - Some use a _pll suffix after dsi%d or even _phy_pll suffix. Are there any thoughts or feelings towards unifying these? Theoretically no clock names are used anywhere in the kernel, and everything is based on a phandle + index in DT (I have yet to validate this). Obviously no .name/.fw_name will be updated to not break DT. Which, by the way, is there a particular reason for: #define DSI_BYTE_PLL_CLK 0 #define DSI_PIXEL_PLL_CLK 1 To not be in the dt-bindings and used in the DT? And with enough future improvements out of the way, let's round out this patch-series by stating that it has been successfully tested on: - Sony Nile Discovery (Xperia XA2 Ultra): 14nm; - Sony Seine PDX201 (Xperia 10II): 14nm; - Sony Loire Suzu (Xperia X): 28nm. And no diff is observed in debugfs's clk_summary. Unfortunately all other devices in my collection with a 7/10nm DSI PHY have a DSC panel which we have yet to get working. [1]: https://lore.kernel.org/linux-arm-msm/20220502214235.s5plebunh4ttj...@somainline.org/ Marijn Suijten (9): clk: divider: Introduce devm_clk_hw_register_divider_parent_hw() clk: mux: Introduce devm_clk_hw_register_mux_parent_hws() clk: fixed-factor: Introduce *clk_hw_register_fixed_factor_parent_hw() drm/msm/dsi_phy_28nm: Replace parent names with clk_hw pointers drm/msm/dsi_phy_28nm_8960: Replace parent names with clk_hw pointers drm/msm/dsi_phy_28nm_8960: Use stack memory for temporary clock names drm/msm/dsi_phy_14nm: Replace parent names with clk_hw pointers drm/msm/dsi_phy_10nm: Replace parent names with clk_hw pointers drm/msm/dsi_phy_7nm: Replace parent names with clk_hw pointers drivers/clk/clk-fixed-factor.c| 57 ++-- drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c| 92 --- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c| 36 drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c| 52 +-- .../gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c | 26 ++ drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 92 +-- include/linux/clk-provider.h | 34 +++ 7 files changed, 209 insertions(+), 180 deletions(-) -- 2.36.1
[PATCH 1/9] clk: divider: Introduce devm_clk_hw_register_divider_parent_hw()
Add the devres variant of clk_hw_register_divider_parent_hw() for registering a divider clock with clk_hw parent pointer instead of parent name. Signed-off-by: Marijn Suijten --- include/linux/clk-provider.h | 19 +++ 1 file changed, 19 insertions(+) diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index c10dc4c659e2..4e07621849e6 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -831,6 +831,25 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name, __devm_clk_hw_register_divider((dev), NULL, (name), (parent_name), NULL, \ NULL, (flags), (reg), (shift), (width), \ (clk_divider_flags), NULL, (lock)) +/** + * devm_clk_hw_register_divider_parent_hw - register a divider clock with the clock framework + * @dev: device registering this clock + * @name: name of this clock + * @parent_hw: pointer to parent clk + * @flags: framework-specific flags + * @reg: register address to adjust divider + * @shift: number of bits to shift the bitfield + * @width: width of the bitfield + * @clk_divider_flags: divider-specific flags for this clock + * @lock: shared register lock for this clock + */ +#define devm_clk_hw_register_divider_parent_hw(dev, name, parent_hw, flags, \ + reg, shift, width, \ + clk_divider_flags, lock) \ + __devm_clk_hw_register_divider((dev), NULL, (name), NULL, \ + (parent_hw), NULL, (flags), (reg), \ + (shift), (width), (clk_divider_flags), \ + NULL, (lock)) /** * devm_clk_hw_register_divider_table - register a table based divider clock * with the clock framework (devres variant) -- 2.36.1
Re: [PATCH] drm/i915/hwconfig: Report no hwconfig support on ADL-N
On Mon, May 23, 2022 at 01:21:16PM +0530, Balasubramani Vivekanandan wrote: > ADL-N being a subplatform of ADL-P, it lacks support for hwconfig > table. Explicit check added to skip ADL-N. > > Signed-off-by: Balasubramani Vivekanandan > Reviewed-by: Matt Roper > --- > drivers/gpu/drm/i915/gt/uc/intel_guc_hwconfig.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_hwconfig.c > b/drivers/gpu/drm/i915/gt/uc/intel_guc_hwconfig.c > index 79c66b6b51a3..5aaa3948de74 100644 > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_hwconfig.c > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_hwconfig.c > @@ -94,7 +94,7 @@ static int guc_hwconfig_fill_buffer(struct intel_guc *guc, > struct intel_hwconfig > > static bool has_table(struct drm_i915_private *i915) > { > - if (IS_ALDERLAKE_P(i915)) > + if (IS_ALDERLAKE_P(i915) && !IS_ADLP_N(i915)) > return true; > if (IS_DG2(i915)) > return true; > -- > 2.25.1 > -- Matt Roper Graphics Software Engineer VTT-OSGC Platform Enablement Intel Corporation
[PATCH v5 5/6] drm/i915/sseu: Disassociate internal subslice mask representation from uapi
As with EU masks, it's easier to store subslice/DSS masks internally in a format that's more natural for the driver to work with, and then only covert into the u8[] uapi form when the query ioctl is invoked. Since the hardware design changed significantly with Xe_HP, we'll use a union to choose between the old "hsw-style" subslice masks or the newer xehp mask. HSW-style masks will be stored in an array of u8's, indexed by slice (there's never more than 6 subslices per slice on older platforms). For Xe_HP and beyond where slices no longer exist, we only need a single bitmask. However we already know that this mask is eventually going to grow too large for a simple u64 to hold, so we'll represent it in a manner that can be operated on by the utilities in linux/bitmap.h. v2: - Fix typo: BIT(s) -> BIT(ss) in gen9_sseu_device_status() v3: - Eliminate sseu->ss_stride and just calculate the stride while specifically handling uapi. (Tvrtko) - Use BITMAP_BITS() macro to refer to size of masks rather than passing I915_MAX_SS_FUSE_BITS directly. (Tvrtko) - Report compute/geometry DSS masks separately when dumping Xe_HP SSEU info. (Tvrtko) - Restore dropped range checks to intel_sseu_has_subslice(). (Tvrtko) v4: - Make the bitmap size macro check the size of the .xehp field rather than the containing union. (Tvrtko) - Don't add GEM_BUG_ON() intel_sseu_has_subslice()'s check for whether slice or subslice ID exceed sseu->max_[sub]slices; various loops in the driver are expected to exceed these, so we should just silently return 'false.' Cc: Tvrtko Ursulin Signed-off-by: Matt Roper --- drivers/gpu/drm/i915/gem/i915_gem_context.c | 5 +- drivers/gpu/drm/i915/gt/intel_engine_cs.c| 4 +- drivers/gpu/drm/i915/gt/intel_gt.c | 12 +- drivers/gpu/drm/i915/gt/intel_sseu.c | 261 +++ drivers/gpu/drm/i915/gt/intel_sseu.h | 76 -- drivers/gpu/drm/i915/gt/intel_sseu_debugfs.c | 30 +-- drivers/gpu/drm/i915/gt/intel_workarounds.c | 24 +- drivers/gpu/drm/i915/i915_getparam.c | 3 +- drivers/gpu/drm/i915/i915_query.c| 13 +- 9 files changed, 241 insertions(+), 187 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c index ab4c5ab28e4d..a3bb73f5d53b 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c @@ -1875,6 +1875,7 @@ i915_gem_user_to_context_sseu(struct intel_gt *gt, { const struct sseu_dev_info *device = >->info.sseu; struct drm_i915_private *i915 = gt->i915; + unsigned int dev_subslice_mask = intel_sseu_get_hsw_subslices(device, 0); /* No zeros in any field. */ if (!user->slice_mask || !user->subslice_mask || @@ -1901,7 +1902,7 @@ i915_gem_user_to_context_sseu(struct intel_gt *gt, if (user->slice_mask & ~device->slice_mask) return -EINVAL; - if (user->subslice_mask & ~device->subslice_mask[0]) + if (user->subslice_mask & ~dev_subslice_mask) return -EINVAL; if (user->max_eus_per_subslice > device->max_eus_per_subslice) @@ -1915,7 +1916,7 @@ i915_gem_user_to_context_sseu(struct intel_gt *gt, /* Part specific restrictions. */ if (GRAPHICS_VER(i915) == 11) { unsigned int hw_s = hweight8(device->slice_mask); - unsigned int hw_ss_per_s = hweight8(device->subslice_mask[0]); + unsigned int hw_ss_per_s = hweight8(dev_subslice_mask); unsigned int req_s = hweight8(context->slice_mask); unsigned int req_ss = hweight8(context->subslice_mask); diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c index 1adbf34c3632..f0acf8518a51 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -674,8 +674,8 @@ static void engine_mask_apply_compute_fuses(struct intel_gt *gt) if (GRAPHICS_VER_FULL(i915) < IP_VER(12, 50)) return; - ccs_mask = intel_slicemask_from_dssmask(intel_sseu_get_compute_subslices(&info->sseu), - ss_per_ccs); + ccs_mask = intel_slicemask_from_xehp_dssmask(info->sseu.compute_subslice_mask, +ss_per_ccs); /* * If all DSS in a quadrant are fused off, the corresponding CCS * engine is not available for use. diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c index 034182f85501..2921f510642f 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt.c +++ b/drivers/gpu/drm/i915/gt/intel_gt.c @@ -133,13 +133,6 @@ static const struct intel_mmio_range dg2_lncf_steering_table[] = { {}, }; -static u16 slicemask(struct intel_gt *gt, int count) -{ - u64 dss_mask = intel_sseu_get_subslices(>->info.sseu, 0); - -
[PATCH -next] drm/msm: DRM_DP_AUX_BUS depends on OF
Fix a Kconfig warning for DRM_MSM by making it depend on OF, since 'select' does not follow any dependency chaings. WARNING: unmet direct dependencies detected for DRM_DP_AUX_BUS Depends on [n]: HAS_IOMEM [=y] && DRM [=m] && OF [=n] Selected by [m]: - DRM_MSM [=m] && HAS_IOMEM [=y] && DRM [=m] && (ARCH_QCOM || SOC_IMX5 || COMPILE_TEST [=y]) && COMMON_CLK [=y] && IOMMU_SUPPORT [=y] && (QCOM_OCMEM [=n] || QCOM_OCMEM [=n]=n) && (QCOM_LLCC [=y] || QCOM_LLCC [=y]=n) && (QCOM_COMMAND_DB [=n] || QCOM_COMMAND_DB [=n]=n) Fixes: f5d01644921b ("drm/msm: select DRM_DP_AUX_BUS for the AUX bus support") Signed-off-by: Randy Dunlap Cc: Rob Clark Cc: Abhinav Kumar Cc: Dmitry Baryshkov Cc: Sean Paul Cc: linux-arm-...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: freedr...@lists.freedesktop.org Cc: David Airlie Cc: Daniel Vetter --- drivers/gpu/drm/msm/Kconfig |1 + 1 file changed, 1 insertion(+) --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -3,6 +3,7 @@ config DRM_MSM tristate "MSM DRM" depends on DRM + depends on OF depends on ARCH_QCOM || SOC_IMX5 || COMPILE_TEST depends on COMMON_CLK depends on IOMMU_SUPPORT
Re: [PATCH] drm/amdkfd: fix typo in comment
Applied. Thanks! Alex On Sat, May 21, 2022 at 7:12 AM Julia Lawall wrote: > > Spelling mistake (triple letters) in comment. > Detected with the help of Coccinelle. > > Signed-off-by: Julia Lawall > > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c |2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c > index 8b5452a8d330..67abf8dcd30a 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c > @@ -1621,7 +1621,7 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu( > > mutex_lock(&mem->lock); > > - /* Unpin MMIO/DOORBELL BO's that were pinnned during allocation */ > + /* Unpin MMIO/DOORBELL BO's that were pinned during allocation */ > if (mem->alloc_flags & > (KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL | > KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP)) { >
Re: [PATCH] drm/amdgpu/gfx: fix typos in comments
Applied. Thanks! Alex On Sat, May 21, 2022 at 7:12 AM Julia Lawall wrote: > > Spelling mistakes (triple letters) in comments. > Detected with the help of Coccinelle. > > Signed-off-by: Julia Lawall > > --- > drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c |2 +- > drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c |4 ++-- > drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c |2 +- > 3 files changed, 4 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c > b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c > index 02754ee86c81..c5f46d264b23 100644 > --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c > @@ -5111,7 +5111,7 @@ static void gfx_v10_0_init_compute_vmid(struct > amdgpu_device *adev) > mutex_unlock(&adev->srbm_mutex); > > /* Initialize all compute VMIDs to have no GDS, GWS, or OA > - acccess. These should be enabled by FW for target VMIDs. */ > + access. These should be enabled by FW for target VMIDs. */ > for (i = adev->vm_manager.first_kfd_vmid; i < AMDGPU_NUM_VMID; i++) { > WREG32_SOC15_OFFSET(GC, 0, mmGDS_VMID0_BASE, 2 * i, 0); > WREG32_SOC15_OFFSET(GC, 0, mmGDS_VMID0_SIZE, 2 * i, 0); > diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c > b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c > index fb9302910742..7f0b18b0d4c4 100644 > --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c > @@ -3714,7 +3714,7 @@ static void gfx_v8_0_init_compute_vmid(struct > amdgpu_device *adev) > mutex_unlock(&adev->srbm_mutex); > > /* Initialize all compute VMIDs to have no GDS, GWS, or OA > - acccess. These should be enabled by FW for target VMIDs. */ > + access. These should be enabled by FW for target VMIDs. */ > for (i = adev->vm_manager.first_kfd_vmid; i < AMDGPU_NUM_VMID; i++) { > WREG32(amdgpu_gds_reg_offset[i].mem_base, 0); > WREG32(amdgpu_gds_reg_offset[i].mem_size, 0); > @@ -5815,7 +5815,7 @@ static void > gfx_v8_0_update_coarse_grain_clock_gating(struct amdgpu_device *adev > /* wait for RLC_SERDES_CU_MASTER & RLC_SERDES_NONCU_MASTER > idle */ > gfx_v8_0_wait_for_rlc_serdes(adev); > > - /* write cmd to Set CGCG Overrride */ > + /* write cmd to Set CGCG Override */ > gfx_v8_0_send_serdes_cmd(adev, BPM_REG_CGCG_OVERRIDE, > SET_BPM_SERDES_CMD); > > /* wait for RLC_SERDES_CU_MASTER & RLC_SERDES_NONCU_MASTER > idle */ > diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c > b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c > index f12ae6e2359a..5349ca4d19e3 100644 > --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c > @@ -2535,7 +2535,7 @@ static void gfx_v9_0_init_compute_vmid(struct > amdgpu_device *adev) > mutex_unlock(&adev->srbm_mutex); > > /* Initialize all compute VMIDs to have no GDS, GWS, or OA > - acccess. These should be enabled by FW for target VMIDs. */ > + access. These should be enabled by FW for target VMIDs. */ > for (i = adev->vm_manager.first_kfd_vmid; i < AMDGPU_NUM_VMID; i++) { > WREG32_SOC15_OFFSET(GC, 0, mmGDS_VMID0_BASE, 2 * i, 0); > WREG32_SOC15_OFFSET(GC, 0, mmGDS_VMID0_SIZE, 2 * i, 0); >
Re: [PATCH] drm/nouveau/tegra: remove needless NULL check
Reviewed-by: Lyude Paul Will push to the appropriate branch in a moment On Thu, 2022-05-19 at 15:29 +0800, Guo Zhengkui wrote: > There has already been NULL check in clk_prepare_enable() and > clk_disable_unprepare(), so remove needless NULL check before > calling them. > > Signed-off-by: Guo Zhengkui > --- > drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c | 14 +- > 1 file changed, 5 insertions(+), 9 deletions(-) > > diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c > b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c > index 2ed528c065fa..ac9e122586bc 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c > +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c > @@ -41,11 +41,9 @@ nvkm_device_tegra_power_up(struct nvkm_device_tegra > *tdev) > ret = clk_prepare_enable(tdev->clk); > if (ret) > goto err_clk; > - if (tdev->clk_ref) { > - ret = clk_prepare_enable(tdev->clk_ref); > - if (ret) > - goto err_clk_ref; > - } > + ret = clk_prepare_enable(tdev->clk_ref); > + if (ret) > + goto err_clk_ref; > ret = clk_prepare_enable(tdev->clk_pwr); > if (ret) > goto err_clk_pwr; > @@ -70,8 +68,7 @@ nvkm_device_tegra_power_up(struct nvkm_device_tegra *tdev) > err_clamp: > clk_disable_unprepare(tdev->clk_pwr); > err_clk_pwr: > - if (tdev->clk_ref) > - clk_disable_unprepare(tdev->clk_ref); > + clk_disable_unprepare(tdev->clk_ref); > err_clk_ref: > clk_disable_unprepare(tdev->clk); > err_clk: > @@ -87,8 +84,7 @@ nvkm_device_tegra_power_down(struct nvkm_device_tegra > *tdev) > int ret; > > clk_disable_unprepare(tdev->clk_pwr); > - if (tdev->clk_ref) > - clk_disable_unprepare(tdev->clk_ref); > + clk_disable_unprepare(tdev->clk_ref); > clk_disable_unprepare(tdev->clk); > udelay(10); > -- Cheers, Lyude Paul (she/her) Software Engineer at Red Hat
Re: [Nouveau] nouveau lockdep deadlock report with 5.18-rc6
On Fri, 2022-05-20 at 13:46 +0200, Computer Enthusiastic wrote: > Hello, > > Il giorno mer 18 mag 2022 alle ore 19:42 Lyude Paul > ha scritto: > > > > On Tue, 2022-05-17 at 13:10 +0200, Hans de Goede wrote: > > > Hi All, > > > I just noticed the below lockdep possible deadlock report with a 5.18- > > > rc6 > > > kernel on a Dell Latitude E6430 laptop with the following nvidia GPU: > > > [..] > I hope not to be off topic in regard to kernel version, otherwise I > apologize in advance. > > I would like to report that I'm constantly observing a similar, but > somehow different, lockdep warning (see [1]) in kernels 5.16 and 5.17 > (compiled with lockdep debugging features) every time I activate the > Suspend To Ram (regardless if STR succeeds or not). You may be on the right track actually, as so far my investigation has shown that this bug definitely would have been present around those kernel versions as well. Trying to come up with a solution for this > > Thanks. > > [1] > https://gitlab.freedesktop.org/xorg/driver/xf86-video-nouveau/-/issues/547#note_1361411 > -- Cheers, Lyude Paul (she/her) Software Engineer at Red Hat
Re: [PATCH] drm/nouveau/mmu: fix typo in comment
Reviewed-by: Lyude Paul Will fix that double space after the punctuation while I'm at it as well, and will push to the appropriate branch in a little bit. Thanks! On Sat, 2022-05-21 at 13:11 +0200, Julia Lawall wrote: > Spelling mistake (triple letters) in comment. > Detected with the help of Coccinelle. > > Signed-off-by: Julia Lawall > > --- > drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c > b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c > index 8bf00b396ec1..8b11dfa0998d 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c > +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c > @@ -280,7 +280,7 @@ nvkm_vmm_unref_ptes(struct nvkm_vmm_iter *it, bool pfn, > u32 ptei, u32 ptes) > if (desc->type == SPT && (pgt->refs[0] || pgt->refs[1])) > nvkm_vmm_unref_sptes(it, pgt, desc, ptei, ptes); > > - /* PT no longer neeed? Destroy it. */ > + /* PT no longer needed? Destroy it. */ > if (!pgt->refs[type]) { > it->lvl++; > TRA(it, "%s empty", nvkm_vmm_desc_type(desc)); > -- Cheers, Lyude Paul (she/her) Software Engineer at Red Hat
Re: [Intel-gfx] [RFC v3 3/3] drm/doc/rfc: VM_BIND uapi definition
On Thu, May 19, 2022 at 04:07:30PM -0700, Zanoni, Paulo R wrote: On Tue, 2022-05-17 at 11:32 -0700, Niranjana Vishwanathapura wrote: VM_BIND and related uapi definitions v2: Ensure proper kernel-doc formatting with cross references. Also add new uapi and documentation as per review comments from Daniel. Signed-off-by: Niranjana Vishwanathapura --- Documentation/gpu/rfc/i915_vm_bind.h | 399 +++ 1 file changed, 399 insertions(+) create mode 100644 Documentation/gpu/rfc/i915_vm_bind.h diff --git a/Documentation/gpu/rfc/i915_vm_bind.h b/Documentation/gpu/rfc/i915_vm_bind.h new file mode 100644 index ..589c0a009107 --- /dev/null +++ b/Documentation/gpu/rfc/i915_vm_bind.h @@ -0,0 +1,399 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2022 Intel Corporation + */ + +/** + * DOC: I915_PARAM_HAS_VM_BIND + * + * VM_BIND feature availability. + * See typedef drm_i915_getparam_t param. + */ +#define I915_PARAM_HAS_VM_BIND 57 + +/** + * DOC: I915_VM_CREATE_FLAGS_USE_VM_BIND + * + * Flag to opt-in for VM_BIND mode of binding during VM creation. + * See struct drm_i915_gem_vm_control flags. + * + * A VM in VM_BIND mode will not support the older execbuff mode of binding. + * In VM_BIND mode, execbuff ioctl will not accept any execlist (ie., the + * &drm_i915_gem_execbuffer2.buffer_count must be 0). + * Also, &drm_i915_gem_execbuffer2.batch_start_offset and + * &drm_i915_gem_execbuffer2.batch_len must be 0. + * DRM_I915_GEM_EXECBUFFER_EXT_BATCH_ADDRESSES extension must be provided + * to pass in the batch buffer addresses. + * + * Additionally, I915_EXEC_NO_RELOC, I915_EXEC_HANDLE_LUT and + * I915_EXEC_BATCH_FIRST of &drm_i915_gem_execbuffer2.flags must be 0 + * (not used) in VM_BIND mode. I915_EXEC_USE_EXTENSIONS flag must always be + * set (See struct drm_i915_gem_execbuffer_ext_batch_addresses). + * The buffers_ptr, buffer_count, batch_start_offset and batch_len fields + * of struct drm_i915_gem_execbuffer2 are also not used and must be 0. + */ From that description, it seems we have: struct drm_i915_gem_execbuffer2 { __u64 buffers_ptr; -> must be 0 (new) __u32 buffer_count; -> must be 0 (new) __u32 batch_start_offset; -> must be 0 (new) __u32 batch_len;-> must be 0 (new) __u32 DR1; -> must be 0 (old) __u32 DR4; -> must be 0 (old) __u32 num_cliprects; (fences) -> must be 0 since using extensions __u64 cliprects_ptr; (fences, extensions) -> contains an actual pointer! __u64 flags;-> some flags must be 0 (new) __u64 rsvd1; (context info) -> repurposed field (old) __u64 rsvd2;-> unused }; Based on that, why can't we just get drm_i915_gem_execbuffer3 instead of adding even more complexity to an already abused interface? While the Vulkan-like extension thing is really nice, I don't think what we're doing here is extending the ioctl usage, we're completely changing how the base struct should be interpreted based on how the VM was created (which is an entirely different ioctl). From Rusty Russel's API Design grading, drm_i915_gem_execbuffer2 is already at -6 without these changes. I think after vm_bind we'll need to create a -11 entry just to deal with this ioctl. The only change here is removing the execlist support for VM_BIND mode (other than natual extensions). Adding a new execbuffer3 was considered, but I think we need to be careful with that as that goes beyond the VM_BIND support, including any future requirements (as we don't want an execbuffer4 after VM_BIND). Niranjana +#define I915_VM_CREATE_FLAGS_USE_VM_BIND (1 << 0) + +/** + * DOC: I915_CONTEXT_CREATE_FLAGS_LONG_RUNNING + * + * Flag to declare context as long running. + * See struct drm_i915_gem_context_create_ext flags. + * + * Usage of dma-fence expects that they complete in reasonable amount of time. + * Compute on the other hand can be long running. Hence it is not appropriate + * for compute contexts to export request completion dma-fence to user. + * The dma-fence usage will be limited to in-kernel consumption only. + * Compute contexts need to use user/memory fence. + * + * So, long running contexts do not support output fences. Hence, + * I915_EXEC_FENCE_OUT (See &drm_i915_gem_execbuffer2.flags and + * I915_EXEC_FENCE_SIGNAL (See &drm_i915_gem_exec_fence.flags) are expected + * to be not used. + * + * DRM_I915_GEM_WAIT ioctl call is also not supported for objects mapped + * to long running contexts. + */ +#define I915_CONTEXT_CREATE_FLAGS_LONG_RUNNING (1u << 2) + +/* VM_BIND related ioctls */ +#define DRM_I915_GEM_VM_BIND 0x3d +#define DRM_I915_GEM_VM_UNBIND 0x3e +#define DRM_I915_GEM_WAIT_USER_FENCE 0x3f + +#define DRM_IOCTL_I915_GEM_VM_BIND DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_BIND, struct drm_i915_gem_vm_bi
Re: [RFC v3 1/3] drm/doc/rfc: VM_BIND feature design document
On Mon, May 23, 2022 at 12:05:05PM -0700, Niranjana Vishwanathapura wrote: On Thu, May 19, 2022 at 03:52:01PM -0700, Zanoni, Paulo R wrote: On Tue, 2022-05-17 at 11:32 -0700, Niranjana Vishwanathapura wrote: VM_BIND design document with description of intended use cases. v2: Add more documentation and format as per review comments from Daniel. Signed-off-by: Niranjana Vishwanathapura --- diff --git a/Documentation/gpu/rfc/i915_vm_bind.rst b/Documentation/gpu/rfc/i915_vm_bind.rst new file mode 100644 index ..f1be560d313c --- /dev/null +++ b/Documentation/gpu/rfc/i915_vm_bind.rst @@ -0,0 +1,304 @@ +== +I915 VM_BIND feature design and use cases +== + +VM_BIND feature + +DRM_I915_GEM_VM_BIND/UNBIND ioctls allows UMD to bind/unbind GEM buffer +objects (BOs) or sections of a BOs at specified GPU virtual addresses on a +specified address space (VM). These mappings (also referred to as persistent +mappings) will be persistent across multiple GPU submissions (execbuff calls) +issued by the UMD, without user having to provide a list of all required +mappings during each submission (as required by older execbuff mode). + +VM_BIND/UNBIND ioctls will support 'in' and 'out' fences to allow userpace +to specify how the binding/unbinding should sync with other operations +like the GPU job submission. These fences will be timeline 'drm_syncobj's +for non-Compute contexts (See struct drm_i915_vm_bind_ext_timeline_fences). +For Compute contexts, they will be user/memory fences (See struct +drm_i915_vm_bind_ext_user_fence). + +VM_BIND feature is advertised to user via I915_PARAM_HAS_VM_BIND. +User has to opt-in for VM_BIND mode of binding for an address space (VM) +during VM creation time via I915_VM_CREATE_FLAGS_USE_VM_BIND extension. + +VM_BIND/UNBIND ioctl will immediately start binding/unbinding the mapping in an +async worker. The binding and unbinding will work like a special GPU engine. +The binding and unbinding operations are serialized and will wait on specified +input fences before the operation and will signal the output fences upon the +completion of the operation. Due to serialization, completion of an operation +will also indicate that all previous operations are also complete. + +VM_BIND features include: + +* Multiple Virtual Address (VA) mappings can map to the same physical pages + of an object (aliasing). +* VA mapping can map to a partial section of the BO (partial binding). +* Support capture of persistent mappings in the dump upon GPU error. +* TLB is flushed upon unbind completion. Batching of TLB flushes in some + use cases will be helpful. +* Asynchronous vm_bind and vm_unbind support with 'in' and 'out' fences. +* Support for userptr gem objects (no special uapi is required for this). + +Execbuff ioctl in VM_BIND mode +--- +The execbuff ioctl handling in VM_BIND mode differs significantly from the +older method. A VM in VM_BIND mode will not support older execbuff mode of +binding. In VM_BIND mode, execbuff ioctl will not accept any execlist. Hence, +no support for implicit sync. It is expected that the below work will be able +to support requirements of object dependency setting in all use cases: + +"dma-buf: Add an API for exporting sync files" +(https://lwn.net/Articles/859290/) I would really like to have more details here. The link provided points to new ioctls and we're not very familiar with those yet, so I think you should really clarify the interaction between the new additions here. Having some sample code would be really nice too. For Mesa at least (and I believe for the other drivers too) we always have a few exported buffers in every execbuf call, and we rely on the implicit synchronization provided by execbuf to make sure everything works. The execbuf ioctl also has some code to flush caches during implicit synchronization AFAIR, so I would guess we rely on it too and whatever else the Kernel does. Is that covered by the new ioctls? In addition, as far as I remember, one of the big improvements of vm_bind was that it would help reduce ioctl latency and cpu overhead. But if making execbuf faster comes at the cost of requiring additional ioctls calls for implicit synchronization, which is required on ever execbuf call, then I wonder if we'll even get any faster at all. Comparing old execbuf vs plain new execbuf without the new required ioctls won't make sense. But maybe I'm wrong and we won't need to call these new ioctls around every single execbuf ioctl we submit? Again, more clarification and some code examples here would be really nice. This is a big change on an important part of the API, we should clarify the new expected usage. Thanks Paulo for the comments. In VM_BIND mode, the only reason we would need execlist support in execbuff path is for implicit synchronization. And AFAIK, this work from Jason is expected replace imp
Re: [RFC v3 1/3] drm/doc/rfc: VM_BIND feature design document
On Thu, May 19, 2022 at 03:52:01PM -0700, Zanoni, Paulo R wrote: On Tue, 2022-05-17 at 11:32 -0700, Niranjana Vishwanathapura wrote: VM_BIND design document with description of intended use cases. v2: Add more documentation and format as per review comments from Daniel. Signed-off-by: Niranjana Vishwanathapura --- diff --git a/Documentation/gpu/rfc/i915_vm_bind.rst b/Documentation/gpu/rfc/i915_vm_bind.rst new file mode 100644 index ..f1be560d313c --- /dev/null +++ b/Documentation/gpu/rfc/i915_vm_bind.rst @@ -0,0 +1,304 @@ +== +I915 VM_BIND feature design and use cases +== + +VM_BIND feature + +DRM_I915_GEM_VM_BIND/UNBIND ioctls allows UMD to bind/unbind GEM buffer +objects (BOs) or sections of a BOs at specified GPU virtual addresses on a +specified address space (VM). These mappings (also referred to as persistent +mappings) will be persistent across multiple GPU submissions (execbuff calls) +issued by the UMD, without user having to provide a list of all required +mappings during each submission (as required by older execbuff mode). + +VM_BIND/UNBIND ioctls will support 'in' and 'out' fences to allow userpace +to specify how the binding/unbinding should sync with other operations +like the GPU job submission. These fences will be timeline 'drm_syncobj's +for non-Compute contexts (See struct drm_i915_vm_bind_ext_timeline_fences). +For Compute contexts, they will be user/memory fences (See struct +drm_i915_vm_bind_ext_user_fence). + +VM_BIND feature is advertised to user via I915_PARAM_HAS_VM_BIND. +User has to opt-in for VM_BIND mode of binding for an address space (VM) +during VM creation time via I915_VM_CREATE_FLAGS_USE_VM_BIND extension. + +VM_BIND/UNBIND ioctl will immediately start binding/unbinding the mapping in an +async worker. The binding and unbinding will work like a special GPU engine. +The binding and unbinding operations are serialized and will wait on specified +input fences before the operation and will signal the output fences upon the +completion of the operation. Due to serialization, completion of an operation +will also indicate that all previous operations are also complete. + +VM_BIND features include: + +* Multiple Virtual Address (VA) mappings can map to the same physical pages + of an object (aliasing). +* VA mapping can map to a partial section of the BO (partial binding). +* Support capture of persistent mappings in the dump upon GPU error. +* TLB is flushed upon unbind completion. Batching of TLB flushes in some + use cases will be helpful. +* Asynchronous vm_bind and vm_unbind support with 'in' and 'out' fences. +* Support for userptr gem objects (no special uapi is required for this). + +Execbuff ioctl in VM_BIND mode +--- +The execbuff ioctl handling in VM_BIND mode differs significantly from the +older method. A VM in VM_BIND mode will not support older execbuff mode of +binding. In VM_BIND mode, execbuff ioctl will not accept any execlist. Hence, +no support for implicit sync. It is expected that the below work will be able +to support requirements of object dependency setting in all use cases: + +"dma-buf: Add an API for exporting sync files" +(https://lwn.net/Articles/859290/) I would really like to have more details here. The link provided points to new ioctls and we're not very familiar with those yet, so I think you should really clarify the interaction between the new additions here. Having some sample code would be really nice too. For Mesa at least (and I believe for the other drivers too) we always have a few exported buffers in every execbuf call, and we rely on the implicit synchronization provided by execbuf to make sure everything works. The execbuf ioctl also has some code to flush caches during implicit synchronization AFAIR, so I would guess we rely on it too and whatever else the Kernel does. Is that covered by the new ioctls? In addition, as far as I remember, one of the big improvements of vm_bind was that it would help reduce ioctl latency and cpu overhead. But if making execbuf faster comes at the cost of requiring additional ioctls calls for implicit synchronization, which is required on ever execbuf call, then I wonder if we'll even get any faster at all. Comparing old execbuf vs plain new execbuf without the new required ioctls won't make sense. But maybe I'm wrong and we won't need to call these new ioctls around every single execbuf ioctl we submit? Again, more clarification and some code examples here would be really nice. This is a big change on an important part of the API, we should clarify the new expected usage. Thanks Paulo for the comments. In VM_BIND mode, the only reason we would need execlist support in execbuff path is for implicit synchronization. And AFAIK, this work from Jason is expected replace implict synchronization with new ioctls. Hence, VM_BIND mode will not be needi
Re: [PATCH v3] drm/nouveau: clear output poll workers before nouveau_fbcon_destroy()
Reviewed-by: Lyude Paul Will push to the appropriate branch in a bit, thanks! On Mon, 2022-05-23 at 13:35 +0200, Mark Menzynski wrote: > Resources needed for output poll workers are destroyed in > nouveau_fbcon_fini() before output poll workers are cleared in > nouveau_display_fini(). This means there is a time between fbcon_fini() > and display_fini(), where if output poll happens, it crashes. > > This patch introduces another output poll clearing before fbcon > resources are destroyed. > > BUG: KASAN: use-after-free in > __drm_fb_helper_initial_config_and_unlock.cold+0x1f3/0x291 > [drm_kms_helper] > > Cc: Ben Skeggs > Cc: Karol Herbst > Cc: Lyude Paul > Cc: David Airlie > Cc: Daniel Vetter > Cc: dri-devel@lists.freedesktop.org > Cc: nouv...@lists.freedesktop.org > Cc: linux-ker...@vger.kernel.org > Signed-off-by: Mark Menzynski > --- > drivers/gpu/drm/nouveau/nouveau_fbcon.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c > b/drivers/gpu/drm/nouveau/nouveau_fbcon.c > index 4f9b3aa5deda..5226323e55d3 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c > +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c > @@ -39,6 +39,7 @@ > > #include > #include > +#include > #include > #include > #include > @@ -605,6 +606,7 @@ nouveau_fbcon_fini(struct drm_device *dev) > if (!drm->fbcon) > return; > > + drm_kms_helper_poll_fini(dev); > nouveau_fbcon_accel_fini(dev); > nouveau_fbcon_destroy(dev, drm->fbcon); > kfree(drm->fbcon); -- Cheers, Lyude Paul (she/her) Software Engineer at Red Hat
Re: [PATCH v3 3/4] drm/bridge: Add devm_drm_bridge_add()
Hi, On Sat, May 21, 2022 at 2:17 AM Maxime Ripard wrote: > > Hi, > > On Tue, May 10, 2022 at 12:29:43PM -0700, Douglas Anderson wrote: > > This adds a devm managed version of drm_bridge_add(). Like other > > "devm" function listed in drm_bridge.h, this function takes an > > explicit "dev" to use for the lifetime management. A few notes: > > * In general we have a "struct device" for bridges that makes a good > > candidate for where the lifetime matches exactly what we want. > > * The "bridge->dev->dev" device appears to be the encoder > > device. That's not the right device to use for lifetime management. > > > > Suggested-by: Dmitry Baryshkov > > Signed-off-by: Douglas Anderson > > If we are to introduce more managed helpers, I think it'd be wiser to > introduce them as DRM-managed, and not device managed. > > Otherwise, you'll end up in a weird state when a device has been removed > but the DRM device is still around. I'm kinda confused. In this case there is no DRM device for the bridge and, as per my CL description, "bridge-dev->dev" appears to be the encoder device. I wasn't personally involved in discussions about it, but I was under the impression that this was expected / normal. Thus we can't make this DRM-managed. -Doug
Re: [PATCH] dt-bindings: Fix properties without any type
On Sat, May 21, 2022 at 05:03:41PM +0200, Krzysztof Kozlowski wrote: > On 19/05/2022 23:14, Rob Herring wrote: > > Now that the schema tools can extract type information for all > > properties (in order to decode dtb files), finding properties missing > > any type definition is fairly trivial though not yet automated. > > > > Fix the various property schemas which are missing a type. Most of these > > tend to be device specific properties which don't have a vendor prefix. > > A vendor prefix is how we normally ensure a type is defined. > > > > Signed-off-by: Rob Herring > > --- > > .../arm/hisilicon/controller/hip04-bootwrapper.yaml | 5 +++-- > > .../bindings/display/bridge/toshiba,tc358768.yaml | 1 + > > .../devicetree/bindings/display/panel/panel-timing.yaml | 5 + > > .../bindings/display/panel/raydium,rm67191.yaml | 1 + > > .../bindings/display/panel/samsung,s6e8aa0.yaml | 1 + > > .../devicetree/bindings/gpio/fairchild,74hc595.yaml | 1 + > > .../devicetree/bindings/input/google,cros-ec-keyb.yaml| 1 + > > .../devicetree/bindings/input/matrix-keymap.yaml | 4 > > Documentation/devicetree/bindings/media/i2c/adv7604.yaml | 3 ++- > > Documentation/devicetree/bindings/mux/reg-mux.yaml| 8 ++-- > > Documentation/devicetree/bindings/net/cdns,macb.yaml | 1 + > > Documentation/devicetree/bindings/net/ingenic,mac.yaml| 1 + > > .../devicetree/bindings/net/ti,davinci-mdio.yaml | 1 + > > .../devicetree/bindings/net/wireless/ti,wlcore.yaml | 2 ++ > > .../devicetree/bindings/pci/snps,dw-pcie-ep.yaml | 6 -- > > Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml | 2 ++ > > .../devicetree/bindings/pinctrl/canaan,k210-fpioa.yaml| 2 ++ > > Documentation/devicetree/bindings/power/avs/qcom,cpr.yaml | 1 + > > .../devicetree/bindings/power/supply/battery.yaml | 7 ++- > > .../devicetree/bindings/power/supply/charger-manager.yaml | 1 + > > Documentation/devicetree/bindings/rng/st,stm32-rng.yaml | 1 + > > Documentation/devicetree/bindings/serial/8250.yaml| 1 + > > .../devicetree/bindings/sound/audio-graph-card2.yaml | 3 +++ > > .../devicetree/bindings/sound/imx-audio-hdmi.yaml | 3 +++ > > Documentation/devicetree/bindings/usb/smsc,usb3503.yaml | 1 + > > 25 files changed, 55 insertions(+), 8 deletions(-) > > > > diff --git > > a/Documentation/devicetree/bindings/arm/hisilicon/controller/hip04-bootwrapper.yaml > > > > b/Documentation/devicetree/bindings/arm/hisilicon/controller/hip04-bootwrapper.yaml > > index 7378159e61df..483caf0ce25b 100644 > > --- > > a/Documentation/devicetree/bindings/arm/hisilicon/controller/hip04-bootwrapper.yaml > > +++ > > b/Documentation/devicetree/bindings/arm/hisilicon/controller/hip04-bootwrapper.yaml > > @@ -17,14 +17,15 @@ properties: > >- const: hisilicon,hip04-bootwrapper > > > >boot-method: > > +$ref: /schemas/types.yaml#/definitions/uint32-array > > description: | > >Address and size of boot method. > >[0]: bootwrapper physical address > >[1]: bootwrapper size > >[2]: relocation physical address > >[3]: relocation size > > -minItems: 1 > > -maxItems: 2 > > +minItems: 2 > > +maxItems: 4 > > > > required: > >- compatible > > diff --git > > a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358768.yaml > > b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358768.yaml > > index 3bd670b8e5cd..0b6f5bef120f 100644 > > --- a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358768.yaml > > +++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358768.yaml > > @@ -58,6 +58,7 @@ properties: > > > > properties: > >data-lines: > > +$ref: /schemas/types.yaml#/definitions/uint32 > > enum: [ 16, 18, 24 ] > > > >port@1: > > diff --git > > a/Documentation/devicetree/bindings/display/panel/panel-timing.yaml > > b/Documentation/devicetree/bindings/display/panel/panel-timing.yaml > > index 7749de95ee40..229e3b36ee29 100644 > > --- a/Documentation/devicetree/bindings/display/panel/panel-timing.yaml > > +++ b/Documentation/devicetree/bindings/display/panel/panel-timing.yaml > > @@ -146,6 +146,7 @@ properties: > >Horizontal sync pulse. > >0 selects active low, 1 selects active high. > >If omitted then it is not used by the hardware > > +$ref: /schemas/types.yaml#/definitions/uint32 > > enum: [0, 1] > > > >vsync-active: > > @@ -153,6 +154,7 @@ properties: > >Vertical sync pulse. > >0 selects active low, 1 selects active high. > >If omitted then it is not used by the hardware > > +$ref: /schemas/types.yaml#/definitions/uint32 > > enum: [0, 1] > > > >de-active: > > @@ -160,6 +162,7 @@ properties: > >Data enable. > >0 selects active low, 1
Re: [PATCH -next] drm/panel: Fix build error when CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20=y && CONFIG_DRM_DISPLAY_HELPER=m
Hi, On Mon, May 23, 2022 at 1:58 AM gaochao wrote: > > If CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20=y && CONFIG_DRM_DISPLAY_HELPER=m, > bulding fails: > > drivers/gpu/drm/panel/panel-samsung-atna33xc20.o: In function > `atana33xc20_probe': > panel-samsung-atna33xc20.c:(.text+0x744): undefined reference to > `drm_panel_dp_aux_backlight' > make: *** [vmlinux] Error 1 > > Let CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20 select DRM_DISPLAY_DP_HELPER and > CONFIG_DRM_DISPLAY_HELPER to fix this error. > > Fixes: 32ce3b320343 ("drm/panel: atna33xc20: Introduce the Samsung ATNA33XC20 > panel") > Reported-by: Hulk Robot > Signed-off-by: gaochao I think the author / Signed-off-by are supposed to be real names. Is "gaochao" your legal name? > --- > drivers/gpu/drm/panel/Kconfig | 2 ++ > 1 file changed, 2 insertions(+) Other than the Signed-off-by / Author issue: Reviewed-by: Douglas Anderson
Re: [PATCH] drm/sun4i: mixer: fix scanline for V3s and D1
在 2022-05-22星期日的 10:36 +0200,Jernej Škrabec写道: > Hi! > > Dne sobota, 21. maj 2022 ob 15:34:43 CEST je Genfu Pan napisal(a): > > Accrording the SDK from Allwinner, the scanline value of yuv and > > rgb for > > V3s are both 1024. > > s/scanline value/scanline length/ > > Which SDK? All SDKs that I have or found on internet don't mention > YUV nor RGB > scanline limit. That doesn't mean there is none, I'm just unable to > verify > your claim. Did you test this by yourself? Also, please make YUV > scanline > change separate patch with fixes tag. BTW I think chip manuals all say that the chip supports NxN resolution in DE2 chapter, e.g. the V3 datasheet says DE2 "Output size up to 1024x1024". However there's no information about D1's second mixer. > > > The is also the same for mixer 1 of D1. Currently the > > scanline value of rgb is hardcoded to 2048 for all SOCs. > > > > Change the scanline_yuv property of V3s to 1024. > Add the > > scanline_rgb > > property to the mixer config and replace the hardcoded value with > > it before > > scaling. > > I guess RGB scanline patch would also need fixes tag, since it fixes > existing > bug. > > > > > Signed-off-by: Genfu Pan > > --- > > drivers/gpu/drm/sun4i/sun8i_mixer.c | 13 - > > drivers/gpu/drm/sun4i/sun8i_mixer.h | 1 + > > drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 3 +-- > > 3 files changed, 14 insertions(+), 3 deletions(-) > > > > diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c > > b/drivers/gpu/drm/sun4i/sun8i_mixer.c index 875a1156c..e64e08207 > > 100644 > > --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c > > +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c > > @@ -567,6 +567,7 @@ static const struct sun8i_mixer_cfg > > sun8i_a83t_mixer0_cfg = { .ccsc = CCSC_MIXER0_LAYOUT, > > .scaler_mask= 0xf, > > .scanline_yuv = 2048, > > + .scanline_rgb = 2048, > > .ui_num = 3, > > .vi_num = 1, > > }; > > @@ -575,6 +576,7 @@ static const struct sun8i_mixer_cfg > > sun8i_a83t_mixer1_cfg = { .ccsc = CCSC_MIXER1_LAYOUT, > > .scaler_mask= 0x3, > > .scanline_yuv = 2048, > > + .scanline_rgb = 2048, > > .ui_num = 1, > > .vi_num = 1, > > }; > > @@ -584,6 +586,7 @@ static const struct sun8i_mixer_cfg > > sun8i_h3_mixer0_cfg > > = { .mod_rate = 43200, > > .scaler_mask= 0xf, > > .scanline_yuv = 2048, > > + .scanline_rgb = 2048, > > .ui_num = 3, > > .vi_num = 1, > > }; > > @@ -593,6 +596,7 @@ static const struct sun8i_mixer_cfg > > sun8i_r40_mixer0_cfg > > = { .mod_rate = 29700, > > .scaler_mask= 0xf, > > .scanline_yuv = 2048, > > + .scanline_rgb = 2048, > > .ui_num = 3, > > .vi_num = 1, > > }; > > @@ -602,6 +606,7 @@ static const struct sun8i_mixer_cfg > > sun8i_r40_mixer1_cfg > > = { .mod_rate = 29700, > > .scaler_mask= 0x3, > > .scanline_yuv = 2048, > > + .scanline_rgb = 2048, > > .ui_num = 1, > > .vi_num = 1, > > }; > > @@ -610,7 +615,8 @@ static const struct sun8i_mixer_cfg > > sun8i_v3s_mixer_cfg > > = { .vi_num = 2, > > .ui_num = 1, > > .scaler_mask = 0x3, > > - .scanline_yuv = 2048, > > + .scanline_yuv = 1024, > > + .scanline_rgb = 1024, > > .ccsc = CCSC_MIXER0_LAYOUT, > > .mod_rate = 15000, > > }; > > @@ -620,6 +626,7 @@ static const struct sun8i_mixer_cfg > > sun20i_d1_mixer0_cfg > > = { .mod_rate = 29700, > > .scaler_mask= 0x3, > > .scanline_yuv = 2048, > > + .scanline_rgb = 2048, > > .ui_num = 1, > > .vi_num = 1, > > }; > > @@ -629,6 +636,7 @@ static const struct sun8i_mixer_cfg > > sun20i_d1_mixer1_cfg > > = { .mod_rate = 29700, > > .scaler_mask= 0x1, > > .scanline_yuv = 1024, > > + .scanline_rgb = 1024, > > .ui_num = 0, > > .vi_num = 1, > > }; > > @@ -638,6 +646,7 @@ static const struct sun8i_mixer_cfg > > sun50i_a64_mixer0_cfg = { .mod_rate = 29700, > > .scaler_mask= 0xf, > > .scanline_yuv = 4096, > > + .scanline_rgb = 2048, > > .ui_num = 3, > > .vi_num = 1, > > }; > > @@ -647,6 +656,7 @@ static const struct sun8i_mixer_cfg > > sun50i_a64_mixer1_cfg = { .mod_rate = 29700, > > .scaler_mask= 0x3, > > .scanline_yuv = 2048, > > + .scanline_rgb = 2048, > > .ui_num = 1, > > .vi_num = 1, > > }; > > @@ -657,6 +667,7 @@ static const struct sun8i_mixer_cfg > > sun50i_h6_mixer0_cfg > > = { .mod_rate = 6, > > .scaler_mask= 0xf, > > .scanline_yuv = 4096, > > + .scanline_rgb = 2048, > > .ui_num = 3, > > .vi_num = 1,
Re: [PATCH v2 1/2] Revert "drm/bridge: anx7625: Use DPI bus type"
On Mon, 23 May 2022 at 18:15, Robert Foss wrote: > > This reverts commit a77c2af0994e24ee36c7ffb6dc852770bdf06fb1. > > This patch depends on the patches just aplied to the media tree, and will > not build without them, which leaves drm-misc-next in a broken state. > Let's revert the two latter patches until rc1 has been branched, > and rc1 has been backmerged into drm-misc-next. > > Signed-off-by: Robert Foss > Acked-by: Daniel Vetter > --- > drivers/gpu/drm/bridge/analogix/anx7625.c | 8 > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c > b/drivers/gpu/drm/bridge/analogix/anx7625.c > index 0fab2aa47c67..e92eb4a40745 100644 > --- a/drivers/gpu/drm/bridge/analogix/anx7625.c > +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c > @@ -1623,14 +1623,14 @@ static int anx7625_parse_dt(struct device *dev, > > anx7625_get_swing_setting(dev, pdata); > > - pdata->is_dpi = 0; /* default dsi mode */ > + pdata->is_dpi = 1; /* default dpi mode */ > pdata->mipi_host_node = of_graph_get_remote_node(np, 0, 0); > if (!pdata->mipi_host_node) { > DRM_DEV_ERROR(dev, "fail to get internal panel.\n"); > return -ENODEV; > } > > - bus_type = 0; > + bus_type = V4L2_FWNODE_BUS_TYPE_PARALLEL; > mipi_lanes = MAX_LANES_SUPPORT; > ep0 = of_graph_get_endpoint_by_regs(np, 0, 0); > if (ep0) { > @@ -1641,8 +1641,8 @@ static int anx7625_parse_dt(struct device *dev, > of_node_put(ep0); > } > > - if (bus_type == V4L2_FWNODE_BUS_TYPE_DPI) /* bus type is DPI */ > - pdata->is_dpi = 1; > + if (bus_type == V4L2_FWNODE_BUS_TYPE_PARALLEL) /* bus type is > Parallel(DSI) */ > + pdata->is_dpi = 0; > > pdata->mipi_lanes = mipi_lanes; > if (pdata->mipi_lanes > MAX_LANES_SUPPORT || pdata->mipi_lanes <= 0) > -- > 2.34.1 > Series applied to drm-misc-next.
[PATCH v2 2/2] Revert "dt-bindings:drm/bridge:anx7625: add port@0 property"
This reverts commit 7328736d270aa4fa6fcd033ade02acc2874a2db5. This patch depends on the patches just aplied to the media tree, and will not build without them, which leaves drm-misc-next in a broken state. Let's revert the two latter patches until rc1 has been branched, and rc1 has been backmerged into drm-misc-next. Signed-off-by: Robert Foss Acked-by: Daniel Vetter --- .../display/bridge/analogix,anx7625.yaml | 19 +-- 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml index 4590186c4a0b..35a48515836e 100644 --- a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml +++ b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml @@ -94,22 +94,7 @@ properties: $ref: /schemas/graph.yaml#/$defs/port-base unevaluatedProperties: false description: - MIPI DSI/DPI input. - -properties: - endpoint: -$ref: /schemas/media/video-interfaces.yaml# -type: object -additionalProperties: false - -properties: - remote-endpoint: true - - bus-type: -enum: [7] -default: 1 - - data-lanes: true + Video port for MIPI DSI input. port@1: $ref: /schemas/graph.yaml#/properties/port @@ -158,8 +143,6 @@ examples: reg = <0>; anx7625_in: endpoint { remote-endpoint = <&mipi_dsi>; -bus-type = <7>; -data-lanes = <0 1 2 3>; }; }; -- 2.34.1
[PATCH v2 1/2] Revert "drm/bridge: anx7625: Use DPI bus type"
This reverts commit a77c2af0994e24ee36c7ffb6dc852770bdf06fb1. This patch depends on the patches just aplied to the media tree, and will not build without them, which leaves drm-misc-next in a broken state. Let's revert the two latter patches until rc1 has been branched, and rc1 has been backmerged into drm-misc-next. Signed-off-by: Robert Foss Acked-by: Daniel Vetter --- drivers/gpu/drm/bridge/analogix/anx7625.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 0fab2aa47c67..e92eb4a40745 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1623,14 +1623,14 @@ static int anx7625_parse_dt(struct device *dev, anx7625_get_swing_setting(dev, pdata); - pdata->is_dpi = 0; /* default dsi mode */ + pdata->is_dpi = 1; /* default dpi mode */ pdata->mipi_host_node = of_graph_get_remote_node(np, 0, 0); if (!pdata->mipi_host_node) { DRM_DEV_ERROR(dev, "fail to get internal panel.\n"); return -ENODEV; } - bus_type = 0; + bus_type = V4L2_FWNODE_BUS_TYPE_PARALLEL; mipi_lanes = MAX_LANES_SUPPORT; ep0 = of_graph_get_endpoint_by_regs(np, 0, 0); if (ep0) { @@ -1641,8 +1641,8 @@ static int anx7625_parse_dt(struct device *dev, of_node_put(ep0); } - if (bus_type == V4L2_FWNODE_BUS_TYPE_DPI) /* bus type is DPI */ - pdata->is_dpi = 1; + if (bus_type == V4L2_FWNODE_BUS_TYPE_PARALLEL) /* bus type is Parallel(DSI) */ + pdata->is_dpi = 0; pdata->mipi_lanes = mipi_lanes; if (pdata->mipi_lanes > MAX_LANES_SUPPORT || pdata->mipi_lanes <= 0) -- 2.34.1
Re: [PATCH v1 1/2] Revert "drm/bridge: anx7625: Use DPI bus type"
On Mon, 23 May 2022 at 14:54, Robert Foss wrote: > > These two patches need to be reverted since they were part (3/4 & 4/4) > of a series, that was partially (1/4 + 2/4) on the linux-media tree. > These two patches depend on the patches in the media tree, and will > not build without them, which leaves linux-drm-misc-next in a broken > state. Let's revert the two latter patches until rc1 has been branched > and the dependency wont cause issues any more. > > On Mon, 23 May 2022 at 14:50, Robert Foss wrote: > > > > On Mon, 23 May 2022 at 10:46, Robert Foss wrote: > > > > > > This reverts commit a77c2af0994e24ee36c7ffb6dc852770bdf06fb1. > > > --- > > > drivers/gpu/drm/bridge/analogix/anx7625.c | 8 > > > 1 file changed, 4 insertions(+), 4 deletions(-) > > > > > > diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c > > > b/drivers/gpu/drm/bridge/analogix/anx7625.c > > > index 01f46d9189c1..53a5da6c49dd 100644 > > > --- a/drivers/gpu/drm/bridge/analogix/anx7625.c > > > +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c > > > @@ -1623,14 +1623,14 @@ static int anx7625_parse_dt(struct device *dev, > > > > > > anx7625_get_swing_setting(dev, pdata); > > > > > > - pdata->is_dpi = 0; /* default dsi mode */ > > > + pdata->is_dpi = 1; /* default dpi mode */ > > > pdata->mipi_host_node = of_graph_get_remote_node(np, 0, 0); > > > if (!pdata->mipi_host_node) { > > > DRM_DEV_ERROR(dev, "fail to get internal panel.\n"); > > > return -ENODEV; > > > } > > > > > > - bus_type = 0; > > > + bus_type = V4L2_FWNODE_BUS_TYPE_PARALLEL; > > > mipi_lanes = MAX_LANES_SUPPORT; > > > ep0 = of_graph_get_endpoint_by_regs(np, 0, 0); > > > if (ep0) { > > > @@ -1640,8 +1640,8 @@ static int anx7625_parse_dt(struct device *dev, > > > mipi_lanes = of_property_count_u32_elems(ep0, > > > "data-lanes"); > > > } > > > > > > - if (bus_type == V4L2_FWNODE_BUS_TYPE_DPI) /* bus type is DPI */ > > > - pdata->is_dpi = 1; > > > + if (bus_type == V4L2_FWNODE_BUS_TYPE_PARALLEL) /* bus type is > > > Parallel(DSI) */ > > > + pdata->is_dpi = 0; > > > > > > pdata->mipi_lanes = mipi_lanes; > > > if (pdata->mipi_lanes > MAX_LANES_SUPPORT || pdata->mipi_lanes <= > > > 0) > > > -- > > > 2.34.1 > > > > > > > Signed-off-by: Robert Foss Acked-by: Daniel Vetter
Re: [PATCH v1 1/2] Revert "drm/bridge: anx7625: Use DPI bus type"
On Mon, 23 May 2022 at 14:54, Robert Foss wrote: > These two patches need to be reverted since they were part (3/4 & 4/4) > of a series, that was partially (1/4 + 2/4) on the linux-media tree. > These two patches depend on the patches in the media tree, and will > not build without them, which leaves linux-drm-misc-next in a broken > state. Let's revert the two latter patches until rc1 has been branched "rc1 has been backmerged into drm-misc-next" is missing here. > and the dependency wont cause issues any more. With explainer and sob added to both: Acked-by: Daniel Vetter > > On Mon, 23 May 2022 at 14:50, Robert Foss wrote: > > > > On Mon, 23 May 2022 at 10:46, Robert Foss wrote: > > > > > > This reverts commit a77c2af0994e24ee36c7ffb6dc852770bdf06fb1. > > > --- > > > drivers/gpu/drm/bridge/analogix/anx7625.c | 8 > > > 1 file changed, 4 insertions(+), 4 deletions(-) > > > > > > diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c > > > b/drivers/gpu/drm/bridge/analogix/anx7625.c > > > index 01f46d9189c1..53a5da6c49dd 100644 > > > --- a/drivers/gpu/drm/bridge/analogix/anx7625.c > > > +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c > > > @@ -1623,14 +1623,14 @@ static int anx7625_parse_dt(struct device *dev, > > > > > > anx7625_get_swing_setting(dev, pdata); > > > > > > - pdata->is_dpi = 0; /* default dsi mode */ > > > + pdata->is_dpi = 1; /* default dpi mode */ > > > pdata->mipi_host_node = of_graph_get_remote_node(np, 0, 0); > > > if (!pdata->mipi_host_node) { > > > DRM_DEV_ERROR(dev, "fail to get internal panel.\n"); > > > return -ENODEV; > > > } > > > > > > - bus_type = 0; > > > + bus_type = V4L2_FWNODE_BUS_TYPE_PARALLEL; > > > mipi_lanes = MAX_LANES_SUPPORT; > > > ep0 = of_graph_get_endpoint_by_regs(np, 0, 0); > > > if (ep0) { > > > @@ -1640,8 +1640,8 @@ static int anx7625_parse_dt(struct device *dev, > > > mipi_lanes = of_property_count_u32_elems(ep0, > > > "data-lanes"); > > > } > > > > > > - if (bus_type == V4L2_FWNODE_BUS_TYPE_DPI) /* bus type is DPI */ > > > - pdata->is_dpi = 1; > > > + if (bus_type == V4L2_FWNODE_BUS_TYPE_PARALLEL) /* bus type is > > > Parallel(DSI) */ > > > + pdata->is_dpi = 0; > > > > > > pdata->mipi_lanes = mipi_lanes; > > > if (pdata->mipi_lanes > MAX_LANES_SUPPORT || pdata->mipi_lanes <= > > > 0) > > > -- > > > 2.34.1 > > > > > > > Signed-off-by: Robert Foss -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch
Re: [PATCH 3/4] drm/i915: allow volatile buffers to use ttm pool allocator
On 11/05/2022 13:42, Thomas Hellström wrote: Hi, Bob, On Tue, 2022-05-03 at 19:13 +, Robert Beckett wrote: internal buffers should be shmem backed. if a volatile buffer is requested, allow ttm to use the pool allocator to provide volatile pages as backing Signed-off-by: Robert Beckett --- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 3 ++- 1 file changed, 2 insertions(+), 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 4c25d9b2f138..fdb3a1c18cb6 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -309,7 +309,8 @@ static struct ttm_tt *i915_ttm_tt_create(struct ttm_buffer_object *bo, page_flags |= TTM_TT_FLAG_ZERO_ALLOC; caching = i915_ttm_select_tt_caching(obj); - if (i915_gem_object_is_shrinkable(obj) && caching == ttm_cached) { + if (i915_gem_object_is_shrinkable(obj) && caching == ttm_cached && + !i915_gem_object_is_volatile(obj)) { page_flags |= TTM_TT_FLAG_EXTERNAL | TTM_TT_FLAG_EXTERNAL_MAPPABLE; i915_tt->is_shmem = true; While this is ok, I think it also needs adjustment in the i915_ttm shrink callback. If someone creates a volatile smem object which then hits the shrinker, I think we might hit asserts that it's a is_shem ttm? In this case, the shrink callback should just i915_ttm_purge(). agreed. nice catch. I'll fix for v2 looks like we could maybe do with some extra shrinker testing too? looks like nothing caught this during CI testing /Thomas
Re: [PATCH 1/4] drm/i915: add gen6 ppgtt dummy creation function
On 11/05/2022 11:13, Thomas Hellström wrote: Hi, On Tue, 2022-05-03 at 19:13 +, Robert Beckett wrote: Internal gem objects will soon just be volatile system memory region objects. To enable this, create a separate dummy object creation function for gen6 ppgtt It's not clear from the commit message why we need a special case for this. Could you describe more in detail? it always was a special case, that used the internal backend but provided it's own ops, so actually had no benefit from using the internal backend. See b0b0f2d225da6fe58417fae37e3f797e2db27b62 I'll add some further explanation in the commit message for v2. Thanks, Thomas Signed-off-by: Robert Beckett --- drivers/gpu/drm/i915/gt/gen6_ppgtt.c | 43 ++-- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c index 1bb766c79dcb..f3b660cfeb7f 100644 --- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c +++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c @@ -372,6 +372,45 @@ static const struct drm_i915_gem_object_ops pd_dummy_obj_ops = { .put_pages = pd_dummy_obj_put_pages, }; +static struct drm_i915_gem_object * +i915_gem_object_create_dummy(struct drm_i915_private *i915, phys_addr_t size) +{ + static struct lock_class_key lock_class; + struct drm_i915_gem_object *obj; + unsigned int cache_level; + + GEM_BUG_ON(!size); + GEM_BUG_ON(!IS_ALIGNED(size, PAGE_SIZE)); + + if (overflows_type(size, obj->base.size)) + return ERR_PTR(-E2BIG); + + obj = i915_gem_object_alloc(); + if (!obj) + return ERR_PTR(-ENOMEM); + + drm_gem_private_object_init(&i915->drm, &obj->base, size); + i915_gem_object_init(obj, &pd_dummy_obj_ops, &lock_class, 0); + obj->mem_flags |= I915_BO_FLAG_STRUCT_PAGE; + + /* + * Mark the object as volatile, such that the pages are marked as + * dontneed whilst they are still pinned. As soon as they are unpinned + * they are allowed to be reaped by the shrinker, and the caller is + * expected to repopulate - the contents of this object are only valid + * whilst active and pinned. + */ + i915_gem_object_set_volatile(obj); + + obj->read_domains = I915_GEM_DOMAIN_CPU; + obj->write_domain = I915_GEM_DOMAIN_CPU; + + cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE; + i915_gem_object_set_cache_coherency(obj, cache_level); + + return obj; +} + static struct i915_page_directory * gen6_alloc_top_pd(struct gen6_ppgtt *ppgtt) { @@ -383,9 +422,7 @@ gen6_alloc_top_pd(struct gen6_ppgtt *ppgtt) if (unlikely(!pd)) return ERR_PTR(-ENOMEM); - pd->pt.base = __i915_gem_object_create_internal(ppgtt- base.vm.gt->i915, - &pd_dummy_obj_o ps, - I915_PDES * SZ_4K); + pd->pt.base = i915_gem_object_create_dummy(ppgtt->base.vm.gt- i915, I915_PDES * SZ_4K); if (IS_ERR(pd->pt.base)) { err = PTR_ERR(pd->pt.base); pd->pt.base = NULL;
Re: [PATCH 4/4] drm/i915: internal buffers use ttm backend
On 11/05/2022 15:14, Thomas Hellström wrote: On Tue, 2022-05-03 at 19:13 +, Robert Beckett wrote: refactor internal buffer backend to allocate volatile pages via ttm pool allocator Signed-off-by: Robert Beckett --- drivers/gpu/drm/i915/gem/i915_gem_internal.c | 264 - -- drivers/gpu/drm/i915/gem/i915_gem_internal.h | 5 - drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 12 +- drivers/gpu/drm/i915/gem/i915_gem_ttm.h | 12 +- 4 files changed, 125 insertions(+), 168 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_internal.c b/drivers/gpu/drm/i915/gem/i915_gem_internal.c index c698f95af15f..815ec9466cc0 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_internal.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_internal.c @@ -4,156 +4,119 @@ * Copyright © 2014-2016 Intel Corporation */ -#include -#include -#include - +#include +#include +#include "drm/ttm/ttm_bo_api.h" +#include "gem/i915_gem_internal.h" +#include "gem/i915_gem_region.h" +#include "gem/i915_gem_ttm.h" #include "i915_drv.h" -#include "i915_gem.h" -#include "i915_gem_internal.h" -#include "i915_gem_object.h" -#include "i915_scatterlist.h" -#include "i915_utils.h" - -#define QUIET (__GFP_NORETRY | __GFP_NOWARN) -#define MAYFAIL (__GFP_RETRY_MAYFAIL | __GFP_NOWARN) - -static void internal_free_pages(struct sg_table *st) -{ - struct scatterlist *sg; - - for (sg = st->sgl; sg; sg = __sg_next(sg)) { - if (sg_page(sg)) - __free_pages(sg_page(sg), get_order(sg- length)); - } - - sg_free_table(st); - kfree(st); -} -static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj) +static int i915_internal_get_pages(struct drm_i915_gem_object *obj) { - struct drm_i915_private *i915 = to_i915(obj->base.dev); - struct sg_table *st; - struct scatterlist *sg; - unsigned int sg_page_sizes; - unsigned int npages; - int max_order; - gfp_t gfp; - - max_order = MAX_ORDER; -#ifdef CONFIG_SWIOTLB - if (is_swiotlb_active(obj->base.dev->dev)) { - unsigned int max_segment; - - max_segment = swiotlb_max_segment(); - if (max_segment) { - max_segment = max_t(unsigned int, max_segment, - PAGE_SIZE) >> PAGE_SHIFT; - max_order = min(max_order, ilog2(max_segment)); - } + struct ttm_buffer_object *bo = i915_gem_to_ttm(obj); + struct ttm_operation_ctx ctx = { + .interruptible = true, + .no_wait_gpu = false, + }; + struct ttm_place place = { + .fpfn = 0, + .lpfn = 0, + .mem_type = I915_PL_SYSTEM, + .flags = 0, + }; + struct ttm_placement placement = { + .num_placement = 1, + .placement = &place, + .num_busy_placement = 0, + .busy_placement = NULL, + }; + int ret; + + ret = ttm_bo_validate(bo, &placement, &ctx); + if (ret) { + ret = i915_ttm_err_to_gem(ret); + return ret; } -#endif - gfp = GFP_KERNEL | __GFP_HIGHMEM | __GFP_RECLAIMABLE; - if (IS_I965GM(i915) || IS_I965G(i915)) { - /* 965gm cannot relocate objects above 4GiB. */ - gfp &= ~__GFP_HIGHMEM; - gfp |= __GFP_DMA32; It looks like we're losing this restriction? There is a flag to ttm_device_init() to make TTM only do __GFP_DMA32 allocations. agreed. will fix for v2 + if (bo->ttm && !ttm_tt_is_populated(bo->ttm)) { + ret = ttm_tt_populate(bo->bdev, bo->ttm, &ctx); + if (ret) + return ret; } -create_st: - st = kmalloc(sizeof(*st), GFP_KERNEL); - if (!st) - return -ENOMEM; + if (!i915_gem_object_has_pages(obj)) { + struct i915_refct_sgt *rsgt = + i915_ttm_resource_get_st(obj, bo->resource); - npages = obj->base.size / PAGE_SIZE; - if (sg_alloc_table(st, npages, GFP_KERNEL)) { - kfree(st); - return -ENOMEM; - } + if (IS_ERR(rsgt)) + return PTR_ERR(rsgt); - sg = st->sgl; - st->nents = 0; - sg_page_sizes = 0; - - do { - int order = min(fls(npages) - 1, max_order); - struct page *page; - - do { - page = alloc_pages(gfp | (order ? QUIET : MAYFAIL), - order); - if (page) - break; - if (!order--) - goto err; - - /* Limit subsequent allocations as well */ - max_order = order; - } while (1)
Re: [PATCH 03/11] drm/bridge: icn6211: Convert to drm_of_get_data_lanes_ep
On 19.05.2022 13:26, Marek Vasut wrote: Convert driver to use this new helper to standardize OF "data-lanes" parsing. Signed-off-by: Marek Vasut Cc: Andrzej Hajda Cc: Jagan Teki Cc: Laurent Pinchart Cc: Lucas Stach Cc: Maxime Ripard Cc: Robert Foss Cc: Sam Ravnborg To: dri-devel@lists.freedesktop.org --- drivers/gpu/drm/bridge/chipone-icn6211.c | 11 --- 1 file changed, 4 insertions(+), 7 deletions(-) For this and the rest: Reviewed-by: Andrzej Hajda Regards Andrzej diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c b/drivers/gpu/drm/bridge/chipone-icn6211.c index 45bb89ac3fff7..e53a19f721c8c 100644 --- a/drivers/gpu/drm/bridge/chipone-icn6211.c +++ b/drivers/gpu/drm/bridge/chipone-icn6211.c @@ -496,21 +496,18 @@ static int chipone_dsi_attach(struct chipone *icn) { struct mipi_dsi_device *dsi = icn->dsi; struct device *dev = icn->dev; - struct device_node *endpoint; int dsi_lanes, ret; - endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, 0); - dsi_lanes = of_property_count_u32_elems(endpoint, "data-lanes"); - of_node_put(endpoint); + dsi_lanes = drm_of_get_data_lanes_ep(dev->of_node, 0, 0, 1, 4); /* * If the 'data-lanes' property does not exist in DT or is invalid, * default to previously hard-coded behavior, which was 4 data lanes. */ - if (dsi_lanes >= 1 && dsi_lanes <= 4) - icn->dsi->lanes = dsi_lanes; - else + if (dsi_lanes < 0) icn->dsi->lanes = 4; + else + icn->dsi->lanes = dsi_lanes; dsi->format = MIPI_DSI_FMT_RGB888; dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
Re: [PATCH 02/11] drm/bridge: anx7625: Convert to drm_of_get_data_lanes
On 19.05.2022 13:26, Marek Vasut wrote: Convert driver to use this new helper to standardize OF "data-lanes" parsing. Signed-off-by: Marek Vasut Cc: Andrzej Hajda Cc: Laurent Pinchart Cc: Lucas Stach Cc: Maxime Ripard Cc: Robert Foss Cc: Sam Ravnborg Cc: Xin Ji To: dri-devel@lists.freedesktop.org --- drivers/gpu/drm/bridge/analogix/anx7625.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index e92eb4a407452..87d7658b92fac 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1637,16 +1637,16 @@ static int anx7625_parse_dt(struct device *dev, if (of_property_read_u32(ep0, "bus-type", &bus_type)) bus_type = 0; - mipi_lanes = of_property_count_u32_elems(ep0, "data-lanes"); + mipi_lanes = drm_of_get_data_lanes(ep0, 1, MAX_LANES_SUPPORT); of_node_put(ep0); } if (bus_type == V4L2_FWNODE_BUS_TYPE_PARALLEL) /* bus type is Parallel(DSI) */ pdata->is_dpi = 0; - pdata->mipi_lanes = mipi_lanes; - if (pdata->mipi_lanes > MAX_LANES_SUPPORT || pdata->mipi_lanes <= 0) - pdata->mipi_lanes = MAX_LANES_SUPPORT; + pdata->mipi_lanes = MAX_LANES_SUPPORT; + if (mipi_lanes > 0) + pdata->mipi_lanes = mipi_lanes; Reviewed-by: Andrzej Hajda Regards Andrzej if (pdata->is_dpi) DRM_DEV_DEBUG_DRIVER(dev, "found MIPI DPI host node.\n");
Re: [PATCH v4 12/13] drm/msm: Utilize gpu scheduler priorities
Hi Rob, On 28/07/2021 02:06, Rob Clark wrote: From: Rob Clark The drm/scheduler provides additional prioritization on top of that provided by however many number of ringbuffers (each with their own priority level) is supported on a given generation. Expose the additional levels of priority to userspace and map the userspace priority back to ring (first level of priority) and schedular priority (additional priority levels within the ring). Signed-off-by: Rob Clark Acked-by: Christian König --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 4 +- drivers/gpu/drm/msm/msm_gem_submit.c| 4 +- drivers/gpu/drm/msm/msm_gpu.h | 58 - drivers/gpu/drm/msm/msm_submitqueue.c | 35 +++ include/uapi/drm/msm_drm.h | 14 +- 5 files changed, 88 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index bad4809b68ef..748665232d29 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -261,8 +261,8 @@ int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value) return ret; } return -EINVAL; - case MSM_PARAM_NR_RINGS: - *value = gpu->nr_rings; + case MSM_PARAM_PRIORITIES: + *value = gpu->nr_rings * NR_SCHED_PRIORITIES; return 0; case MSM_PARAM_PP_PGTABLE: *value = 0; diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 450efe59abb5..c2ecec5b11c4 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -59,7 +59,7 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev, submit->gpu = gpu; submit->cmd = (void *)&submit->bos[nr_bos]; submit->queue = queue; - submit->ring = gpu->rb[queue->prio]; + submit->ring = gpu->rb[queue->ring_nr]; submit->fault_dumped = false; INIT_LIST_HEAD(&submit->node); @@ -749,7 +749,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, /* Get a unique identifier for the submission for logging purposes */ submitid = atomic_inc_return(&ident) - 1; - ring = gpu->rb[queue->prio]; + ring = gpu->rb[queue->ring_nr]; trace_msm_gpu_submit(pid_nr(pid), ring->id, submitid, args->nr_bos, args->nr_cmds); diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index b912cacaecc0..0e4b45bff2e6 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -250,6 +250,59 @@ struct msm_gpu_perfcntr { const char *name; }; +/* + * The number of priority levels provided by drm gpu scheduler. The + * DRM_SCHED_PRIORITY_KERNEL priority level is treated specially in some + * cases, so we don't use it (no need for kernel generated jobs). + */ +#define NR_SCHED_PRIORITIES (1 + DRM_SCHED_PRIORITY_HIGH - DRM_SCHED_PRIORITY_MIN) + +/** + * msm_gpu_convert_priority - Map userspace priority to ring # and sched priority + * + * @gpu:the gpu instance + * @prio: the userspace priority level + * @ring_nr:[out] the ringbuffer the userspace priority maps to + * @sched_prio: [out] the gpu scheduler priority level which the userspace + * priority maps to + * + * With drm/scheduler providing it's own level of prioritization, our total + * number of available priority levels is (nr_rings * NR_SCHED_PRIORITIES). + * Each ring is associated with it's own scheduler instance. However, our + * UABI is that lower numerical values are higher priority. So mapping the + * single userspace priority level into ring_nr and sched_prio takes some + * care. The userspace provided priority (when a submitqueue is created) + * is mapped to ring nr and scheduler priority as such: + * + * ring_nr= userspace_prio / NR_SCHED_PRIORITIES + * sched_prio = NR_SCHED_PRIORITIES - + *(userspace_prio % NR_SCHED_PRIORITIES) - 1 + * + * This allows generations without preemption (nr_rings==1) to have some + * amount of prioritization, and provides more priority levels for gens + * that do have preemption. I am exploring how different drivers handle priority levels and this caught my eye. Is the implication of the last paragraphs that on hw with nr_rings > 1, ring + 1 preempts ring? If so I am wondering does the "spreading" of user visible priorities by NR_SCHED_PRIORITIES creates a non-preemptable levels within every "bucket" or how does that work? Regards, Tvrtko + */ +static inline int msm_gpu_convert_priority(struct msm_gpu *gpu, int prio, + unsigned *ring_nr, enum drm_sched_priority *sched_prio) +{ + unsigned rn, sp; + + rn = div_u64_rem(prio, NR_SCHED_PRIORITIES, &sp); + + /* invert sched priority to map to higher-numeric-is-higher- +* priority
Re: [PATCH 01/11] drm: of: Add drm_of_get_data_lanes and drm_of_get_data_lanes_ep
On 19.05.2022 13:26, Marek Vasut wrote: Add helper function to count and sanitize DT "data-lanes" property and return either error or the data-lanes count. This is useful for both DSI and (e)DP "data-lanes" property. The later version of the function is an extra wrapper which handles the endpoint look up by regs, that's what majority of the drivers duplicate too, but not all of them. Signed-off-by: Marek Vasut Cc: Andrzej Hajda Cc: Laurent Pinchart Cc: Lucas Stach Cc: Maxime Ripard Cc: Robert Foss Cc: Sam Ravnborg To: dri-devel@lists.freedesktop.org --- drivers/gpu/drm/drm_of.c | 61 include/drm/drm_of.h | 20 + 2 files changed, 81 insertions(+) diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c index 9a2cfab3a177f..2186f966d2820 100644 --- a/drivers/gpu/drm/drm_of.c +++ b/drivers/gpu/drm/drm_of.c @@ -430,3 +430,64 @@ int drm_of_lvds_get_data_mapping(const struct device_node *port) return -EINVAL; } EXPORT_SYMBOL_GPL(drm_of_lvds_get_data_mapping); + +/** + * drm_of_get_data_lanes - Get DSI/(e)DP data lane count + * @endpoint: DT endpoint node of the DSI/(e)DP source or sink + * @min: minimum supported number of data lanes + * @max: maximum supported number of data lanes + * + * Count DT "data-lanes" property elements and check for validity. + * + * Return: + * * min..max - positive integer count of "data-lanes" elements + * * -ve - the "data-lanes" property is missing or invalid + * * -EINVAL - the "data-lanes" property is unsupported + */ +int drm_of_get_data_lanes(const struct device_node *endpoint, + const unsigned int min, const unsigned int max) Adding count to the name would be more accurate, for example drm_of_get_data_lanes_count ? Up to you. Reviewed-by: Andrzej Hajda Regards Andrzej +{ + int ret; + + ret = of_property_count_u32_elems(endpoint, "data-lanes"); + if (ret < 0) + return ret; + + if (ret < min || ret > max) + return -EINVAL; + + return ret; +} +EXPORT_SYMBOL_GPL(drm_of_get_data_lanes); + +/** + * drm_of_get_data_lanes_ep - Get DSI/(e)DP data lane count by endpoint + * @port: DT port node of the DSI/(e)DP source or sink + * @port_reg: identifier (value of reg property) of the parent port node + * @reg: identifier (value of reg property) of the endpoint node + * @min: minimum supported number of data lanes + * @max: maximum supported number of data lanes + * + * Count DT "data-lanes" property elements and check for validity. + * This variant uses endpoint specifier. + * + * Return: + * * min..max - positive integer count of "data-lanes" elements + * * -EINVAL - the "data-mapping" property is unsupported + * * -ENODEV - the "data-mapping" property is missing + */ +int drm_of_get_data_lanes_ep(const struct device_node *port, +int port_reg, int reg, +const unsigned int min, +const unsigned int max) +{ + struct device_node *endpoint; + int ret; + + endpoint = of_graph_get_endpoint_by_regs(port, port_reg, reg); + ret = drm_of_get_data_lanes(endpoint, min, max); + of_node_put(endpoint); + + return ret; +} +EXPORT_SYMBOL_GPL(drm_of_get_data_lanes_ep); diff --git a/include/drm/drm_of.h b/include/drm/drm_of.h index 99f79ac8b4cd7..b559c53756196 100644 --- a/include/drm/drm_of.h +++ b/include/drm/drm_of.h @@ -50,6 +50,12 @@ int drm_of_find_panel_or_bridge(const struct device_node *np, int drm_of_lvds_get_dual_link_pixel_order(const struct device_node *port1, const struct device_node *port2); int drm_of_lvds_get_data_mapping(const struct device_node *port); +int drm_of_get_data_lanes(const struct device_node *endpoint, + const unsigned int min, const unsigned int max); +int drm_of_get_data_lanes_ep(const struct device_node *port, +int port_reg, int reg, +const unsigned int min, +const unsigned int max); #else static inline uint32_t drm_of_crtc_port_mask(struct drm_device *dev, struct device_node *port) @@ -105,6 +111,20 @@ drm_of_lvds_get_data_mapping(const struct device_node *port) { return -EINVAL; } + +int drm_of_get_data_lanes(const struct device_node *endpoint, + const unsigned int min, const unsigned int max) +{ + return -EINVAL; +} + +int drm_of_get_data_lanes_ep(const struct device_node *port, +int port_reg, int reg +const unsigned int min, +const unsigned int max) +{ + return -EINVAL; +} #endif /*
Re: [PATCH] drm/st7735r: Fix module autoloading for Okaya RH128128T
Hello Geert, On 5/20/22 14:02, Geert Uytterhoeven wrote: > Hi Javier, > > CC spi > > On Fri, May 20, 2022 at 11:16 AM Javier Martinez Canillas > wrote: >> The SPI core always reports a "MODALIAS=spi:", even if the device was >> registered via OF. This means that the st7735r.ko module won't autoload if >> a DT has a node with a compatible "okaya,rh128128t" string. >> >> In that case, kmod expects a "MODALIAS=of:N*T*Cokaya,rh128128t" uevent but >> instead will get a "MODALIAS=spi:rh128128t", which is not present in the >> list of aliases: >> >> $ modinfo drivers/gpu/drm/tiny/st7735r.ko | grep alias >> alias: of:N*T*Cokaya,rh128128tC* >> alias: of:N*T*Cokaya,rh128128t >> alias: of:N*T*Cjianda,jd-t18003-t01C* >> alias: of:N*T*Cjianda,jd-t18003-t01 >> alias: spi:jd-t18003-t01 >> >> To workaround this issue, add in the SPI table an entry for that device. >> >> Fixes: d1d511d516f7 ("drm: tiny: st7735r: Add support for Okaya RH128128T") >> Signed-off-by: Javier Martinez Canillas > > Thanks for your patch! > We really need to fix this at the subsystem level. > Yes, agreed. > Reviewed-by: Geert Uytterhoeven > Thanks! I've pushed this to drm-misc (drm-misc-next) with your Reviewed-by and David's Acked-by. -- Best regards, Javier Martinez Canillas Linux Engineering Red Hat
Re: [PATCH v2] drm: bridge: icn6211: Adjust clock phase using SYS_CTRL_1
On 5/23/22 15:20, Jonathan Liu wrote: Hi Marek, On Mon, 23 May 2022 at 23:15, Marek Vasut wrote: On 5/23/22 15:01, Jonathan Liu wrote: The code from [1] sets SYS_CTRL_1 to different values depending on the desired clock phase (0, 1/4, 1/2 or 3/4). A clock phase of 0 aligns the positive edge of the clock with the pixel data while other values delay the clock by a fraction of the clock period. A clock phase of 1/2 aligns the negative edge of the clock with the pixel data. The driver currently hard codes SYS_CTRL_1 to 0x88 which corresponds to aligning the positive edge of the clock with the pixel data. This won't work correctly for panels that require aligning the negative edge of the clock with the pixel data. Adjust the clock phase to 0 if DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE is present in bus_flags, otherwise adjust the clock phase to 1/2 as appropriate for DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE. [1] https://github.com/tdjastrzebski/ICN6211-Configurator Signed-off-by: Jonathan Liu --- V2: Use GENMASK and FIELD_PREP macros --- drivers/gpu/drm/bridge/chipone-icn6211.c | 18 -- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c b/drivers/gpu/drm/bridge/chipone-icn6211.c index 47dea657a752..f1538fb5f8a9 100644 --- a/drivers/gpu/drm/bridge/chipone-icn6211.c +++ b/drivers/gpu/drm/bridge/chipone-icn6211.c @@ -9,6 +9,8 @@ #include #include +#include +#include #include #include #include @@ -26,6 +28,11 @@ #define PD_CTRL(n) (0x0a + ((n) & 0x3)) /* 0..3 */ #define RST_CTRL(n) (0x0e + ((n) & 0x1)) /* 0..1 */ #define SYS_CTRL(n) (0x10 + ((n) & 0x7)) /* 0..4 */ +#define SYS_CTRL_1_CLK_PHASE_MSK GENMASK(5, 4) This should be GENMASK(7, 6) , no ? Clock phase 0 = 0b_1000_1000 = 0x88 Clock phase 1/4 = 0b_1001_1000 = 0x98 Clock phase 1/2 = 0b_1010_1000 = 0xA8 Clock phase 3/4 = 0b_1011_1000 = 0xB8 The clock phase bits are 5:4 not 7:6. The upper 2 bits and lower 4 bits are unknown. Doh, you're right. Reviewed-by: Marek Vasut
Re: [PATCH v2] drm: bridge: icn6211: Adjust clock phase using SYS_CTRL_1
Hi Marek, On Mon, 23 May 2022 at 23:15, Marek Vasut wrote: > > On 5/23/22 15:01, Jonathan Liu wrote: > > The code from [1] sets SYS_CTRL_1 to different values depending on the > > desired clock phase (0, 1/4, 1/2 or 3/4). A clock phase of 0 aligns the > > positive edge of the clock with the pixel data while other values delay > > the clock by a fraction of the clock period. A clock phase of 1/2 aligns > > the negative edge of the clock with the pixel data. > > > > The driver currently hard codes SYS_CTRL_1 to 0x88 which corresponds to > > aligning the positive edge of the clock with the pixel data. This won't > > work correctly for panels that require aligning the negative edge of the > > clock with the pixel data. > > > > Adjust the clock phase to 0 if DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE is > > present in bus_flags, otherwise adjust the clock phase to 1/2 as > > appropriate for DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE. > > > > [1] https://github.com/tdjastrzebski/ICN6211-Configurator > > > > Signed-off-by: Jonathan Liu > > --- > > V2: Use GENMASK and FIELD_PREP macros > > --- > > drivers/gpu/drm/bridge/chipone-icn6211.c | 18 -- > > 1 file changed, 16 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c > > b/drivers/gpu/drm/bridge/chipone-icn6211.c > > index 47dea657a752..f1538fb5f8a9 100644 > > --- a/drivers/gpu/drm/bridge/chipone-icn6211.c > > +++ b/drivers/gpu/drm/bridge/chipone-icn6211.c > > @@ -9,6 +9,8 @@ > > #include > > #include > > > > +#include > > +#include > > #include > > #include > > #include > > @@ -26,6 +28,11 @@ > > #define PD_CTRL(n) (0x0a + ((n) & 0x3)) /* 0..3 */ > > #define RST_CTRL(n) (0x0e + ((n) & 0x1)) /* 0..1 */ > > #define SYS_CTRL(n) (0x10 + ((n) & 0x7)) /* 0..4 */ > > +#define SYS_CTRL_1_CLK_PHASE_MSK GENMASK(5, 4) > > This should be GENMASK(7, 6) , no ? Clock phase 0 = 0b_1000_1000 = 0x88 Clock phase 1/4 = 0b_1001_1000 = 0x98 Clock phase 1/2 = 0b_1010_1000 = 0xA8 Clock phase 3/4 = 0b_1011_1000 = 0xB8 The clock phase bits are 5:4 not 7:6. The upper 2 bits and lower 4 bits are unknown. Regards, Jonathan
Re: [PATCH v2] drm: bridge: icn6211: Adjust clock phase using SYS_CTRL_1
On 5/23/22 15:01, Jonathan Liu wrote: The code from [1] sets SYS_CTRL_1 to different values depending on the desired clock phase (0, 1/4, 1/2 or 3/4). A clock phase of 0 aligns the positive edge of the clock with the pixel data while other values delay the clock by a fraction of the clock period. A clock phase of 1/2 aligns the negative edge of the clock with the pixel data. The driver currently hard codes SYS_CTRL_1 to 0x88 which corresponds to aligning the positive edge of the clock with the pixel data. This won't work correctly for panels that require aligning the negative edge of the clock with the pixel data. Adjust the clock phase to 0 if DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE is present in bus_flags, otherwise adjust the clock phase to 1/2 as appropriate for DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE. [1] https://github.com/tdjastrzebski/ICN6211-Configurator Signed-off-by: Jonathan Liu --- V2: Use GENMASK and FIELD_PREP macros --- drivers/gpu/drm/bridge/chipone-icn6211.c | 18 -- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c b/drivers/gpu/drm/bridge/chipone-icn6211.c index 47dea657a752..f1538fb5f8a9 100644 --- a/drivers/gpu/drm/bridge/chipone-icn6211.c +++ b/drivers/gpu/drm/bridge/chipone-icn6211.c @@ -9,6 +9,8 @@ #include #include +#include +#include #include #include #include @@ -26,6 +28,11 @@ #define PD_CTRL(n)(0x0a + ((n) & 0x3)) /* 0..3 */ #define RST_CTRL(n) (0x0e + ((n) & 0x1)) /* 0..1 */ #define SYS_CTRL(n) (0x10 + ((n) & 0x7)) /* 0..4 */ +#define SYS_CTRL_1_CLK_PHASE_MSK GENMASK(5, 4) This should be GENMASK(7, 6) , no ?
[PATCH v2] drm: bridge: icn6211: Adjust clock phase using SYS_CTRL_1
The code from [1] sets SYS_CTRL_1 to different values depending on the desired clock phase (0, 1/4, 1/2 or 3/4). A clock phase of 0 aligns the positive edge of the clock with the pixel data while other values delay the clock by a fraction of the clock period. A clock phase of 1/2 aligns the negative edge of the clock with the pixel data. The driver currently hard codes SYS_CTRL_1 to 0x88 which corresponds to aligning the positive edge of the clock with the pixel data. This won't work correctly for panels that require aligning the negative edge of the clock with the pixel data. Adjust the clock phase to 0 if DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE is present in bus_flags, otherwise adjust the clock phase to 1/2 as appropriate for DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE. [1] https://github.com/tdjastrzebski/ICN6211-Configurator Signed-off-by: Jonathan Liu --- V2: Use GENMASK and FIELD_PREP macros --- drivers/gpu/drm/bridge/chipone-icn6211.c | 18 -- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c b/drivers/gpu/drm/bridge/chipone-icn6211.c index 47dea657a752..f1538fb5f8a9 100644 --- a/drivers/gpu/drm/bridge/chipone-icn6211.c +++ b/drivers/gpu/drm/bridge/chipone-icn6211.c @@ -9,6 +9,8 @@ #include #include +#include +#include #include #include #include @@ -26,6 +28,11 @@ #define PD_CTRL(n) (0x0a + ((n) & 0x3)) /* 0..3 */ #define RST_CTRL(n)(0x0e + ((n) & 0x1)) /* 0..1 */ #define SYS_CTRL(n)(0x10 + ((n) & 0x7)) /* 0..4 */ +#define SYS_CTRL_1_CLK_PHASE_MSK GENMASK(5, 4) +#define CLK_PHASE_00 +#define CLK_PHASE_1_4 1 +#define CLK_PHASE_1_2 2 +#define CLK_PHASE_3_4 3 #define RGB_DRV(n) (0x18 + ((n) & 0x3)) /* 0..3 */ #define RGB_DLY(n) (0x1c + ((n) & 0x1)) /* 0..1 */ #define RGB_TEST_CTRL 0x1e @@ -336,7 +343,7 @@ static void chipone_atomic_enable(struct drm_bridge *bridge, const struct drm_bridge_state *bridge_state; u16 hfp, hbp, hsync; u32 bus_flags; - u8 pol, id[4]; + u8 pol, sys_ctrl_1, id[4]; chipone_readb(icn, VENDOR_ID, id); chipone_readb(icn, DEVICE_ID_H, id + 1); @@ -414,7 +421,14 @@ static void chipone_atomic_enable(struct drm_bridge *bridge, chipone_configure_pll(icn, mode); chipone_writeb(icn, SYS_CTRL(0), 0x40); - chipone_writeb(icn, SYS_CTRL(1), 0x88); + sys_ctrl_1 = 0x88; + + if (bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE) + sys_ctrl_1 |= FIELD_PREP(SYS_CTRL_1_CLK_PHASE_MSK, CLK_PHASE_0); + else + sys_ctrl_1 |= FIELD_PREP(SYS_CTRL_1_CLK_PHASE_MSK, CLK_PHASE_1_2); + + chipone_writeb(icn, SYS_CTRL(1), sys_ctrl_1); /* icn6211 specific sequence */ chipone_writeb(icn, MIPI_FORCE_0, 0x20); -- 2.36.1
Re: [PATCH v2 -next] drm/display: Fix build error without CONFIG_OF
On 23/05/2022 15:54, Linus Walleij wrote: On Mon, May 23, 2022 at 2:46 PM Linus Walleij wrote: On Fri, May 6, 2022 at 2:33 PM YueHaibing wrote: While CONFIG_OF is n but COMPILE_TEST is y, we got this: WARNING: unmet direct dependencies detected for DRM_DP_AUX_BUS Depends on [n]: HAS_IOMEM [=y] && DRM [=y] && OF [=n] Selected by [y]: - DRM_MSM [=y] && HAS_IOMEM [=y] && DRM [=y] && (ARCH_QCOM || SOC_IMX5 || COMPILE_TEST [=y]) && COMMON_CLK [=y] && IOMMU_SUPPORT [=y] && (QCOM_OCMEM [=n] || QCOM_OCMEM [=n]=n) && (QCOM_LLCC [=y] || QCOM_LLCC [=y]=n) && (QCOM_COMMAND_DB [=n] || QCOM_COMMAND_DB [=n]=n) Make DRM_DP_AUX_BUS depends on OF || COMPILE_TEST to fix this warning. Fixes: f5d01644921b ("drm/msm: select DRM_DP_AUX_BUS for the AUX bus support") Signed-off-by: YueHaibing Patch applied to the DRM tree. Nope, failed: $ dim push-branch drm-misc-next dim: ac890b9eeb9b ("drm/display: Fix build error without CONFIG_OF"): Fixes: SHA1 in not pointing at an ancestor: dim: f5d01644921b ("drm/msm: select DRM_DP_AUX_BUS for the AUX bus support") dim: ERROR: issues in commits detected, aborting I don't know what to do with this, sorry. The other committers are maybe better with this kind of situations. I think it is designed to stop me from shooting myself in the foot. It 'Fixes' a commit in the drm/msm tree, however a fix is not msm-specific. We can push it out through the drm/msm, but we'd need an ack from drm/core. -- With best wishes Dmitry
Re: [PATCH v2 -next] drm/display: Fix build error without CONFIG_OF
On Mon, May 23, 2022 at 2:46 PM Linus Walleij wrote: > On Fri, May 6, 2022 at 2:33 PM YueHaibing wrote: > > > While CONFIG_OF is n but COMPILE_TEST is y, we got this: > > > > WARNING: unmet direct dependencies detected for DRM_DP_AUX_BUS > > Depends on [n]: HAS_IOMEM [=y] && DRM [=y] && OF [=n] > > Selected by [y]: > > - DRM_MSM [=y] && HAS_IOMEM [=y] && DRM [=y] && (ARCH_QCOM || SOC_IMX5 || > > COMPILE_TEST [=y]) && COMMON_CLK [=y] && IOMMU_SUPPORT [=y] && (QCOM_OCMEM > > [=n] || QCOM_OCMEM [=n]=n) && (QCOM_LLCC [=y] || QCOM_LLCC [=y]=n) && > > (QCOM_COMMAND_DB [=n] || QCOM_COMMAND_DB [=n]=n) > > > > Make DRM_DP_AUX_BUS depends on OF || COMPILE_TEST to fix this warning. > > > > Fixes: f5d01644921b ("drm/msm: select DRM_DP_AUX_BUS for the AUX bus > > support") > > Signed-off-by: YueHaibing > > Patch applied to the DRM tree. Nope, failed: $ dim push-branch drm-misc-next dim: ac890b9eeb9b ("drm/display: Fix build error without CONFIG_OF"): Fixes: SHA1 in not pointing at an ancestor: dim: f5d01644921b ("drm/msm: select DRM_DP_AUX_BUS for the AUX bus support") dim: ERROR: issues in commits detected, aborting I don't know what to do with this, sorry. The other committers are maybe better with this kind of situations. I think it is designed to stop me from shooting myself in the foot. Yours, Linus Walleij
Re: [PATCH v1 1/2] Revert "drm/bridge: anx7625: Use DPI bus type"
These two patches need to be reverted since they were part (3/4 & 4/4) of a series, that was partially (1/4 + 2/4) on the linux-media tree. These two patches depend on the patches in the media tree, and will not build without them, which leaves linux-drm-misc-next in a broken state. Let's revert the two latter patches until rc1 has been branched and the dependency wont cause issues any more. On Mon, 23 May 2022 at 14:50, Robert Foss wrote: > > On Mon, 23 May 2022 at 10:46, Robert Foss wrote: > > > > This reverts commit a77c2af0994e24ee36c7ffb6dc852770bdf06fb1. > > --- > > drivers/gpu/drm/bridge/analogix/anx7625.c | 8 > > 1 file changed, 4 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c > > b/drivers/gpu/drm/bridge/analogix/anx7625.c > > index 01f46d9189c1..53a5da6c49dd 100644 > > --- a/drivers/gpu/drm/bridge/analogix/anx7625.c > > +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c > > @@ -1623,14 +1623,14 @@ static int anx7625_parse_dt(struct device *dev, > > > > anx7625_get_swing_setting(dev, pdata); > > > > - pdata->is_dpi = 0; /* default dsi mode */ > > + pdata->is_dpi = 1; /* default dpi mode */ > > pdata->mipi_host_node = of_graph_get_remote_node(np, 0, 0); > > if (!pdata->mipi_host_node) { > > DRM_DEV_ERROR(dev, "fail to get internal panel.\n"); > > return -ENODEV; > > } > > > > - bus_type = 0; > > + bus_type = V4L2_FWNODE_BUS_TYPE_PARALLEL; > > mipi_lanes = MAX_LANES_SUPPORT; > > ep0 = of_graph_get_endpoint_by_regs(np, 0, 0); > > if (ep0) { > > @@ -1640,8 +1640,8 @@ static int anx7625_parse_dt(struct device *dev, > > mipi_lanes = of_property_count_u32_elems(ep0, "data-lanes"); > > } > > > > - if (bus_type == V4L2_FWNODE_BUS_TYPE_DPI) /* bus type is DPI */ > > - pdata->is_dpi = 1; > > + if (bus_type == V4L2_FWNODE_BUS_TYPE_PARALLEL) /* bus type is > > Parallel(DSI) */ > > + pdata->is_dpi = 0; > > > > pdata->mipi_lanes = mipi_lanes; > > if (pdata->mipi_lanes > MAX_LANES_SUPPORT || pdata->mipi_lanes <= 0) > > -- > > 2.34.1 > > > > Signed-off-by: Robert Foss
Re: [PATCH v1 2/2] Revert "dt-bindings:drm/bridge:anx7625: add port@0 property"
On Mon, 23 May 2022 at 10:46, Robert Foss wrote: > > This reverts commit 7328736d270aa4fa6fcd033ade02acc2874a2db5. > --- > .../display/bridge/analogix,anx7625.yaml | 19 +-- > 1 file changed, 1 insertion(+), 18 deletions(-) > > diff --git > a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml > b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml > index 4590186c4a0b..35a48515836e 100644 > --- a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml > +++ b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml > @@ -94,22 +94,7 @@ properties: > $ref: /schemas/graph.yaml#/$defs/port-base > unevaluatedProperties: false > description: > - MIPI DSI/DPI input. > - > -properties: > - endpoint: > -$ref: /schemas/media/video-interfaces.yaml# > -type: object > -additionalProperties: false > - > -properties: > - remote-endpoint: true > - > - bus-type: > -enum: [7] > -default: 1 > - > - data-lanes: true > + Video port for MIPI DSI input. > >port@1: > $ref: /schemas/graph.yaml#/properties/port > @@ -158,8 +143,6 @@ examples: > reg = <0>; > anx7625_in: endpoint { > remote-endpoint = <&mipi_dsi>; > -bus-type = <7>; > -data-lanes = <0 1 2 3>; > }; > }; > > -- > 2.34.1 > Signed-off-by: Robert Foss
Re: [PATCH v1 1/2] Revert "drm/bridge: anx7625: Use DPI bus type"
On Mon, 23 May 2022 at 10:46, Robert Foss wrote: > > This reverts commit a77c2af0994e24ee36c7ffb6dc852770bdf06fb1. > --- > drivers/gpu/drm/bridge/analogix/anx7625.c | 8 > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c > b/drivers/gpu/drm/bridge/analogix/anx7625.c > index 01f46d9189c1..53a5da6c49dd 100644 > --- a/drivers/gpu/drm/bridge/analogix/anx7625.c > +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c > @@ -1623,14 +1623,14 @@ static int anx7625_parse_dt(struct device *dev, > > anx7625_get_swing_setting(dev, pdata); > > - pdata->is_dpi = 0; /* default dsi mode */ > + pdata->is_dpi = 1; /* default dpi mode */ > pdata->mipi_host_node = of_graph_get_remote_node(np, 0, 0); > if (!pdata->mipi_host_node) { > DRM_DEV_ERROR(dev, "fail to get internal panel.\n"); > return -ENODEV; > } > > - bus_type = 0; > + bus_type = V4L2_FWNODE_BUS_TYPE_PARALLEL; > mipi_lanes = MAX_LANES_SUPPORT; > ep0 = of_graph_get_endpoint_by_regs(np, 0, 0); > if (ep0) { > @@ -1640,8 +1640,8 @@ static int anx7625_parse_dt(struct device *dev, > mipi_lanes = of_property_count_u32_elems(ep0, "data-lanes"); > } > > - if (bus_type == V4L2_FWNODE_BUS_TYPE_DPI) /* bus type is DPI */ > - pdata->is_dpi = 1; > + if (bus_type == V4L2_FWNODE_BUS_TYPE_PARALLEL) /* bus type is > Parallel(DSI) */ > + pdata->is_dpi = 0; > > pdata->mipi_lanes = mipi_lanes; > if (pdata->mipi_lanes > MAX_LANES_SUPPORT || pdata->mipi_lanes <= 0) > -- > 2.34.1 > Signed-off-by: Robert Foss
Re: [PATCH v2 -next] drm/display: Fix build error without CONFIG_OF
On Fri, May 6, 2022 at 2:33 PM YueHaibing wrote: > While CONFIG_OF is n but COMPILE_TEST is y, we got this: > > WARNING: unmet direct dependencies detected for DRM_DP_AUX_BUS > Depends on [n]: HAS_IOMEM [=y] && DRM [=y] && OF [=n] > Selected by [y]: > - DRM_MSM [=y] && HAS_IOMEM [=y] && DRM [=y] && (ARCH_QCOM || SOC_IMX5 || > COMPILE_TEST [=y]) && COMMON_CLK [=y] && IOMMU_SUPPORT [=y] && (QCOM_OCMEM > [=n] || QCOM_OCMEM [=n]=n) && (QCOM_LLCC [=y] || QCOM_LLCC [=y]=n) && > (QCOM_COMMAND_DB [=n] || QCOM_COMMAND_DB [=n]=n) > > Make DRM_DP_AUX_BUS depends on OF || COMPILE_TEST to fix this warning. > > Fixes: f5d01644921b ("drm/msm: select DRM_DP_AUX_BUS for the AUX bus support") > Signed-off-by: YueHaibing Patch applied to the DRM tree. Yours, Linus Walleij
Re: [PATCH v2 11/13] mm: handling Non-LRU pages returned by vm_normal_pages
Technically I think this patch should be earlier in the series. As I understand it patch 1 allows DEVICE_COHERENT pages to be inserted in the page tables and therefore makes it possible for page table walkers to see non-LRU pages. Some more comments below: Alex Sierra writes: > With DEVICE_COHERENT, we'll soon have vm_normal_pages() return > device-managed anonymous pages that are not LRU pages. Although they > behave like normal pages for purposes of mapping in CPU page, and for > COW. They do not support LRU lists, NUMA migration or THP. > > We also introduced a FOLL_LRU flag that adds the same behaviour to > follow_page and related APIs, to allow callers to specify that they > expect to put pages on an LRU list. This means by default GUP can return non-LRU pages. I didn't see anywhere that would be a problem but I didn't check everything. Did you check this or is there some other reason I've missed that makes this not a problem? [...] > diff --git a/mm/khugepaged.c b/mm/khugepaged.c > index a4e5eaf3eb01..eb3cfd679800 100644 > --- a/mm/khugepaged.c > +++ b/mm/khugepaged.c > @@ -627,7 +627,7 @@ static int __collapse_huge_page_isolate(struct > vm_area_struct *vma, > goto out; > } > page = vm_normal_page(vma, address, pteval); > - if (unlikely(!page)) { > + if (unlikely(!page) || unlikely(is_zone_device_page(page))) { > result = SCAN_PAGE_NULL; > goto out; > } > @@ -1276,7 +1276,7 @@ static int khugepaged_scan_pmd(struct mm_struct *mm, > writable = true; > > page = vm_normal_page(vma, _address, pteval); > - if (unlikely(!page)) { > + if (unlikely(!page) || unlikely(is_zone_device_page(page))) { > result = SCAN_PAGE_NULL; > goto out_unmap; > } > @@ -1484,7 +1484,8 @@ void collapse_pte_mapped_thp(struct mm_struct *mm, > unsigned long addr) > goto abort; > > page = vm_normal_page(vma, addr, *pte); > - > + if (page && is_zone_device_page(page)) > + page = NULL; > /* >* Note that uprobe, debugger, or MAP_PRIVATE may change the >* page table, but the new page will not be a subpage of hpage. > @@ -1502,6 +1503,8 @@ void collapse_pte_mapped_thp(struct mm_struct *mm, > unsigned long addr) > if (pte_none(*pte)) > continue; > page = vm_normal_page(vma, addr, *pte); > + if (page && is_zone_device_page(page)) > + goto abort; Are either of these two cases actually possible? DEVICE_COHERENT doesn't currently support THP, so if I'm understanding correctly we couldn't have a pte mapped DEVICE_COHERENT THP right? Assuming that's the case I think WARN_ON_ONCE() would be better. Otherwise I think everything else looks reasonable. > page_remove_rmap(page, vma, false); > } > > diff --git a/mm/ksm.c b/mm/ksm.c > index 063a48eeb5ee..f16056efca21 100644 > --- a/mm/ksm.c > +++ b/mm/ksm.c > @@ -474,7 +474,7 @@ static int break_ksm(struct vm_area_struct *vma, unsigned > long addr) > do { > cond_resched(); > page = follow_page(vma, addr, > - FOLL_GET | FOLL_MIGRATION | FOLL_REMOTE); > + FOLL_GET | FOLL_MIGRATION | FOLL_REMOTE | > FOLL_LRU); > if (IS_ERR_OR_NULL(page)) > break; > if (PageKsm(page)) > @@ -559,7 +559,7 @@ static struct page *get_mergeable_page(struct rmap_item > *rmap_item) > if (!vma) > goto out; > > - page = follow_page(vma, addr, FOLL_GET); > + page = follow_page(vma, addr, FOLL_GET | FOLL_LRU); > if (IS_ERR_OR_NULL(page)) > goto out; > if (PageAnon(page)) { > @@ -2288,7 +2288,7 @@ static struct rmap_item *scan_get_next_rmap_item(struct > page **page) > while (ksm_scan.address < vma->vm_end) { > if (ksm_test_exit(mm)) > break; > - *page = follow_page(vma, ksm_scan.address, FOLL_GET); > + *page = follow_page(vma, ksm_scan.address, FOLL_GET | > FOLL_LRU); > if (IS_ERR_OR_NULL(*page)) { > ksm_scan.address += PAGE_SIZE; > cond_resched(); > diff --git a/mm/madvise.c b/mm/madvise.c > index 1873616a37d2..e9c24c834e98 100644 > --- a/mm/madvise.c > +++ b/mm/madvise.c > @@ -413,7 +413,7 @@ static int madvise_cold_or_pageout_pte_range(pmd_t *pmd, > continue; > > page = vm_normal_page(vma, addr, ptent); > - if (!page) > + if (!page || is_zone_device_page(page)) > continue; > > /* > @@
Re: [PATCH v10 01/21] dt-bindings: mediatek, dpi: Add DPINTF compatible
On Mon, 23 May 2022 12:47:34 +0200, Guillaume Ranquet wrote: > From: Markus Schneider-Pargmann > > DPINTF is similar to DPI but does not have the exact same feature set > or register layouts. > > DPINTF is the sink of the display pipeline that is connected to the > DisplayPort controller and encoder unit. It takes the same clocks as > DPI. > > Signed-off-by: Markus Schneider-Pargmann > Signed-off-by: Guillaume Ranquet > --- > .../bindings/display/mediatek/mediatek,dpi.yaml | 13 - > 1 file changed, 8 insertions(+), 5 deletions(-) > Running 'make dtbs_check' with the schema in this patch gives the following warnings. Consider if they are expected or the schema is incorrect. These may not be new warnings. Note that it is not yet a requirement to have 0 warnings for dtbs_check. This will change in the future. Full log is available here: https://patchwork.ozlabs.org/patch/ dpi@14014000: Additional properties are not allowed ('ports' was unexpected) arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb arch/arm/boot/dts/mt7623n-rfb-emmc.dtb dpi@14014000: clock-names: ['pixel', 'engine', 'pll'] is too short arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb arch/arm/boot/dts/mt7623n-rfb-emmc.dtb dpi@14014000: clocks: [[59, 26], [59, 27], [3, 6]] is too short arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb dpi@14014000: clocks: [[61, 26], [61, 27], [3, 6]] is too short arch/arm/boot/dts/mt7623n-rfb-emmc.dtb dpi@14014000: compatible: ['mediatek,mt7623-dpi', 'mediatek,mt2701-dpi'] is too long arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb arch/arm/boot/dts/mt7623n-rfb-emmc.dtb dpi@14014000: 'port' is a required property arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dtb arch/arm/boot/dts/mt7623n-rfb-emmc.dtb dpi@1401d000: Additional properties are not allowed ('power-domains' was unexpected) arch/arm64/boot/dts/mediatek/mt8173-elm.dtb arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtb arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dtb arch/arm64/boot/dts/mediatek/mt8173-evb.dtb dpi@1401d000: clock-names: ['pixel', 'engine', 'pll'] is too short arch/arm64/boot/dts/mediatek/mt8173-elm.dtb arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtb arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dtb arch/arm64/boot/dts/mediatek/mt8173-evb.dtb dpi@1401d000: clocks: [[57, 40], [57, 41], [8, 8]] is too short arch/arm64/boot/dts/mediatek/mt8173-evb.dtb dpi@1401d000: clocks: [[68, 40], [68, 41], [8, 8]] is too short arch/arm64/boot/dts/mediatek/mt8173-elm.dtb arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtb arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dtb
Re: How should "max bpc" KMS property work?
On Mon, May 23, 2022 at 10:23 AM Pekka Paalanen wrote: > > On Fri, 20 May 2022 17:20:50 +0200 > Hans de Goede wrote: > > > I got pointed to this thread by Jonas Ådahl while asking some questions > > the "max bpc" property related to: > > > > https://gitlab.freedesktop.org/plymouth/plymouth/-/issues/102#note_1382328 > > > > The current i915 behavior which you describe here, which if I understand > > things correctly is for "max bpc" to default to as high as possible is > > causing problems with flickerfree boot in plymouth. Plymouth does a modeset > > on the monitor's native resolution in case the BIOS/GOP setup the monitor > > in a non native mode. Plymouth does not touch the "max bpc" property when > > doing this modeset. Normally this works fine and when the BIOS/GOP has > > already configured the monitor at the native resolution the i915 driver > > will do a fastset and all is well. > > > > Still the modeset is causing the screen to go black for multiple seconds, > > despite the resolution being unchanged. What is happening according to > > the on screen mode info from the monitor is that on plymouth's modeset > > the link is being configured changes from 8 bpc to 10 bpc. > > > > Is there anyway to avoid this without hardcoding "max bpc" to 8 in > > plymouth (which would cause the same problem in the other direction > > if the firmware sets up the link for 10bpc I believe) ? > > Hi Hans, > > there was an attempt to get much of the current link state information > delivered to userspace, but I've forgot most about it. > I did find https://lkml.org/lkml/2021/6/18/294 linked from > https://gitlab.freedesktop.org/drm/amd/-/issues/476#note_963469 . > I said the same in the Plymouth Gitlab issue you linked to. > > Personally, I would need to know all current link details for > (professional) color management: am I still driving the monitor with > the same signal as I did when I measured the monitor one reboot ago? > If not, I cannot trust the color output and need to measure again. I would go further and say that not being in control of all the link details is an issue for user space. Max bpc doesn't give us a minimum guarantee. Bpc doesn't really make sense for YUV. We don't know if the link is using RGB or YUV. The Colorspace property requires user space to know if the link is RGB or YUV (or does the link change depending on the Colorspace property? What about the default Colorspace?). Link compression can mess up colors. There simply is no way to write a proper user space with the current KMS API. > > Nice to see there would be other uses for knowing which might be higher > priority to the larger community. > > Would it be proper to initialize 'max bpc' to the link depth used by > boot-up firmware? I guess it could make things more reliable and solve > the Plymouth blanking issue, but not the professional color management > use cases. I was always under the impression that if you do an atomic commit without changing any properties that it won't result in a mode set which would clearly make the current behavior a bug. > > > Thanks, > pq
[PATCH v3] drm/nouveau: clear output poll workers before nouveau_fbcon_destroy()
Resources needed for output poll workers are destroyed in nouveau_fbcon_fini() before output poll workers are cleared in nouveau_display_fini(). This means there is a time between fbcon_fini() and display_fini(), where if output poll happens, it crashes. This patch introduces another output poll clearing before fbcon resources are destroyed. BUG: KASAN: use-after-free in __drm_fb_helper_initial_config_and_unlock.cold+0x1f3/0x291 [drm_kms_helper] Cc: Ben Skeggs Cc: Karol Herbst Cc: Lyude Paul Cc: David Airlie Cc: Daniel Vetter Cc: dri-devel@lists.freedesktop.org Cc: nouv...@lists.freedesktop.org Cc: linux-ker...@vger.kernel.org Signed-off-by: Mark Menzynski --- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 4f9b3aa5deda..5226323e55d3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -39,6 +39,7 @@ #include #include +#include #include #include #include @@ -605,6 +606,7 @@ nouveau_fbcon_fini(struct drm_device *dev) if (!drm->fbcon) return; + drm_kms_helper_poll_fini(dev); nouveau_fbcon_accel_fini(dev); nouveau_fbcon_destroy(dev, drm->fbcon); kfree(drm->fbcon); -- 2.32.0
Re: [PATCH] drm: bridge: icn6211: Adjust clock phase using SYS_CTRL_1
On 5/23/22 04:38, Jonathan Liu wrote: The code from [1] sets SYS_CTRL_1 to different values depending on the desired clock phase (0, 1/4, 1/2 or 3/4). A clock phase of 0 aligns the positive edge of the clock with the pixel data while other values delay the clock by a fraction of the clock period. A clock phase of 1/2 aligns the negative edge of the clock with the pixel data. The driver currently hard codes SYS_CTRL_1 to 0x88 which corresponds to aligning the positive edge of the clock with the pixel data. This won't work correctly for panels that require aligning the negative edge of the clock with the pixel data. Adjust the clock phase to 0 if DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE is present in bus_flags, otherwise adjust the clock phase to 1/2 as appropriate for DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE. [1] https://github.com/tdjastrzebski/ICN6211-Configurator Signed-off-by: Jonathan Liu --- drivers/gpu/drm/bridge/chipone-icn6211.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c b/drivers/gpu/drm/bridge/chipone-icn6211.c index 47dea657a752..df0290059aa3 100644 --- a/drivers/gpu/drm/bridge/chipone-icn6211.c +++ b/drivers/gpu/drm/bridge/chipone-icn6211.c @@ -57,6 +57,10 @@ #define BIST_CHESS_XY_H 0x30 #define BIST_FRAME_TIME_L 0x31 #define BIST_FRAME_TIME_H 0x32 +#define CLK_PHASE_00x88 +#define CLK_PHASE_1_4 0x98 +#define CLK_PHASE_1_2 0xa8 +#define CLK_PHASE_3_4 0xb8 #define FIFO_MAX_ADDR_LOW 0x33 #define SYNC_EVENT_DLY0x34 #define HSW_MIN 0x35 @@ -414,7 +418,11 @@ static void chipone_atomic_enable(struct drm_bridge *bridge, chipone_configure_pll(icn, mode); chipone_writeb(icn, SYS_CTRL(0), 0x40); - chipone_writeb(icn, SYS_CTRL(1), 0x88); + + if (bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE) + chipone_writeb(icn, SYS_CTRL(1), CLK_PHASE_0); + else + chipone_writeb(icn, SYS_CTRL(1), CLK_PHASE_1_2); Shouldn't both be "chipone_writeb(icn, SYS_CTRL(1), CLK_PHASE_0 | 0x8); and chipone_writeb(icn, SYS_CTRL(1), CLK_PHASE_1_2 | 0x8); respectively ? I recall you mentioned that only the top two bits indicate the clock polarity , so the bottom 6 bits are something else ? With that fixed: Reviewed-by: Marek Vasut Thanks
Re: [PATCH] udmabuf: Set the DMA mask for the udmabuf device
Hi Vivek, url: https://github.com/intel-lab-lkp/linux/commits/Vivek-Kasireddy/udmabuf-Set-the-DMA-mask-for-the-udmabuf-device/20220520-144218 base: git://anongit.freedesktop.org/drm/drm-tip drm-tip config: x86_64-randconfig-m001 (https://download.01.org/0day-ci/archive/20220521/202205210319.ovui0mkr-...@intel.com/config) compiler: gcc-11 (Debian 11.3.0-1) 11.3.0 If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot Reported-by: Dan Carpenter New smatch warnings: drivers/dma-buf/udmabuf.c:383 udmabuf_dev_init() warn: '&udmabuf_misc' from misc_register() not released on lines: 380. vim +383 drivers/dma-buf/udmabuf.c fbb0de79507819 Gerd Hoffmann 2018-08-27 366 static int __init udmabuf_dev_init(void) fbb0de79507819 Gerd Hoffmann 2018-08-27 367 { 0fdcc793991b9f Vivek Kasireddy 2022-05-19 368 int ret; 0fdcc793991b9f Vivek Kasireddy 2022-05-19 369 0fdcc793991b9f Vivek Kasireddy 2022-05-19 370 ret = misc_register(&udmabuf_misc); 0fdcc793991b9f Vivek Kasireddy 2022-05-19 371 if (ret < 0) { 0fdcc793991b9f Vivek Kasireddy 2022-05-19 372 pr_err("Could not initialize udmabuf device\n"); 0fdcc793991b9f Vivek Kasireddy 2022-05-19 373 return ret; 0fdcc793991b9f Vivek Kasireddy 2022-05-19 374 } 0fdcc793991b9f Vivek Kasireddy 2022-05-19 375 0fdcc793991b9f Vivek Kasireddy 2022-05-19 376 ret = dma_coerce_mask_and_coherent(udmabuf_misc.this_device, 0fdcc793991b9f Vivek Kasireddy 2022-05-19 377 DMA_BIT_MASK(64)); 0fdcc793991b9f Vivek Kasireddy 2022-05-19 378 if (ret < 0) { 0fdcc793991b9f Vivek Kasireddy 2022-05-19 379 pr_err("Could not setup DMA mask for udmabuf device\n"); misc_unregister()? 0fdcc793991b9f Vivek Kasireddy 2022-05-19 380 return ret; 0fdcc793991b9f Vivek Kasireddy 2022-05-19 381 } 0fdcc793991b9f Vivek Kasireddy 2022-05-19 382 0fdcc793991b9f Vivek Kasireddy 2022-05-19 @383 return 0; fbb0de79507819 Gerd Hoffmann 2018-08-27 384 } -- 0-DAY CI Kernel Test Service https://01.org/lkp
Re: [PATCH v10 03/21] drm/edid: Convert cea_sad helper struct to kernelDoc
On Mon, 2022-05-23 at 12:47 +0200, Guillaume Ranquet wrote: > Signed-off-by: Guillaume Ranquet > We need a commit message here. > --- > include/drm/drm_edid.h | 12 +--- > 1 file changed, 9 insertions(+), 3 deletions(-) > > diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h > index 144c495b99c4..37c420423625 100644 > --- a/include/drm/drm_edid.h > +++ b/include/drm/drm_edid.h > @@ -359,12 +359,18 @@ struct edid { > > #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] > << 8)) > > -/* Short Audio Descriptor */ > +/** > + * struct cea_sad - Short Audio Descriptor. > + * @format: See HDMI_AUDIO_CODING_TYPE_*. > + * @channels: max number of channels - 1. > + * @freq: See CEA_SAD_FREQ_*. > + * @byte2: meaning depends on format. > + */ > struct cea_sad { > u8 format; > - u8 channels; /* max number of channels - 1 */ > + u8 channels; > u8 freq; > - u8 byte2; /* meaning depends on format */ > + u8 byte2; > }; > > struct drm_encoder;
Re: [PATCH] drm/bridge: ti-sn65dsi83: Handle dsi_lanes == 0 as invalid
On 5/23/22 12:23, Robert Foss wrote: On Mon, 23 May 2022 at 11:58, Marek Vasut wrote: On 5/23/22 11:40, Robert Foss wrote: On Thu, 19 May 2022 at 09:57, Lucas Stach wrote: Am Donnerstag, dem 19.05.2022 um 01:38 +0200 schrieb Marek Vasut: Handle empty data-lanes = < >; property, which translates to dsi_lanes = 0 as invalid. [...] diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c index d64d4385188dd..dc65f424e7f3c 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c @@ -585,7 +585,7 @@ static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model) ctx->host_node = of_graph_get_remote_port_parent(endpoint); of_node_put(endpoint); - if (ctx->dsi_lanes < 0 || ctx->dsi_lanes > 4) { + if (ctx->dsi_lanes <= 0 || ctx->dsi_lanes > 4) { ret = -EINVAL; goto err_put_node; } Applied to drm-misc-next. This was already applied to drm-misc-next-fixes , since this is a fix for something that was already in release . The conflict will resolve itself easily though ? Ah, I didn't realize. I'm not sure if it will resolve itself or not. But I think either it is reverted in drm-misc-next now, or we wait for an issue to crop up. I think either way is acceptable, but waiting maybe causes less churn. So unless someone has another preference, let's wait and see if a conflict arises. I agree, we wait.
[PATCH v10 21/21] drm/mediatek: DP audio support for mt8195
This patch adds audio support to the DP driver for mt8195 with up to 8 channels. Signed-off-by: Guillaume Ranquet --- drivers/gpu/drm/mediatek/mtk_dp.c | 784 +- 1 file changed, 777 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c index c056bc3ca9f6..05da6565c7f9 100644 --- a/drivers/gpu/drm/mediatek/mtk_dp.c +++ b/drivers/gpu/drm/mediatek/mtk_dp.c @@ -108,9 +108,41 @@ enum mtk_dp_color_depth { MTK_DP_COLOR_DEPTH_UNKNOWN = 5, }; +enum mtk_dp_sdp_type { + MTK_DP_SDP_NONE = 0x00, + MTK_DP_SDP_ACM = 0x01, + MTK_DP_SDP_ISRC = 0x02, + MTK_DP_SDP_AVI = 0x03, + MTK_DP_SDP_AUI = 0x04, + MTK_DP_SDP_SPD = 0x05, + MTK_DP_SDP_MPEG = 0x06, + MTK_DP_SDP_NTSC = 0x07, + MTK_DP_SDP_VSP = 0x08, + MTK_DP_SDP_VSC = 0x09, + MTK_DP_SDP_EXT = 0x0A, + MTK_DP_SDP_PPS0 = 0x0B, + MTK_DP_SDP_PPS1 = 0x0C, + MTK_DP_SDP_PPS2 = 0x0D, + MTK_DP_SDP_PPS3 = 0x0E, + MTK_DP_SDP_DRM = 0x10, + MTK_DP_SDP_MAX_NUM +}; + +struct mtk_dp_sdp_packet { + enum mtk_dp_sdp_type type; + struct dp_sdp sdp; +}; + +struct mtk_dp_audio_cfg { + int sample_rate; + int word_length_bits; + int channels; +}; + struct mtk_dp_info { enum mtk_dp_color_depth depth; enum dp_pixelformat format; + struct mtk_dp_audio_cfg audio_caps; struct mtk_dp_timings timings; }; @@ -148,10 +180,22 @@ struct mtk_dp { struct clk *dp_tx_clk; bool enabled; + bool audio_enable; bool has_fec; /* Protects the mtk_dp struct */ struct mutex dp_lock; + /* Protects the plugged_cb as it's used in both bridge ops and audio */ + struct mutex update_plugged_status_lock; + /* Protects the eld data as it's used in both bridge ops and audio */ + struct mutex eld_lock; + /* Protects edid as it is used in both bridge ops and IRQ handler */ + struct mutex edid_lock; + struct edid *edid; + + hdmi_codec_plugged_cb plugged_cb; + struct device *codec_dev; + u8 connector_eld[MAX_ELD_BYTES]; struct drm_connector *conn; bool need_debounce; @@ -512,15 +556,363 @@ static int mtk_dp_pg_disable(struct mtk_dp *mtk_dp) return ret; } +static int mtk_dp_audio_setup_channels(struct mtk_dp *mtk_dp, + struct mtk_dp_audio_cfg *cfg) +{ + int ret; + u32 channel_enable_bits; + + ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3324, +AUDIO_SOURCE_MUX_DP_ENC1_P0_DPRX, + AUDIO_SOURCE_MUX_DP_ENC1_P0_MASK); + if (ret) + return ret; + + /* audio channel count change reset */ + ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_33F4, BIT(9), BIT(9)); + if (ret) + return ret; + + ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3304, +AU_PRTY_REGEN_DP_ENC1_P0_MASK, + AU_PRTY_REGEN_DP_ENC1_P0_MASK); + if (ret) + return ret; + + ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3304, +AU_CH_STS_REGEN_DP_ENC1_P0_MASK, + AU_CH_STS_REGEN_DP_ENC1_P0_MASK); + if (ret) + return ret; + + ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3304, +AUDIO_SAMPLE_PRSENT_REGEN_DP_ENC1_P0_MASK, + AUDIO_SAMPLE_PRSENT_REGEN_DP_ENC1_P0_MASK); + if (ret) + return ret; + + switch (cfg->channels) { + case 2: + channel_enable_bits = AUDIO_2CH_SEL_DP_ENC0_P0_MASK | + AUDIO_2CH_EN_DP_ENC0_P0_MASK; + break; + case 8: + default: + channel_enable_bits = AUDIO_8CH_SEL_DP_ENC0_P0_MASK | + AUDIO_8CH_EN_DP_ENC0_P0_MASK; + break; + } + ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3088, +channel_enable_bits | AU_EN_DP_ENC0_P0_MASK, + AUDIO_2CH_SEL_DP_ENC0_P0_MASK | AUDIO_2CH_EN_DP_ENC0_P0_MASK | + AUDIO_8CH_SEL_DP_ENC0_P0_MASK | + AUDIO_8CH_EN_DP_ENC0_P0_MASK | AU_EN_DP_ENC0_P0_MASK); + if (ret) + return ret; + + /* audio channel count change reset */ + ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_33F4, 0, BIT(9)); + if (ret) + return ret; + + /* enable audio reset */ + ret = mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_33F4, BIT(0), BIT(0)); + + return ret; +} + +static int mtk_dp_audio_channel_status_set(struct mtk_dp *mtk_dp, + struct mtk_dp_audio_cfg *cfg) +{ + int ret; +
[PATCH v10 20/21] drm/mediatek: add hpd debounce
From: Jitao Shi >From the DP spec 1.4a chapter 3.3, upstream devices should implement HPD signal de-bouncing on an external connection. A period of 100ms should be used to detect an HPD connect event. To cover these cases, HPD de-bounce should be implemented only after HPD low has been detected for at least 100ms. Therefore, 1. If HPD is low (which means plugging out) for longer than 100ms: we need to do de-bouncing (which means we need to wait for 100ms). 2. If HPD low is for less than 100ms: we don't need to care about the de-bouncing. In this patch, we start a 100ms timer and use a need_debounce boolean to implement the feature. Two cases when HPD is high: 1. If the timer is expired (>100ms): - need_debounce is true. - When HPD high (plugging event comes), need_debounce will be true and then we need to do de-bouncing (wait for 100ms). 2. If the timer is not expired (<100ms): - need_debounce is false. - When HPD high (plugging event comes), need_debounce will be false and no need to do de-bouncing. HPD___ __ ||<- 100ms -> || <- 100ms -> Without HPD de-bouncing, USB-C to HDMI Adapaters will not be detected. The change has been successfully tested with the following devices: - Dell Adapter - USB-C to HDMI - Acer 1in1 HDMI dongle - Ugreen 1in1 HDMI dongle - innowatt HDMI + USB3 hub - Acer 2in1 HDMI dongle - Apple 3in1 HDMI dongle (A2119) - J5Create 3in1 HDMI dongle (JAC379) Tested-by: Rex-BC Chen Reviewed-by: Rex-BC Chen Signed-off-by: Jitao Shi Signed-off-by: Guillaume Ranquet --- drivers/gpu/drm/mediatek/mtk_dp.c | 21 + 1 file changed, 21 insertions(+) diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c index 4789853ec5ff..c056bc3ca9f6 100644 --- a/drivers/gpu/drm/mediatek/mtk_dp.c +++ b/drivers/gpu/drm/mediatek/mtk_dp.c @@ -154,6 +154,8 @@ struct mtk_dp { struct mutex dp_lock; struct drm_connector *conn; + bool need_debounce; + struct timer_list debounce_timer; }; static struct regmap_config mtk_dp_regmap_config = { @@ -1970,6 +1972,9 @@ static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev) if (event < 0) return IRQ_HANDLED; + if (mtk_dp->need_debounce && mtk_dp->train_info.cable_plugged_in) + msleep(100); + if (mtk_dp->drm_dev) { dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n"); drm_helper_hpd_irq_event(mtk_dp->bridge.dev); @@ -2047,6 +2052,11 @@ static irqreturn_t mtk_dp_hpd_isr_handler(struct mtk_dp *mtk_dp) } train_info->cable_state_change = true; + if (!train_info->cable_plugged_in) { + mod_timer(&mtk_dp->debounce_timer, jiffies + msecs_to_jiffies(100) - 1); + mtk_dp->need_debounce = false; + } + return IRQ_WAKE_THREAD; } @@ -2474,6 +2484,13 @@ static const struct drm_bridge_funcs mtk_dp_bridge_funcs = { .detect = mtk_dp_bdg_detect, }; +static void mtk_dp_debounce_timer(struct timer_list *t) +{ + struct mtk_dp *mtk_dp = from_timer(mtk_dp, t, debounce_timer); + + mtk_dp->need_debounce = true; +} + static int mtk_dp_probe(struct platform_device *pdev) { struct mtk_dp *mtk_dp; @@ -2547,6 +2564,9 @@ static int mtk_dp_probe(struct platform_device *pdev) else mtk_dp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort; + mtk_dp->need_debounce = true; + timer_setup(&mtk_dp->debounce_timer, mtk_dp_debounce_timer, 0); + pm_runtime_enable(dev); pm_runtime_get_sync(dev); @@ -2559,6 +2579,7 @@ static int mtk_dp_remove(struct platform_device *pdev) platform_device_unregister(mtk_dp->phy_dev); mtk_dp_video_mute(mtk_dp, true); + del_timer_sync(&mtk_dp->debounce_timer); pm_runtime_disable(&pdev->dev); -- 2.35.1
[PATCH v10 19/21] drm/mediatek: Add mt8195 External DisplayPort support
This patch adds External DisplayPort support to the mt8195 eDP driver. Signed-off-by: Guillaume Ranquet --- drivers/gpu/drm/mediatek/mtk_dp.c | 104 +++--- 1 file changed, 81 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c index 8eb17ae82bfd..4789853ec5ff 100644 --- a/drivers/gpu/drm/mediatek/mtk_dp.c +++ b/drivers/gpu/drm/mediatek/mtk_dp.c @@ -164,6 +164,11 @@ static struct regmap_config mtk_dp_regmap_config = { .name = "mtk-dp-registers", }; +static bool mtk_dp_is_edp(struct mtk_dp *mtk_dp) +{ + return mtk_dp->next_bridge; +} + static struct mtk_dp *mtk_dp_from_bridge(struct drm_bridge *b) { return container_of(b, struct mtk_dp, bridge); @@ -1054,26 +1059,49 @@ static int mtk_dp_get_calibration_data(struct mtk_dp *mtk_dp) if (!cal_data->ln_tx_impsel_pmos) return -ENOMEM; - cal_data->glb_bias_trim = - check_cal_data_valid(mtk_dp, 1, 0x1e, (buf[3] >> 27) & 0x1f, 0xf); - cal_data->clktx_impse = - check_cal_data_valid(mtk_dp, 1, 0xe, (buf[0] >> 9) & 0xf, 0x8); - cal_data->ln_tx_impsel_pmos[0] = - check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 28) & 0xf, 0x8); - cal_data->ln_tx_impsel_nmos[0] = - check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 24) & 0xf, 0x8); - cal_data->ln_tx_impsel_pmos[1] = - check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 20) & 0xf, 0x8); - cal_data->ln_tx_impsel_nmos[1] = - check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 16) & 0xf, 0x8); - cal_data->ln_tx_impsel_pmos[2] = - check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 12) & 0xf, 0x8); - cal_data->ln_tx_impsel_nmos[2] = - check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 8) & 0xf, 0x8); - cal_data->ln_tx_impsel_pmos[3] = - check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 4) & 0xf, 0x8); - cal_data->ln_tx_impsel_nmos[3] = - check_cal_data_valid(mtk_dp, 1, 0xe, buf[2] & 0xf, 0x8); + if (mtk_dp_is_edp(mtk_dp)) { + cal_data->glb_bias_trim = + check_cal_data_valid(mtk_dp, 1, 0x1e, (buf[3] >> 27) & 0x1f, 0xf); + cal_data->clktx_impse = + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[0] >> 9) & 0xf, 0x8); + cal_data->ln_tx_impsel_pmos[0] = + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 28) & 0xf, 0x8); + cal_data->ln_tx_impsel_nmos[0] = + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 24) & 0xf, 0x8); + cal_data->ln_tx_impsel_pmos[1] = + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 20) & 0xf, 0x8); + cal_data->ln_tx_impsel_nmos[1] = + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 16) & 0xf, 0x8); + cal_data->ln_tx_impsel_pmos[2] = + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 12) & 0xf, 0x8); + cal_data->ln_tx_impsel_nmos[2] = + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 8) & 0xf, 0x8); + cal_data->ln_tx_impsel_pmos[3] = + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 4) & 0xf, 0x8); + cal_data->ln_tx_impsel_nmos[3] = + check_cal_data_valid(mtk_dp, 1, 0xe, buf[2] & 0xf, 0x8); + } else { + cal_data->glb_bias_trim = + check_cal_data_valid(mtk_dp, 1, 0x1e, (buf[0] >> 27) & 0x1f, 0xf); + cal_data->clktx_impse = + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[0] >> 13) & 0xf, 0x8); + cal_data->ln_tx_impsel_pmos[0] = + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 28) & 0xf, 0x8); + cal_data->ln_tx_impsel_nmos[0] = + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 24) & 0xf, 0x8); + cal_data->ln_tx_impsel_pmos[1] = + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 20) & 0xf, 0x8); + cal_data->ln_tx_impsel_nmos[1] = + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 16) & 0xf, 0x8); + cal_data->ln_tx_impsel_pmos[2] = + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 12) & 0xf, 0x8); + cal_data->ln_tx_impsel_nmos[2] = + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 8) & 0xf, 0x8); + cal_data->ln_tx_impsel_pmos[3] = + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 4) & 0xf, 0x8); + cal_data->ln_tx_impsel_nmos[3] = + check_cal_data_valid(mtk_dp, 1, 0xe, buf[1] & 0xf, 0x8); + } kfree(buf); @@ -1224,7 +1252,10 @@ static void mtk_dp_video_mute(
[PATCH v10 18/21] drm/mediatek: Add mt8195 Embedded DisplayPort driver
From: Markus Schneider-Pargmann This patch adds a DisplayPort driver for the Mediatek mt8195 SoC. It supports the mt8195, the embedded DisplayPort units. It offers DisplayPort 1.4 with up to 4 lanes. The driver creates a child device for the phy. The child device will never exist without the parent being active. As they are sharing a register range, the parent passes a regmap pointer to the child so that both can work with the same register range. The phy driver sets device data that is read by the parent to get the phy device that can be used to control the phy properties. This driver is based on an initial version by Jason-JH.Lin . Signed-off-by: Markus Schneider-Pargmann Signed-off-by: Guillaume Ranquet --- drivers/gpu/drm/mediatek/Kconfig |8 + drivers/gpu/drm/mediatek/Makefile |2 + drivers/gpu/drm/mediatek/mtk_dp.c | 2570 drivers/gpu/drm/mediatek/mtk_dp_reg.h | 570 ++ drivers/gpu/drm/mediatek/mtk_drm_drv.c |3 + drivers/gpu/drm/mediatek/mtk_drm_drv.h |3 + 6 files changed, 3156 insertions(+) create mode 100644 drivers/gpu/drm/mediatek/mtk_dp.c create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_reg.h diff --git a/drivers/gpu/drm/mediatek/Kconfig b/drivers/gpu/drm/mediatek/Kconfig index 2976d21e9a34..a37b6ec9f01e 100644 --- a/drivers/gpu/drm/mediatek/Kconfig +++ b/drivers/gpu/drm/mediatek/Kconfig @@ -21,6 +21,14 @@ config DRM_MEDIATEK This driver provides kernel mode setting and buffer management to userspace. +config DRM_MEDIATEK_DP + tristate "DRM DPTX Support for Mediatek SoCs" + depends on DRM_MEDIATEK + select PHY_MTK_DP + select DRM_DP_HELPER + help + DRM/KMS Display Port driver for Mediatek SoCs. + config DRM_MEDIATEK_HDMI tristate "DRM HDMI Support for Mediatek SoCs" depends on DRM_MEDIATEK diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile index 3abd27d7c91d..d4d193f60271 100644 --- a/drivers/gpu/drm/mediatek/Makefile +++ b/drivers/gpu/drm/mediatek/Makefile @@ -25,3 +25,5 @@ mediatek-drm-hdmi-objs := mtk_cec.o \ mtk_hdmi_ddc.o obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o + +obj-$(CONFIG_DRM_MEDIATEK_DP) += mtk_dp.o diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c new file mode 100644 index ..8eb17ae82bfd --- /dev/null +++ b/drivers/gpu/drm/mediatek/mtk_dp.c @@ -0,0 +-2,2567 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + * Copyright (c) 2022 BayLibre + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mtk_dp_reg.h" + +#define MTK_VDOSYS1_MAX_FRAMERATE 60 +#define MTK_DP_4P1T 4 +#define MTK_DP_HDE 2 +#define MTK_DP_PIX_PER_ADDR 2 +#define MTK_DP_AUX_WAIT_REPLY_COUNT 20 +#define MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT 3 + +#define MTK_DP_TBC_BUF_READ_START_ADDR 0x08 + +#define MTK_DP_TRAIN_RETRY_LIMIT 8 +#define MTK_DP_TRAIN_MAX_ITERATIONS 5 + +#define MTK_DP_AUX_WRITE_READ_WAIT_TIME_US 20 + +#define MTK_DP_DP_VERSION_11 0x11 + +enum mtk_dp_state { + MTK_DP_STATE_INITIAL, + MTK_DP_STATE_IDLE, + MTK_DP_STATE_PREPARE, + MTK_DP_STATE_NORMAL, +}; + +enum mtk_dp_train_state { + MTK_DP_TRAIN_STATE_STARTUP = 0, + MTK_DP_TRAIN_STATE_CHECKCAP, + MTK_DP_TRAIN_STATE_CHECKEDID, + MTK_DP_TRAIN_STATE_TRAINING_PRE, + MTK_DP_TRAIN_STATE_TRAINING, + MTK_DP_TRAIN_STATE_NORMAL, + MTK_DP_TRAIN_STATE_DPIDLE, +}; + +struct mtk_dp_timings { + struct videomode vm; + + u8 frame_rate; + u32 pix_rate_khz; +}; + +struct mtk_dp_train_info { + bool tps3; + bool tps4; + bool sink_ssc; + bool cable_plugged_in; + bool cable_state_change; + bool cr_done; + bool eq_done; + + /* link_rate is in multiple of 0.27Gbps */ + int link_rate; + int lane_count; + + u8 irq_status; + int check_cap_count; +}; + +/* Multiple of 0.27Gbps */ +enum mtk_dp_linkrate { + MTK_DP_LINKRATE_RBR = 0x6, + MTK_DP_LINKRATE_HBR = 0xA, + MTK_DP_LINKRATE_HBR2 = 0x14, + MTK_DP_LINKRATE_HBR25 = 0x19, + MTK_DP_LINKRATE_HBR3 = 0x1E, +}; + +//TODO: redundant with DP_MSA_MISC_*_BPC ? +/* Same values as used for DP Spec MISC0 bits 5,6,7 */ +enum mtk_dp_color_depth { + MTK_DP_COLOR_DEPTH_6BIT = 0, + MTK_DP_COLOR_DEPTH_8BIT = 1, + MTK_DP_COLOR_DEPTH_10BIT = 2, + MTK_DP_COLOR_DEPTH_12BIT = 3, + MTK_DP_COLOR_DEPTH_16BIT = 4, + MTK_DP_COLOR_DEPTH_UNKNOWN = 5, +}; + +struct mtk_dp_info { + enum mtk_dp_color_depth depth; + enum dp_pixelformat format; + struct mtk_dp_timings timings; +}; + +struct dp_cal_data { +
[PATCH v10 17/21] phy: phy-mtk-dp: Add driver for DP phy
From: Markus Schneider-Pargmann This is a new driver that supports the integrated DisplayPort phy for mediatek SoCs, especially the mt8195. The phy is integrated into the DisplayPort controller and will be created by the mtk-dp driver. This driver expects a struct regmap to be able to work on the same registers as the DisplayPort controller. It sets the device data to be the struct phy so that the DisplayPort controller can easily work with it. The driver does not have any devicetree bindings because the datasheet does not list the controller and the phy as distinct units. The interaction with the controller can be covered by the configure callback of the phy framework and its displayport parameters. Signed-off-by: Markus Schneider-Pargmann Signed-off-by: Guillaume Ranquet --- MAINTAINERS | 1 + drivers/phy/mediatek/Kconfig | 8 ++ drivers/phy/mediatek/Makefile | 1 + drivers/phy/mediatek/phy-mtk-dp.c | 200 ++ 4 files changed, 210 insertions(+) create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c diff --git a/MAINTAINERS b/MAINTAINERS index 4cc47b2dbdc9..bfca96469d80 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6604,6 +6604,7 @@ L:linux-media...@lists.infradead.org (moderated for non-subscribers) S: Supported F: Documentation/devicetree/bindings/display/mediatek/ F: drivers/gpu/drm/mediatek/ +F: drivers/phy/mediatek/phy-mtk-dp.c F: drivers/phy/mediatek/phy-mtk-hdmi* F: drivers/phy/mediatek/phy-mtk-mipi* diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig index 55f8e6c048ab..f7ec86059049 100644 --- a/drivers/phy/mediatek/Kconfig +++ b/drivers/phy/mediatek/Kconfig @@ -55,3 +55,11 @@ config PHY_MTK_MIPI_DSI select GENERIC_PHY help Support MIPI DSI for Mediatek SoCs. + +config PHY_MTK_DP + tristate "MediaTek DP-PHY Driver" + depends on ARCH_MEDIATEK || COMPILE_TEST + depends on OF + select GENERIC_PHY + help + Support DisplayPort PHY for Mediatek SoCs. diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile index ace660fbed3a..4ba1e0650434 100644 --- a/drivers/phy/mediatek/Makefile +++ b/drivers/phy/mediatek/Makefile @@ -3,6 +3,7 @@ # Makefile for the phy drivers. # +obj-$(CONFIG_PHY_MTK_DP) += phy-mtk-dp.o obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o obj-$(CONFIG_PHY_MTK_UFS) += phy-mtk-ufs.o obj-$(CONFIG_PHY_MTK_XSPHY)+= phy-mtk-xsphy.o diff --git a/drivers/phy/mediatek/phy-mtk-dp.c b/drivers/phy/mediatek/phy-mtk-dp.c new file mode 100644 index ..6f29854f0c2f --- /dev/null +++ b/drivers/phy/mediatek/phy-mtk-dp.c @@ -0,0 +1,200 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MediaTek DisplayPort PHY driver + * + * Copyright (c) 2021 BayLibre + * Author: Markus Schneider-Pargmann + */ + +#include +#include +#include +#include +#include +#include +#include + +#define PHY_OFFSET 0x1000 + +#define MTK_DP_PHY_DIG_PLL_CTL_1 (PHY_OFFSET + 0x14) +#define TPLL_SSC_ENBIT(3) + +#define MTK_DP_PHY_DIG_BIT_RATE(PHY_OFFSET + 0x3C) +#define BIT_RATE_RBR 0 +#define BIT_RATE_HBR 1 +#define BIT_RATE_HBR2 2 +#define BIT_RATE_HBR3 3 + +#define MTK_DP_PHY_DIG_SW_RST (PHY_OFFSET + 0x38) +#define DP_GLB_SW_RST_PHYD BIT(0) + +#define MTK_DP_LANE0_DRIVING_PARAM_3 (PHY_OFFSET + 0x138) +#define MTK_DP_LANE1_DRIVING_PARAM_3 (PHY_OFFSET + 0x238) +#define MTK_DP_LANE2_DRIVING_PARAM_3 (PHY_OFFSET + 0x338) +#define MTK_DP_LANE3_DRIVING_PARAM_3 (PHY_OFFSET + 0x438) +#define XTP_LN_TX_LCTXC0_SW0_PRE0_DEFAULT BIT(4) +#define XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT ((BIT(2) | BIT(4)) << 8) +#define XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT GENMASK(20, 19) +#define XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT GENMASK(29, 29) +#define DRIVING_PARAM_3_DEFAULT (XTP_LN_TX_LCTXC0_SW0_PRE0_DEFAULT | \ + XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT | \ + XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT | \ + XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT) + +#define XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT GENMASK(4, 3) +#define XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT GENMASK(12, 9) +#define XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT ((BIT(2) | BIT(5)) << 16) +#define XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT GENMASK(29, 29) +#define DRIVING_PARAM_4_DEFAULT (XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT | \ + XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT | \ + XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT | \ +
[PATCH v10 16/21] drm/meditek: dpi: Add matrix_sel helper
Add a mtk_dpi_matrix_sel() helper to update the DPI_MATRIX_SET register depending on the color format. Signed-off-by: Guillaume Ranquet --- drivers/gpu/drm/mediatek/mtk_dpi.c | 21 + drivers/gpu/drm/mediatek/mtk_dpi_regs.h | 3 +++ 2 files changed, 24 insertions(+) diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index a6b6d62a17e7..5b88a7ed5845 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -386,6 +386,25 @@ static void mtk_dpi_config_disable_edge(struct mtk_dpi *dpi) mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, 0, EDGE_SEL_EN); } +static void mtk_dpi_matrix_sel(struct mtk_dpi *dpi, enum mtk_dpi_out_color_format format) +{ + u32 matrix_sel = 0; + + switch (format) { + case MTK_DPI_COLOR_FORMAT_YCBCR_422: + case MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL: + case MTK_DPI_COLOR_FORMAT_YCBCR_444: + case MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL: + case MTK_DPI_COLOR_FORMAT_XV_YCC: + if (dpi->mode.hdisplay <= 720) + matrix_sel = 0x2; + break; + default: + break; + } + mtk_dpi_mask(dpi, DPI_MATRIX_SET, matrix_sel, INT_MATRIX_SEL_MASK); +} + static void mtk_dpi_config_color_format(struct mtk_dpi *dpi, enum mtk_dpi_out_color_format format) { @@ -393,6 +412,7 @@ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi, (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) { mtk_dpi_config_yuv422_enable(dpi, false); mtk_dpi_config_csc_enable(dpi, true); + mtk_dpi_matrix_sel(dpi, format); if (dpi->conf->swap_input_support) mtk_dpi_config_swap_input(dpi, false); mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_BGR); @@ -400,6 +420,7 @@ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi, (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) { mtk_dpi_config_yuv422_enable(dpi, true); mtk_dpi_config_csc_enable(dpi, true); + mtk_dpi_matrix_sel(dpi, format); if (dpi->conf->swap_input_support) mtk_dpi_config_swap_input(dpi, true); mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB); diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h index dd47dd3f2e4f..91b32dfffced 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h +++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h @@ -231,6 +231,9 @@ #define EDGE_SEL_ENBIT(5) #define H_FRE_2N BIT(25) +#define DPI_MATRIX_SET 0xB4 +#define INT_MATRIX_SEL BIT(0) +#define INT_MATRIX_SEL_MASK(0x1F << 0) #define RGB_TO_JPEG0x00 #define RGB_TO_FULL709 0x01 #define RGB_TO_BT601 0x02 -- 2.35.1
[PATCH v10 15/21] drm/mediatek: dpi: Only enable dpi after the bridge is enabled
Enabling the dpi too early causes glitches on screen. Move the call to mtk_dpi_enable() at the end of the bridge_enable callback to ensure everything is setup properly before enabling dpi. Signed-off-by: Guillaume Ranquet --- drivers/gpu/drm/mediatek/mtk_dpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index 763bfb700135..a6b6d62a17e7 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -478,7 +478,6 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi) if (dpi->pinctrl && dpi->pins_dpi) pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi); - mtk_dpi_enable(dpi); return 0; err_pixel: @@ -711,6 +710,7 @@ static void mtk_dpi_bridge_enable(struct drm_bridge *bridge) mtk_dpi_power_on(dpi); mtk_dpi_set_display_mode(dpi, &dpi->mode); + mtk_dpi_enable(dpi); } static enum drm_mode_status -- 2.35.1
[PATCH v10 14/21] drm/mediatek: dpi: Add dpintf support
dpintf is the displayport interface hardware unit. This unit is similar to dpi and can reuse most of the code. This patch adds support for mt8195-dpintf to this dpi driver. Main differences are: - Some features/functional components are not available for dpintf which are now excluded from code execution once is_dpintf is set - dpintf can and needs to choose between different clockdividers based on the clockspeed. This is done by choosing a different clock parent. - There are two additional clocks that need to be managed. These are only set for dpintf and will be set to NULL if not supplied. The clk_* calls handle these as normal clocks then. - Some register contents differ slightly between the two components. To work around this I added register bits/masks with a DPINTF_ prefix and use them where different. Based on a separate driver for dpintf created by Jason-JH.Lin . Signed-off-by: Markus Schneider-Pargmann Signed-off-by: Guillaume Ranquet --- drivers/gpu/drm/mediatek/mtk_dpi.c | 126 +--- drivers/gpu/drm/mediatek/mtk_dpi_regs.h | 35 ++ drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 8 ++ drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 1 + drivers/gpu/drm/mediatek/mtk_drm_drv.c | 5 +- include/linux/soc/mediatek/mtk-mmsys.h | 4 +- 6 files changed, 159 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index eb969c5c5c2e..763bfb700135 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -71,6 +71,7 @@ struct mtk_dpi { void __iomem *regs; struct device *dev; struct clk *engine_clk; + struct clk *dpi_ck_cg; struct clk *pixel_clk; struct clk *tvd_clk; int irq; @@ -126,6 +127,7 @@ struct mtk_dpi_conf { const u32 *output_fmts; u32 num_output_fmts; bool is_ck_de_pol; + bool is_dpintf; bool swap_input_support; /* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift) */ u32 dimension_mask; @@ -438,6 +440,8 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi) mtk_dpi_disable(dpi); clk_disable_unprepare(dpi->pixel_clk); clk_disable_unprepare(dpi->engine_clk); + clk_disable_unprepare(dpi->dpi_ck_cg); + clk_disable_unprepare(dpi->tvd_clk); } static int mtk_dpi_power_on(struct mtk_dpi *dpi) @@ -447,12 +451,24 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi) if (++dpi->refcount != 1) return 0; + ret = clk_prepare_enable(dpi->tvd_clk); + if (ret) { + dev_err(dpi->dev, "Failed to enable tvd pll: %d\n", ret); + goto err_pixel; + } + ret = clk_prepare_enable(dpi->engine_clk); if (ret) { dev_err(dpi->dev, "Failed to enable engine clock: %d\n", ret); goto err_refcount; } + ret = clk_prepare_enable(dpi->dpi_ck_cg); + if (ret) { + dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock: %d\n", ret); + goto err_ck_cg; + } + ret = clk_prepare_enable(dpi->pixel_clk); if (ret) { dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret); @@ -466,6 +482,8 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi) return 0; err_pixel: + clk_disable_unprepare(dpi->dpi_ck_cg); +err_ck_cg: clk_disable_unprepare(dpi->engine_clk); err_refcount: dpi->refcount--; @@ -498,11 +516,11 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi, vm.pixelclock = pll_rate / factor; if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) || - (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE)) +(dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE)) { clk_set_rate(dpi->pixel_clk, vm.pixelclock * 2); - else + } else { clk_set_rate(dpi->pixel_clk, vm.pixelclock); - + } vm.pixelclock = clk_get_rate(dpi->pixel_clk); @@ -515,9 +533,15 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi, MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING; dpi_pol.vsync_pol = vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ? MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING; - hsync.sync_width = vm.hsync_len; - hsync.back_porch = vm.hback_porch; - hsync.front_porch = vm.hfront_porch; + if (dpi->conf->is_dpintf) { + hsync.sync_width = vm.hsync_len / 4; + hsync.back_porch = vm.hback_porch / 4; + hsync.front_porch = vm.hfront_porch / 4; + } else { + hsync.sync_width = vm.hsync_len; + hsync.back_porch = vm.hback_porch; + hsync.front_porch = vm.hfront_porch; + } hsync.shift_half_line = false; vsync_lodd.sync_w
[PATCH v10 13/21] drm/mediatek: dpi: move the csc_enable bit to SoC config
Add flexibility by moving the csc_enable bit to SoC specific config Signed-off-by: Guillaume Ranquet Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Rex-BC Chen --- drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index 40254cd9d168..eb969c5c5c2e 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -133,6 +133,7 @@ struct mtk_dpi_conf { u32 hvsize_mask; u32 channel_swap_shift; u32 yuv422_en_bit; + u32 csc_enable_bit; const struct mtk_dpi_yc_limit *limit; }; @@ -363,7 +364,8 @@ static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable) static void mtk_dpi_config_csc_enable(struct mtk_dpi *dpi, bool enable) { - mtk_dpi_mask(dpi, DPI_CON, enable ? CSC_ENABLE : 0, CSC_ENABLE); + mtk_dpi_mask(dpi, DPI_CON, enable ? dpi->conf->csc_enable_bit : 0, +dpi->conf->csc_enable_bit); } static void mtk_dpi_config_swap_input(struct mtk_dpi *dpi, bool enable) @@ -827,6 +829,7 @@ static const struct mtk_dpi_conf mt8173_conf = { .hvsize_mask = HSIZE_MASK, .channel_swap_shift = CH_SWAP, .yuv422_en_bit = YUV422_EN, + .csc_enable_bit = CSC_ENABLE, .limit = &mtk_dpi_limit, }; @@ -843,6 +846,7 @@ static const struct mtk_dpi_conf mt2701_conf = { .hvsize_mask = HSIZE_MASK, .channel_swap_shift = CH_SWAP, .yuv422_en_bit = YUV422_EN, + .csc_enable_bit = CSC_ENABLE, .limit = &mtk_dpi_limit, }; @@ -858,6 +862,7 @@ static const struct mtk_dpi_conf mt8183_conf = { .hvsize_mask = HSIZE_MASK, .channel_swap_shift = CH_SWAP, .yuv422_en_bit = YUV422_EN, + .csc_enable_bit = CSC_ENABLE, .limit = &mtk_dpi_limit, }; @@ -873,6 +878,7 @@ static const struct mtk_dpi_conf mt8192_conf = { .hvsize_mask = HSIZE_MASK, .channel_swap_shift = CH_SWAP, .yuv422_en_bit = YUV422_EN, + .csc_enable_bit = CSC_ENABLE, .limit = &mtk_dpi_limit, }; -- 2.35.1
[PATCH v10 12/21] drm/mediatek: dpi: move the yuv422_en_bit to SoC config
Add flexibility by moving the yuv422 en bit to SoC specific config Signed-off-by: Guillaume Ranquet Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Rex-BC Chen --- drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index 6d4d8c6ec47d..40254cd9d168 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -132,6 +132,7 @@ struct mtk_dpi_conf { /* HSIZE and VSIZE mask (no shift) */ u32 hvsize_mask; u32 channel_swap_shift; + u32 yuv422_en_bit; const struct mtk_dpi_yc_limit *limit; }; @@ -356,7 +357,8 @@ static void mtk_dpi_config_channel_swap(struct mtk_dpi *dpi, static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable) { - mtk_dpi_mask(dpi, DPI_CON, enable ? YUV422_EN : 0, YUV422_EN); + mtk_dpi_mask(dpi, DPI_CON, enable ? dpi->conf->yuv422_en_bit : 0, +dpi->conf->yuv422_en_bit); } static void mtk_dpi_config_csc_enable(struct mtk_dpi *dpi, bool enable) @@ -824,6 +826,7 @@ static const struct mtk_dpi_conf mt8173_conf = { .dimension_mask = HPW_MASK, .hvsize_mask = HSIZE_MASK, .channel_swap_shift = CH_SWAP, + .yuv422_en_bit = YUV422_EN, .limit = &mtk_dpi_limit, }; @@ -839,6 +842,7 @@ static const struct mtk_dpi_conf mt2701_conf = { .dimension_mask = HPW_MASK, .hvsize_mask = HSIZE_MASK, .channel_swap_shift = CH_SWAP, + .yuv422_en_bit = YUV422_EN, .limit = &mtk_dpi_limit, }; @@ -853,6 +857,7 @@ static const struct mtk_dpi_conf mt8183_conf = { .dimension_mask = HPW_MASK, .hvsize_mask = HSIZE_MASK, .channel_swap_shift = CH_SWAP, + .yuv422_en_bit = YUV422_EN, .limit = &mtk_dpi_limit, }; @@ -867,6 +872,7 @@ static const struct mtk_dpi_conf mt8192_conf = { .dimension_mask = HPW_MASK, .hvsize_mask = HSIZE_MASK, .channel_swap_shift = CH_SWAP, + .yuv422_en_bit = YUV422_EN, .limit = &mtk_dpi_limit, }; -- 2.35.1
[PATCH v10 11/21] drm/mediatek: dpi: move swap_shift to SoC config
Add flexibility by moving the swap shift value to SoC specific config Signed-off-by: Guillaume Ranquet Reviewed-by: Rex-BC Chen Reviewed-by: AngeloGioacchino Del Regno --- drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index 6eeda222a973..6d4d8c6ec47d 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -131,6 +131,7 @@ struct mtk_dpi_conf { u32 dimension_mask; /* HSIZE and VSIZE mask (no shift) */ u32 hvsize_mask; + u32 channel_swap_shift; const struct mtk_dpi_yc_limit *limit; }; @@ -349,7 +350,8 @@ static void mtk_dpi_config_channel_swap(struct mtk_dpi *dpi, break; } - mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP, CH_SWAP_MASK); + mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << dpi->conf->channel_swap_shift, +CH_SWAP_MASK); } static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable) @@ -821,6 +823,7 @@ static const struct mtk_dpi_conf mt8173_conf = { .swap_input_support = true, .dimension_mask = HPW_MASK, .hvsize_mask = HSIZE_MASK, + .channel_swap_shift = CH_SWAP, .limit = &mtk_dpi_limit, }; @@ -835,6 +838,7 @@ static const struct mtk_dpi_conf mt2701_conf = { .swap_input_support = true, .dimension_mask = HPW_MASK, .hvsize_mask = HSIZE_MASK, + .channel_swap_shift = CH_SWAP, .limit = &mtk_dpi_limit, }; @@ -848,6 +852,7 @@ static const struct mtk_dpi_conf mt8183_conf = { .swap_input_support = true, .dimension_mask = HPW_MASK, .hvsize_mask = HSIZE_MASK, + .channel_swap_shift = CH_SWAP, .limit = &mtk_dpi_limit, }; @@ -861,6 +866,7 @@ static const struct mtk_dpi_conf mt8192_conf = { .swap_input_support = true, .dimension_mask = HPW_MASK, .hvsize_mask = HSIZE_MASK, + .channel_swap_shift = CH_SWAP, .limit = &mtk_dpi_limit, }; -- 2.35.1
[PATCH v10 10/21] drm/mediatek: dpi: move hvsize_mask to SoC config
Add flexibility by moving the hvsize mask to SoC specific config Signed-off-by: Guillaume Ranquet Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Rex-BC Chen --- drivers/gpu/drm/mediatek/mtk_dpi.c | 12 ++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index bf098f36a466..6eeda222a973 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -129,6 +129,8 @@ struct mtk_dpi_conf { bool swap_input_support; /* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift) */ u32 dimension_mask; + /* HSIZE and VSIZE mask (no shift) */ + u32 hvsize_mask; const struct mtk_dpi_yc_limit *limit; }; @@ -243,8 +245,10 @@ static void mtk_dpi_config_interface(struct mtk_dpi *dpi, bool inter) static void mtk_dpi_config_fb_size(struct mtk_dpi *dpi, u32 width, u32 height) { - mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE, HSIZE_MASK); - mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, VSIZE_MASK); + mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE, +dpi->conf->hvsize_mask << HSIZE); + mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, +dpi->conf->hvsize_mask << VSIZE); } static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi) @@ -816,6 +820,7 @@ static const struct mtk_dpi_conf mt8173_conf = { .is_ck_de_pol = true, .swap_input_support = true, .dimension_mask = HPW_MASK, + .hvsize_mask = HSIZE_MASK, .limit = &mtk_dpi_limit, }; @@ -829,6 +834,7 @@ static const struct mtk_dpi_conf mt2701_conf = { .is_ck_de_pol = true, .swap_input_support = true, .dimension_mask = HPW_MASK, + .hvsize_mask = HSIZE_MASK, .limit = &mtk_dpi_limit, }; @@ -841,6 +847,7 @@ static const struct mtk_dpi_conf mt8183_conf = { .is_ck_de_pol = true, .swap_input_support = true, .dimension_mask = HPW_MASK, + .hvsize_mask = HSIZE_MASK, .limit = &mtk_dpi_limit, }; @@ -853,6 +860,7 @@ static const struct mtk_dpi_conf mt8192_conf = { .is_ck_de_pol = true, .swap_input_support = true, .dimension_mask = HPW_MASK, + .hvsize_mask = HSIZE_MASK, .limit = &mtk_dpi_limit, }; -- 2.35.1
[PATCH v10 09/21] drm/mediatek: dpi: move dimension mask to SoC config
Add flexibility by moving the dimension mask to the SoC config Signed-off-by: Guillaume Ranquet Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Rex-BC Chen --- drivers/gpu/drm/mediatek/mtk_dpi.c | 26 -- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index 454f8563efae..bf098f36a466 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -127,6 +127,8 @@ struct mtk_dpi_conf { u32 num_output_fmts; bool is_ck_de_pol; bool swap_input_support; + /* Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift) */ + u32 dimension_mask; const struct mtk_dpi_yc_limit *limit; }; @@ -156,30 +158,30 @@ static void mtk_dpi_disable(struct mtk_dpi *dpi) static void mtk_dpi_config_hsync(struct mtk_dpi *dpi, struct mtk_dpi_sync_param *sync) { - mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH, -sync->sync_width << HPW, HPW_MASK); - mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, -sync->back_porch << HBP, HBP_MASK); + mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH, sync->sync_width << HPW, +dpi->conf->dimension_mask << HPW); + mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->back_porch << HBP, +dpi->conf->dimension_mask << HBP); mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP, -HFP_MASK); +dpi->conf->dimension_mask << HFP); } static void mtk_dpi_config_vsync(struct mtk_dpi *dpi, struct mtk_dpi_sync_param *sync, u32 width_addr, u32 porch_addr) { - mtk_dpi_mask(dpi, width_addr, -sync->sync_width << VSYNC_WIDTH_SHIFT, -VSYNC_WIDTH_MASK); mtk_dpi_mask(dpi, width_addr, sync->shift_half_line << VSYNC_HALF_LINE_SHIFT, VSYNC_HALF_LINE_MASK); + mtk_dpi_mask(dpi, width_addr, +sync->sync_width << VSYNC_WIDTH_SHIFT, +dpi->conf->dimension_mask << VSYNC_WIDTH_SHIFT); mtk_dpi_mask(dpi, porch_addr, sync->back_porch << VSYNC_BACK_PORCH_SHIFT, -VSYNC_BACK_PORCH_MASK); +dpi->conf->dimension_mask << VSYNC_BACK_PORCH_SHIFT); mtk_dpi_mask(dpi, porch_addr, sync->front_porch << VSYNC_FRONT_PORCH_SHIFT, -VSYNC_FRONT_PORCH_MASK); +dpi->conf->dimension_mask << VSYNC_FRONT_PORCH_SHIFT); } static void mtk_dpi_config_vsync_lodd(struct mtk_dpi *dpi, @@ -813,6 +815,7 @@ static const struct mtk_dpi_conf mt8173_conf = { .num_output_fmts = ARRAY_SIZE(mt8173_output_fmts), .is_ck_de_pol = true, .swap_input_support = true, + .dimension_mask = HPW_MASK, .limit = &mtk_dpi_limit, }; @@ -825,6 +828,7 @@ static const struct mtk_dpi_conf mt2701_conf = { .num_output_fmts = ARRAY_SIZE(mt8173_output_fmts), .is_ck_de_pol = true, .swap_input_support = true, + .dimension_mask = HPW_MASK, .limit = &mtk_dpi_limit, }; @@ -836,6 +840,7 @@ static const struct mtk_dpi_conf mt8183_conf = { .num_output_fmts = ARRAY_SIZE(mt8183_output_fmts), .is_ck_de_pol = true, .swap_input_support = true, + .dimension_mask = HPW_MASK, .limit = &mtk_dpi_limit, }; @@ -847,6 +852,7 @@ static const struct mtk_dpi_conf mt8192_conf = { .num_output_fmts = ARRAY_SIZE(mt8173_output_fmts), .is_ck_de_pol = true, .swap_input_support = true, + .dimension_mask = HPW_MASK, .limit = &mtk_dpi_limit, }; -- 2.35.1
[PATCH v10 08/21] drm/mediatek: dpi: implement a swap_input toggle in SoC config
Adds a bit of flexibility to support SoCs without swap_input support Signed-off-by: Guillaume Ranquet Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Rex-BC Chen --- drivers/gpu/drm/mediatek/mtk_dpi.c | 14 +++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index 545a1337cc89..454f8563efae 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -126,6 +126,7 @@ struct mtk_dpi_conf { const u32 *output_fmts; u32 num_output_fmts; bool is_ck_de_pol; + bool swap_input_support; const struct mtk_dpi_yc_limit *limit; }; @@ -378,18 +379,21 @@ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi, (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) { mtk_dpi_config_yuv422_enable(dpi, false); mtk_dpi_config_csc_enable(dpi, true); - mtk_dpi_config_swap_input(dpi, false); + if (dpi->conf->swap_input_support) + mtk_dpi_config_swap_input(dpi, false); mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_BGR); } else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) || (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) { mtk_dpi_config_yuv422_enable(dpi, true); mtk_dpi_config_csc_enable(dpi, true); - mtk_dpi_config_swap_input(dpi, true); + if (dpi->conf->swap_input_support) + mtk_dpi_config_swap_input(dpi, true); mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB); } else { mtk_dpi_config_yuv422_enable(dpi, false); mtk_dpi_config_csc_enable(dpi, false); - mtk_dpi_config_swap_input(dpi, false); + if (dpi->conf->swap_input_support) + mtk_dpi_config_swap_input(dpi, false); mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB); } } @@ -808,6 +812,7 @@ static const struct mtk_dpi_conf mt8173_conf = { .output_fmts = mt8173_output_fmts, .num_output_fmts = ARRAY_SIZE(mt8173_output_fmts), .is_ck_de_pol = true, + .swap_input_support = true, .limit = &mtk_dpi_limit, }; @@ -819,6 +824,7 @@ static const struct mtk_dpi_conf mt2701_conf = { .output_fmts = mt8173_output_fmts, .num_output_fmts = ARRAY_SIZE(mt8173_output_fmts), .is_ck_de_pol = true, + .swap_input_support = true, .limit = &mtk_dpi_limit, }; @@ -829,6 +835,7 @@ static const struct mtk_dpi_conf mt8183_conf = { .output_fmts = mt8183_output_fmts, .num_output_fmts = ARRAY_SIZE(mt8183_output_fmts), .is_ck_de_pol = true, + .swap_input_support = true, .limit = &mtk_dpi_limit, }; @@ -839,6 +846,7 @@ static const struct mtk_dpi_conf mt8192_conf = { .output_fmts = mt8173_output_fmts, .num_output_fmts = ARRAY_SIZE(mt8173_output_fmts), .is_ck_de_pol = true, + .swap_input_support = true, .limit = &mtk_dpi_limit, }; -- 2.35.1