[PATCH v3 37/65] drm/tegra: sor: Add a determine_rate hook
The Tegra sor pad clock implements a mux with a set_parent hook, but doesn't provide a determine_rate implementation. This is a bit odd, since set_parent() is there to, as its name implies, change the parent of a clock. However, the most likely candidate to trigger that parent change is a call to clk_set_rate(), with determine_rate() figuring out which parent is the best suited for a given rate. The other trigger would be a call to clk_set_parent(), but it's far less used, and it doesn't look like there's any obvious user for that clock. So, the set_parent hook is effectively unused, possibly because of an oversight. However, it could also be an explicit decision by the original author to avoid any reparenting but through an explicit call to clk_set_parent(). The latter case would be equivalent to setting the flag CLK_SET_RATE_NO_REPARENT, together with setting our determine_rate hook to __clk_mux_determine_rate(). Indeed, if no determine_rate implementation is provided, clk_round_rate() (through clk_core_round_rate_nolock()) will call itself on the parent if CLK_SET_RATE_PARENT is set, and will not change the clock rate otherwise. __clk_mux_determine_rate() has the exact same behavior when CLK_SET_RATE_NO_REPARENT is set. And if it was an oversight, then we are at least explicit about our behavior now and it can be further refined down the line. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/tegra/sor.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c index 8af632740673..92084a9a67c5 100644 --- a/drivers/gpu/drm/tegra/sor.c +++ b/drivers/gpu/drm/tegra/sor.c @@ -586,6 +586,7 @@ static u8 tegra_clk_sor_pad_get_parent(struct clk_hw *hw) } static const struct clk_ops tegra_clk_sor_pad_ops = { + .determine_rate = __clk_mux_determine_rate, .set_parent = tegra_clk_sor_pad_set_parent, .get_parent = tegra_clk_sor_pad_get_parent, }; @@ -604,7 +605,7 @@ static struct clk *tegra_clk_sor_pad_register(struct tegra_sor *sor, pad->sor = sor; init.name = name; - init.flags = 0; + init.flags = CLK_SET_RATE_NO_REPARENT; init.parent_names = tegra_clk_sor_pad_parents[sor->index]; init.num_parents = ARRAY_SIZE(tegra_clk_sor_pad_parents[sor->index]); init.ops = &tegra_clk_sor_pad_ops; -- 2.39.2
[PATCH v3 26/65] clk: mediatek: cpumux: Add a determine_rate hook
The Mediatek cpumux clock implements a mux with a set_parent hook, but doesn't provide a determine_rate implementation. This is a bit odd, since set_parent() is there to, as its name implies, change the parent of a clock. However, the most likely candidate to trigger that parent change is a call to clk_set_rate(), with determine_rate() figuring out which parent is the best suited for a given rate. The other trigger would be a call to clk_set_parent(), but it's far less used, and it doesn't look like there's any obvious user for that clock. So, the set_parent hook is effectively unused, possibly because of an oversight. However, it could also be an explicit decision by the original author to avoid any reparenting but through an explicit call to clk_set_parent(). The latter case would be equivalent to setting the flag CLK_SET_RATE_NO_REPARENT, together with setting our determine_rate hook to __clk_mux_determine_rate(). Indeed, if no determine_rate implementation is provided, clk_round_rate() (through clk_core_round_rate_nolock()) will call itself on the parent if CLK_SET_RATE_PARENT is set, and will not change the clock rate otherwise. __clk_mux_determine_rate() has the exact same behavior when CLK_SET_RATE_NO_REPARENT is set. And if it was an oversight, then we are at least explicit about our behavior now and it can be further refined down the line. Signed-off-by: Maxime Ripard --- drivers/clk/mediatek/clk-cpumux.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c index da05f06192c0..dd4eb3f215cc 100644 --- a/drivers/clk/mediatek/clk-cpumux.c +++ b/drivers/clk/mediatek/clk-cpumux.c @@ -53,6 +53,7 @@ static int clk_cpumux_set_parent(struct clk_hw *hw, u8 index) } static const struct clk_ops clk_cpumux_ops = { + .determine_rate = __clk_mux_determine_rate, .get_parent = clk_cpumux_get_parent, .set_parent = clk_cpumux_set_parent, }; @@ -73,7 +74,7 @@ mtk_clk_register_cpumux(struct device *dev, const struct mtk_composite *mux, init.ops = &clk_cpumux_ops; init.parent_names = mux->parent_names; init.num_parents = mux->num_parents; - init.flags = mux->flags; + init.flags = mux->flags | CLK_SET_RATE_NO_REPARENT; cpumux->reg = mux->mux_reg; cpumux->shift = mux->mux_shift; -- 2.39.2
[PATCH v3 38/65] phy: cadence: sierra: Add a determine_rate hook
The Cadence Sierra PLL clock implements a mux with a set_parent hook, but doesn't provide a determine_rate implementation. This is a bit odd, since set_parent() is there to, as its name implies, change the parent of a clock. However, the most likely candidate to trigger that parent change is a call to clk_set_rate(), with determine_rate() figuring out which parent is the best suited for a given rate. The other trigger would be a call to clk_set_parent(), but it's far less used, and it doesn't look like there's any obvious user for that clock. So, the set_parent hook is effectively unused, possibly because of an oversight. However, it could also be an explicit decision by the original author to avoid any reparenting but through an explicit call to clk_set_parent(). The latter case would be equivalent to setting the flag CLK_SET_RATE_NO_REPARENT, together with setting our determine_rate hook to __clk_mux_determine_rate(). Indeed, if no determine_rate implementation is provided, clk_round_rate() (through clk_core_round_rate_nolock()) will call itself on the parent if CLK_SET_RATE_PARENT is set, and will not change the clock rate otherwise. __clk_mux_determine_rate() has the exact same behavior when CLK_SET_RATE_NO_REPARENT is set. And if it was an oversight, then we are at least explicit about our behavior now and it can be further refined down the line. Since the CLK_SET_RATE_NO_REPARENT flag was already set though, it seems unlikely. Signed-off-by: Maxime Ripard --- drivers/phy/cadence/phy-cadence-sierra.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/phy/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c index ab0a37618ef3..19a50247e305 100644 --- a/drivers/phy/cadence/phy-cadence-sierra.c +++ b/drivers/phy/cadence/phy-cadence-sierra.c @@ -716,6 +716,7 @@ static int cdns_sierra_pll_mux_set_parent(struct clk_hw *hw, u8 index) } static const struct clk_ops cdns_sierra_pll_mux_ops = { + .determine_rate = __clk_mux_determine_rate, .set_parent = cdns_sierra_pll_mux_set_parent, .get_parent = cdns_sierra_pll_mux_get_parent, }; -- 2.39.2
Re: [RFC PATCH 08/10] dma-buf/dma-fence: Introduce long-running completion fences
Hi, Christian, On 4/4/23 11:09, Christian König wrote: Am 04.04.23 um 02:22 schrieb Matthew Brost: From: Thomas Hellström For long-running workloads, drivers either need to open-code completion waits, invent their own synchronization primitives or internally use dma-fences that do not obey the cross-driver dma-fence protocol, but without any lockdep annotation all these approaches are error prone. So since for example the drm scheduler uses dma-fences it is desirable for a driver to be able to use it for throttling and error handling also with internal dma-fences tha do not obey the cros-driver dma-fence protocol. Introduce long-running completion fences in form of dma-fences, and add lockdep annotation for them. In particular: * Do not allow waiting under any memory management locks. * Do not allow to attach them to a dma-resv object. * Introduce a new interface for adding callbacks making the helper adding a callback sign off on that it is aware that the dma-fence may not complete anytime soon. Typically this will be the scheduler chaining a new long-running fence on another one. Well that's pretty much what I tried before: https://lwn.net/Articles/893704/ And the reasons why it was rejected haven't changed. Regards, Christian. Yes, TBH this was mostly to get discussion going how we'd best tackle this problem while being able to reuse the scheduler for long-running workloads. I couldn't see any clear decision on your series, though, but one main difference I see is that this is intended for driver-internal use only. (I'm counting using the drm_scheduler as a helper for driver-private use). This is by no means a way to try tackle the indefinite fence problem. We could ofc invent a completely different data-type that abstracts the synchronization the scheduler needs in the long-running case, or each driver could hack something up, like sleeping in the prepare_job() or run_job() callback for throttling, but those waits should still be annotated in one way or annotated one way or another (and probably in a similar way across drivers) to make sure we don't do anything bad. So any suggestions as to what would be the better solution here would be appreciated. Thanks, Thomas
[PATCH v4 00/42] drm/msm/dpu: rework HW catalog
This huge series attempts to restructure the DPU HW catalog into a manageable and reviewable data set. In order to ease review and testing I merged all the necessary fixes into this series. Also I cherry-picked & slightly fixed Konrad's patch adding size to the SSPP and INTF macros. First 6 patches clean up the catalog a bit in order to make it more suitable for refactoring. Second batch of 13 + 5 + 4 patches split the hw catalog entries into per-SoC files. Then the next 6 patches perform a post-split cleanup. They enable missing features, drop obvious duplicates, etc. Then 6 patches rename/inline existing macros to ease using them while adding support for new devices. And last 2 patches migrate HW catalog entries to be tied to the of_device_id rather than using HW revision to obtain one: in the email discussion of the previous revision of the patchset it was revealed that there exist different SoCs with the same DPU hw revision, but different fetures being enabled in the hardware. This pile of patches is submitted in a single batch to allow one to observe the final goal of the cleanup which otherwise might be hard to assess. Changes since v3: - Split the SSPP/INTF size patch into SSPP and INTF parts (Abhinav) - Dropped the deduplication part for now. Replaced that with _duplicating_ the data (Abhinav) - Reworked catalog/kms interface to bind data using device match table Changes since v2: - Fixed sc8280xp SSPP size to 0x2ac - Rebased on top of msm-next-lumag, dropped merged patches Changes since v1: - Picked up Konrad's patch - Picked up dependencies into the main series - Moved qseed3lite vs qseed4 patches into the fixes part - Fixed sm6115 in a similar manner. Dmitry Baryshkov (40): drm/msm/dpu: use CTL_SC7280_MASK for sm8450's ctl_0 drm/msm/dpu: constify DSC data structures drm/msm/dpu: mark remaining pp data as const drm/msm/dpu: move UBWC/memory configuration to separate struct drm/msm/dpu: split SM8550 catalog entry to the separate file drm/msm/dpu: split SM8450 catalog entry to the separate file drm/msm/dpu: split SC8280XP catalog entry to the separate file drm/msm/dpu: split SC7280 catalog entry to the separate file drm/msm/dpu: split SM8350 catalog entry to the separate file drm/msm/dpu: split SM6115 catalog entry to the separate file drm/msm/dpu: split QCM2290 catalog entry to the separate file drm/msm/dpu: split SC7180 catalog entry to the separate file drm/msm/dpu: split SM8250 catalog entry to the separate file drm/msm/dpu: split SC8180X catalog entry to the separate file drm/msm/dpu: split SM8150 catalog entry to the separate file drm/msm/dpu: split MSM8998 catalog entry to the separate file drm/msm/dpu: split SDM845 catalog entry to the separate file drm/msm/dpu: duplicate sdm845 catalog entries drm/msm/dpu: duplicate sc7180 catalog entries drm/msm/dpu: duplicate sm8150 catalog entries drm/msm/dpu: duplicate sm8250 catalog entries drm/msm/dpu: duplicate sm8350 catalog entries drm/msm/dpu: expand sc8180x catalog drm/msm/dpu: expand sc7180 catalog drm/msm/dpu: expand sm6115 catalog drm/msm/dpu: expand sm8550 catalog drm/msm/dpu: use defined symbol for sc8280xp's maxwidth drm/msm/dpu: catalog: add comments regarding DPU_CTL_SPLIT_DISPLAY drm/msm/dpu: enable DPU_CTL_SPLIT_DISPLAY for sc8280xp drm/msm/dpu: enable DSPP_2/3 for LM_2/3 on sm8450 drm/msm/dpu: drop duplicate vig_sblk instances drm/msm/dpu: enable DSPP and DSC on sc8180x drm/msm/dpu: inline IRQ_n_MASK defines drm/msm/dpu: rename INTF_foo_MASK to contain major DPU version drm/msm/dpu: rename CTL_foo_MASK to contain major DPU version drm/msm/dpu: rename VIG and DMA_foo_MASK to contain major DPU version drm/msm/dpu: rename MIXER_foo_MASK to contain major DPU version drm/msm/dpu: rename MERGE_3D_foo_MASK to contain major DPU version drm/msm/dpu: fetch DPU configuration from match data drm/msm/dpu: drop unused macros from hw catalog Konrad Dybcio (2): drm/msm/dpu: Allow variable SSPP_BLK size drm/msm/dpu: Allow variable INTF_BLK size .../msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 210 ++ .../msm/disp/dpu1/catalog/dpu_4_0_sdm845.h| 210 ++ .../msm/disp/dpu1/catalog/dpu_5_0_sm8150.h| 237 ++ .../msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 239 ++ .../msm/disp/dpu1/catalog/dpu_6_0_sm8250.h| 244 ++ .../msm/disp/dpu1/catalog/dpu_6_2_sc7180.h| 156 ++ .../msm/disp/dpu1/catalog/dpu_6_3_sm6115.h| 131 + .../msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 122 + .../msm/disp/dpu1/catalog/dpu_7_0_sm8350.h| 226 ++ .../msm/disp/dpu1/catalog/dpu_7_2_sc7280.h| 158 ++ .../msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 223 ++ .../msm/disp/dpu1/catalog/dpu_8_1_sm8450.h| 234 ++ .../msm/disp/dpu1/catalog/dpu_9_0_sm8550.h| 239 ++ .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 2209 + .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h| 89 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c|4 +- d
[PATCH v4 01/42] drm/msm/dpu: use CTL_SC7280_MASK for sm8450's ctl_0
On sm8450 platform the CTL_0 doesn't differ from the rest of CTL blocks, so switch it to CTL_SC7280_MASK too. Some background: original commit 100d7ef6995d ("drm/msm/dpu: add support for SM8450") had all (relevant at that time) bit spelled individually. Then commit 0e91bcbb0016 ("drm/msm/dpu: Add SM8350 to hw catalog"), despite being a mismerge, correctly changed all other CTL entries to use CTL_SC7280_MASK, except CTL_0. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 6840b22a4159..83f8f83e2b29 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -975,7 +975,7 @@ static const struct dpu_ctl_cfg sm8450_ctl[] = { { .name = "ctl_0", .id = CTL_0, .base = 0x15000, .len = 0x204, - .features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY) | BIT(DPU_CTL_FETCH_ACTIVE), + .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), }, { -- 2.39.2
[PATCH v4 04/42] drm/msm/dpu: constify DSC data structures
DSC hw catalog data is not supposed to be changed, so mark it as const data. Reviewed-by: Konrad Dybcio Reviewed-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 4 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index f4ffd7fc4424..2dbd4783a57b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -1836,14 +1836,14 @@ static const struct dpu_merge_3d_cfg sm8550_merge_3d[] = { .features = _features, \ } -static struct dpu_dsc_cfg sdm845_dsc[] = { +static const struct dpu_dsc_cfg sdm845_dsc[] = { DSC_BLK("dsc_0", DSC_0, 0x8, 0), DSC_BLK("dsc_1", DSC_1, 0x80400, 0), DSC_BLK("dsc_2", DSC_2, 0x80800, 0), DSC_BLK("dsc_3", DSC_3, 0x80c00, 0), }; -static struct dpu_dsc_cfg sm8150_dsc[] = { +static const struct dpu_dsc_cfg sm8150_dsc[] = { DSC_BLK("dsc_0", DSC_0, 0x8, BIT(DPU_DSC_OUTPUT_CTRL)), DSC_BLK("dsc_1", DSC_1, 0x80400, BIT(DPU_DSC_OUTPUT_CTRL)), DSC_BLK("dsc_2", DSC_2, 0x80800, BIT(DPU_DSC_OUTPUT_CTRL)), diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index 2f532543848c..fe360fb7c77b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -872,7 +872,7 @@ struct dpu_mdss_cfg { const struct dpu_merge_3d_cfg *merge_3d; u32 dsc_count; - struct dpu_dsc_cfg *dsc; + const struct dpu_dsc_cfg *dsc; u32 intf_count; const struct dpu_intf_cfg *intf; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c index 619926da1441..4e1396575e6a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c @@ -175,7 +175,7 @@ static void dpu_hw_dsc_bind_pingpong_blk( DPU_REG_WRITE(c, dsc_ctl_offset, mux_cfg); } -static struct dpu_dsc_cfg *_dsc_offset(enum dpu_dsc dsc, +static const struct dpu_dsc_cfg *_dsc_offset(enum dpu_dsc dsc, const struct dpu_mdss_cfg *m, void __iomem *addr, struct dpu_hw_blk_reg_map *b) @@ -207,7 +207,7 @@ struct dpu_hw_dsc *dpu_hw_dsc_init(enum dpu_dsc idx, void __iomem *addr, const struct dpu_mdss_cfg *m) { struct dpu_hw_dsc *c; - struct dpu_dsc_cfg *cfg; + const struct dpu_dsc_cfg *cfg; c = kzalloc(sizeof(*c), GFP_KERNEL); if (!c) -- 2.39.2
[PATCH v4 02/42] drm/msm/dpu: Allow variable SSPP_BLK size
From: Konrad Dybcio These blocks are of variable length on different SoCs. Set the correct values where I was able to retrieve it from downstream DTs and leave the old defaults (0x1c8) otherwise. Signed-off-by: Konrad Dybcio [DB: fixed some of lengths, split the INTF changes away] Signed-off-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 146 +- 1 file changed, 73 insertions(+), 73 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 83f8f83e2b29..9e20ab6acbd2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -1172,11 +1172,11 @@ static const struct dpu_sspp_sub_blks sdm845_dma_sblk_1 = _DMA_SBLK("9", 2); static const struct dpu_sspp_sub_blks sdm845_dma_sblk_2 = _DMA_SBLK("10", 3); static const struct dpu_sspp_sub_blks sdm845_dma_sblk_3 = _DMA_SBLK("11", 4); -#define SSPP_BLK(_name, _id, _base, _features, \ +#define SSPP_BLK(_name, _id, _base, _len, _features, \ _sblk, _xinid, _type, _clkctrl) \ { \ .name = _name, .id = _id, \ - .base = _base, .len = 0x1c8, \ + .base = _base, .len = _len, \ .features = _features, \ .sblk = &_sblk, \ .xin_id = _xinid, \ @@ -1185,40 +1185,40 @@ static const struct dpu_sspp_sub_blks sdm845_dma_sblk_3 = _DMA_SBLK("11", 4); } static const struct dpu_sspp_cfg msm8998_sspp[] = { - SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_MSM8998_MASK, + SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, 0x1ac, VIG_MSM8998_MASK, msm8998_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), - SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_MSM8998_MASK, + SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, 0x1ac, VIG_MSM8998_MASK, msm8998_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1), - SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_MSM8998_MASK, + SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, 0x1ac, VIG_MSM8998_MASK, msm8998_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2), - SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_MSM8998_MASK, + SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, 0x1ac, VIG_MSM8998_MASK, msm8998_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3), - SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_MSM8998_MASK, + SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, 0x1ac, DMA_MSM8998_MASK, sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), - SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_MSM8998_MASK, + SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, 0x1ac, DMA_MSM8998_MASK, sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1), - SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_MSM8998_MASK, + SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, 0x1ac, DMA_CURSOR_MSM8998_MASK, sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2), - SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, DMA_CURSOR_MSM8998_MASK, + SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, 0x1ac, DMA_CURSOR_MSM8998_MASK, sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3), }; static const struct dpu_sspp_cfg sdm845_sspp[] = { - SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SDM845_MASK_SDMA, + SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, 0x1c8, VIG_SDM845_MASK_SDMA, sdm845_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), - SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SDM845_MASK_SDMA, + SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, 0x1c8, VIG_SDM845_MASK_SDMA, sdm845_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1), - SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SDM845_MASK_SDMA, + SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, 0x1c8, VIG_SDM845_MASK_SDMA, sdm845_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2), - SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SDM845_MASK_SDMA, + SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, 0x1c8, VIG_SDM845_MASK_SDMA, sdm845_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3), - SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_SDM845_MASK_SDMA, + SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, 0x1c8, DMA_SDM845_MASK_SDMA, sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), - SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_SDM845_MASK_SDMA, + SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, 0x1c8, DMA_SDM845_MASK_SDMA, sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1), - SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_SDM845_MASK_SDMA, + SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, 0x1c8, DMA_CURSOR_SDM845_MASK_SDMA, sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2), - SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, DMA_CURSOR_SDM845_MASK_SDMA, + SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, 0x1c8, DMA_CURSOR_SDM845_MASK_SDMA, sd
[PATCH v4 05/42] drm/msm/dpu: mark remaining pp data as const
Fix several leftover _pp strutures and mark them as const, making all hw catalog fit into the rodata section. Reviewed-by: Konrad Dybcio Reviewed-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 2dbd4783a57b..69ea713405bd 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -1659,12 +1659,12 @@ static const struct dpu_pingpong_cfg sdm845_pp[] = { DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)), }; -static struct dpu_pingpong_cfg sc7180_pp[] = { +static const struct dpu_pingpong_cfg sc7180_pp[] = { PP_BLK_TE("pingpong_0", PINGPONG_0, 0x7, 0, sdm845_pp_sblk_te, -1, -1), PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, 0, sdm845_pp_sblk_te, -1, -1), }; -static struct dpu_pingpong_cfg sc8280xp_pp[] = { +static const struct dpu_pingpong_cfg sc8280xp_pp[] = { PP_BLK_TE("pingpong_0", PINGPONG_0, 0x69000, MERGE_3D_0, sdm845_pp_sblk_te, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), -1), PP_BLK_TE("pingpong_1", PINGPONG_1, 0x6a000, MERGE_3D_0, sdm845_pp_sblk_te, @@ -1728,7 +1728,7 @@ static const struct dpu_pingpong_cfg sc7280_pp[] = { PP_BLK("pingpong_3", PINGPONG_3, 0x6c000, 0, sc7280_pp_sblk, -1, -1), }; -static struct dpu_pingpong_cfg qcm2290_pp[] = { +static const struct dpu_pingpong_cfg qcm2290_pp[] = { PP_BLK("pingpong_0", PINGPONG_0, 0x7, 0, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)), -- 2.39.2
[PATCH v4 03/42] drm/msm/dpu: Allow variable INTF_BLK size
From: Konrad Dybcio These blocks are of variable length on different SoCs. Set the correct values where I was able to retrieve it from downstream DTs and leave the old defaults (0x280) otherwise. Signed-off-by: Konrad Dybcio [DB: fixed some lengths, split the INTF changes away] Signed-off-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 96 +-- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 9e20ab6acbd2..f4ffd7fc4424 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -1853,10 +1853,10 @@ static struct dpu_dsc_cfg sm8150_dsc[] = { /* * INTF sub blocks config */ -#define INTF_BLK(_name, _id, _base, _type, _ctrl_id, _progfetch, _features, _reg, _underrun_bit, _vsync_bit) \ +#define INTF_BLK(_name, _id, _base, _len, _type, _ctrl_id, _progfetch, _features, _reg, _underrun_bit, _vsync_bit) \ {\ .name = _name, .id = _id, \ - .base = _base, .len = 0x280, \ + .base = _base, .len = _len, \ .features = _features, \ .type = _type, \ .controller_id = _ctrl_id, \ @@ -1866,85 +1866,85 @@ static struct dpu_dsc_cfg sm8150_dsc[] = { } static const struct dpu_intf_cfg msm8998_intf[] = { - INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25), - INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27), - INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 28, 29), - INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_HDMI, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 30, 31), + INTF_BLK("intf_0", INTF_0, 0x6A000, 0x280, INTF_DP, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25), + INTF_BLK("intf_1", INTF_1, 0x6A800, 0x280, INTF_DSI, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27), + INTF_BLK("intf_2", INTF_2, 0x6B000, 0x280, INTF_DSI, 1, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 28, 29), + INTF_BLK("intf_3", INTF_3, 0x6B800, 0x280, INTF_HDMI, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 30, 31), }; static const struct dpu_intf_cfg sdm845_intf[] = { - INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25), - INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27), - INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 28, 29), - INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 1, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 30, 31), + INTF_BLK("intf_0", INTF_0, 0x6A000, 0x280, INTF_DP, 0, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25), + INTF_BLK("intf_1", INTF_1, 0x6A800, 0x280, INTF_DSI, 0, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27), + INTF_BLK("intf_2", INTF_2, 0x6B000, 0x280, INTF_DSI, 1, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 28, 29), + INTF_BLK("intf_3", INTF_3, 0x6B800, 0x280, INTF_DP, 1, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 30, 31), }; static const struct dpu_intf_cfg sc7180_intf[] = { - INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25), - INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27), + INTF_BLK("intf_0", INTF_0, 0x6A000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25), + INTF_BLK("intf_1", INTF_1, 0x6A800, 0x2c0, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27), }; static const struct dpu_intf_cfg sm8150_intf[] = { - INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25), - INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27), - INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 28, 29), - INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 30, 31), + INTF_BLK("intf_0", INTF_0, 0x6A000, 0x280, INTF_DP, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25), + INTF_BLK("intf_1", INTF_1, 0x6A800, 0x2bc, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27), + INTF_BLK("intf_2", INTF_2, 0x6B000, 0x2bc, INTF_DSI, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 28, 29), + INTF_BLK("intf_3", INTF_3, 0x6B800, 0x280, INTF_DP, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 30, 31), }; static const struct dpu_intf_cfg sc7280_intf[] = { - INTF_BLK("intf_0", INTF_0, 0x34000, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_S
[PATCH v4 06/42] drm/msm/dpu: move UBWC/memory configuration to separate struct
UBWC and highest bank settings differ slightly between different DPU units of the same generation, while the dpu_caps and dpu_mdp_cfg are much more stable. To ease configuration reuse move ubwc_swizzle and highest_bank_bit data to separate structure. Reviewed-by: Konrad Dybcio Reviewed-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 112 +- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h| 19 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 18 +-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 4 +- 4 files changed, 107 insertions(+), 46 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 69ea713405bd..ba01f3106560 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -323,7 +323,6 @@ static const struct dpu_caps msm8998_dpu_caps = { .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, .max_mixer_blendstages = 0x7, .qseed_type = DPU_SSPP_SCALER_QSEED3, - .ubwc_version = DPU_HW_UBWC_VER_10, .has_src_split = true, .has_dim_layer = true, .has_idle_pc = true, @@ -347,7 +346,6 @@ static const struct dpu_caps sdm845_dpu_caps = { .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, .max_mixer_blendstages = 0xb, .qseed_type = DPU_SSPP_SCALER_QSEED3, - .ubwc_version = DPU_HW_UBWC_VER_20, .has_src_split = true, .has_dim_layer = true, .has_idle_pc = true, @@ -362,7 +360,6 @@ static const struct dpu_caps sc7180_dpu_caps = { .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, .max_mixer_blendstages = 0x9, .qseed_type = DPU_SSPP_SCALER_QSEED4, - .ubwc_version = DPU_HW_UBWC_VER_20, .has_dim_layer = true, .has_idle_pc = true, .max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH, @@ -373,7 +370,6 @@ static const struct dpu_caps sm6115_dpu_caps = { .max_mixer_width = DEFAULT_DPU_LINE_WIDTH, .max_mixer_blendstages = 0x4, .qseed_type = DPU_SSPP_SCALER_QSEED4, - .ubwc_version = DPU_HW_UBWC_VER_10, .has_dim_layer = true, .has_idle_pc = true, .max_linewidth = 2160, @@ -384,7 +380,6 @@ static const struct dpu_caps sm8150_dpu_caps = { .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, .max_mixer_blendstages = 0xb, .qseed_type = DPU_SSPP_SCALER_QSEED3, - .ubwc_version = DPU_HW_UBWC_VER_30, .has_src_split = true, .has_dim_layer = true, .has_idle_pc = true, @@ -399,7 +394,6 @@ static const struct dpu_caps sc8180x_dpu_caps = { .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, .max_mixer_blendstages = 0xb, .qseed_type = DPU_SSPP_SCALER_QSEED3, - .ubwc_version = DPU_HW_UBWC_VER_30, .has_src_split = true, .has_dim_layer = true, .has_idle_pc = true, @@ -414,7 +408,6 @@ static const struct dpu_caps sc8280xp_dpu_caps = { .max_mixer_width = 2560, .max_mixer_blendstages = 11, .qseed_type = DPU_SSPP_SCALER_QSEED4, - .ubwc_version = DPU_HW_UBWC_VER_40, .has_src_split = true, .has_dim_layer = true, .has_idle_pc = true, @@ -427,7 +420,6 @@ static const struct dpu_caps sm8250_dpu_caps = { .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, .max_mixer_blendstages = 0xb, .qseed_type = DPU_SSPP_SCALER_QSEED4, - .ubwc_version = DPU_HW_UBWC_VER_40, .has_src_split = true, .has_dim_layer = true, .has_idle_pc = true, @@ -440,7 +432,6 @@ static const struct dpu_caps sm8350_dpu_caps = { .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, .max_mixer_blendstages = 0xb, .qseed_type = DPU_SSPP_SCALER_QSEED4, - .ubwc_version = DPU_HW_UBWC_VER_40, .has_src_split = true, .has_dim_layer = true, .has_idle_pc = true, @@ -453,7 +444,6 @@ static const struct dpu_caps sm8450_dpu_caps = { .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, .max_mixer_blendstages = 0xb, .qseed_type = DPU_SSPP_SCALER_QSEED4, - .ubwc_version = DPU_HW_UBWC_VER_40, .has_src_split = true, .has_dim_layer = true, .has_idle_pc = true, @@ -466,7 +456,6 @@ static const struct dpu_caps sm8550_dpu_caps = { .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, .max_mixer_blendstages = 0xb, .qseed_type = DPU_SSPP_SCALER_QSEED4, - .ubwc_version = DPU_HW_UBWC_VER_40, .has_src_split = true, .has_dim_layer = true, .has_idle_pc = true, @@ -479,19 +468,86 @@ static const struct dpu_caps sc7280_dpu_caps = { .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, .max_mixer_blendstages = 0x7, .qseed_type = DPU_SSPP_SCALER_QSEED4, - .ubwc_version = DPU_HW_UBWC_VER_30, .has_dim_layer = true, .has
[PATCH v4 08/42] drm/msm/dpu: split SM8450 catalog entry to the separate file
Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_8_1_sm8450.h| 202 + .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 203 +- 2 files changed, 204 insertions(+), 201 deletions(-) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h new file mode 100644 index ..9a6ddd1c410a --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h @@ -0,0 +1,202 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved. + */ + +#ifndef _DPU_8_1_SM8450_H +#define _DPU_8_1_SM8450_H + +static const struct dpu_caps sm8450_dpu_caps = { + .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, + .max_mixer_blendstages = 0xb, + .qseed_type = DPU_SSPP_SCALER_QSEED4, + .has_src_split = true, + .has_dim_layer = true, + .has_idle_pc = true, + .has_3d_merge = true, + .max_linewidth = 5120, + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, +}; + +static const struct dpu_ubwc_cfg sm8450_ubwc_cfg = { + .ubwc_version = DPU_HW_UBWC_VER_40, + .highest_bank_bit = 0x3, /* TODO: 2 for LP_DDR4 */ + .ubwc_swizzle = 0x6, +}; + +static const struct dpu_mdp_cfg sm8450_mdp[] = { + { + .name = "top_0", .id = MDP_TOP, + .base = 0x0, .len = 0x494, + .features = BIT(DPU_MDP_PERIPH_0_REMOVED), + .clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 }, + }, +}; + +static const struct dpu_ctl_cfg sm8450_ctl[] = { + { + .name = "ctl_0", .id = CTL_0, + .base = 0x15000, .len = 0x204, + .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), + }, + { + .name = "ctl_1", .id = CTL_1, + .base = 0x16000, .len = 0x204, + .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), + }, + { + .name = "ctl_2", .id = CTL_2, + .base = 0x17000, .len = 0x204, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11), + }, + { + .name = "ctl_3", .id = CTL_3, + .base = 0x18000, .len = 0x204, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12), + }, + { + .name = "ctl_4", .id = CTL_4, + .base = 0x19000, .len = 0x204, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13), + }, + { + .name = "ctl_5", .id = CTL_5, + .base = 0x1a000, .len = 0x204, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23), + }, +}; + +static const struct dpu_sspp_cfg sm8450_sspp[] = { + SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, 0x328, VIG_SC7180_MASK, + sm8450_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), + SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, 0x328, VIG_SC7180_MASK, + sm8450_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1), + SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, 0x328, VIG_SC7180_MASK, + sm8450_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2), + SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, 0x328, VIG_SC7180_MASK, + sm8450_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3), + SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, 0x328, DMA_SDM845_MASK, + sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), + SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, 0x328, DMA_SDM845_MASK, + sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1), + SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, 0x328, DMA_CURSOR_SDM845_MASK, + sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2), + SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, 0x328, DMA_CURSOR_SDM845_MASK, + sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3), +}; + +/* FIXME: interrupts */ +static const struct dpu_pingpong_cfg sm8450_pp[] = { + PP_BLK_TE("pingpong_0", PINGPONG_0, 0x69000,
[PATCH v4 09/42] drm/msm/dpu: split SC8280XP catalog entry to the separate file
Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 194 ++ .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 187 + 2 files changed, 195 insertions(+), 186 deletions(-) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h new file mode 100644 index ..9cba45b4cf0e --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h @@ -0,0 +1,194 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved. + */ + +#ifndef _DPU_8_0_SC8280XP_H +#define _DPU_8_0_SC8280XP_H + +static const struct dpu_caps sc8280xp_dpu_caps = { + .max_mixer_width = 2560, + .max_mixer_blendstages = 11, + .qseed_type = DPU_SSPP_SCALER_QSEED4, + .has_src_split = true, + .has_dim_layer = true, + .has_idle_pc = true, + .has_3d_merge = true, + .max_linewidth = 5120, + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, +}; + +static const struct dpu_ubwc_cfg sc8280xp_ubwc_cfg = { + .ubwc_version = DPU_HW_UBWC_VER_40, + .highest_bank_bit = 2, + .ubwc_swizzle = 6, +}; + +static const struct dpu_mdp_cfg sc8280xp_mdp[] = { + { + .name = "top_0", .id = MDP_TOP, + .base = 0x0, .len = 0x494, + .features = BIT(DPU_MDP_PERIPH_0_REMOVED), + .clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 }, + }, +}; + +static const struct dpu_ctl_cfg sc8280xp_ctl[] = { + { + .name = "ctl_0", .id = CTL_0, + .base = 0x15000, .len = 0x204, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), + }, + { + .name = "ctl_1", .id = CTL_1, + .base = 0x16000, .len = 0x204, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), + }, + { + .name = "ctl_2", .id = CTL_2, + .base = 0x17000, .len = 0x204, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11), + }, + { + .name = "ctl_3", .id = CTL_3, + .base = 0x18000, .len = 0x204, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12), + }, + { + .name = "ctl_4", .id = CTL_4, + .base = 0x19000, .len = 0x204, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13), + }, + { + .name = "ctl_5", .id = CTL_5, + .base = 0x1a000, .len = 0x204, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23), + }, +}; + +static const struct dpu_sspp_cfg sc8280xp_sspp[] = { + SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, 0x2ac, VIG_SC7180_MASK, +sc8280xp_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), + SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, 0x2ac, VIG_SC7180_MASK, +sc8280xp_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1), + SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, 0x2ac, VIG_SC7180_MASK, +sc8280xp_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2), + SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, 0x2ac, VIG_SC7180_MASK, +sc8280xp_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3), + SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, 0x2ac, DMA_SDM845_MASK, +sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), + SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, 0x2ac, DMA_SDM845_MASK, +sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1), + SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, 0x2ac, DMA_CURSOR_SDM845_MASK, +sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2), + SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, 0x2ac, DMA_CURSOR_SDM845_MASK, +sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3), +}; + +static const struct dpu_lm_cfg sc8280xp_lm[] = { + LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK, &sdm845_lm_sblk, PINGPONG_0, LM_1, DSPP_0), + LM_BLK("lm_1", LM_1, 0x45000, MIXER_SDM845_MASK
[PATCH v4 07/42] drm/msm/dpu: split SM8550 catalog entry to the separate file
Reviewed-by: Konrad DYbcio Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_9_0_sm8550.h| 177 + .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 180 +- 2 files changed, 179 insertions(+), 178 deletions(-) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h new file mode 100644 index ..29d878625707 --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h @@ -0,0 +1,177 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved. + */ + +#ifndef _DPU_9_0_SM8550_H +#define _DPU_9_0_SM8550_H + +static const struct dpu_caps sm8550_dpu_caps = { + .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, + .max_mixer_blendstages = 0xb, + .qseed_type = DPU_SSPP_SCALER_QSEED4, + .has_src_split = true, + .has_dim_layer = true, + .has_idle_pc = true, + .has_3d_merge = true, + .max_linewidth = 5120, + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, +}; + +static const struct dpu_ubwc_cfg sm8550_ubwc_cfg = { + .ubwc_version = DPU_HW_UBWC_VER_40, + .highest_bank_bit = 0x3, /* TODO: 2 for LP_DDR4 */ +}; + +static const struct dpu_mdp_cfg sm8550_mdp[] = { + { + .name = "top_0", .id = MDP_TOP, + .base = 0, .len = 0x494, + .features = BIT(DPU_MDP_PERIPH_0_REMOVED), + .clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x4330, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_VIG1] = { .reg_off = 0x6330, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_VIG2] = { .reg_off = 0x8330, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_VIG3] = { .reg_off = 0xa330, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x24330, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x26330, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x28330, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2a330, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_DMA4] = { .reg_off = 0x2c330, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_DMA5] = { .reg_off = 0x2e330, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 }, + }, +}; + +static const struct dpu_ctl_cfg sm8550_ctl[] = { + { + .name = "ctl_0", .id = CTL_0, + .base = 0x15000, .len = 0x290, + .features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), + }, + { + .name = "ctl_1", .id = CTL_1, + .base = 0x16000, .len = 0x290, + .features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), + }, + { + .name = "ctl_2", .id = CTL_2, + .base = 0x17000, .len = 0x290, + .features = CTL_SM8550_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11), + }, + { + .name = "ctl_3", .id = CTL_3, + .base = 0x18000, .len = 0x290, + .features = CTL_SM8550_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12), + }, + { + .name = "ctl_4", .id = CTL_4, + .base = 0x19000, .len = 0x290, + .features = CTL_SM8550_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13), + }, + { + .name = "ctl_5", .id = CTL_5, + .base = 0x1a000, .len = 0x290, + .features = CTL_SM8550_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23), + }, +}; + +static const struct dpu_sspp_cfg sm8550_sspp[] = { + SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, 0x344, VIG_SC7180_MASK, + sm8550_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), + SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, 0x344, VIG_SC7180_MASK, + sm8550_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1), + SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, 0x344, VIG_SC7180_MASK, + sm8550_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2), + SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, 0x344, VIG_SC7180_MASK, + sm8550_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3), + SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, 0x344, DMA_SDM845_MASK, + sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), + SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, 0x344, DMA_SDM845_MASK, + sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1), + SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, 0x344, DMA_SDM845_MASK, + sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2), + SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, 0x344, DMA_SDM845_MASK, + sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3), + SSPP_B
[PATCH v4 10/42] drm/msm/dpu: split SC7280 catalog entry to the separate file
Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_7_2_sc7280.h| 148 ++ .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 144 + 2 files changed, 150 insertions(+), 142 deletions(-) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h new file mode 100644 index ..ea34c2c7e25c --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h @@ -0,0 +1,148 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved. + */ + +#ifndef _DPU_7_2_SC7280_H +#define _DPU_7_2_SC7280_H + +static const struct dpu_caps sc7280_dpu_caps = { + .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, + .max_mixer_blendstages = 0x7, + .qseed_type = DPU_SSPP_SCALER_QSEED4, + .has_dim_layer = true, + .has_idle_pc = true, + .max_linewidth = 2400, + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, +}; + +static const struct dpu_ubwc_cfg sc7280_ubwc_cfg = { + .ubwc_version = DPU_HW_UBWC_VER_30, + .highest_bank_bit = 0x1, + .ubwc_swizzle = 0x6, +}; + +static const struct dpu_mdp_cfg sc7280_mdp[] = { + { + .name = "top_0", .id = MDP_TOP, + .base = 0x0, .len = 0x2014, + .clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2c4, .bit_off = 8 }, + }, +}; + +static const struct dpu_ctl_cfg sc7280_ctl[] = { + { + .name = "ctl_0", .id = CTL_0, + .base = 0x15000, .len = 0x1e8, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), + }, + { + .name = "ctl_1", .id = CTL_1, + .base = 0x16000, .len = 0x1e8, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), + }, + { + .name = "ctl_2", .id = CTL_2, + .base = 0x17000, .len = 0x1e8, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11), + }, + { + .name = "ctl_3", .id = CTL_3, + .base = 0x18000, .len = 0x1e8, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12), + }, +}; + +static const struct dpu_sspp_cfg sc7280_sspp[] = { + SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, 0x1f8, VIG_SC7280_MASK_SDMA, + sc7280_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), + SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, 0x1f8, DMA_SDM845_MASK_SDMA, + sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), + SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, 0x1f8, DMA_CURSOR_SDM845_MASK_SDMA, + sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1), + SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, 0x1f8, DMA_CURSOR_SDM845_MASK_SDMA, + sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2), +}; + +static const struct dpu_lm_cfg sc7280_lm[] = { + LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK, + &sc7180_lm_sblk, PINGPONG_0, 0, DSPP_0), + LM_BLK("lm_2", LM_2, 0x46000, MIXER_SDM845_MASK, + &sc7180_lm_sblk, PINGPONG_2, LM_3, 0), + LM_BLK("lm_3", LM_3, 0x47000, MIXER_SDM845_MASK, + &sc7180_lm_sblk, PINGPONG_3, LM_2, 0), +}; + +static const struct dpu_pingpong_cfg sc7280_pp[] = { + PP_BLK("pingpong_0", PINGPONG_0, 0x69000, 0, sc7280_pp_sblk, -1, -1), + PP_BLK("pingpong_1", PINGPONG_1, 0x6a000, 0, sc7280_pp_sblk, -1, -1), + PP_BLK("pingpong_2", PINGPONG_2, 0x6b000, 0, sc7280_pp_sblk, -1, -1), + PP_BLK("pingpong_3", PINGPONG_3, 0x6c000, 0, sc7280_pp_sblk, -1, -1), +}; + +static const struct dpu_intf_cfg sc7280_intf[] = { + INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 24, 25), + INTF_BLK("intf_1", INTF_1, 0x35000, 0x2c4, INTF_DSI, 0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 26, 27), + INTF_BLK("intf_5", INTF_5, 0x39000, 0x280, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 22, 23), +}; + +static const struct dpu_perf_cfg sc7280_perf_data = { + .max_bw_low = 470, + .max_bw_high = 880, + .min_core_ib = 250, + .min_llcc_ib = 0, + .min_dram_ib = 160, + .min_prefill_lines = 24, + .danger_lut_tbl = {0x, 0x, 0x0}, + .safe_lut_tbl = {0xff00, 0xff00, 0x}, + .qos_lut_tbl = { + {.nentry = ARRAY_SIZE(sc7180_qos_macrotile), + .entries
[PATCH v4 12/42] drm/msm/dpu: split SM6115 catalog entry to the separate file
Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_6_3_sm6115.h| 95 +++ .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 89 + 2 files changed, 97 insertions(+), 87 deletions(-) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h new file mode 100644 index ..f6db2d42a0ed --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h @@ -0,0 +1,95 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved. + */ + +#ifndef _DPU_6_3_SM6115_H +#define _DPU_6_3_SM6115_H + +static const struct dpu_caps sm6115_dpu_caps = { + .max_mixer_width = DEFAULT_DPU_LINE_WIDTH, + .max_mixer_blendstages = 0x4, + .qseed_type = DPU_SSPP_SCALER_QSEED4, + .has_dim_layer = true, + .has_idle_pc = true, + .max_linewidth = 2160, + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, +}; + +static const struct dpu_ubwc_cfg sm6115_ubwc_cfg = { + .ubwc_version = DPU_HW_UBWC_VER_10, + .highest_bank_bit = 0x1, + .ubwc_swizzle = 0x7, +}; + +static const struct dpu_mdp_cfg sm6115_mdp[] = { + { + .name = "top_0", .id = MDP_TOP, + .base = 0x0, .len = 0x494, + .features = 0, + .clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, + }, +}; + +static const struct dpu_sspp_cfg sm6115_sspp[] = { + SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, 0x1f8, VIG_SC7180_MASK, + sm6115_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), + SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, 0x1f8, DMA_SDM845_MASK, + sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), +}; + +static const struct dpu_perf_cfg sm6115_perf_data = { + .max_bw_low = 310, + .max_bw_high = 400, + .min_core_ib = 240, + .min_llcc_ib = 80, + .min_dram_ib = 80, + .min_prefill_lines = 24, + .danger_lut_tbl = {0xff, 0x, 0x0}, + .safe_lut_tbl = {0xfff0, 0xff00, 0x}, + .qos_lut_tbl = { + {.nentry = ARRAY_SIZE(sc7180_qos_linear), + .entries = sc7180_qos_linear + }, + {.nentry = ARRAY_SIZE(sc7180_qos_macrotile), + .entries = sc7180_qos_macrotile + }, + {.nentry = ARRAY_SIZE(sc7180_qos_nrt), + .entries = sc7180_qos_nrt + }, + /* TODO: macrotile-qseed is different from macrotile */ + }, + .cdp_cfg = { + {.rd_enable = 1, .wr_enable = 1}, + {.rd_enable = 1, .wr_enable = 0} + }, + .clk_inefficiency_factor = 105, + .bw_inefficiency_factor = 120, +}; + +static const struct dpu_mdss_cfg sm6115_dpu_cfg = { + .caps = &sm6115_dpu_caps, + .ubwc = &sm6115_ubwc_cfg, + .mdp_count = ARRAY_SIZE(sm6115_mdp), + .mdp = sm6115_mdp, + .ctl_count = ARRAY_SIZE(qcm2290_ctl), + .ctl = qcm2290_ctl, + .sspp_count = ARRAY_SIZE(sm6115_sspp), + .sspp = sm6115_sspp, + .mixer_count = ARRAY_SIZE(qcm2290_lm), + .mixer = qcm2290_lm, + .dspp_count = ARRAY_SIZE(qcm2290_dspp), + .dspp = qcm2290_dspp, + .pingpong_count = ARRAY_SIZE(qcm2290_pp), + .pingpong = qcm2290_pp, + .intf_count = ARRAY_SIZE(qcm2290_intf), + .intf = qcm2290_intf, + .vbif_count = ARRAY_SIZE(sdm845_vbif), + .vbif = sdm845_vbif, + .perf = &sm6115_perf_data, + .mdss_irqs = IRQ_SC7180_MASK, +}; + +#endif diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 16fd7fd41ea0..6a31a70ea764 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -366,16 +366,6 @@ static const struct dpu_caps sc7180_dpu_caps = { .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, }; -static const struct dpu_caps sm6115_dpu_caps = { - .max_mixer_width = DEFAULT_DPU_LINE_WIDTH, - .max_mixer_blendstages = 0x4, - .qseed_type = DPU_SSPP_SCALER_QSEED4, - .has_dim_layer = true, - .has_idle_pc = true, - .max_linewidth = 2160, - .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, -}; - static const struct dpu_caps sm8150_dpu_caps = { .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, .max_mixer_blendstages = 0xb, @@ -435,12 +425,6 @@ static const struct dpu_ubwc_cfg sc7180_ubwc_cfg = { .highest_bank_bit = 0x3, }; -static const struct dpu_ubwc_cfg sm6115_ubwc_cfg = { - .ubwc_version = DPU_HW_UBWC_VER_10, - .highest_bank_bit = 0x1,
[PATCH v4 11/42] drm/msm/dpu: split SM8350 catalog entry to the separate file
Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_7_0_sm8350.h| 174 ++ .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 174 +- 2 files changed, 175 insertions(+), 173 deletions(-) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h new file mode 100644 index ..a08fec2a3bcb --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h @@ -0,0 +1,174 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved. + */ + +#ifndef _DPU_7_0_SM8350_H +#define _DPU_7_0_SM8350_H + +static const struct dpu_caps sm8350_dpu_caps = { + .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, + .max_mixer_blendstages = 0xb, + .qseed_type = DPU_SSPP_SCALER_QSEED4, + .has_src_split = true, + .has_dim_layer = true, + .has_idle_pc = true, + .has_3d_merge = true, + .max_linewidth = 4096, + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, +}; + +static const struct dpu_ubwc_cfg sm8350_ubwc_cfg = { + .ubwc_version = DPU_HW_UBWC_VER_40, + .highest_bank_bit = 0x3, /* TODO: 2 for LP_DDR4 */ +}; + +static const struct dpu_mdp_cfg sm8350_mdp[] = { + { + .name = "top_0", .id = MDP_TOP, + .base = 0x0, .len = 0x494, + .features = 0, + .clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 }, + }, +}; + +static const struct dpu_ctl_cfg sm8350_ctl[] = { + { + .name = "ctl_0", .id = CTL_0, + .base = 0x15000, .len = 0x1e8, + .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), + }, + { + .name = "ctl_1", .id = CTL_1, + .base = 0x16000, .len = 0x1e8, + .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), + }, + { + .name = "ctl_2", .id = CTL_2, + .base = 0x17000, .len = 0x1e8, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11), + }, + { + .name = "ctl_3", .id = CTL_3, + .base = 0x18000, .len = 0x1e8, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12), + }, + { + .name = "ctl_4", .id = CTL_4, + .base = 0x19000, .len = 0x1e8, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13), + }, + { + .name = "ctl_5", .id = CTL_5, + .base = 0x1a000, .len = 0x1e8, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23), + }, +}; + +static const struct dpu_pingpong_cfg sm8350_pp[] = { + PP_BLK_TE("pingpong_0", PINGPONG_0, 0x69000, MERGE_3D_0, sdm845_pp_sblk_te, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)), + PP_BLK_TE("pingpong_1", PINGPONG_1, 0x6a000, MERGE_3D_0, sdm845_pp_sblk_te, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13)), + PP_BLK("pingpong_2", PINGPONG_2, 0x6b000, MERGE_3D_1, sdm845_pp_sblk, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14)), + PP_BLK("pingpong_3", PINGPONG_3, 0x6c000, MERGE_3D_1, sdm845_pp_sblk, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)), + PP_BLK("pingpong_4", PINGPONG_4, 0x6d000, MERGE_3D_2, sdm845_pp_sblk, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), + -1), + PP_BLK("pingpong_5", PINGPONG_5, 0x6e000, MERGE_3D_2, sdm845_pp_sblk, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31), + -1), +}; + +static const struct dpu_merge_3d_cfg sm8350_merge_3d[] = { + MERGE_3D_BLK("merge_3d_0", MERGE_3D_0, 0x4e000), + MERGE_3D_BLK("merge_3d_1", MERGE_3D_1, 0x4f000), + MERGE_3D_BLK("m
[PATCH v4 13/42] drm/msm/dpu: split QCM2290 catalog entry to the separate file
Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 115 ++ .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 107 +--- 2 files changed, 116 insertions(+), 106 deletions(-) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h new file mode 100644 index ..c0f95473611d --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h @@ -0,0 +1,115 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved. + */ + +#ifndef _DPU_6_5_QCM2290_H +#define _DPU_6_5_QCM2290_H + +static const struct dpu_caps qcm2290_dpu_caps = { + .max_mixer_width = DEFAULT_DPU_LINE_WIDTH, + .max_mixer_blendstages = 0x4, + .has_dim_layer = true, + .has_idle_pc = true, + .max_linewidth = 2160, + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, +}; + +static const struct dpu_ubwc_cfg qcm2290_ubwc_cfg = { + .highest_bank_bit = 0x2, +}; + +static const struct dpu_mdp_cfg qcm2290_mdp[] = { + { + .name = "top_0", .id = MDP_TOP, + .base = 0x0, .len = 0x494, + .features = 0, + .clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, + }, +}; + +static const struct dpu_ctl_cfg qcm2290_ctl[] = { + { + .name = "ctl_0", .id = CTL_0, + .base = 0x1000, .len = 0x1dc, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), + }, +}; + +static const struct dpu_sspp_cfg qcm2290_sspp[] = { + SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, 0x1f8, VIG_QCM2290_MASK, +qcm2290_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), + SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, 0x1f8, DMA_SDM845_MASK, +qcm2290_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), +}; + +static const struct dpu_lm_cfg qcm2290_lm[] = { + LM_BLK("lm_0", LM_0, 0x44000, MIXER_QCM2290_MASK, + &qcm2290_lm_sblk, PINGPONG_0, 0, DSPP_0), +}; + +static const struct dpu_dspp_cfg qcm2290_dspp[] = { + DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_SC7180_MASK, +&sm8150_dspp_sblk), +}; + +static const struct dpu_pingpong_cfg qcm2290_pp[] = { + PP_BLK("pingpong_0", PINGPONG_0, 0x7, 0, sdm845_pp_sblk, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)), +}; + +static const struct dpu_intf_cfg qcm2290_intf[] = { + INTF_BLK("intf_0", INTF_0, 0x0, 0x280, INTF_NONE, 0, 0, 0, 0, 0, 0), + INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2c0, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27), +}; + +static const struct dpu_perf_cfg qcm2290_perf_data = { + .max_bw_low = 270, + .max_bw_high = 270, + .min_core_ib = 130, + .min_llcc_ib = 0, + .min_dram_ib = 160, + .min_prefill_lines = 24, + .danger_lut_tbl = {0xff, 0x0, 0x0}, + .safe_lut_tbl = {0xfff0, 0x0, 0x0}, + .qos_lut_tbl = { + {.nentry = ARRAY_SIZE(qcm2290_qos_linear), + .entries = qcm2290_qos_linear + }, + }, + .cdp_cfg = { + {.rd_enable = 1, .wr_enable = 1}, + {.rd_enable = 1, .wr_enable = 0} + }, + .clk_inefficiency_factor = 105, + .bw_inefficiency_factor = 120, +}; + +static const struct dpu_mdss_cfg qcm2290_dpu_cfg = { + .caps = &qcm2290_dpu_caps, + .ubwc = &qcm2290_ubwc_cfg, + .mdp_count = ARRAY_SIZE(qcm2290_mdp), + .mdp = qcm2290_mdp, + .ctl_count = ARRAY_SIZE(qcm2290_ctl), + .ctl = qcm2290_ctl, + .sspp_count = ARRAY_SIZE(qcm2290_sspp), + .sspp = qcm2290_sspp, + .mixer_count = ARRAY_SIZE(qcm2290_lm), + .mixer = qcm2290_lm, + .dspp_count = ARRAY_SIZE(qcm2290_dspp), + .dspp = qcm2290_dspp, + .pingpong_count = ARRAY_SIZE(qcm2290_pp), + .pingpong = qcm2290_pp, + .intf_count = ARRAY_SIZE(qcm2290_intf), + .intf = qcm2290_intf, + .vbif_count = ARRAY_SIZE(sdm845_vbif), + .vbif = sdm845_vbif, + .perf = &qcm2290_perf_data, + .mdss_irqs = IRQ_SC7180_MASK, +}; + +#endif diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 6a31a70ea764..d2b8292155df 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -333,15 +333,6 @@ static const struct dpu_caps msm8998_dpu_caps = { .max_vdeci_exp = MAX_VERT_DECIMATION, }; -static const struct dpu_caps qcm2290_dpu_caps = { - .max_
[PATCH v4 16/42] drm/msm/dpu: split SC8180X catalog entry to the separate file
Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 107 ++ .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 105 + 2 files changed, 108 insertions(+), 104 deletions(-) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h new file mode 100644 index ..cd505605be1f --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h @@ -0,0 +1,107 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved. + */ + +#ifndef _DPU_5_1_SC8180X_H +#define _DPU_5_1_SC8180X_H + +static const struct dpu_caps sc8180x_dpu_caps = { + .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, + .max_mixer_blendstages = 0xb, + .qseed_type = DPU_SSPP_SCALER_QSEED3, + .has_src_split = true, + .has_dim_layer = true, + .has_idle_pc = true, + .has_3d_merge = true, + .max_linewidth = 4096, + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, + .max_hdeci_exp = MAX_HORZ_DECIMATION, + .max_vdeci_exp = MAX_VERT_DECIMATION, +}; + +static const struct dpu_ubwc_cfg sc8180x_ubwc_cfg = { + .ubwc_version = DPU_HW_UBWC_VER_30, + .highest_bank_bit = 0x3, +}; + +static const struct dpu_mdp_cfg sc8180x_mdp[] = { + { + .name = "top_0", .id = MDP_TOP, + .base = 0x0, .len = 0x45c, + .features = BIT(DPU_MDP_AUDIO_SELECT), + .clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 }, + }, +}; + +static const struct dpu_intf_cfg sc8180x_intf[] = { + INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25), + INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2bc, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27), + INTF_BLK("intf_2", INTF_2, 0x6b000, 0x2bc, INTF_DSI, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 28, 29), + /* INTF_3 is for MST, wired to INTF_DP 0 and 1, use dummy index until this is supported */ + INTF_BLK("intf_3", INTF_3, 0x6b800, 0x280, INTF_DP, 999, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 30, 31), + INTF_BLK("intf_4", INTF_4, 0x6c000, 0x280, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 20, 21), + INTF_BLK("intf_5", INTF_5, 0x6c800, 0x280, INTF_DP, MSM_DP_CONTROLLER_2, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 22, 23), +}; + +static const struct dpu_perf_cfg sc8180x_perf_data = { + .max_bw_low = 960, + .max_bw_high = 960, + .min_core_ib = 240, + .min_llcc_ib = 80, + .min_dram_ib = 80, + .danger_lut_tbl = {0xf, 0x, 0x0}, + .qos_lut_tbl = { + {.nentry = ARRAY_SIZE(sc7180_qos_linear), + .entries = sc7180_qos_linear + }, + {.nentry = ARRAY_SIZE(sc7180_qos_macrotile), + .entries = sc7180_qos_macrotile + }, + {.nentry = ARRAY_SIZE(sc7180_qos_nrt), + .entries = sc7180_qos_nrt + }, + /* TODO: macrotile-qseed is different from macrotile */ + }, + .cdp_cfg = { + {.rd_enable = 1, .wr_enable = 1}, + {.rd_enable = 1, .wr_enable = 0} + }, + .clk_inefficiency_factor = 105, + .bw_inefficiency_factor = 120, +}; + +static const struct dpu_mdss_cfg sc8180x_dpu_cfg = { + .caps = &sc8180x_dpu_caps, + .ubwc = &sc8180x_ubwc_cfg, + .mdp_count = ARRAY_SIZE(sc8180x_mdp), + .mdp = sc8180x_mdp, + .ctl_count = ARRAY_SIZE(sm8150_ctl), + .ctl = sm8150_ctl, + .sspp_count = ARRAY_SIZE(sdm845_sspp), + .sspp = sdm845_sspp, + .mixer_count = ARRAY_SIZE(sm8150_lm), + .mixer = sm8150_lm, + .pingpong_count = ARRAY_SIZE(sm8150_pp), + .pingpong = sm8150_pp, + .merge_3d_count = ARRAY_SIZE(sm8150_merge_3d), + .merge_3d = sm8150_merge_3d, + .intf_count = ARRAY_SIZE(sc8180x_intf), + .intf = sc8180x_intf, + .vbif_count = ARRAY_SIZE(sdm845_vbif), + .vbif = sdm845_vbif, + .reg_dma_count = 1, + .dma_cfg = &sm8150_regdma, + .pe
[PATCH v4 18/42] drm/msm/dpu: split MSM8998 catalog entry to the separate file
Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 188 + .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 190 +- 2 files changed, 190 insertions(+), 188 deletions(-) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h new file mode 100644 index ..6c988b3a7325 --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h @@ -0,0 +1,188 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved. + */ + +#ifndef _DPU_3_0_MSM8998_H +#define _DPU_3_0_MSM8998_H + +static const struct dpu_caps msm8998_dpu_caps = { + .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, + .max_mixer_blendstages = 0x7, + .qseed_type = DPU_SSPP_SCALER_QSEED3, + .has_src_split = true, + .has_dim_layer = true, + .has_idle_pc = true, + .has_3d_merge = true, + .max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH, + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, + .max_hdeci_exp = MAX_HORZ_DECIMATION, + .max_vdeci_exp = MAX_VERT_DECIMATION, +}; + +static const struct dpu_ubwc_cfg msm8998_ubwc_cfg = { + .ubwc_version = DPU_HW_UBWC_VER_10, + .highest_bank_bit = 0x2, +}; + +static const struct dpu_mdp_cfg msm8998_mdp[] = { + { + .name = "top_0", .id = MDP_TOP, + .base = 0x0, .len = 0x458, + .features = 0, + .clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2c4, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 12 }, + .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = { .reg_off = 0x3a8, .bit_off = 15 }, + .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = { .reg_off = 0x3b0, .bit_off = 15 }, + }, +}; + +static const struct dpu_ctl_cfg msm8998_ctl[] = { + { + .name = "ctl_0", .id = CTL_0, + .base = 0x1000, .len = 0x94, + .features = BIT(DPU_CTL_SPLIT_DISPLAY), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), + }, + { + .name = "ctl_1", .id = CTL_1, + .base = 0x1200, .len = 0x94, + .features = 0, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), + }, + { + .name = "ctl_2", .id = CTL_2, + .base = 0x1400, .len = 0x94, + .features = BIT(DPU_CTL_SPLIT_DISPLAY), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11), + }, + { + .name = "ctl_3", .id = CTL_3, + .base = 0x1600, .len = 0x94, + .features = 0, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12), + }, + { + .name = "ctl_4", .id = CTL_4, + .base = 0x1800, .len = 0x94, + .features = 0, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13), + }, +}; + +static const struct dpu_sspp_cfg msm8998_sspp[] = { + SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, 0x1ac, VIG_MSM8998_MASK, + msm8998_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), + SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, 0x1ac, VIG_MSM8998_MASK, + msm8998_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1), + SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, 0x1ac, VIG_MSM8998_MASK, + msm8998_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2), + SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, 0x1ac, VIG_MSM8998_MASK, + msm8998_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3), + SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, 0x1ac, DMA_MSM8998_MASK, + sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), + SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, 0x1ac, DMA_MSM8998_MASK, + sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1), + SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, 0x1ac, DMA_CURSOR_MSM8998_MASK, + sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2), + SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, 0x1ac, DMA_CURSOR_MSM8998_MASK, + sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3), +}; + +static const struct dpu_lm_cfg msm8998_lm[] = { + LM_BLK("lm_0", LM_0, 0x44000, MIXER_MSM8998_MASK, + &msm8998_lm_sblk, PINGPONG_0, LM_2, DSPP_0), + LM_BLK("lm_1", LM_1, 0x45000, MIXER_MSM8998_MASK, + &msm8998_lm_sblk, PINGPONG_1, LM_5
[PATCH v4 14/42] drm/msm/dpu: split SC7180 catalog entry to the separate file
Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_6_2_sc7180.h| 147 ++ .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 143 + 2 files changed, 148 insertions(+), 142 deletions(-) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h new file mode 100644 index ..2326be2900ea --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h @@ -0,0 +1,147 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved. + */ + +#ifndef _DPU_6_2_SC7180_H +#define _DPU_6_2_SC7180_H + +static const struct dpu_caps sc7180_dpu_caps = { + .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, + .max_mixer_blendstages = 0x9, + .qseed_type = DPU_SSPP_SCALER_QSEED4, + .has_dim_layer = true, + .has_idle_pc = true, + .max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH, + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, +}; + +static const struct dpu_ubwc_cfg sc7180_ubwc_cfg = { + .ubwc_version = DPU_HW_UBWC_VER_20, + .highest_bank_bit = 0x3, +}; + +static const struct dpu_mdp_cfg sc7180_mdp[] = { + { + .name = "top_0", .id = MDP_TOP, + .base = 0x0, .len = 0x494, + .features = 0, + .clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2c4, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_WB2] = { .reg_off = 0x3b8, .bit_off = 24 }, + }, +}; + +static const struct dpu_ctl_cfg sc7180_ctl[] = { + { + .name = "ctl_0", .id = CTL_0, + .base = 0x1000, .len = 0x1dc, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), + }, + { + .name = "ctl_1", .id = CTL_1, + .base = 0x1200, .len = 0x1dc, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), + }, + { + .name = "ctl_2", .id = CTL_2, + .base = 0x1400, .len = 0x1dc, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11), + }, +}; + +static const struct dpu_sspp_cfg sc7180_sspp[] = { + SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, 0x1f8, VIG_SC7180_MASK, + sc7180_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), + SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, 0x1f8, DMA_SDM845_MASK, + sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), + SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, 0x1f8, DMA_CURSOR_SDM845_MASK, + sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1), + SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, 0x1f8, DMA_CURSOR_SDM845_MASK, + sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2), +}; + +static const struct dpu_lm_cfg sc7180_lm[] = { + LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK, + &sc7180_lm_sblk, PINGPONG_0, LM_1, DSPP_0), + LM_BLK("lm_1", LM_1, 0x45000, MIXER_SDM845_MASK, + &sc7180_lm_sblk, PINGPONG_1, LM_0, 0), +}; + +static const struct dpu_dspp_cfg sc7180_dspp[] = { + DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_SC7180_MASK, +&sc7180_dspp_sblk), +}; + +static const struct dpu_pingpong_cfg sc7180_pp[] = { + PP_BLK_TE("pingpong_0", PINGPONG_0, 0x7, 0, sdm845_pp_sblk_te, -1, -1), + PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, 0, sdm845_pp_sblk_te, -1, -1), +}; + +static const struct dpu_intf_cfg sc7180_intf[] = { + INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25), + INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2c0, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27), +}; + +static const struct dpu_perf_cfg sc7180_perf_data = { + .max_bw_low = 680, + .max_bw_high = 680, + .min_core_ib = 240, + .min_llcc_ib = 80, + .min_dram_ib = 160, + .min_prefill_lines = 24, + .danger_lut_tbl = {0xff, 0x, 0x0}, + .safe_lut_tbl = {0xfff0, 0xff00, 0x}, + .qos_lut_tbl = { + {.nentry = ARRAY_SIZE(sc7180_qos_linear), + .entries = sc7180_qos_linear + }, + {.nentry = ARRAY_SIZE(sc7180_qos_macrotile), + .entries = sc7180_qos_macrotile + }, + {.nentry = ARRAY_SIZE(sc7180_qos_nrt), + .entries = sc7180_qos_nrt + }, + }, + .cdp_cfg = { +
[PATCH v4 17/42] drm/msm/dpu: split SM8150 catalog entry to the separate file
Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_5_0_sm8150.h| 193 ++ .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 186 + 2 files changed, 194 insertions(+), 185 deletions(-) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h new file mode 100644 index ..6f46baad920f --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h @@ -0,0 +1,193 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved. + */ + +#ifndef _DPU_5_0_SM8150_H +#define _DPU_5_0_SM8150_H + +static const struct dpu_caps sm8150_dpu_caps = { + .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, + .max_mixer_blendstages = 0xb, + .qseed_type = DPU_SSPP_SCALER_QSEED3, + .has_src_split = true, + .has_dim_layer = true, + .has_idle_pc = true, + .has_3d_merge = true, + .max_linewidth = 4096, + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, + .max_hdeci_exp = MAX_HORZ_DECIMATION, + .max_vdeci_exp = MAX_VERT_DECIMATION, +}; + +static const struct dpu_ubwc_cfg sm8150_ubwc_cfg = { + .ubwc_version = DPU_HW_UBWC_VER_30, + .highest_bank_bit = 0x2, +}; + +static const struct dpu_ctl_cfg sm8150_ctl[] = { + { + .name = "ctl_0", .id = CTL_0, + .base = 0x1000, .len = 0x1e0, + .features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), + }, + { + .name = "ctl_1", .id = CTL_1, + .base = 0x1200, .len = 0x1e0, + .features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), + }, + { + .name = "ctl_2", .id = CTL_2, + .base = 0x1400, .len = 0x1e0, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11), + }, + { + .name = "ctl_3", .id = CTL_3, + .base = 0x1600, .len = 0x1e0, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12), + }, + { + .name = "ctl_4", .id = CTL_4, + .base = 0x1800, .len = 0x1e0, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13), + }, + { + .name = "ctl_5", .id = CTL_5, + .base = 0x1a00, .len = 0x1e0, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23), + }, +}; + +static const struct dpu_lm_cfg sm8150_lm[] = { + LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK, + &sdm845_lm_sblk, PINGPONG_0, LM_1, DSPP_0), + LM_BLK("lm_1", LM_1, 0x45000, MIXER_SDM845_MASK, + &sdm845_lm_sblk, PINGPONG_1, LM_0, DSPP_1), + LM_BLK("lm_2", LM_2, 0x46000, MIXER_SDM845_MASK, + &sdm845_lm_sblk, PINGPONG_2, LM_3, 0), + LM_BLK("lm_3", LM_3, 0x47000, MIXER_SDM845_MASK, + &sdm845_lm_sblk, PINGPONG_3, LM_2, 0), + LM_BLK("lm_4", LM_4, 0x48000, MIXER_SDM845_MASK, + &sdm845_lm_sblk, PINGPONG_4, LM_5, 0), + LM_BLK("lm_5", LM_5, 0x49000, MIXER_SDM845_MASK, + &sdm845_lm_sblk, PINGPONG_5, LM_4, 0), +}; + +static const struct dpu_dspp_cfg sm8150_dspp[] = { + DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_SC7180_MASK, +&sm8150_dspp_sblk), + DSPP_BLK("dspp_1", DSPP_1, 0x56000, DSPP_SC7180_MASK, +&sm8150_dspp_sblk), + DSPP_BLK("dspp_2", DSPP_2, 0x58000, DSPP_SC7180_MASK, +&sm8150_dspp_sblk), + DSPP_BLK("dspp_3", DSPP_3, 0x5a000, DSPP_SC7180_MASK, +&sm8150_dspp_sblk), +}; + +static const struct dpu_pingpong_cfg sm8150_pp[] = { + PP_BLK_TE("pingpong_0", PINGPONG_0, 0x7, MERGE_3D_0, sdm845_pp_sblk_te, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)), + PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0, sdm845_pp_sblk_te, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13)), + PP_BLK("pingpong_2", PINGPONG_2, 0x71000, MERGE_3D_1, sdm845_pp_sblk, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14)), + PP_BLK("pingpong_3", PINGPONG_3, 0x71800, MERGE_3D_1, sdm845_pp_sblk, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)), + PP_BLK("pingpong_4", PINGPONG_4, 0x72000, MERGE_3D_2, sdm845_pp_sblk, + DPU_I
[PATCH v4 19/42] drm/msm/dpu: split SDM845 catalog entry to the separate file
Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_4_0_sdm845.h| 202 + .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 207 +- 2 files changed, 203 insertions(+), 206 deletions(-) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h new file mode 100644 index ..3e3b9967dd12 --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h @@ -0,0 +1,202 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved. + */ + +#ifndef _DPU_4_0_SDM845_H +#define _DPU_4_0_SDM845_H + +static const struct dpu_caps sdm845_dpu_caps = { + .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, + .max_mixer_blendstages = 0xb, + .qseed_type = DPU_SSPP_SCALER_QSEED3, + .has_src_split = true, + .has_dim_layer = true, + .has_idle_pc = true, + .has_3d_merge = true, + .max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH, + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, + .max_hdeci_exp = MAX_HORZ_DECIMATION, + .max_vdeci_exp = MAX_VERT_DECIMATION, +}; + +static const struct dpu_ubwc_cfg sdm845_ubwc_cfg = { + .ubwc_version = DPU_HW_UBWC_VER_20, + .highest_bank_bit = 0x2, +}; + +static const struct dpu_mdp_cfg sdm845_mdp[] = { + { + .name = "top_0", .id = MDP_TOP, + .base = 0x0, .len = 0x45c, + .features = BIT(DPU_MDP_AUDIO_SELECT), + .clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 }, + }, +}; + +static const struct dpu_ctl_cfg sdm845_ctl[] = { + { + .name = "ctl_0", .id = CTL_0, + .base = 0x1000, .len = 0xe4, + .features = BIT(DPU_CTL_SPLIT_DISPLAY), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), + }, + { + .name = "ctl_1", .id = CTL_1, + .base = 0x1200, .len = 0xe4, + .features = BIT(DPU_CTL_SPLIT_DISPLAY), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), + }, + { + .name = "ctl_2", .id = CTL_2, + .base = 0x1400, .len = 0xe4, + .features = 0, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11), + }, + { + .name = "ctl_3", .id = CTL_3, + .base = 0x1600, .len = 0xe4, + .features = 0, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12), + }, + { + .name = "ctl_4", .id = CTL_4, + .base = 0x1800, .len = 0xe4, + .features = 0, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13), + }, +}; + +static const struct dpu_sspp_cfg sdm845_sspp[] = { + SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, 0x1c8, VIG_SDM845_MASK_SDMA, + sdm845_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), + SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, 0x1c8, VIG_SDM845_MASK_SDMA, + sdm845_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1), + SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, 0x1c8, VIG_SDM845_MASK_SDMA, + sdm845_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2), + SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, 0x1c8, VIG_SDM845_MASK_SDMA, + sdm845_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3), + SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, 0x1c8, DMA_SDM845_MASK_SDMA, + sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), + SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, 0x1c8, DMA_SDM845_MASK_SDMA, + sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1), + SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, 0x1c8, DMA_CURSOR_SDM845_MASK_SDMA, + sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2), + SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, 0x1c8, DMA_CURSOR_SDM845_MASK_SDMA, + sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3), +}; + +static const struct dpu_lm_cfg sdm845_lm[] = { + LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK, + &sdm845_lm_sblk, PINGPONG_0, LM_1, 0), + LM_BLK("lm_1", LM_1, 0x45000, MIXER_SDM845_MASK, + &sdm845_lm_sblk, PINGPONG_1, LM_0, 0), + LM_BLK("lm_2", LM_2, 0x46000, MIXER_SDM845_MASK, + &sdm845_lm_sblk, PINGPONG_2, LM_5, 0), + LM
[PATCH v4 15/42] drm/msm/dpu: split SM8250 catalog entry to the separate file
Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_6_0_sm8250.h| 130 + .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 131 +- 2 files changed, 131 insertions(+), 130 deletions(-) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h new file mode 100644 index ..92a4b21c4493 --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h @@ -0,0 +1,130 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved. + */ + +#ifndef _DPU_6_0_SM8250_H +#define _DPU_6_0_SM8250_H + +static const struct dpu_caps sm8250_dpu_caps = { + .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, + .max_mixer_blendstages = 0xb, + .qseed_type = DPU_SSPP_SCALER_QSEED4, + .has_src_split = true, + .has_dim_layer = true, + .has_idle_pc = true, + .has_3d_merge = true, + .max_linewidth = 4096, + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, +}; + +static const struct dpu_ubwc_cfg sm8250_ubwc_cfg = { + .ubwc_version = DPU_HW_UBWC_VER_40, + .highest_bank_bit = 0x3, /* TODO: 2 for LP_DDR4 */ + .ubwc_swizzle = 0x6, +}; + +static const struct dpu_mdp_cfg sm8250_mdp[] = { + { + .name = "top_0", .id = MDP_TOP, + .base = 0x0, .len = 0x494, + .features = 0, + .clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 }, + .clk_ctrls[DPU_CLK_CTRL_WB2] = { .reg_off = 0x3b8, .bit_off = 24 }, + }, +}; + +static const struct dpu_sspp_cfg sm8250_sspp[] = { + SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, 0x1f8, VIG_SC7180_MASK_SDMA, + sm8250_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), + SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, 0x1f8, VIG_SC7180_MASK_SDMA, + sm8250_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1), + SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, 0x1f8, VIG_SC7180_MASK_SDMA, + sm8250_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2), + SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, 0x1f8, VIG_SC7180_MASK_SDMA, + sm8250_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3), + SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, 0x1f8, DMA_SDM845_MASK_SDMA, + sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), + SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, 0x1f8, DMA_SDM845_MASK_SDMA, + sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1), + SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, 0x1f8, DMA_CURSOR_SDM845_MASK_SDMA, + sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2), + SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, 0x1f8, DMA_CURSOR_SDM845_MASK_SDMA, + sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3), +}; + +static const struct dpu_wb_cfg sm8250_wb[] = { + WB_BLK("wb_2", WB_2, 0x65000, WB_SM8250_MASK, DPU_CLK_CTRL_WB2, 6, + VBIF_RT, MDP_SSPP_TOP0_INTR, 4096, 4), +}; + +static const struct dpu_perf_cfg sm8250_perf_data = { + .max_bw_low = 1370, + .max_bw_high = 1660, + .min_core_ib = 480, + .min_llcc_ib = 0, + .min_dram_ib = 80, + .min_prefill_lines = 35, + .danger_lut_tbl = {0xf, 0x, 0x0}, + .safe_lut_tbl = {0xfff0, 0xff00, 0x}, + .qos_lut_tbl = { + {.nentry = ARRAY_SIZE(sc7180_qos_linear), + .entries = sc7180_qos_linear + }, + {.nentry = ARRAY_SIZE(sc7180_qos_macrotile), + .entries = sc7180_qos_macrotile + }, + {.nentry = ARRAY_SIZE(sc7180_qos_nrt), + .entries = sc7180_qos_nrt + }, + /* TODO: macrotile-qseed is different from macrotile */ + }, + .cdp_cfg = { + {.rd_enable = 1, .wr_enable = 1}, + {.rd_enable = 1, .wr_enable = 0} + }, + .clk_inefficiency_factor = 105, + .bw_inefficiency_factor = 120, +}; + +static const struct dpu_mdss_cfg sm8250_dpu_cfg = { + .caps = &sm8250_dpu_caps, + .ubwc = &
[PATCH v4 21/42] drm/msm/dpu: duplicate sc7180 catalog entries
Duplicate some of sc7180 catalog entries to remove dependencies between DPU major generations. Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h index ea34c2c7e25c..0b10e2060591 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h @@ -81,6 +81,11 @@ static const struct dpu_lm_cfg sc7280_lm[] = { &sc7180_lm_sblk, PINGPONG_3, LM_2, 0), }; +static const struct dpu_dspp_cfg sc7280_dspp[] = { + DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_SC7180_MASK, +&sc7180_dspp_sblk), +}; + static const struct dpu_pingpong_cfg sc7280_pp[] = { PP_BLK("pingpong_0", PINGPONG_0, 0x69000, 0, sc7280_pp_sblk, -1, -1), PP_BLK("pingpong_1", PINGPONG_1, 0x6a000, 0, sc7280_pp_sblk, -1, -1), @@ -131,8 +136,8 @@ static const struct dpu_mdss_cfg sc7280_dpu_cfg = { .ctl = sc7280_ctl, .sspp_count = ARRAY_SIZE(sc7280_sspp), .sspp = sc7280_sspp, - .dspp_count = ARRAY_SIZE(sc7180_dspp), - .dspp = sc7180_dspp, + .dspp_count = ARRAY_SIZE(sc7280_dspp), + .dspp = sc7280_dspp, .mixer_count = ARRAY_SIZE(sc7280_lm), .mixer = sc7280_lm, .pingpong_count = ARRAY_SIZE(sc7280_pp), -- 2.39.2
[PATCH v4 20/42] drm/msm/dpu: duplicate sdm845 catalog entries
Duplicate some of sdm845 catalog entries to remove dependencies between DPU major generations. Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 19 +++- .../msm/disp/dpu1/catalog/dpu_5_0_sm8150.h| 43 +-- .../msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 4 +- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 4 +- 4 files changed, 60 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h index 6c988b3a7325..8e6650aaa8a2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h @@ -111,6 +111,21 @@ static const struct dpu_lm_cfg msm8998_lm[] = { &msm8998_lm_sblk, PINGPONG_3, LM_1, 0), }; +static const struct dpu_pingpong_cfg msm8998_pp[] = { + PP_BLK_TE("pingpong_0", PINGPONG_0, 0x7, 0, sdm845_pp_sblk_te, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)), + PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, 0, sdm845_pp_sblk_te, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13)), + PP_BLK("pingpong_2", PINGPONG_2, 0x71000, 0, sdm845_pp_sblk, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14)), + PP_BLK("pingpong_3", PINGPONG_3, 0x71800, 0, sdm845_pp_sblk, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)), +}; + static const struct dpu_dspp_cfg msm8998_dspp[] = { DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_MSM8998_MASK, &msm8998_dspp_sblk), @@ -174,8 +189,8 @@ static const struct dpu_mdss_cfg msm8998_dpu_cfg = { .mixer = msm8998_lm, .dspp_count = ARRAY_SIZE(msm8998_dspp), .dspp = msm8998_dspp, - .pingpong_count = ARRAY_SIZE(sdm845_pp), - .pingpong = sdm845_pp, + .pingpong_count = ARRAY_SIZE(msm8998_pp), + .pingpong = msm8998_pp, .intf_count = ARRAY_SIZE(msm8998_intf), .intf = msm8998_intf, .vbif_count = ARRAY_SIZE(msm8998_vbif), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h index 6f46baad920f..6db0f64142d5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h @@ -26,6 +26,22 @@ static const struct dpu_ubwc_cfg sm8150_ubwc_cfg = { .highest_bank_bit = 0x2, }; +static const struct dpu_mdp_cfg sm8150_mdp[] = { + { + .name = "top_0", .id = MDP_TOP, + .base = 0x0, .len = 0x45c, + .features = BIT(DPU_MDP_AUDIO_SELECT), + .clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 }, + }, +}; + static const struct dpu_ctl_cfg sm8150_ctl[] = { { .name = "ctl_0", .id = CTL_0, @@ -65,6 +81,25 @@ static const struct dpu_ctl_cfg sm8150_ctl[] = { }, }; +static const struct dpu_sspp_cfg sm8150_sspp[] = { + SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, 0x1f0, VIG_SDM845_MASK, + sdm845_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), + SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, 0x1f0, VIG_SDM845_MASK, + sdm845_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1), + SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, 0x1f0, VIG_SDM845_MASK, + sdm845_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2), + SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, 0x1f0, VIG_SDM845_MASK, + sdm845_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3), + SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, 0x1f0, DMA_SDM845_MASK, + sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), + SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, 0x1f0, DMA_SDM845_MASK, + sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1), + SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, 0x1f0, DMA_CURSOR_SDM845_MASK, + sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2), + SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, 0x1f0, DMA_CURSOR_SDM845_MASK, + sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3), +}; + static const struct dpu_lm_cfg sm8150_lm[] =
[PATCH v4 24/42] drm/msm/dpu: duplicate sm8350 catalog entries
Duplicate some of sm8350 catalog entries to remove dependencies between DPU major generations. Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h index d8435c55c396..39894cbf456d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h @@ -135,6 +135,12 @@ static const struct dpu_pingpong_cfg sc8280xp_pp[] = { DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31), -1), }; +static const struct dpu_merge_3d_cfg sc8280xp_merge_3d[] = { + MERGE_3D_BLK("merge_3d_0", MERGE_3D_0, 0x4e000), + MERGE_3D_BLK("merge_3d_1", MERGE_3D_1, 0x4f000), + MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x5), +}; + /* TODO: INTF 3, 8 and 7 are used for MST, marked as INTF_NONE for now */ static const struct dpu_intf_cfg sc8280xp_intf[] = { INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 24, 25), @@ -190,8 +196,8 @@ static const struct dpu_mdss_cfg sc8280xp_dpu_cfg = { .dspp = sc8280xp_dspp, .pingpong_count = ARRAY_SIZE(sc8280xp_pp), .pingpong = sc8280xp_pp, - .merge_3d_count = ARRAY_SIZE(sm8350_merge_3d), - .merge_3d = sm8350_merge_3d, + .merge_3d_count = ARRAY_SIZE(sc8280xp_merge_3d), + .merge_3d = sc8280xp_merge_3d, .intf_count = ARRAY_SIZE(sc8280xp_intf), .intf = sc8280xp_intf, .vbif_count = ARRAY_SIZE(sdm845_vbif), -- 2.39.2
[PATCH v4 23/42] drm/msm/dpu: duplicate sm8250 catalog entries
Duplicate some of sm8250 catalog entries to remove dependencies between DPU major generations. Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_7_0_sm8350.h| 23 +-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h index 295e2370b3f2..787d67a28490 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h @@ -80,6 +80,25 @@ static const struct dpu_ctl_cfg sm8350_ctl[] = { }, }; +static const struct dpu_sspp_cfg sm8350_sspp[] = { + SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, 0x1f8, VIG_SC7180_MASK, + sm8250_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), + SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, 0x1f8, VIG_SC7180_MASK, + sm8250_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1), + SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, 0x1f8, VIG_SC7180_MASK, + sm8250_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2), + SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, 0x1f8, VIG_SC7180_MASK, + sm8250_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3), + SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, 0x1f8, DMA_SDM845_MASK, + sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), + SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, 0x1f8, DMA_SDM845_MASK, + sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1), + SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, 0x1f8, DMA_CURSOR_SDM845_MASK, + sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2), + SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, 0x1f8, DMA_CURSOR_SDM845_MASK, + sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3), +}; + static const struct dpu_lm_cfg sm8350_lm[] = { LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK, &sdm845_lm_sblk, PINGPONG_0, LM_1, DSPP_0), @@ -177,8 +196,8 @@ static const struct dpu_mdss_cfg sm8350_dpu_cfg = { .mdp = sm8350_mdp, .ctl_count = ARRAY_SIZE(sm8350_ctl), .ctl = sm8350_ctl, - .sspp_count = ARRAY_SIZE(sm8250_sspp), - .sspp = sm8250_sspp, + .sspp_count = ARRAY_SIZE(sm8350_sspp), + .sspp = sm8350_sspp, .mixer_count = ARRAY_SIZE(sm8350_lm), .mixer = sm8350_lm, .dspp_count = ARRAY_SIZE(sm8350_dspp), -- 2.39.2
[PATCH v4 27/42] drm/msm/dpu: expand sm6115 catalog
Duplicate qcm2290 catalog entries to sm6115 to remove dependencies between DPU instances. Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_6_3_sm6115.h| 50 +++ .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 2 +- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h index f6db2d42a0ed..e741cb3e7888 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h @@ -33,6 +33,15 @@ static const struct dpu_mdp_cfg sm6115_mdp[] = { }, }; +static const struct dpu_ctl_cfg sm6115_ctl[] = { + { + .name = "ctl_0", .id = CTL_0, + .base = 0x1000, .len = 0x1dc, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), + }, +}; + static const struct dpu_sspp_cfg sm6115_sspp[] = { SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, 0x1f8, VIG_SC7180_MASK, sm6115_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), @@ -40,6 +49,27 @@ static const struct dpu_sspp_cfg sm6115_sspp[] = { sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), }; +static const struct dpu_lm_cfg sm6115_lm[] = { + LM_BLK("lm_0", LM_0, 0x44000, MIXER_QCM2290_MASK, + &qcm2290_lm_sblk, PINGPONG_0, 0, DSPP_0), +}; + +static const struct dpu_dspp_cfg sm6115_dspp[] = { + DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_SC7180_MASK, +&sm8150_dspp_sblk), +}; + +static const struct dpu_pingpong_cfg sm6115_pp[] = { + PP_BLK("pingpong_0", PINGPONG_0, 0x7, 0, sdm845_pp_sblk, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)), +}; + +static const struct dpu_intf_cfg sm6115_intf[] = { + INTF_BLK("intf_0", INTF_0, 0x0, 0x280, INTF_NONE, 0, 0, 0, 0, 0, 0), + INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2c0, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27), +}; + static const struct dpu_perf_cfg sm6115_perf_data = { .max_bw_low = 310, .max_bw_high = 400, @@ -74,18 +104,18 @@ static const struct dpu_mdss_cfg sm6115_dpu_cfg = { .ubwc = &sm6115_ubwc_cfg, .mdp_count = ARRAY_SIZE(sm6115_mdp), .mdp = sm6115_mdp, - .ctl_count = ARRAY_SIZE(qcm2290_ctl), - .ctl = qcm2290_ctl, + .ctl_count = ARRAY_SIZE(sm6115_ctl), + .ctl = sm6115_ctl, .sspp_count = ARRAY_SIZE(sm6115_sspp), .sspp = sm6115_sspp, - .mixer_count = ARRAY_SIZE(qcm2290_lm), - .mixer = qcm2290_lm, - .dspp_count = ARRAY_SIZE(qcm2290_dspp), - .dspp = qcm2290_dspp, - .pingpong_count = ARRAY_SIZE(qcm2290_pp), - .pingpong = qcm2290_pp, - .intf_count = ARRAY_SIZE(qcm2290_intf), - .intf = qcm2290_intf, + .mixer_count = ARRAY_SIZE(sm6115_lm), + .mixer = sm6115_lm, + .dspp_count = ARRAY_SIZE(sm6115_dspp), + .dspp = sm6115_dspp, + .pingpong_count = ARRAY_SIZE(sm6115_pp), + .pingpong = sm6115_pp, + .intf_count = ARRAY_SIZE(sm6115_intf), + .intf = sm6115_intf, .vbif_count = ARRAY_SIZE(sdm845_vbif), .vbif = sdm845_vbif, .perf = &sm6115_perf_data, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 105fa05454e1..e338155e2b82 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -884,8 +884,8 @@ static const struct dpu_qos_lut_entry sc7180_qos_nrt[] = { #include "catalog/dpu_6_0_sm8250.h" #include "catalog/dpu_6_2_sc7180.h" -#include "catalog/dpu_6_5_qcm2290.h" #include "catalog/dpu_6_3_sm6115.h" +#include "catalog/dpu_6_5_qcm2290.h" #include "catalog/dpu_7_0_sm8350.h" #include "catalog/dpu_7_2_sc7280.h" -- 2.39.2
[PATCH v4 22/42] drm/msm/dpu: duplicate sm8150 catalog entries
Duplicate some of sm8150 catalog entries to remove dependencies between DPU major generations. Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_6_0_sm8250.h| 134 -- .../msm/disp/dpu1/catalog/dpu_7_0_sm8350.h| 34 - .../msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 15 +- .../msm/disp/dpu1/catalog/dpu_8_1_sm8450.h| 33 - .../msm/disp/dpu1/catalog/dpu_9_0_sm8550.h| 33 - 5 files changed, 221 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h index 92a4b21c4493..53a27461da05 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h @@ -43,6 +43,45 @@ static const struct dpu_mdp_cfg sm8250_mdp[] = { }, }; +static const struct dpu_ctl_cfg sm8250_ctl[] = { + { + .name = "ctl_0", .id = CTL_0, + .base = 0x1000, .len = 0x1e0, + .features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), + }, + { + .name = "ctl_1", .id = CTL_1, + .base = 0x1200, .len = 0x1e0, + .features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), + }, + { + .name = "ctl_2", .id = CTL_2, + .base = 0x1400, .len = 0x1e0, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11), + }, + { + .name = "ctl_3", .id = CTL_3, + .base = 0x1600, .len = 0x1e0, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12), + }, + { + .name = "ctl_4", .id = CTL_4, + .base = 0x1800, .len = 0x1e0, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13), + }, + { + .name = "ctl_5", .id = CTL_5, + .base = 0x1a00, .len = 0x1e0, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23), + }, +}; + static const struct dpu_sspp_cfg sm8250_sspp[] = { SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, 0x1f8, VIG_SC7180_MASK_SDMA, sm8250_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), @@ -62,6 +101,73 @@ static const struct dpu_sspp_cfg sm8250_sspp[] = { sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3), }; +static const struct dpu_lm_cfg sm8250_lm[] = { + LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK, + &sdm845_lm_sblk, PINGPONG_0, LM_1, DSPP_0), + LM_BLK("lm_1", LM_1, 0x45000, MIXER_SDM845_MASK, + &sdm845_lm_sblk, PINGPONG_1, LM_0, DSPP_1), + LM_BLK("lm_2", LM_2, 0x46000, MIXER_SDM845_MASK, + &sdm845_lm_sblk, PINGPONG_2, LM_3, 0), + LM_BLK("lm_3", LM_3, 0x47000, MIXER_SDM845_MASK, + &sdm845_lm_sblk, PINGPONG_3, LM_2, 0), + LM_BLK("lm_4", LM_4, 0x48000, MIXER_SDM845_MASK, + &sdm845_lm_sblk, PINGPONG_4, LM_5, 0), + LM_BLK("lm_5", LM_5, 0x49000, MIXER_SDM845_MASK, + &sdm845_lm_sblk, PINGPONG_5, LM_4, 0), +}; + +static const struct dpu_dspp_cfg sm8250_dspp[] = { + DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_SC7180_MASK, +&sm8150_dspp_sblk), + DSPP_BLK("dspp_1", DSPP_1, 0x56000, DSPP_SC7180_MASK, +&sm8150_dspp_sblk), + DSPP_BLK("dspp_2", DSPP_2, 0x58000, DSPP_SC7180_MASK, +&sm8150_dspp_sblk), + DSPP_BLK("dspp_3", DSPP_3, 0x5a000, DSPP_SC7180_MASK, +&sm8150_dspp_sblk), +}; + +static const struct dpu_pingpong_cfg sm8250_pp[] = { + PP_BLK_TE("pingpong_0", PINGPONG_0, 0x7, MERGE_3D_0, sdm845_pp_sblk_te, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)), + PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0, sdm845_pp_sblk_te, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13)), + PP_BLK("pingpong_2", PINGPONG_2, 0x71000, MERGE_3D_1, sdm845_pp_sblk, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14)), + PP_BLK("pingpong_3", PINGPONG_3, 0x71800, MERGE_3D_1, sdm845_pp_sblk, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)), + PP_BLK("pingpong_4", PINGPONG_4, 0x72000, MERGE_3D_2, sdm845_pp_sblk, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), + -1), + PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2, sdm845_pp_sblk, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31), + -1), +}; + +static const struct dpu_m
[PATCH v4 28/42] drm/msm/dpu: expand sm8550 catalog
Duplicate sm8450 catalog entries to sm8550 to remove dependencies between DPU instances. Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_9_0_sm8550.h| 32 ++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h index 95bb8dbdecc3..c7247a5739f1 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h @@ -172,6 +172,36 @@ static const struct dpu_intf_cfg sm8550_intf[] = { INTF_BLK("intf_3", INTF_3, 0x37000, 0x280, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 30, 31), }; +static const struct dpu_perf_cfg sm8550_perf_data = { + .max_bw_low = 1360, + .max_bw_high = 1820, + .min_core_ib = 250, + .min_llcc_ib = 0, + .min_dram_ib = 80, + .min_prefill_lines = 35, + /* FIXME: lut tables */ + .danger_lut_tbl = {0x3, 0x3, 0x0}, + .safe_lut_tbl = {0xfe00, 0xfe00, 0x}, + .qos_lut_tbl = { + {.nentry = ARRAY_SIZE(sc7180_qos_linear), + .entries = sc7180_qos_linear + }, + {.nentry = ARRAY_SIZE(sc7180_qos_macrotile), + .entries = sc7180_qos_macrotile + }, + {.nentry = ARRAY_SIZE(sc7180_qos_nrt), + .entries = sc7180_qos_nrt + }, + /* TODO: macrotile-qseed is different from macrotile */ + }, + .cdp_cfg = { + {.rd_enable = 1, .wr_enable = 1}, + {.rd_enable = 1, .wr_enable = 0} + }, + .clk_inefficiency_factor = 105, + .bw_inefficiency_factor = 120, +}; + static const struct dpu_mdss_cfg sm8550_dpu_cfg = { .caps = &sm8550_dpu_caps, .ubwc = &sm8550_ubwc_cfg, @@ -195,7 +225,7 @@ static const struct dpu_mdss_cfg sm8550_dpu_cfg = { .vbif = sdm845_vbif, .reg_dma_count = 1, .dma_cfg = &sm8450_regdma, - .perf = &sm8450_perf_data, + .perf = &sm8550_perf_data, .mdss_irqs = IRQ_SM8450_MASK, }; -- 2.39.2
[PATCH v4 25/42] drm/msm/dpu: expand sc8180x catalog
Duplicate sm8150 catalog entries to sc8180x to remove dependencies between DPU instances. Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 120 -- 1 file changed, 110 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h index 5a426b881e20..fb8cdcd6bfe9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h @@ -42,6 +42,106 @@ static const struct dpu_mdp_cfg sc8180x_mdp[] = { }, }; +static const struct dpu_ctl_cfg sc8180x_ctl[] = { + { + .name = "ctl_0", .id = CTL_0, + .base = 0x1000, .len = 0x1e0, + .features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), + }, + { + .name = "ctl_1", .id = CTL_1, + .base = 0x1200, .len = 0x1e0, + .features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), + }, + { + .name = "ctl_2", .id = CTL_2, + .base = 0x1400, .len = 0x1e0, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11), + }, + { + .name = "ctl_3", .id = CTL_3, + .base = 0x1600, .len = 0x1e0, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12), + }, + { + .name = "ctl_4", .id = CTL_4, + .base = 0x1800, .len = 0x1e0, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13), + }, + { + .name = "ctl_5", .id = CTL_5, + .base = 0x1a00, .len = 0x1e0, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23), + }, +}; + +static const struct dpu_sspp_cfg sc8180x_sspp[] = { + SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, 0x1f0, VIG_SDM845_MASK, + sdm845_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), + SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, 0x1f0, VIG_SDM845_MASK, + sdm845_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1), + SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, 0x1f0, VIG_SDM845_MASK, + sdm845_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2), + SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, 0x1f0, VIG_SDM845_MASK, + sdm845_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3), + SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, 0x1f0, DMA_SDM845_MASK, + sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), + SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, 0x1f0, DMA_SDM845_MASK, + sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1), + SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, 0x1f0, DMA_CURSOR_SDM845_MASK, + sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2), + SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, 0x1f0, DMA_CURSOR_SDM845_MASK, + sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3), +}; + +static const struct dpu_lm_cfg sc8180x_lm[] = { + LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK, + &sdm845_lm_sblk, PINGPONG_0, LM_1, 0), + LM_BLK("lm_1", LM_1, 0x45000, MIXER_SDM845_MASK, + &sdm845_lm_sblk, PINGPONG_1, LM_0, 0), + LM_BLK("lm_2", LM_2, 0x46000, MIXER_SDM845_MASK, + &sdm845_lm_sblk, PINGPONG_2, LM_3, 0), + LM_BLK("lm_3", LM_3, 0x47000, MIXER_SDM845_MASK, + &sdm845_lm_sblk, PINGPONG_3, LM_2, 0), + LM_BLK("lm_4", LM_4, 0x48000, MIXER_SDM845_MASK, + &sdm845_lm_sblk, PINGPONG_4, LM_5, 0), + LM_BLK("lm_5", LM_5, 0x49000, MIXER_SDM845_MASK, + &sdm845_lm_sblk, PINGPONG_5, LM_4, 0), +}; + +static const struct dpu_pingpong_cfg sc8180x_pp[] = { + PP_BLK_TE("pingpong_0", PINGPONG_0, 0x7, MERGE_3D_0, sdm845_pp_sblk_te, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)), + PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0, sdm845_pp_sblk_te, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13)), + PP_BLK("pingpong_2", PINGPONG_2, 0x71000, MERGE_3D_1, sdm845_pp_sblk, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14)), + PP_BLK("pingpong_3", PINGPONG_3, 0x71800, MERGE_3D_1, sdm845_pp_sblk, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)), + PP_BLK("pingpong_4", PINGPONG_4, 0x72000, MERGE_3D_2, sdm845_pp_sblk, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), + -1), + PP_BLK("pingpong_5", PINGPONG_5, 0x72800,
[PATCH v4 29/42] drm/msm/dpu: use defined symbol for sc8280xp's maxwidth
Use defined name DEFAULT_DPU_OUTPUT_LINE_WIDTH instead of open coding the value. Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h index 39894cbf456d..d30b797e90e0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h @@ -8,7 +8,7 @@ #define _DPU_8_0_SC8280XP_H static const struct dpu_caps sc8280xp_dpu_caps = { - .max_mixer_width = 2560, + .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, .max_mixer_blendstages = 11, .qseed_type = DPU_SSPP_SCALER_QSEED4, .has_src_split = true, -- 2.39.2
[PATCH v4 26/42] drm/msm/dpu: expand sc7180 catalog
Duplicate sm8250 catalog entries to sc7180 to remove dependencies between DPU instances. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h index 2326be2900ea..433f7b259f7b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h @@ -89,6 +89,11 @@ static const struct dpu_intf_cfg sc7180_intf[] = { INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2c0, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27), }; +static const struct dpu_wb_cfg sc7180_wb[] = { + WB_BLK("wb_2", WB_2, 0x65000, WB_SM8250_MASK, DPU_CLK_CTRL_WB2, 6, + VBIF_RT, MDP_SSPP_TOP0_INTR, 4096, 4), +}; + static const struct dpu_perf_cfg sc7180_perf_data = { .max_bw_low = 680, .max_bw_high = 680, @@ -134,8 +139,8 @@ static const struct dpu_mdss_cfg sc7180_dpu_cfg = { .pingpong = sc7180_pp, .intf_count = ARRAY_SIZE(sc7180_intf), .intf = sc7180_intf, - .wb_count = ARRAY_SIZE(sm8250_wb), - .wb = sm8250_wb, + .wb_count = ARRAY_SIZE(sc7180_wb), + .wb = sc7180_wb, .vbif_count = ARRAY_SIZE(sdm845_vbif), .vbif = sdm845_vbif, .reg_dma_count = 1, -- 2.39.2
[PATCH v4 30/42] drm/msm/dpu: catalog: add comments regarding DPU_CTL_SPLIT_DISPLAY
For sm8150+ the DPU_CTL_SPLIT_DISPLAY should be replaced with DPU_CTL_ACTIVE_CFG support (which supports having a single CTL for both interfaces in a split). Add comments where this conversion is required. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 1 + drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 1 + drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 1 + drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 1 + drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 1 + 5 files changed, 5 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h index 6db0f64142d5..29bcbc88cd5a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h @@ -42,6 +42,7 @@ static const struct dpu_mdp_cfg sm8150_mdp[] = { }, }; +/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */ static const struct dpu_ctl_cfg sm8150_ctl[] = { { .name = "ctl_0", .id = CTL_0, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h index 53a27461da05..233ea66155bd 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h @@ -43,6 +43,7 @@ static const struct dpu_mdp_cfg sm8250_mdp[] = { }, }; +/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */ static const struct dpu_ctl_cfg sm8250_ctl[] = { { .name = "ctl_0", .id = CTL_0, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h index 787d67a28490..a5818878ee0a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h @@ -41,6 +41,7 @@ static const struct dpu_mdp_cfg sm8350_mdp[] = { }, }; +/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */ static const struct dpu_ctl_cfg sm8350_ctl[] = { { .name = "ctl_0", .id = CTL_0, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h index e7272bc7670a..6f573e28582e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h @@ -42,6 +42,7 @@ static const struct dpu_mdp_cfg sm8450_mdp[] = { }, }; +/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */ static const struct dpu_ctl_cfg sm8450_ctl[] = { { .name = "ctl_0", .id = CTL_0, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h index c7247a5739f1..9acd9fcf39a1 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h @@ -43,6 +43,7 @@ static const struct dpu_mdp_cfg sm8550_mdp[] = { }, }; +/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */ static const struct dpu_ctl_cfg sm8550_ctl[] = { { .name = "ctl_0", .id = CTL_0, -- 2.39.2
[PATCH v4 31/42] drm/msm/dpu: enable DPU_CTL_SPLIT_DISPLAY for sc8280xp
Theoretically since sm8150 we should be using a single CTL for the source split case, but since we do not support it for now, fallback to DPU_CTL_SPLIT_DISPLAY. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h index d30b797e90e0..3dc850a681bb 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h @@ -42,17 +42,18 @@ static const struct dpu_mdp_cfg sc8280xp_mdp[] = { }, }; +/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */ static const struct dpu_ctl_cfg sc8280xp_ctl[] = { { .name = "ctl_0", .id = CTL_0, .base = 0x15000, .len = 0x204, - .features = CTL_SC7280_MASK, + .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), }, { .name = "ctl_1", .id = CTL_1, .base = 0x16000, .len = 0x204, - .features = CTL_SC7280_MASK, + .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), }, { -- 2.39.2
[PATCH v4 32/42] drm/msm/dpu: enable DSPP_2/3 for LM_2/3 on sm8450
Mark DSPP_2 and DSPP_3 as used for LM_2 and LM_3 Fixes: 100d7ef6995d ("drm/msm/dpu: add support for SM8450") Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h index 6f573e28582e..cae08b5207ff 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h @@ -107,9 +107,9 @@ static const struct dpu_lm_cfg sm8450_lm[] = { LM_BLK("lm_1", LM_1, 0x45000, MIXER_SDM845_MASK, &sdm845_lm_sblk, PINGPONG_1, LM_0, DSPP_1), LM_BLK("lm_2", LM_2, 0x46000, MIXER_SDM845_MASK, - &sdm845_lm_sblk, PINGPONG_2, LM_3, 0), + &sdm845_lm_sblk, PINGPONG_2, LM_3, DSPP_2), LM_BLK("lm_3", LM_3, 0x47000, MIXER_SDM845_MASK, - &sdm845_lm_sblk, PINGPONG_3, LM_2, 0), + &sdm845_lm_sblk, PINGPONG_3, LM_2, DSPP_3), LM_BLK("lm_4", LM_4, 0x48000, MIXER_SDM845_MASK, &sdm845_lm_sblk, PINGPONG_4, LM_5, 0), LM_BLK("lm_5", LM_5, 0x49000, MIXER_SDM845_MASK, -- 2.39.2
[PATCH v4 35/42] drm/msm/dpu: inline IRQ_n_MASK defines
IRQ masks are rarely shared between different DPU revisions. Inline them to the dpu_mdss_cfg intances and drop them from the dpu_hw_catalog.c Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 9 ++- .../msm/disp/dpu1/catalog/dpu_4_0_sdm845.h| 10 ++- .../msm/disp/dpu1/catalog/dpu_5_0_sm8150.h| 10 ++- .../msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 12 ++- .../msm/disp/dpu1/catalog/dpu_6_0_sm8250.h| 9 ++- .../msm/disp/dpu1/catalog/dpu_6_2_sc7180.h| 6 +- .../msm/disp/dpu1/catalog/dpu_6_3_sm6115.h| 6 +- .../msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 6 +- .../msm/disp/dpu1/catalog/dpu_7_0_sm8350.h| 8 +- .../msm/disp/dpu1/catalog/dpu_7_2_sc7280.h| 7 +- .../msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 13 +++- .../msm/disp/dpu1/catalog/dpu_8_1_sm8450.h| 8 +- .../msm/disp/dpu1/catalog/dpu_9_0_sm8550.h| 8 +- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 73 --- 14 files changed, 99 insertions(+), 86 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h index 8e6650aaa8a2..e5a42ebda4d7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h @@ -197,7 +197,14 @@ static const struct dpu_mdss_cfg msm8998_dpu_cfg = { .vbif = msm8998_vbif, .reg_dma_count = 0, .perf = &msm8998_perf_data, - .mdss_irqs = IRQ_SM8250_MASK, + .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ +BIT(MDP_SSPP_TOP0_INTR2) | \ +BIT(MDP_SSPP_TOP0_HIST_INTR) | \ +BIT(MDP_INTF0_INTR) | \ +BIT(MDP_INTF1_INTR) | \ +BIT(MDP_INTF2_INTR) | \ +BIT(MDP_INTF3_INTR) | \ +BIT(MDP_INTF4_INTR), }; #endif diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h index 3e3b9967dd12..46b0e9e50ced 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h @@ -196,7 +196,15 @@ static const struct dpu_mdss_cfg sdm845_dpu_cfg = { .reg_dma_count = 1, .dma_cfg = &sdm845_regdma, .perf = &sdm845_perf_data, - .mdss_irqs = IRQ_SDM845_MASK, + .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ +BIT(MDP_SSPP_TOP0_INTR2) | \ +BIT(MDP_SSPP_TOP0_HIST_INTR) | \ +BIT(MDP_INTF0_INTR) | \ +BIT(MDP_INTF1_INTR) | \ +BIT(MDP_INTF2_INTR) | \ +BIT(MDP_INTF3_INTR) | \ +BIT(MDP_AD4_0_INTR) | \ +BIT(MDP_AD4_1_INTR), }; #endif diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h index 29bcbc88cd5a..0d9c627b467b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h @@ -223,7 +223,15 @@ static const struct dpu_mdss_cfg sm8150_dpu_cfg = { .reg_dma_count = 1, .dma_cfg = &sm8150_regdma, .perf = &sm8150_perf_data, - .mdss_irqs = IRQ_SDM845_MASK, + .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ +BIT(MDP_SSPP_TOP0_INTR2) | \ +BIT(MDP_SSPP_TOP0_HIST_INTR) | \ +BIT(MDP_INTF0_INTR) | \ +BIT(MDP_INTF1_INTR) | \ +BIT(MDP_INTF2_INTR) | \ +BIT(MDP_INTF3_INTR) | \ +BIT(MDP_AD4_0_INTR) | \ +BIT(MDP_AD4_1_INTR), }; #endif diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h index 93d303cc0dc5..57272b9a8e3b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h @@ -223,7 +223,17 @@ static const struct dpu_mdss_cfg sc8180x_dpu_cfg = { .reg_dma_count = 1, .dma_cfg = &sm8150_regdma, .perf = &sc8180x_perf_data, - .mdss_irqs = IRQ_SC8180X_MASK, + .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ +BIT(MDP_SSPP_TOP0_INTR2) | \ +BIT(MDP_SSPP_TOP0_HIST_INTR) | \ +BIT(MDP_INTF0_INTR) | \ +BIT(MDP_INTF1_INTR) | \ +BIT(MDP_INTF2_INTR) | \ +BIT(MDP_INTF3_INTR) | \ +BIT(MDP_INTF4_INTR) | \ +BIT(MDP_INTF5_INTR) | \ +BIT(MDP_AD4_0_INTR) | \ +BIT(MDP_AD4_1_INTR), }; #endif diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h index 233ea66155bd..857f8aab4e0d 100644
[PATCH v4 34/42] drm/msm/dpu: enable DSPP and DSC on sc8180x
Enable DSPP and DSC hardware blocks on sc8180x platform. Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 26 +-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h index fb8cdcd6bfe9..93d303cc0dc5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h @@ -102,9 +102,9 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { static const struct dpu_lm_cfg sc8180x_lm[] = { LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK, - &sdm845_lm_sblk, PINGPONG_0, LM_1, 0), + &sdm845_lm_sblk, PINGPONG_0, LM_1, DSPP_0), LM_BLK("lm_1", LM_1, 0x45000, MIXER_SDM845_MASK, - &sdm845_lm_sblk, PINGPONG_1, LM_0, 0), + &sdm845_lm_sblk, PINGPONG_1, LM_0, DSPP_1), LM_BLK("lm_2", LM_2, 0x46000, MIXER_SDM845_MASK, &sdm845_lm_sblk, PINGPONG_2, LM_3, 0), LM_BLK("lm_3", LM_3, 0x47000, MIXER_SDM845_MASK, @@ -115,6 +115,17 @@ static const struct dpu_lm_cfg sc8180x_lm[] = { &sdm845_lm_sblk, PINGPONG_5, LM_4, 0), }; +static const struct dpu_dspp_cfg sc8180x_dspp[] = { + DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_SC7180_MASK, +&sm8150_dspp_sblk), + DSPP_BLK("dspp_1", DSPP_1, 0x56000, DSPP_SC7180_MASK, +&sm8150_dspp_sblk), + DSPP_BLK("dspp_2", DSPP_2, 0x58000, DSPP_SC7180_MASK, +&sm8150_dspp_sblk), + DSPP_BLK("dspp_3", DSPP_3, 0x5a000, DSPP_SC7180_MASK, +&sm8150_dspp_sblk), +}; + static const struct dpu_pingpong_cfg sc8180x_pp[] = { PP_BLK_TE("pingpong_0", PINGPONG_0, 0x7, MERGE_3D_0, sdm845_pp_sblk_te, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), @@ -142,6 +153,13 @@ static const struct dpu_merge_3d_cfg sc8180x_merge_3d[] = { MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x83200), }; +static const struct dpu_dsc_cfg sc8180x_dsc[] = { + DSC_BLK("dsc_0", DSC_0, 0x8, BIT(DPU_DSC_OUTPUT_CTRL)), + DSC_BLK("dsc_1", DSC_1, 0x80400, BIT(DPU_DSC_OUTPUT_CTRL)), + DSC_BLK("dsc_2", DSC_2, 0x80800, BIT(DPU_DSC_OUTPUT_CTRL)), + DSC_BLK("dsc_3", DSC_3, 0x80c00, BIT(DPU_DSC_OUTPUT_CTRL)), +}; + static const struct dpu_intf_cfg sc8180x_intf[] = { INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25), INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2bc, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27), @@ -190,6 +208,10 @@ static const struct dpu_mdss_cfg sc8180x_dpu_cfg = { .sspp = sc8180x_sspp, .mixer_count = ARRAY_SIZE(sc8180x_lm), .mixer = sc8180x_lm, + .dspp_count = ARRAY_SIZE(sc8180x_dspp), + .dspp = sc8180x_dspp, + .dsc_count = ARRAY_SIZE(sc8180x_dsc), + .dsc = sc8180x_dsc, .pingpong_count = ARRAY_SIZE(sc8180x_pp), .pingpong = sc8180x_pp, .merge_3d_count = ARRAY_SIZE(sc8180x_merge_3d), -- 2.39.2
[PATCH v4 36/42] drm/msm/dpu: rename INTF_foo_MASK to contain major DPU version
To ease review and reuse rename INTF feature masks to contain base DPU version since which this mask is used. Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_3_0_msm8998.h| 8 .../drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h | 8 .../drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 8 .../msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h| 12 ++-- .../drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 8 .../drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h | 4 ++-- .../drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h | 2 +- .../msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h| 2 +- .../drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 8 .../drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 6 +++--- .../msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 18 +- .../drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 8 .../drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 8 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 9 + 14 files changed, 55 insertions(+), 54 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h index e5a42ebda4d7..3f1931808c3f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h @@ -134,10 +134,10 @@ static const struct dpu_dspp_cfg msm8998_dspp[] = { }; static const struct dpu_intf_cfg msm8998_intf[] = { - INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25), - INTF_BLK("intf_1", INTF_1, 0x6a800, 0x280, INTF_DSI, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27), - INTF_BLK("intf_2", INTF_2, 0x6b000, 0x280, INTF_DSI, 1, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 28, 29), - INTF_BLK("intf_3", INTF_3, 0x6b800, 0x280, INTF_HDMI, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 30, 31), + INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, 0, 25, INTF_DPU_0_MASK, MDP_SSPP_TOP0_INTR, 24, 25), + INTF_BLK("intf_1", INTF_1, 0x6a800, 0x280, INTF_DSI, 0, 25, INTF_DPU_0_MASK, MDP_SSPP_TOP0_INTR, 26, 27), + INTF_BLK("intf_2", INTF_2, 0x6b000, 0x280, INTF_DSI, 1, 25, INTF_DPU_0_MASK, MDP_SSPP_TOP0_INTR, 28, 29), + INTF_BLK("intf_3", INTF_3, 0x6b800, 0x280, INTF_HDMI, 0, 25, INTF_DPU_0_MASK, MDP_SSPP_TOP0_INTR, 30, 31), }; static const struct dpu_perf_cfg msm8998_perf_data = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h index 46b0e9e50ced..eb008a05af37 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h @@ -132,10 +132,10 @@ static const struct dpu_dsc_cfg sdm845_dsc[] = { }; static const struct dpu_intf_cfg sdm845_intf[] = { - INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, 0, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25), - INTF_BLK("intf_1", INTF_1, 0x6a800, 0x280, INTF_DSI, 0, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27), - INTF_BLK("intf_2", INTF_2, 0x6b000, 0x280, INTF_DSI, 1, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 28, 29), - INTF_BLK("intf_3", INTF_3, 0x6b800, 0x280, INTF_DP, 1, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 30, 31), + INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, 0, 24, INTF_DPU_0_MASK, MDP_SSPP_TOP0_INTR, 24, 25), + INTF_BLK("intf_1", INTF_1, 0x6a800, 0x280, INTF_DSI, 0, 24, INTF_DPU_0_MASK, MDP_SSPP_TOP0_INTR, 26, 27), + INTF_BLK("intf_2", INTF_2, 0x6b000, 0x280, INTF_DSI, 1, 24, INTF_DPU_0_MASK, MDP_SSPP_TOP0_INTR, 28, 29), + INTF_BLK("intf_3", INTF_3, 0x6b800, 0x280, INTF_DP, 1, 24, INTF_DPU_0_MASK, MDP_SSPP_TOP0_INTR, 30, 31), }; static const struct dpu_perf_cfg sdm845_perf_data = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h index 0d9c627b467b..a18ae2bb28ab 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h @@ -162,10 +162,10 @@ static const struct dpu_dsc_cfg sm8150_dsc[] = { }; static const struct dpu_intf_cfg sm8150_intf[] = { - INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25), - INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2bc, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27), - INTF_BLK("intf_2", INTF_2, 0x6b000, 0x2bc, INTF_DSI, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 28, 29), - INTF_BLK("intf_3", INTF_3, 0x6b800, 0x280, INTF_DP, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 30, 31), + INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, 0, 24, INTF_DPU_5_MASK, MDP_SSPP_TOP0_INTR, 24, 25), + INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2bc, INTF_DSI, 0, 24, INTF_DPU_5_MASK, MDP_SSPP_TOP0_IN
[PATCH v4 33/42] drm/msm/dpu: drop duplicate vig_sblk instances
After fixing scaler version we are sure that sm8450 and sc8280xp vig sblk's are duplicates of sm8250_vig_sblk and thus can be dropped. Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 8 .../drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 8 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 18 -- 3 files changed, 8 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h index 3dc850a681bb..b2160cf5a049 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h @@ -84,13 +84,13 @@ static const struct dpu_ctl_cfg sc8280xp_ctl[] = { static const struct dpu_sspp_cfg sc8280xp_sspp[] = { SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, 0x2ac, VIG_SC7180_MASK, -sc8280xp_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), +sm8250_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, 0x2ac, VIG_SC7180_MASK, -sc8280xp_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1), +sm8250_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1), SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, 0x2ac, VIG_SC7180_MASK, -sc8280xp_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2), +sm8250_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2), SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, 0x2ac, VIG_SC7180_MASK, -sc8280xp_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3), +sm8250_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3), SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, 0x2ac, DMA_SDM845_MASK, sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, 0x2ac, DMA_SDM845_MASK, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h index cae08b5207ff..2e52ae045ceb 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h @@ -84,13 +84,13 @@ static const struct dpu_ctl_cfg sm8450_ctl[] = { static const struct dpu_sspp_cfg sm8450_sspp[] = { SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, 0x328, VIG_SC7180_MASK, - sm8450_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), + sm8250_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, 0x328, VIG_SC7180_MASK, - sm8450_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1), + sm8250_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1), SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, 0x328, VIG_SC7180_MASK, - sm8450_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2), + sm8250_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2), SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, 0x328, VIG_SC7180_MASK, - sm8450_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3), + sm8250_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3), SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, 0x328, DMA_SDM845_MASK, sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, 0x328, DMA_SDM845_MASK, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index e338155e2b82..547546d85474 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -432,15 +432,6 @@ static const struct dpu_sspp_sub_blks sm8250_vig_sblk_2 = static const struct dpu_sspp_sub_blks sm8250_vig_sblk_3 = _VIG_SBLK("3", 8, DPU_SSPP_SCALER_QSEED4); -static const struct dpu_sspp_sub_blks sm8450_vig_sblk_0 = - _VIG_SBLK("0", 5, DPU_SSPP_SCALER_QSEED4); -static const struct dpu_sspp_sub_blks sm8450_vig_sblk_1 = - _VIG_SBLK("1", 6, DPU_SSPP_SCALER_QSEED4); -static const struct dpu_sspp_sub_blks sm8450_vig_sblk_2 = - _VIG_SBLK("2", 7, DPU_SSPP_SCALER_QSEED4); -static const struct dpu_sspp_sub_blks sm8450_vig_sblk_3 = - _VIG_SBLK("3", 8, DPU_SSPP_SCALER_QSEED4); - static const struct dpu_sspp_sub_blks sm8550_vig_sblk_0 = _VIG_SBLK("0", 7, DPU_SSPP_SCALER_QSEED4); static const struct dpu_sspp_sub_blks sm8550_vig_sblk_1 = @@ -452,15 +443,6 @@ static const struct dpu_sspp_sub_blks sm8550_vig_sblk_3 = static const struct dpu_sspp_sub_blks sm8550_dma_sblk_4 = _DMA_SBLK("12", 5); static const struct dpu_sspp_sub_blks sm8550_dma_sblk_5 = _DMA_SBLK("13", 6); -static const struct dpu_sspp_sub_blks sc8280xp_vig_sblk_0 = - _VI
[PATCH v4 38/42] drm/msm/dpu: rename VIG and DMA_foo_MASK to contain major DPU version
To ease review and reuse rename VIG and DMA feature masks to contain base DPU version since which this mask is used. Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 16 +++ .../msm/disp/dpu1/catalog/dpu_4_0_sdm845.h| 16 +++ .../msm/disp/dpu1/catalog/dpu_5_0_sm8150.h| 16 +++ .../msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 16 +++ .../msm/disp/dpu1/catalog/dpu_6_0_sm8250.h| 16 +++ .../msm/disp/dpu1/catalog/dpu_6_2_sc7180.h| 8 ++-- .../msm/disp/dpu1/catalog/dpu_6_3_sm6115.h| 4 +- .../msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 4 +- .../msm/disp/dpu1/catalog/dpu_7_0_sm8350.h| 16 +++ .../msm/disp/dpu1/catalog/dpu_7_2_sc7280.h| 8 ++-- .../msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 16 +++ .../msm/disp/dpu1/catalog/dpu_8_1_sm8450.h| 16 +++ .../msm/disp/dpu1/catalog/dpu_9_0_sm8550.h| 20 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 48 +-- 14 files changed, 110 insertions(+), 110 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h index 6afabd251a9d..f8893f0f3886 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h @@ -78,21 +78,21 @@ static const struct dpu_ctl_cfg msm8998_ctl[] = { }; static const struct dpu_sspp_cfg msm8998_sspp[] = { - SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, 0x1ac, VIG_MSM8998_MASK, + SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, 0x1ac, VIG_DPU_3_MASK, msm8998_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), - SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, 0x1ac, VIG_MSM8998_MASK, + SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, 0x1ac, VIG_DPU_3_MASK, msm8998_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1), - SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, 0x1ac, VIG_MSM8998_MASK, + SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, 0x1ac, VIG_DPU_3_MASK, msm8998_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2), - SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, 0x1ac, VIG_MSM8998_MASK, + SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, 0x1ac, VIG_DPU_3_MASK, msm8998_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3), - SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, 0x1ac, DMA_MSM8998_MASK, + SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, 0x1ac, DMA_DPU_3_MASK, sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), - SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, 0x1ac, DMA_MSM8998_MASK, + SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, 0x1ac, DMA_DPU_3_MASK, sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1), - SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, 0x1ac, DMA_CURSOR_MSM8998_MASK, + SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, 0x1ac, DMA_DPU_3_CURSOR_MASK, sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2), - SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, 0x1ac, DMA_CURSOR_MSM8998_MASK, + SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, 0x1ac, DMA_DPU_3_CURSOR_MASK, sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3), }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h index cace399551cd..339627ac4189 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h @@ -76,21 +76,21 @@ static const struct dpu_ctl_cfg sdm845_ctl[] = { }; static const struct dpu_sspp_cfg sdm845_sspp[] = { - SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, 0x1c8, VIG_SDM845_MASK_SDMA, + SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, 0x1c8, VIG_DPU_4_SDMA_MASK, sdm845_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), - SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, 0x1c8, VIG_SDM845_MASK_SDMA, + SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, 0x1c8, VIG_DPU_4_SDMA_MASK, sdm845_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1), - SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, 0x1c8, VIG_SDM845_MASK_SDMA, + SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, 0x1c8, VIG_DPU_4_SDMA_MASK, sdm845_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2), - SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, 0x1c8, VIG_SDM845_MASK_SDMA, + SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, 0x1c8, VIG_DPU_4_SDMA_MASK, sdm845_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3), - SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, 0x1c8, DMA_SDM845_MASK_SDMA, + SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, 0x1c8, DMA_DPU_4_SDMA_MASK, sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), - SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, 0x1c8, DMA_SDM845_MASK_SDMA, + SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, 0x1c8, DMA_DPU_4_SDMA_MASK, sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_D
[PATCH v4 39/42] drm/msm/dpu: rename MIXER_foo_MASK to contain major DPU version
To ease review and reuse rename MIXER feature masks to contain base DPU version since which this mask is used. Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 12 ++-- .../gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h | 12 ++-- .../gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 12 ++-- .../gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 12 ++-- .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 12 ++-- .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h | 4 ++-- .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h | 4 +++- .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 1 + .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 12 ++-- .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 6 +++--- .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 12 ++-- .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 12 ++-- .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 12 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 9 +++-- 14 files changed, 66 insertions(+), 66 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h index f8893f0f3886..a34e9506e6d4 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h @@ -97,17 +97,17 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { }; static const struct dpu_lm_cfg msm8998_lm[] = { - LM_BLK("lm_0", LM_0, 0x44000, MIXER_MSM8998_MASK, + LM_BLK("lm_0", LM_0, 0x44000, MIXER_DPU_3_MASK, &msm8998_lm_sblk, PINGPONG_0, LM_2, DSPP_0), - LM_BLK("lm_1", LM_1, 0x45000, MIXER_MSM8998_MASK, + LM_BLK("lm_1", LM_1, 0x45000, MIXER_DPU_3_MASK, &msm8998_lm_sblk, PINGPONG_1, LM_5, DSPP_1), - LM_BLK("lm_2", LM_2, 0x46000, MIXER_MSM8998_MASK, + LM_BLK("lm_2", LM_2, 0x46000, MIXER_DPU_3_MASK, &msm8998_lm_sblk, PINGPONG_2, LM_0, 0), - LM_BLK("lm_3", LM_3, 0x47000, MIXER_MSM8998_MASK, + LM_BLK("lm_3", LM_3, 0x47000, MIXER_DPU_3_MASK, &msm8998_lm_sblk, PINGPONG_MAX, 0, 0), - LM_BLK("lm_4", LM_4, 0x48000, MIXER_MSM8998_MASK, + LM_BLK("lm_4", LM_4, 0x48000, MIXER_DPU_3_MASK, &msm8998_lm_sblk, PINGPONG_MAX, 0, 0), - LM_BLK("lm_5", LM_5, 0x49000, MIXER_MSM8998_MASK, + LM_BLK("lm_5", LM_5, 0x49000, MIXER_DPU_3_MASK, &msm8998_lm_sblk, PINGPONG_3, LM_1, 0), }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h index 339627ac4189..d247f8d0c0be 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h @@ -95,17 +95,17 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = { }; static const struct dpu_lm_cfg sdm845_lm[] = { - LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK, + LM_BLK("lm_0", LM_0, 0x44000, MIXER_DPU_4_MASK, &sdm845_lm_sblk, PINGPONG_0, LM_1, 0), - LM_BLK("lm_1", LM_1, 0x45000, MIXER_SDM845_MASK, + LM_BLK("lm_1", LM_1, 0x45000, MIXER_DPU_4_MASK, &sdm845_lm_sblk, PINGPONG_1, LM_0, 0), - LM_BLK("lm_2", LM_2, 0x46000, MIXER_SDM845_MASK, + LM_BLK("lm_2", LM_2, 0x46000, MIXER_DPU_4_MASK, &sdm845_lm_sblk, PINGPONG_2, LM_5, 0), - LM_BLK("lm_3", LM_3, 0x0, MIXER_SDM845_MASK, + LM_BLK("lm_3", LM_3, 0x0, MIXER_DPU_4_MASK, &sdm845_lm_sblk, PINGPONG_MAX, 0, 0), - LM_BLK("lm_4", LM_4, 0x0, MIXER_SDM845_MASK, + LM_BLK("lm_4", LM_4, 0x0, MIXER_DPU_4_MASK, &sdm845_lm_sblk, PINGPONG_MAX, 0, 0), - LM_BLK("lm_5", LM_5, 0x49000, MIXER_SDM845_MASK, + LM_BLK("lm_5", LM_5, 0x49000, MIXER_DPU_4_MASK, &sdm845_lm_sblk, PINGPONG_3, LM_2, 0), }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h index 573acfd5356f..15277f9627ae 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h @@ -102,17 +102,17 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { }; static const struct dpu_lm_cfg sm8150_lm[] = { - LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK, + LM_BLK("lm_0", LM_0, 0x44000, MIXER_DPU_4_MASK, &sdm845_lm_sblk, PINGPONG_0, LM_1, DSPP_0), - LM_BLK("lm_1", LM_1, 0x45000, MIXER_SDM845_MASK, + LM_BLK("lm_1", LM_1, 0x45000, MIXER_DPU_4_MASK, &sdm845_lm_sblk, PINGPONG_1, LM_0, DSPP_1), - LM_BLK("lm_2", LM_2, 0x46000, MIXER_SDM845_MASK, + LM_BLK("lm_2", LM_2, 0x46000, MIXER_DPU_4_MASK, &sdm845_lm_sblk, PINGPONG_2, LM_3, 0), -
[PATCH v4 40/42] drm/msm/dpu: rename MERGE_3D_foo_MASK to contain major DPU version
To ease review and reuse rename MERGE_3D feature masks to contain base DPU version since which this mask is used. Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 96c5b94264e8..d74029f163c8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -88,7 +88,7 @@ #define CTL_DPU_9_MASK (CTL_DPU_7_MASK | \ BIT(DPU_CTL_HAS_LAYER_EXT4)) -#define MERGE_3D_SM8150_MASK (0) +#define MERGE_3D_DPU_5_MASK (0) #define DSPP_MSM8998_MASK BIT(DPU_DSPP_PCC) | BIT(DPU_DSPP_GC) @@ -529,7 +529,7 @@ static const struct dpu_pingpong_sub_blks sc7280_pp_sblk = { {\ .name = _name, .id = _id, \ .base = _base, .len = 0x100, \ - .features = MERGE_3D_SM8150_MASK, \ + .features = MERGE_3D_DPU_5_MASK, \ .sblk = NULL \ } -- 2.39.2
[PATCH v4 41/42] drm/msm/dpu: fetch DPU configuration from match data
In email discussion it was noted that there can be different SoC device having slightly different SoC features, but sharing the same DPU hw revision. Stop fetching catalog data using core_rev and use platform's match data instead. Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 2 +- .../msm/disp/dpu1/catalog/dpu_4_0_sdm845.h| 2 +- .../msm/disp/dpu1/catalog/dpu_5_0_sm8150.h| 2 +- .../msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 2 +- .../msm/disp/dpu1/catalog/dpu_6_0_sm8250.h| 2 +- .../msm/disp/dpu1/catalog/dpu_6_2_sc7180.h| 2 +- .../msm/disp/dpu1/catalog/dpu_6_3_sm6115.h| 2 +- .../msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 2 +- .../msm/disp/dpu1/catalog/dpu_7_0_sm8350.h| 2 +- .../msm/disp/dpu1/catalog/dpu_7_2_sc7280.h| 2 +- .../msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 2 +- .../msm/disp/dpu1/catalog/dpu_8_1_sm8450.h| 2 +- .../msm/disp/dpu1/catalog/dpu_9_0_sm8550.h| 2 +- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 34 --- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h| 26 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 42 +-- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 1 - 17 files changed, 46 insertions(+), 83 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h index a34e9506e6d4..dc04289c4622 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h @@ -176,7 +176,7 @@ static const struct dpu_perf_cfg msm8998_perf_data = { .bw_inefficiency_factor = 120, }; -static const struct dpu_mdss_cfg msm8998_dpu_cfg = { +const struct dpu_mdss_cfg dpu_msm8998_cfg = { .caps = &msm8998_dpu_caps, .ubwc = &msm8998_ubwc_cfg, .mdp_count = ARRAY_SIZE(msm8998_mdp), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h index d247f8d0c0be..1ca7635755b6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h @@ -174,7 +174,7 @@ static const struct dpu_perf_cfg sdm845_perf_data = { .bw_inefficiency_factor = 120, }; -static const struct dpu_mdss_cfg sdm845_dpu_cfg = { +const struct dpu_mdss_cfg dpu_sdm845_cfg = { .caps = &sdm845_dpu_caps, .ubwc = &sdm845_ubwc_cfg, .mdp_count = ARRAY_SIZE(sdm845_mdp), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h index 15277f9627ae..c5cc7b54824d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h @@ -197,7 +197,7 @@ static const struct dpu_perf_cfg sm8150_perf_data = { .bw_inefficiency_factor = 120, }; -static const struct dpu_mdss_cfg sm8150_dpu_cfg = { +const struct dpu_mdss_cfg dpu_sm8150_cfg = { .caps = &sm8150_dpu_caps, .ubwc = &sm8150_ubwc_cfg, .mdp_count = ARRAY_SIZE(sm8150_mdp), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h index a1483d5f7448..2954b38fae59 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h @@ -197,7 +197,7 @@ static const struct dpu_perf_cfg sc8180x_perf_data = { .bw_inefficiency_factor = 120, }; -static const struct dpu_mdss_cfg sc8180x_dpu_cfg = { +const struct dpu_mdss_cfg dpu_sc8180x_cfg = { .caps = &sc8180x_dpu_caps, .ubwc = &sc8180x_ubwc_cfg, .mdp_count = ARRAY_SIZE(sc8180x_mdp), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h index fc3f2b180821..37aaa5804ee7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h @@ -203,7 +203,7 @@ static const struct dpu_perf_cfg sm8250_perf_data = { .bw_inefficiency_factor = 120, }; -static const struct dpu_mdss_cfg sm8250_dpu_cfg = { +const struct dpu_mdss_cfg dpu_sm8250_cfg = { .caps = &sm8250_dpu_caps, .ubwc = &sm8250_ubwc_cfg, .mdp_count = ARRAY_SIZE(sm8250_mdp), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h index 8383ba982cb0..06cf9104daa9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h @@ -122,7 +122,7 @@ static const struct dpu_perf_cfg sc7180_perf_data = { .bw_inefficiency_factor = 120, }; -static const struct dpu_mdss_cfg sc7180_dpu_cfg = { +const struct dpu_mdss_cfg dpu_sc7180_cfg = { .caps = &sc7180_dpu_caps, .ubwc = &sc7180_ubwc_cfg, .mdp_
[PATCH v4 37/42] drm/msm/dpu: rename CTL_foo_MASK to contain major DPU version
To ease review and reuse rename CTL feature masks to contain base DPU version since which this mask is used. Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 10 +- .../msm/disp/dpu1/catalog/dpu_4_0_sdm845.h| 10 +- .../msm/disp/dpu1/catalog/dpu_5_0_sm8150.h| 12 +-- .../msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 12 +-- .../msm/disp/dpu1/catalog/dpu_6_0_sm8250.h| 12 +-- .../msm/disp/dpu1/catalog/dpu_6_2_sc7180.h| 6 +++--- .../msm/disp/dpu1/catalog/dpu_6_3_sm6115.h| 2 +- .../msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 2 +- .../msm/disp/dpu1/catalog/dpu_7_0_sm8350.h| 12 +-- .../msm/disp/dpu1/catalog/dpu_7_2_sc7280.h| 8 .../msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 12 +-- .../msm/disp/dpu1/catalog/dpu_8_1_sm8450.h| 12 +-- .../msm/disp/dpu1/catalog/dpu_9_0_sm8550.h| 12 +-- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 20 +++ 14 files changed, 73 insertions(+), 69 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h index 3f1931808c3f..6afabd251a9d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h @@ -48,31 +48,31 @@ static const struct dpu_ctl_cfg msm8998_ctl[] = { { .name = "ctl_0", .id = CTL_0, .base = 0x1000, .len = 0x94, - .features = BIT(DPU_CTL_SPLIT_DISPLAY), + .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_DPU_0_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), }, { .name = "ctl_1", .id = CTL_1, .base = 0x1200, .len = 0x94, - .features = 0, + .features = CTL_DPU_0_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), }, { .name = "ctl_2", .id = CTL_2, .base = 0x1400, .len = 0x94, - .features = BIT(DPU_CTL_SPLIT_DISPLAY), + .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_DPU_0_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11), }, { .name = "ctl_3", .id = CTL_3, .base = 0x1600, .len = 0x94, - .features = 0, + .features = CTL_DPU_0_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12), }, { .name = "ctl_4", .id = CTL_4, .base = 0x1800, .len = 0x94, - .features = 0, + .features = CTL_DPU_0_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13), }, }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h index eb008a05af37..cace399551cd 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h @@ -46,31 +46,31 @@ static const struct dpu_ctl_cfg sdm845_ctl[] = { { .name = "ctl_0", .id = CTL_0, .base = 0x1000, .len = 0xe4, - .features = BIT(DPU_CTL_SPLIT_DISPLAY), + .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_DPU_0_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), }, { .name = "ctl_1", .id = CTL_1, .base = 0x1200, .len = 0xe4, - .features = BIT(DPU_CTL_SPLIT_DISPLAY), + .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_DPU_0_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), }, { .name = "ctl_2", .id = CTL_2, .base = 0x1400, .len = 0xe4, - .features = 0, + .features = CTL_DPU_0_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11), }, { .name = "ctl_3", .id = CTL_3, .base = 0x1600, .len = 0xe4, - .features = 0, + .features = CTL_DPU_0_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12), }, { .name = "ctl_4", .id = CTL_4, .base = 0x1800, .len = 0xe4, - .features = 0, + .features = CTL_DPU_0_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13), }, }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h index a18ae2bb28ab..c09f3c2ac664 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h @@ -47,37 +47,37 @@ static const struct dpu_ctl_cfg sm8150_ctl[] = { { .name = "ctl_0", .id = CTL_0, .base = 0x1000, .len = 0x1e0, - .features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY), + .features = CTL_DPU_5_MASK | BIT(DPU_CTL_SPLIT_DISPLAY), .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), }, { .name = "ctl_1", .id = CTL_1, .base = 0x1200, .len = 0x1e0, - .features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_D
[PATCH v4 42/42] drm/msm/dpu: drop unused macros from hw catalog
Drop the version comparison macros from dpu_hw_catalog.h, they are unused. Signed-off-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h| 42 --- 1 file changed, 42 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index 7c2331d8070a..71584cd56fd7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -19,48 +19,6 @@ */ #define MAX_BLOCKS12 -#define DPU_HW_VER(MAJOR, MINOR, STEP) \ - unsigned int)MAJOR & 0xF) << 28) | \ - ((MINOR & 0xFFF) << 16) | \ - (STEP & 0x)) - -#define DPU_HW_MAJOR(rev) ((rev) >> 28) -#define DPU_HW_MINOR(rev) (((rev) >> 16) & 0xFFF) -#define DPU_HW_STEP(rev) ((rev) & 0x) -#define DPU_HW_MAJOR_MINOR(rev)((rev) >> 16) - -#define IS_DPU_MAJOR_MINOR_SAME(rev1, rev2) \ - (DPU_HW_MAJOR_MINOR((rev1)) == DPU_HW_MAJOR_MINOR((rev2))) - -#define DPU_HW_VER_170 DPU_HW_VER(1, 7, 0) /* 8996 v1.0 */ -#define DPU_HW_VER_171 DPU_HW_VER(1, 7, 1) /* 8996 v2.0 */ -#define DPU_HW_VER_172 DPU_HW_VER(1, 7, 2) /* 8996 v3.0 */ -#define DPU_HW_VER_300 DPU_HW_VER(3, 0, 0) /* 8998 v1.0 */ -#define DPU_HW_VER_301 DPU_HW_VER(3, 0, 1) /* 8998 v1.1 */ -#define DPU_HW_VER_400 DPU_HW_VER(4, 0, 0) /* sdm845 v1.0 */ -#define DPU_HW_VER_401 DPU_HW_VER(4, 0, 1) /* sdm845 v2.0 */ -#define DPU_HW_VER_410 DPU_HW_VER(4, 1, 0) /* sdm670 v1.0 */ -#define DPU_HW_VER_500 DPU_HW_VER(5, 0, 0) /* sm8150 v1.0 */ -#define DPU_HW_VER_501 DPU_HW_VER(5, 0, 1) /* sm8150 v2.0 */ -#define DPU_HW_VER_510 DPU_HW_VER(5, 1, 1) /* sc8180 */ -#define DPU_HW_VER_600 DPU_HW_VER(6, 0, 0) /* sm8250 */ -#define DPU_HW_VER_620 DPU_HW_VER(6, 2, 0) /* sc7180 v1.0 */ -#define DPU_HW_VER_630 DPU_HW_VER(6, 3, 0) /* sm6115|sm4250 */ -#define DPU_HW_VER_650 DPU_HW_VER(6, 5, 0) /* qcm2290|sm4125 */ -#define DPU_HW_VER_700 DPU_HW_VER(7, 0, 0) /* sm8350 */ -#define DPU_HW_VER_720 DPU_HW_VER(7, 2, 0) /* sc7280 */ -#define DPU_HW_VER_800 DPU_HW_VER(8, 0, 0) /* sc8280xp */ -#define DPU_HW_VER_810 DPU_HW_VER(8, 1, 0) /* sm8450 */ -#define DPU_HW_VER_900 DPU_HW_VER(9, 0, 0) /* sm8550 */ - -#define IS_MSM8996_TARGET(rev) IS_DPU_MAJOR_MINOR_SAME((rev), DPU_HW_VER_170) -#define IS_MSM8998_TARGET(rev) IS_DPU_MAJOR_MINOR_SAME((rev), DPU_HW_VER_300) -#define IS_SDM845_TARGET(rev) IS_DPU_MAJOR_MINOR_SAME((rev), DPU_HW_VER_400) -#define IS_SDM670_TARGET(rev) IS_DPU_MAJOR_MINOR_SAME((rev), DPU_HW_VER_410) -#define IS_SDM855_TARGET(rev) IS_DPU_MAJOR_MINOR_SAME((rev), DPU_HW_VER_500) -#define IS_SC7180_TARGET(rev) IS_DPU_MAJOR_MINOR_SAME((rev), DPU_HW_VER_620) -#define IS_SC7280_TARGET(rev) IS_DPU_MAJOR_MINOR_SAME((rev), DPU_HW_VER_720) - #define DPU_HW_BLK_NAME_LEN16 #define MAX_IMG_WIDTH 0x3fff -- 2.39.2
Re: [RFC PATCH 08/10] dma-buf/dma-fence: Introduce long-running completion fences
Am 04.04.23 um 14:54 schrieb Thomas Hellström: Hi, Christian, On 4/4/23 11:09, Christian König wrote: Am 04.04.23 um 02:22 schrieb Matthew Brost: From: Thomas Hellström For long-running workloads, drivers either need to open-code completion waits, invent their own synchronization primitives or internally use dma-fences that do not obey the cross-driver dma-fence protocol, but without any lockdep annotation all these approaches are error prone. So since for example the drm scheduler uses dma-fences it is desirable for a driver to be able to use it for throttling and error handling also with internal dma-fences tha do not obey the cros-driver dma-fence protocol. Introduce long-running completion fences in form of dma-fences, and add lockdep annotation for them. In particular: * Do not allow waiting under any memory management locks. * Do not allow to attach them to a dma-resv object. * Introduce a new interface for adding callbacks making the helper adding a callback sign off on that it is aware that the dma-fence may not complete anytime soon. Typically this will be the scheduler chaining a new long-running fence on another one. Well that's pretty much what I tried before: https://lwn.net/Articles/893704/ And the reasons why it was rejected haven't changed. Regards, Christian. Yes, TBH this was mostly to get discussion going how we'd best tackle this problem while being able to reuse the scheduler for long-running workloads. I couldn't see any clear decision on your series, though, but one main difference I see is that this is intended for driver-internal use only. (I'm counting using the drm_scheduler as a helper for driver-private use). This is by no means a way to try tackle the indefinite fence problem. Well this was just my latest try to tackle this, but essentially the problems are the same as with your approach: When we express such operations as dma_fence there is always the change that we leak that somewhere. My approach of adding a flag noting that this operation is dangerous and can't be synced with something memory management depends on tried to contain this as much as possible, but Daniel still pretty clearly rejected it (for good reasons I think). We could ofc invent a completely different data-type that abstracts the synchronization the scheduler needs in the long-running case, or each driver could hack something up, like sleeping in the prepare_job() or run_job() callback for throttling, but those waits should still be annotated in one way or annotated one way or another (and probably in a similar way across drivers) to make sure we don't do anything bad. So any suggestions as to what would be the better solution here would be appreciated. Mhm, do we really the the GPU scheduler for that? I mean in the 1 to 1 case you basically just need a component which collects the dependencies as dma_fence and if all of them are fulfilled schedules a work item. As long as the work item itself doesn't produce a dma_fence it can then still just wait for other none dma_fence dependencies. Then the work function could submit the work and wait for the result. The work item would then pretty much represent what you want, you can wait for it to finish and pass it along as long running dependency. Maybe give it a funky name and wrap it up in a structure, but that's basically it. Regards, Christian. Thanks, Thomas
Re: [PATCH 1/2] drm/hyperv: Add DRM driver for hyperv synthetic video device
Yeah way late reply, but I just stumbled over this and got a bit puzzled ... On Sat, 2 Jan 2021 at 07:03, Deepak Rawat wrote: > +/* > + * PCI/vmbus interface > + */ > + > +static int hyperv_pci_probe(struct pci_dev *pdev, > + const struct pci_device_id *ent) > +{ > + return 0; > +} Why do you have this dummy driver when it does nothing? Can it just be deleted? If it's just to have a driver, then we really don't need that on linux, there's no requirement to have a device driver for every device in a system. If you actually need to make sure that this pci device isn't passed to a guest vm or something like that, then the main driver must ensure that the pci driver is bound (ideally with component.c because otherwise you'll get the unbind/rebind dance wrong in one of the bazillion of subtle ways). Just having a driver doesn't stop anyone from unbinding it and then wreaking havoc. -Daniel > + > +static void hyperv_pci_remove(struct pci_dev *pdev) > +{ > +} > + > +static const struct pci_device_id hyperv_pci_tbl[] = { > + { > + .vendor = PCI_VENDOR_ID_MICROSOFT, > + .device = PCI_DEVICE_ID_HYPERV_VIDEO, > + }, > + { /* end of list */ } > +}; > + > +static struct pci_driver hyperv_pci_driver = { > + .name = KBUILD_MODNAME, > + .id_table = hyperv_pci_tbl, > + .probe =hyperv_pci_probe, > + .remove = hyperv_pci_remove, > +}; > + > +static int hyperv_get_vram_gen1(struct hyperv_device *hv) > +{ > + struct drm_device *dev = &hv->dev; > + struct pci_dev *pdev; > + int ret; > + > + pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT, > + PCI_DEVICE_ID_HYPERV_VIDEO, NULL); > + if (!pdev) { > + drm_err(dev, "Unable to find PCI Hyper-V video\n"); > + return -ENODEV; > + } > + > + ret = drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, > "hypervdrmfb"); > + if (ret) { > + drm_err(dev, "Not able to remove boot fb\n"); > + return ret; > + } > + > + if (pci_request_region(pdev, 0, DRIVER_NAME) != 0) > + drm_warn(dev, "Cannot request framebuffer, boot fb still > active?\n"); > + > + if ((pdev->resource[0].flags & IORESOURCE_MEM) == 0) { > + drm_err(dev, "Resource at bar 0 is not IORESOURCE_MEM\n"); > + ret = -ENODEV; > + goto error; > + } > + > + hv->fb_base = pci_resource_start(pdev, 0); > + hv->fb_size = pci_resource_len(pdev, 0); > + if (hv->fb_base == 0) { > + drm_err(dev, "Resource not available\n"); > + ret = -ENODEV; > + goto error; > + } > + > + hv->fb_size = min(hv->fb_size, > + (unsigned long)(hv->mmio_megabytes * 1024 * 1024)); > + hv->vram = devm_ioremap(&pdev->dev, hv->fb_base, hv->fb_size); > + if (!hv->vram) { > + drm_err(dev, "Failed to map vram\n"); > + ret = -ENOMEM; > + } > + > +error: > + pci_dev_put(pdev); > + return ret; > +} > + > +static int hyperv_get_vram_gen2(struct hyperv_device *hv, > + struct hv_device *hdev) > +{ > + struct drm_device *dev = &hv->dev; > + struct apertures_struct *ap; > + int ret; > + > + hv->fb_size = (unsigned long)(hv->mmio_megabytes * 1024 * 1024); > + > + ret = vmbus_allocate_mmio(&hv->mem, hdev, 0, -1, hv->fb_size, > 0x10, > + true); > + if (ret) { > + drm_err(dev, "Failed to allocate mmio\n"); > + return -ENOMEM; > + } > + > + hv->vram = ioremap(hv->mem->start, hv->fb_size); > + if (!hv->vram) { > + drm_err(dev, "Failed to map vram\n"); > + ret = -ENOMEM; > + goto error; > + } > + > + hv->fb_base = hv->mem->start; > + > + ap = alloc_apertures(1); > + if (!ap) { > + drm_err(dev, "Failed to get apertures\n"); > + ret = -ENOMEM; > + goto error; > + } > + > + ap->ranges[0].base = screen_info.lfb_base; > + ap->ranges[0].size = screen_info.lfb_size; > + remove_conflicting_framebuffers(ap, KBUILD_MODNAME, false); > + kfree(ap); > + > + return 0; > + > +error: > + vmbus_free_mmio(hv->mem->start, hv->fb_size); > + return ret; > +} > + > +static int hyperv_vmbus_probe(struct hv_device *hdev, > + const struct hv_vmbus_device_id *dev_id) > +{ > + struct hyperv_device *hv; > + struct drm_device *dev; > + int ret; > + > + hv = devm_drm_dev_alloc(&hdev->device, &hyperv_driver, > + struct hyperv_device, dev); > + if (IS_ERR(hv)) > + return PTR_ERR(hv); > + > + dev = &hv->dev; > + init_co
Re: [RFC PATCH 00/10] Xe DRM scheduler and long running workload plans
On Tue, Apr 04, 2023 at 11:04:54AM +0200, Christian König wrote: > Please make sure to CC Luben on scheduler patches. > Sure, figured I was missing a few people. Matt > Regards, > Christian. > > Am 04.04.23 um 02:22 schrieb Matthew Brost: > > Hello, > > > > As a prerequisite to merging the new Intel Xe DRM driver [1] [2], we > > have been asked to merge our common DRM scheduler patches first as well > > as develop a common solution for long running workloads with the DRM > > scheduler. This RFC series is our first attempt at doing this. We > > welcome any and all feedback. > > > > This can we thought of as 4 parts detailed below. > > > > - DRM scheduler changes for 1 to 1 relationship between scheduler and > > entity (patches 1-3) > > > > In Xe all of the scheduling of jobs is done by a firmware scheduler (the > > GuC) which is a new paradigm WRT to the DRM scheduler and presents > > severals problems as the DRM was originally designed to schedule jobs on > > hardware queues. The main problem being that DRM scheduler expects the > > submission order of jobs to be the completion order of jobs even across > > multiple entities. This assumption falls apart with a firmware scheduler > > as a firmware scheduler has no concept of jobs and jobs can complete out > > of order. A novel solution for was originally thought of by Faith during > > the initial prototype of Xe, create a 1 to 1 relationship between scheduler > > and entity. I believe the AGX driver [3] is using this approach and > > Boris may use approach as well for the Mali driver [4]. > > > > To support a 1 to 1 relationship we move the main execution function > > from a kthread to a work queue and add a new scheduling mode which > > bypasses code in the DRM which isn't needed in a 1 to 1 relationship. > > The new scheduling mode should unify all drivers usage with a 1 to 1 > > relationship and can be thought of as using scheduler as a dependency / > > infligt job tracker rather than a true scheduler. > > > > - Generic messaging interface for DRM scheduler > > > > Idea is to be able to communicate to the submission backend with in band > > (relative to main execution function) messages. Messages are backend > > defined and flexable enough for any use case. In Xe we use these > > messages to clean up entites, set properties for entites, and suspend / > > resume execution of an entity [5]. I suspect other driver can leverage > > this messaging concept too as it a convenient way to avoid races in the > > backend. > > > > - Support for using TDR for all error paths of a scheduler / entity > > > > Fix a few races / bugs, add function to dynamically set the TDR timeout. > > > > - Annotate dma-fences for long running workloads. > > > > The idea here is to use dma-fences only as sync points within the > > scheduler and never export them for long running workloads. By > > annotating these fences as long running we ensure that these dma-fences > > are never used in a way that breaks the dma-fence rules. A benefit of > > thus approach is the scheduler can still safely flow control the > > execution ring buffer via the job limit without breaking the dma-fence > > rules. > > > > Again this a first draft and looking forward to feedback. > > > > Enjoy - Matt > > > > [1] https://gitlab.freedesktop.org/drm/xe/kernel > > [2] https://patchwork.freedesktop.org/series/112188/ > > [3] https://patchwork.freedesktop.org/series/114772/ > > [4] https://patchwork.freedesktop.org/patch/515854/?series=112188&rev=1 > > [5] > > https://gitlab.freedesktop.org/drm/xe/kernel/-/blob/drm-xe-next/drivers/gpu/drm/xe/xe_guc_submit.c#L1031 > > > > Matthew Brost (8): > >drm/sched: Convert drm scheduler to use a work queue rather than > > kthread > >drm/sched: Move schedule policy to scheduler / entity > >drm/sched: Add DRM_SCHED_POLICY_SINGLE_ENTITY scheduling policy > >drm/sched: Add generic scheduler message interface > >drm/sched: Start run wq before TDR in drm_sched_start > >drm/sched: Submit job before starting TDR > >drm/sched: Add helper to set TDR timeout > >drm/syncobj: Warn on long running dma-fences > > > > Thomas Hellström (2): > >dma-buf/dma-fence: Introduce long-running completion fences > >drm/sched: Support long-running sched entities > > > > drivers/dma-buf/dma-fence.c | 142 +++--- > > drivers/dma-buf/dma-resv.c | 5 + > > drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 14 +- > > drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 15 +- > > drivers/gpu/drm/drm_syncobj.c | 5 +- > > drivers/gpu/drm/etnaviv/etnaviv_sched.c | 5 +- > > drivers/gpu/drm/lima/lima_sched.c | 5 +- > > drivers/gpu/drm/msm/adreno/adreno_device.c | 6 +- > > drivers/gpu/drm/msm/msm_ringbuffer.c| 5 +- > > drivers/gpu/drm/panfrost/panfrost_job.c | 5 +- > > drivers/gpu/drm/scheduler/sched_entity.c| 127 +++-- > > drivers/gpu/drm/
[PATCH v3 39/65] phy: cadence: torrent: Add a determine_rate hook
The Cadence Torrent refclk clock implements a mux with a set_parent hook, but doesn't provide a determine_rate implementation. This is a bit odd, since set_parent() is there to, as its name implies, change the parent of a clock. However, the most likely candidate to trigger that parent change is a call to clk_set_rate(), with determine_rate() figuring out which parent is the best suited for a given rate. The other trigger would be a call to clk_set_parent(), but it's far less used, and it doesn't look like there's any obvious user for that clock. So, the set_parent hook is effectively unused, possibly because of an oversight. However, it could also be an explicit decision by the original author to avoid any reparenting but through an explicit call to clk_set_parent(). The latter case would be equivalent to setting the flag CLK_SET_RATE_NO_REPARENT, together with setting our determine_rate hook to __clk_mux_determine_rate(). Indeed, if no determine_rate implementation is provided, clk_round_rate() (through clk_core_round_rate_nolock()) will call itself on the parent if CLK_SET_RATE_PARENT is set, and will not change the clock rate otherwise. __clk_mux_determine_rate() has the exact same behavior when CLK_SET_RATE_NO_REPARENT is set. And if it was an oversight, then we are at least explicit about our behavior now and it can be further refined down the line. Since the CLK_SET_RATE_NO_REPARENT flag was already set though, it seems unlikely. Signed-off-by: Maxime Ripard --- drivers/phy/cadence/phy-cadence-torrent.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c index 3831f596d50c..62e59d1bb9c3 100644 --- a/drivers/phy/cadence/phy-cadence-torrent.c +++ b/drivers/phy/cadence/phy-cadence-torrent.c @@ -1861,6 +1861,7 @@ static const struct clk_ops cdns_torrent_refclk_driver_ops = { .enable = cdns_torrent_refclk_driver_enable, .disable = cdns_torrent_refclk_driver_disable, .is_enabled = cdns_torrent_refclk_driver_is_enabled, + .determine_rate = __clk_mux_determine_rate, .set_parent = cdns_torrent_refclk_driver_set_parent, .get_parent = cdns_torrent_refclk_driver_get_parent, }; -- 2.39.2
[PATCH v3 40/65] phy: ti: am654-serdes: Add a determine_rate hook
The TI AM654 SerDes clock implements a mux with a set_parent hook, but doesn't provide a determine_rate implementation. This is a bit odd, since set_parent() is there to, as its name implies, change the parent of a clock. However, the most likely candidate to trigger that parent change is a call to clk_set_rate(), with determine_rate() figuring out which parent is the best suited for a given rate. The other trigger would be a call to clk_set_parent(), but it's far less used, and it doesn't look like there's any obvious user for that clock. So, the set_parent hook is effectively unused, possibly because of an oversight. However, it could also be an explicit decision by the original author to avoid any reparenting but through an explicit call to clk_set_parent(). The latter case would be equivalent to setting the flag CLK_SET_RATE_NO_REPARENT, together with setting our determine_rate hook to __clk_mux_determine_rate(). Indeed, if no determine_rate implementation is provided, clk_round_rate() (through clk_core_round_rate_nolock()) will call itself on the parent if CLK_SET_RATE_PARENT is set, and will not change the clock rate otherwise. __clk_mux_determine_rate() has the exact same behavior when CLK_SET_RATE_NO_REPARENT is set. And if it was an oversight, then we are at least explicit about our behavior now and it can be further refined down the line. Since the CLK_SET_RATE_NO_REPARENT flag was already set though, it seems unlikely. Signed-off-by: Maxime Ripard --- drivers/phy/ti/phy-am654-serdes.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/phy/ti/phy-am654-serdes.c b/drivers/phy/ti/phy-am654-serdes.c index 4ed2d951d3df..3f1d43e8b7ad 100644 --- a/drivers/phy/ti/phy-am654-serdes.c +++ b/drivers/phy/ti/phy-am654-serdes.c @@ -634,6 +634,7 @@ static int serdes_am654_clk_mux_set_parent(struct clk_hw *hw, u8 index) } static const struct clk_ops serdes_am654_clk_mux_ops = { + .determine_rate = __clk_mux_determine_rate, .set_parent = serdes_am654_clk_mux_set_parent, .get_parent = serdes_am654_clk_mux_get_parent, }; -- 2.39.2
[PATCH v3 41/65] phy: ti: j721e-wiz: Add a determine_rate hook
The TI J721e Wiz clock implements a mux with a set_parent hook, but doesn't provide a determine_rate implementation. This is a bit odd, since set_parent() is there to, as its name implies, change the parent of a clock. However, the most likely candidate to trigger that parent change is a call to clk_set_rate(), with determine_rate() figuring out which parent is the best suited for a given rate. The other trigger would be a call to clk_set_parent(), but it's far less used, and it doesn't look like there's any obvious user for that clock. So, the set_parent hook is effectively unused, possibly because of an oversight. However, it could also be an explicit decision by the original author to avoid any reparenting but through an explicit call to clk_set_parent(). The latter case would be equivalent to setting the flag CLK_SET_RATE_NO_REPARENT, together with setting our determine_rate hook to __clk_mux_determine_rate(). Indeed, if no determine_rate implementation is provided, clk_round_rate() (through clk_core_round_rate_nolock()) will call itself on the parent if CLK_SET_RATE_PARENT is set, and will not change the clock rate otherwise. __clk_mux_determine_rate() has the exact same behavior when CLK_SET_RATE_NO_REPARENT is set. And if it was an oversight, then we are at least explicit about our behavior now and it can be further refined down the line. Since the CLK_SET_RATE_NO_REPARENT flag was already set though, it seems unlikely. Signed-off-by: Maxime Ripard --- drivers/phy/ti/phy-j721e-wiz.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c index d2fd2143450a..d97f161dfe0c 100644 --- a/drivers/phy/ti/phy-j721e-wiz.c +++ b/drivers/phy/ti/phy-j721e-wiz.c @@ -802,6 +802,7 @@ static int wiz_clk_mux_set_parent(struct clk_hw *hw, u8 index) } static const struct clk_ops wiz_clk_mux_ops = { + .determine_rate = __clk_mux_determine_rate, .set_parent = wiz_clk_mux_set_parent, .get_parent = wiz_clk_mux_get_parent, }; -- 2.39.2
Re: [PATCH] dt-bindings: arm: nvidia: Drop unneeded quotes
From: Thierry Reding On Fri, 31 Mar 2023 13:21:59 -0500, Rob Herring wrote: > Cleanup bindings dropping unneeded quotes. Once all these are fixed, > checking for this can be enabled in yamllint. > > Applied, thanks! [1/1] dt-bindings: arm: nvidia: Drop unneeded quotes commit: c94673e80377d67ba36ee4059d7814b2ab98fa71 Best regards, -- Thierry Reding
[PATCH v3 42/65] rtc: sun6i: Add a determine_rate hook
The Allwinner sun6i RTC clock implements a mux with a set_parent hook, but doesn't provide a determine_rate implementation. This is a bit odd, since set_parent() is there to, as its name implies, change the parent of a clock. However, the most likely candidate to trigger that parent change is a call to clk_set_rate(), with determine_rate() figuring out which parent is the best suited for a given rate. The other trigger would be a call to clk_set_parent(), but it's far less used, and it doesn't look like there's any obvious user for that clock. So, the set_parent hook is effectively unused, possibly because of an oversight. However, it could also be an explicit decision by the original author to avoid any reparenting but through an explicit call to clk_set_parent(). The latter case would be equivalent to setting the flag CLK_SET_RATE_NO_REPARENT, together with setting our determine_rate hook to __clk_mux_determine_rate(). Indeed, if no determine_rate implementation is provided, clk_round_rate() (through clk_core_round_rate_nolock()) will call itself on the parent if CLK_SET_RATE_PARENT is set, and will not change the clock rate otherwise. __clk_mux_determine_rate() has the exact same behavior when CLK_SET_RATE_NO_REPARENT is set. And if it was an oversight, then we are at least explicit about our behavior now and it can be further refined down the line. Signed-off-by: Maxime Ripard --- drivers/rtc/rtc-sun6i.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c index dc76537f1b62..7d975202e0b9 100644 --- a/drivers/rtc/rtc-sun6i.c +++ b/drivers/rtc/rtc-sun6i.c @@ -214,6 +214,7 @@ static int sun6i_rtc_osc_set_parent(struct clk_hw *hw, u8 index) static const struct clk_ops sun6i_rtc_osc_ops = { .recalc_rate= sun6i_rtc_osc_recalc_rate, + .determine_rate = __clk_mux_determine_rate, .get_parent = sun6i_rtc_osc_get_parent, .set_parent = sun6i_rtc_osc_set_parent, @@ -227,6 +228,7 @@ static void __init sun6i_rtc_clk_init(struct device_node *node, struct clk_init_data init = { .ops= &sun6i_rtc_osc_ops, .name = "losc", + .flags = CLK_SET_RATE_NO_REPARENT, }; const char *iosc_name = "rtc-int-osc"; const char *clkout_name = "osc32k-out"; -- 2.39.2
[PATCH v3 45/65] clk: actions: composite: fact: Switch to determine_rate
The Actions composite factor clocks implements a mux with a set_parent hook, but doesn't provide a determine_rate implementation. This is a bit odd, since set_parent() is there to, as its name implies, change the parent of a clock. However, the most likely candidate to trigger that parent change is a call to clk_set_rate(), with determine_rate() figuring out which parent is the best suited for a given rate. The other trigger would be a call to clk_set_parent(), but it's far less used, and it doesn't look like there's any obvious user for that clock. So, the set_parent hook is effectively unused, possibly because of an oversight. However, it could also be an explicit decision by the original author to avoid any reparenting but through an explicit call to clk_set_parent(). The driver does implement round_rate() though, which means that we can change the rate of the clock, but we will never get to change the parent. However, It's hard to tell whether it's been done on purpose or not. Since we'll start mandating a determine_rate() implementation, let's convert the round_rate() implementation to a determine_rate(), which will also make the current behavior explicit. And if it was an oversight, the clock behaviour can be adjusted later on. Signed-off-by: Maxime Ripard --- drivers/clk/actions/owl-composite.c | 18 -- 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/clk/actions/owl-composite.c b/drivers/clk/actions/owl-composite.c index d66b268563d0..3cac8f0a80dc 100644 --- a/drivers/clk/actions/owl-composite.c +++ b/drivers/clk/actions/owl-composite.c @@ -86,14 +86,20 @@ static int owl_comp_div_set_rate(struct clk_hw *hw, unsigned long rate, rate, parent_rate); } -static long owl_comp_fact_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int owl_comp_fact_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct owl_composite *comp = hw_to_owl_comp(hw); + long rate; - return owl_factor_helper_round_rate(&comp->common, - &comp->rate.factor_hw, - rate, parent_rate); + rate = owl_factor_helper_round_rate(&comp->common, + &comp->rate.factor_hw, + req->rate, &req->best_parent_rate); + if (rate < 0) + return rate; + + req->rate = rate; + return 0; } static unsigned long owl_comp_fact_recalc_rate(struct clk_hw *hw, @@ -175,7 +181,7 @@ const struct clk_ops owl_comp_fact_ops = { .is_enabled = owl_comp_is_enabled, /* fact_ops */ - .round_rate = owl_comp_fact_round_rate, + .determine_rate = owl_comp_fact_determine_rate, .recalc_rate= owl_comp_fact_recalc_rate, .set_rate = owl_comp_fact_set_rate, }; -- 2.39.2
[PATCH v3 43/65] ASoC: tlv320aic32x4: Add a determine_rate hook
The tlv320aic32x4 clkin clock implements a mux with a set_parent hook, but doesn't provide a determine_rate implementation. This is a bit odd, since set_parent() is there to, as its name implies, change the parent of a clock. However, the most likely candidate to trigger that parent change is a call to clk_set_rate(), with determine_rate() figuring out which parent is the best suited for a given rate. The other trigger would be a call to clk_set_parent(), but it's far less used, and it doesn't look like there's any obvious user for that clock. So, the set_parent hook is effectively unused, possibly because of an oversight. However, it could also be an explicit decision by the original author to avoid any reparenting but through an explicit call to clk_set_parent(). The latter case would be equivalent to setting the flag CLK_SET_RATE_NO_REPARENT, together with setting our determine_rate hook to __clk_mux_determine_rate(). Indeed, if no determine_rate implementation is provided, clk_round_rate() (through clk_core_round_rate_nolock()) will call itself on the parent if CLK_SET_RATE_PARENT is set, and will not change the clock rate otherwise. __clk_mux_determine_rate() has the exact same behavior when CLK_SET_RATE_NO_REPARENT is set. And if it was an oversight, then we are at least explicit about our behavior now and it can be further refined down the line. Signed-off-by: Maxime Ripard --- sound/soc/codecs/tlv320aic32x4-clk.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/tlv320aic32x4-clk.c b/sound/soc/codecs/tlv320aic32x4-clk.c index 2f78e6820c75..65b72373cb95 100644 --- a/sound/soc/codecs/tlv320aic32x4-clk.c +++ b/sound/soc/codecs/tlv320aic32x4-clk.c @@ -41,6 +41,7 @@ struct aic32x4_clkdesc { const char * const *parent_names; unsigned int num_parents; const struct clk_ops *ops; + unsigned long flags; unsigned int reg; }; @@ -292,6 +293,7 @@ static u8 clk_aic32x4_codec_clkin_get_parent(struct clk_hw *hw) } static const struct clk_ops aic32x4_codec_clkin_ops = { + .determine_rate = __clk_mux_determine_rate, .set_parent = clk_aic32x4_codec_clkin_set_parent, .get_parent = clk_aic32x4_codec_clkin_get_parent, }; @@ -401,6 +403,7 @@ static struct aic32x4_clkdesc aic32x4_clkdesc_array[] = { (const char *[]) { "mclk", "bclk", "gpio", "pll" }, .num_parents = 4, .ops = &aic32x4_codec_clkin_ops, + .flags = CLK_SET_RATE_NO_REPARENT, .reg = 0, }, { @@ -452,7 +455,7 @@ static struct clk *aic32x4_register_clk(struct device *dev, init.name = desc->name; init.parent_names = desc->parent_names; init.num_parents = desc->num_parents; - init.flags = 0; + init.flags = desc->flags; priv = devm_kzalloc(dev, sizeof(struct clk_aic32x4), GFP_KERNEL); if (priv == NULL) -- 2.39.2
[PATCH v3 44/65] clk: actions: composite: div: Switch to determine_rate
The Actions composite divider clocks implements a mux with a set_parent hook, but doesn't provide a determine_rate implementation. This is a bit odd, since set_parent() is there to, as its name implies, change the parent of a clock. However, the most likely candidate to trigger that parent change is a call to clk_set_rate(), with determine_rate() figuring out which parent is the best suited for a given rate. The other trigger would be a call to clk_set_parent(), but it's far less used, and it doesn't look like there's any obvious user for that clock. So, the set_parent hook is effectively unused, possibly because of an oversight. However, it could also be an explicit decision by the original author to avoid any reparenting but through an explicit call to clk_set_parent(). The driver does implement round_rate() though, which means that we can change the rate of the clock, but we will never get to change the parent. However, It's hard to tell whether it's been done on purpose or not. Since we'll start mandating a determine_rate() implementation, let's convert the round_rate() implementation to a determine_rate(), which will also make the current behavior explicit. And if it was an oversight, the clock behaviour can be adjusted later on. Signed-off-by: Maxime Ripard --- drivers/clk/actions/owl-composite.c | 16 +++- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/clk/actions/owl-composite.c b/drivers/clk/actions/owl-composite.c index 4c844a5613e4..d66b268563d0 100644 --- a/drivers/clk/actions/owl-composite.c +++ b/drivers/clk/actions/owl-composite.c @@ -53,13 +53,19 @@ static int owl_comp_is_enabled(struct clk_hw *hw) return owl_gate_clk_is_enabled(common, &comp->gate_hw); } -static long owl_comp_div_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int owl_comp_div_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct owl_composite *comp = hw_to_owl_comp(hw); + long rate; - return owl_divider_helper_round_rate(&comp->common, &comp->rate.div_hw, - rate, parent_rate); + rate = owl_divider_helper_round_rate(&comp->common, &comp->rate.div_hw, +req->rate, &req->best_parent_rate); + if (rate < 0) + return rate; + + req->rate = rate; + return 0; } static unsigned long owl_comp_div_recalc_rate(struct clk_hw *hw, @@ -152,7 +158,7 @@ const struct clk_ops owl_comp_div_ops = { .is_enabled = owl_comp_is_enabled, /* div_ops */ - .round_rate = owl_comp_div_round_rate, + .determine_rate = owl_comp_div_determine_rate, .recalc_rate= owl_comp_div_recalc_rate, .set_rate = owl_comp_div_set_rate, }; -- 2.39.2
[PATCH v3 47/65] clk: axi-clkgen: Switch to determine_rate
The AXI clkgen clocks implements a mux with a set_parent hook, but doesn't provide a determine_rate implementation. This is a bit odd, since set_parent() is there to, as its name implies, change the parent of a clock. However, the most likely candidate to trigger that parent change is a call to clk_set_rate(), with determine_rate() figuring out which parent is the best suited for a given rate. The other trigger would be a call to clk_set_parent(), but it's far less used, and it doesn't look like there's any obvious user for that clock. So, the set_parent hook is effectively unused, possibly because of an oversight. However, it could also be an explicit decision by the original author to avoid any reparenting but through an explicit call to clk_set_parent(). The driver does implement round_rate() though, which means that we can change the rate of the clock, but we will never get to change the parent. However, It's hard to tell whether it's been done on purpose or not. Since we'll start mandating a determine_rate() implementation, let's convert the round_rate() implementation to a determine_rate(), which will also make the current behavior explicit. And if it was an oversight, the clock behaviour can be adjusted later on. Signed-off-by: Maxime Ripard --- drivers/clk/clk-axi-clkgen.c | 14 -- 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c index 671bee55ceb3..dded52f9c774 100644 --- a/drivers/clk/clk-axi-clkgen.c +++ b/drivers/clk/clk-axi-clkgen.c @@ -384,23 +384,25 @@ static int axi_clkgen_set_rate(struct clk_hw *clk_hw, return 0; } -static long axi_clkgen_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int axi_clkgen_determine_rate(struct clk_hw *hw, +struct clk_rate_request *req) { struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(hw); const struct axi_clkgen_limits *limits = &axi_clkgen->limits; unsigned int d, m, dout; unsigned long long tmp; - axi_clkgen_calc_params(limits, *parent_rate, rate, &d, &m, &dout); + axi_clkgen_calc_params(limits, req->best_parent_rate, req->rate, + &d, &m, &dout); if (d == 0 || dout == 0 || m == 0) return -EINVAL; - tmp = (unsigned long long)*parent_rate * m; + tmp = (unsigned long long)req->best_parent_rate * m; tmp = DIV_ROUND_CLOSEST_ULL(tmp, dout * d); - return min_t(unsigned long long, tmp, LONG_MAX); + req->rate = min_t(unsigned long long, tmp, LONG_MAX); + return 0; } static unsigned int axi_clkgen_get_div(struct axi_clkgen *axi_clkgen, @@ -495,7 +497,7 @@ static u8 axi_clkgen_get_parent(struct clk_hw *clk_hw) static const struct clk_ops axi_clkgen_ops = { .recalc_rate = axi_clkgen_recalc_rate, - .round_rate = axi_clkgen_round_rate, + .determine_rate = axi_clkgen_determine_rate, .set_rate = axi_clkgen_set_rate, .enable = axi_clkgen_enable, .disable = axi_clkgen_disable, -- 2.39.2
[PATCH v3 46/65] clk: at91: smd: Switch to determine_rate
The Atmel SAM9x5 SMD clocks implements a mux with a set_parent hook, but doesn't provide a determine_rate implementation. This is a bit odd, since set_parent() is there to, as its name implies, change the parent of a clock. However, the most likely candidate to trigger that parent change is a call to clk_set_rate(), with determine_rate() figuring out which parent is the best suited for a given rate. The other trigger would be a call to clk_set_parent(), but it's far less used, and it doesn't look like there's any obvious user for that clock. So, the set_parent hook is effectively unused, possibly because of an oversight. However, it could also be an explicit decision by the original author to avoid any reparenting but through an explicit call to clk_set_parent(). The driver does implement round_rate() though, which means that we can change the rate of the clock, but we will never get to change the parent. However, It's hard to tell whether it's been done on purpose or not. Since we'll start mandating a determine_rate() implementation, let's convert the round_rate() implementation to a determine_rate(), which will also make the current behavior explicit. And if it was an oversight, the clock behaviour can be adjusted later on. Signed-off-by: Maxime Ripard --- drivers/clk/at91/clk-smd.c | 29 + 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/drivers/clk/at91/clk-smd.c b/drivers/clk/at91/clk-smd.c index 160378438f1b..09c649c8598e 100644 --- a/drivers/clk/at91/clk-smd.c +++ b/drivers/clk/at91/clk-smd.c @@ -36,26 +36,31 @@ static unsigned long at91sam9x5_clk_smd_recalc_rate(struct clk_hw *hw, return parent_rate / (smddiv + 1); } -static long at91sam9x5_clk_smd_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int at91sam9x5_clk_smd_determine_rate(struct clk_hw *hw, +struct clk_rate_request *req) { unsigned long div; unsigned long bestrate; unsigned long tmp; - if (rate >= *parent_rate) - return *parent_rate; + if (req->rate >= req->best_parent_rate) { + req->rate = req->best_parent_rate; + return 0; + } - div = *parent_rate / rate; - if (div > SMD_MAX_DIV) - return *parent_rate / (SMD_MAX_DIV + 1); + div = req->best_parent_rate / req->rate; + if (div > SMD_MAX_DIV) { + req->rate = req->best_parent_rate / (SMD_MAX_DIV + 1); + return 0; + } - bestrate = *parent_rate / div; - tmp = *parent_rate / (div + 1); - if (bestrate - rate > rate - tmp) + bestrate = req->best_parent_rate / div; + tmp = req->best_parent_rate / (div + 1); + if (bestrate - req->rate > req->rate - tmp) bestrate = tmp; - return bestrate; + req->rate = bestrate; + return 0; } static int at91sam9x5_clk_smd_set_parent(struct clk_hw *hw, u8 index) @@ -98,7 +103,7 @@ static int at91sam9x5_clk_smd_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops at91sam9x5_smd_ops = { .recalc_rate = at91sam9x5_clk_smd_recalc_rate, - .round_rate = at91sam9x5_clk_smd_round_rate, + .determine_rate = at91sam9x5_clk_smd_determine_rate, .get_parent = at91sam9x5_clk_smd_get_parent, .set_parent = at91sam9x5_clk_smd_set_parent, .set_rate = at91sam9x5_clk_smd_set_rate, -- 2.39.2
Re: [PATCH v2] drm/vblank: Fix for drivers that do not drm_vblank_init()
On Mon, Apr 3, 2023 at 6:07 PM Rob Clark wrote: > From: Rob Clark > > This should fix a crash that was reported on ast (and possibly other > drivers which do not initialize vblank). > >fbcon: Taking over console >Unable to handle kernel NULL pointer dereference at virtual address > 0074 Thanks, this fixes a crash seen with the ssd130x DRM driver. Tested-by: Geert Uytterhoeven Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Re: [RFC PATCH 00/10] Xe DRM scheduler and long running workload plans
On Tue, Apr 04, 2023 at 11:13:28AM +0200, Christian König wrote: > Hi, > > Am 04.04.23 um 02:22 schrieb Matthew Brost: > > Hello, > > > > As a prerequisite to merging the new Intel Xe DRM driver [1] [2], we > > have been asked to merge our common DRM scheduler patches first as well > > as develop a common solution for long running workloads with the DRM > > scheduler. This RFC series is our first attempt at doing this. We > > welcome any and all feedback. > > > > This can we thought of as 4 parts detailed below. > > > > - DRM scheduler changes for 1 to 1 relationship between scheduler and > > entity (patches 1-3) > > > > In Xe all of the scheduling of jobs is done by a firmware scheduler (the > > GuC) which is a new paradigm WRT to the DRM scheduler and presents > > severals problems as the DRM was originally designed to schedule jobs on > > hardware queues. The main problem being that DRM scheduler expects the > > submission order of jobs to be the completion order of jobs even across > > multiple entities. This assumption falls apart with a firmware scheduler > > as a firmware scheduler has no concept of jobs and jobs can complete out > > of order. A novel solution for was originally thought of by Faith during > > the initial prototype of Xe, create a 1 to 1 relationship between scheduler > > and entity. I believe the AGX driver [3] is using this approach and > > Boris may use approach as well for the Mali driver [4]. > > > > To support a 1 to 1 relationship we move the main execution function > > from a kthread to a work queue and add a new scheduling mode which > > bypasses code in the DRM which isn't needed in a 1 to 1 relationship. > > The new scheduling mode should unify all drivers usage with a 1 to 1 > > relationship and can be thought of as using scheduler as a dependency / > > infligt job tracker rather than a true scheduler. > > > > - Generic messaging interface for DRM scheduler > > > > Idea is to be able to communicate to the submission backend with in band > > (relative to main execution function) messages. Messages are backend > > defined and flexable enough for any use case. In Xe we use these > > messages to clean up entites, set properties for entites, and suspend / > > resume execution of an entity [5]. I suspect other driver can leverage > > this messaging concept too as it a convenient way to avoid races in the > > backend. > > Oh, please absolutely *don't* do this. > > This is basically the design which makes a bunch of stuff so horrible broken > on Windows. > > I can explain it in more detail if necessary, but I strongly recommend to > not go down this path. > I'm afraid we are going to have to discuss this further. Let me explain my reasoning, basically the idea is to have a single main entry point to backend - the work queue. This avoids the need for lock between run_job and any message that changes an entites state, also it really helps during the reset flows (either TDR or GT reset) as we can call drm_sched_run_wq_stop can ensure that nothing else is in the backend changing an entity state. It all works out really nicely actually, our GuC backend is incredibly stable (hasn't really had a bug pop in about a year) and way simpler than what we did in the i915. I think the simplity to largely due to this design of limiting the entry points. I personally don't see how this a poor design, limiting entry points absolutely makes sense to me, if it didn't why not just call cleanup_job bypassing the main execution thread (now worker), this is the exact same concept. FWIW Asahi liked the idea as well and think it could be useful for AGX. Matt > Regards, > Christian. > > > > > - Support for using TDR for all error paths of a scheduler / entity > > > > Fix a few races / bugs, add function to dynamically set the TDR timeout. > > > > - Annotate dma-fences for long running workloads. > > > > The idea here is to use dma-fences only as sync points within the > > scheduler and never export them for long running workloads. By > > annotating these fences as long running we ensure that these dma-fences > > are never used in a way that breaks the dma-fence rules. A benefit of > > thus approach is the scheduler can still safely flow control the > > execution ring buffer via the job limit without breaking the dma-fence > > rules. > > > > Again this a first draft and looking forward to feedback. > > > > Enjoy - Matt > > > > [1] https://gitlab.freedesktop.org/drm/xe/kernel > > [2] https://patchwork.freedesktop.org/series/112188/ > > [3] https://patchwork.freedesktop.org/series/114772/ > > [4] https://patchwork.freedesktop.org/patch/515854/?series=112188&rev=1 > > [5] > > https://gitlab.freedesktop.org/drm/xe/kernel/-/blob/drm-xe-next/drivers/gpu/drm/xe/xe_guc_submit.c#L1031 > > > > Matthew Brost (8): > >drm/sched: Convert drm scheduler to use a work queue rather than > > kthread > >drm/sched: Move schedule policy to scheduler / entity > >drm/sched: Add DRM_SCHED_
[PATCH v3 48/65] clk: cdce706: divider: Switch to determine_rate
The cdce706 divider clocks implements a mux with a set_parent hook, but doesn't provide a determine_rate implementation. This is a bit odd, since set_parent() is there to, as its name implies, change the parent of a clock. However, the most likely candidate to trigger that parent change is a call to clk_set_rate(), with determine_rate() figuring out which parent is the best suited for a given rate. The other trigger would be a call to clk_set_parent(), but it's far less used, and it doesn't look like there's any obvious user for that clock. So, the set_parent hook is effectively unused, possibly because of an oversight. However, it could also be an explicit decision by the original author to avoid any reparenting but through an explicit call to clk_set_parent(). The driver does implement round_rate() though, which means that we can change the rate of the clock, but we will never get to change the parent. However, It's hard to tell whether it's been done on purpose or not. Since we'll start mandating a determine_rate() implementation, let's convert the round_rate() implementation to a determine_rate(), which will also make the current behavior explicit. And if it was an oversight, the clock behaviour can be adjusted later on. Signed-off-by: Maxime Ripard --- drivers/clk/clk-cdce706.c | 18 ++ 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/clk/clk-cdce706.c b/drivers/clk/clk-cdce706.c index dc046bbf83a1..a53769d239a9 100644 --- a/drivers/clk/clk-cdce706.c +++ b/drivers/clk/clk-cdce706.c @@ -288,18 +288,19 @@ static unsigned long cdce706_divider_recalc_rate(struct clk_hw *hw, return 0; } -static long cdce706_divider_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int cdce706_divider_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct cdce706_hw_data *hwd = to_hw_data(hw); struct cdce706_dev_data *cdce = hwd->dev_data; + unsigned long rate = req->rate; unsigned long mul, div; dev_dbg(&hwd->dev_data->client->dev, "%s, rate: %lu, parent_rate: %lu\n", - __func__, rate, *parent_rate); + __func__, rate, req->best_parent_rate); - rational_best_approximation(rate, *parent_rate, + rational_best_approximation(rate, req->best_parent_rate, 1, CDCE706_DIVIDER_DIVIDER_MAX, &mul, &div); if (!mul) @@ -344,8 +345,8 @@ static long cdce706_divider_round_rate(struct clk_hw *hw, unsigned long rate, dev_dbg(&hwd->dev_data->client->dev, "%s, altering parent rate: %lu -> %lu\n", - __func__, *parent_rate, rate * div); - *parent_rate = rate * div; + __func__, req->best_parent_rate, rate * div); + req->best_parent_rate = rate * div; } hwd->div = div; @@ -353,7 +354,8 @@ static long cdce706_divider_round_rate(struct clk_hw *hw, unsigned long rate, "%s, divider: %d, div: %lu\n", __func__, hwd->idx, div); - return *parent_rate / div; + req->rate = req->best_parent_rate / div; + return 0; } static int cdce706_divider_set_rate(struct clk_hw *hw, unsigned long rate, @@ -375,7 +377,7 @@ static const struct clk_ops cdce706_divider_ops = { .set_parent = cdce706_divider_set_parent, .get_parent = cdce706_divider_get_parent, .recalc_rate = cdce706_divider_recalc_rate, - .round_rate = cdce706_divider_round_rate, + .determine_rate = cdce706_divider_determine_rate, .set_rate = cdce706_divider_set_rate, }; -- 2.39.2
[PATCH v3 50/65] clk: si5341: Switch to determine_rate
The SI5341 output clocks implements a mux with a set_parent hook, but doesn't provide a determine_rate implementation. This is a bit odd, since set_parent() is there to, as its name implies, change the parent of a clock. However, the most likely candidate to trigger that parent change is a call to clk_set_rate(), with determine_rate() figuring out which parent is the best suited for a given rate. The other trigger would be a call to clk_set_parent(), but it's far less used, and it doesn't look like there's any obvious user for that clock. So, the set_parent hook is effectively unused, possibly because of an oversight. However, it could also be an explicit decision by the original author to avoid any reparenting but through an explicit call to clk_set_parent(). The driver does implement round_rate() though, which means that we can change the rate of the clock, but we will never get to change the parent. However, It's hard to tell whether it's been done on purpose or not. Since we'll start mandating a determine_rate() implementation, let's convert the round_rate() implementation to a determine_rate(), which will also make the current behavior explicit. And if it was an oversight, the clock behaviour can be adjusted later on. Signed-off-by: Maxime Ripard --- drivers/clk/clk-si5341.c | 18 ++ 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c index 259861aa2e2f..14792d5ffb4f 100644 --- a/drivers/clk/clk-si5341.c +++ b/drivers/clk/clk-si5341.c @@ -828,19 +828,20 @@ static unsigned long si5341_output_clk_recalc_rate(struct clk_hw *hw, return parent_rate / r_divider; } -static long si5341_output_clk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int si5341_output_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { + unsigned long rate = req->rate; unsigned long r; if (!rate) return 0; - r = *parent_rate >> 1; + r = req->best_parent_rate >> 1; /* If rate is an even divisor, no changes to parent required */ if (r && !(r % rate)) - return (long)rate; + return 0; if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) { if (rate > 2) { @@ -850,14 +851,15 @@ static long si5341_output_clk_round_rate(struct clk_hw *hw, unsigned long rate, /* Take a parent frequency near 400 MHz */ r = (4u / rate) & ~1; } - *parent_rate = r * rate; + req->best_parent_rate = r * rate; } else { /* We cannot change our parent's rate, report what we can do */ r /= rate; - rate = *parent_rate / (r << 1); + rate = req->best_parent_rate / (r << 1); } - return rate; + req->rate = rate; + return 0; } static int si5341_output_clk_set_rate(struct clk_hw *hw, unsigned long rate, @@ -930,7 +932,7 @@ static const struct clk_ops si5341_output_clk_ops = { .prepare = si5341_output_clk_prepare, .unprepare = si5341_output_clk_unprepare, .recalc_rate = si5341_output_clk_recalc_rate, - .round_rate = si5341_output_clk_round_rate, + .determine_rate = si5341_output_clk_determine_rate, .set_rate = si5341_output_clk_set_rate, .set_parent = si5341_output_set_parent, .get_parent = si5341_output_get_parent, -- 2.39.2
[PATCH v3 51/65] clk: si5351: pll: Switch to determine_rate
The SI5351 PLL clocks implements a mux with a set_parent hook, but doesn't provide a determine_rate implementation. This is a bit odd, since set_parent() is there to, as its name implies, change the parent of a clock. However, the most likely candidate to trigger that parent change is a call to clk_set_rate(), with determine_rate() figuring out which parent is the best suited for a given rate. The other trigger would be a call to clk_set_parent(), but it's far less used, and it doesn't look like there's any obvious user for that clock. So, the set_parent hook is effectively unused, possibly because of an oversight. However, it could also be an explicit decision by the original author to avoid any reparenting but through an explicit call to clk_set_parent(). The driver does implement round_rate() though, which means that we can change the rate of the clock, but we will never get to change the parent. However, It's hard to tell whether it's been done on purpose or not. Since we'll start mandating a determine_rate() implementation, let's convert the round_rate() implementation to a determine_rate(), which will also make the current behavior explicit. And if it was an oversight, the clock behaviour can be adjusted later on. Signed-off-by: Maxime Ripard --- drivers/clk/clk-si5351.c | 26 ++ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c index 9e939c98a455..fcf5785ba4ce 100644 --- a/drivers/clk/clk-si5351.c +++ b/drivers/clk/clk-si5351.c @@ -442,11 +442,12 @@ static unsigned long si5351_pll_recalc_rate(struct clk_hw *hw, return (unsigned long)rate; } -static long si5351_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int si5351_pll_determine_rate(struct clk_hw *hw, +struct clk_rate_request *req) { struct si5351_hw_data *hwdata = container_of(hw, struct si5351_hw_data, hw); + unsigned long rate = req->rate; unsigned long rfrac, denom, a, b, c; unsigned long long lltmp; @@ -456,18 +457,18 @@ static long si5351_pll_round_rate(struct clk_hw *hw, unsigned long rate, rate = SI5351_PLL_VCO_MAX; /* determine integer part of feedback equation */ - a = rate / *parent_rate; + a = rate / req->best_parent_rate; if (a < SI5351_PLL_A_MIN) - rate = *parent_rate * SI5351_PLL_A_MIN; + rate = req->best_parent_rate * SI5351_PLL_A_MIN; if (a > SI5351_PLL_A_MAX) - rate = *parent_rate * SI5351_PLL_A_MAX; + rate = req->best_parent_rate * SI5351_PLL_A_MAX; /* find best approximation for b/c = fVCO mod fIN */ denom = 1000 * 1000; - lltmp = rate % (*parent_rate); + lltmp = rate % (req->best_parent_rate); lltmp *= denom; - do_div(lltmp, *parent_rate); + do_div(lltmp, req->best_parent_rate); rfrac = (unsigned long)lltmp; b = 0; @@ -484,19 +485,20 @@ static long si5351_pll_round_rate(struct clk_hw *hw, unsigned long rate, hwdata->params.p1 -= 512; /* recalculate rate by fIN * (a + b/c) */ - lltmp = *parent_rate; + lltmp = req->best_parent_rate; lltmp *= b; do_div(lltmp, c); rate = (unsigned long)lltmp; - rate += *parent_rate * a; + rate += req->best_parent_rate * a; dev_dbg(&hwdata->drvdata->client->dev, "%s - %s: a = %lu, b = %lu, c = %lu, parent_rate = %lu, rate = %lu\n", __func__, clk_hw_get_name(hw), a, b, c, - *parent_rate, rate); + req->best_parent_rate, rate); - return rate; + req->rate = rate; + return 0; } static int si5351_pll_set_rate(struct clk_hw *hw, unsigned long rate, @@ -533,7 +535,7 @@ static const struct clk_ops si5351_pll_ops = { .set_parent = si5351_pll_set_parent, .get_parent = si5351_pll_get_parent, .recalc_rate = si5351_pll_recalc_rate, - .round_rate = si5351_pll_round_rate, + .determine_rate = si5351_pll_determine_rate, .set_rate = si5351_pll_set_rate, }; -- 2.39.2
[PATCH v3 49/65] clk: cdce706: clkout: Switch to determine_rate
The cdce706 clkout clocks implements a mux with a set_parent hook, but doesn't provide a determine_rate implementation. This is a bit odd, since set_parent() is there to, as its name implies, change the parent of a clock. However, the most likely candidate to trigger that parent change is a call to clk_set_rate(), with determine_rate() figuring out which parent is the best suited for a given rate. The other trigger would be a call to clk_set_parent(), but it's far less used, and it doesn't look like there's any obvious user for that clock. So, the set_parent hook is effectively unused, possibly because of an oversight. However, it could also be an explicit decision by the original author to avoid any reparenting but through an explicit call to clk_set_parent(). The driver does implement round_rate() though, which means that we can change the rate of the clock, but we will never get to change the parent. However, It's hard to tell whether it's been done on purpose or not. Since we'll start mandating a determine_rate() implementation, let's convert the round_rate() implementation to a determine_rate(), which will also make the current behavior explicit. And if it was an oversight, the clock behaviour can be adjusted later on. Signed-off-by: Maxime Ripard --- drivers/clk/clk-cdce706.c | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/clk/clk-cdce706.c b/drivers/clk/clk-cdce706.c index a53769d239a9..0a560b4d295e 100644 --- a/drivers/clk/clk-cdce706.c +++ b/drivers/clk/clk-cdce706.c @@ -423,11 +423,12 @@ static unsigned long cdce706_clkout_recalc_rate(struct clk_hw *hw, return parent_rate; } -static long cdce706_clkout_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int cdce706_clkout_determine_rate(struct clk_hw *hw, +struct clk_rate_request *req) { - *parent_rate = rate; - return rate; + req->best_parent_rate = req->rate; + + return 0; } static int cdce706_clkout_set_rate(struct clk_hw *hw, unsigned long rate, @@ -442,7 +443,7 @@ static const struct clk_ops cdce706_clkout_ops = { .set_parent = cdce706_clkout_set_parent, .get_parent = cdce706_clkout_get_parent, .recalc_rate = cdce706_clkout_recalc_rate, - .round_rate = cdce706_clkout_round_rate, + .determine_rate = cdce706_clkout_determine_rate, .set_rate = cdce706_clkout_set_rate, }; -- 2.39.2
[PATCH v3 52/65] clk: si5351: msynth: Switch to determine_rate
The SI5351 msynth clocks implements a mux with a set_parent hook, but doesn't provide a determine_rate implementation. This is a bit odd, since set_parent() is there to, as its name implies, change the parent of a clock. However, the most likely candidate to trigger that parent change is a call to clk_set_rate(), with determine_rate() figuring out which parent is the best suited for a given rate. The other trigger would be a call to clk_set_parent(), but it's far less used, and it doesn't look like there's any obvious user for that clock. So, the set_parent hook is effectively unused, possibly because of an oversight. However, it could also be an explicit decision by the original author to avoid any reparenting but through an explicit call to clk_set_parent(). The driver does implement round_rate() though, which means that we can change the rate of the clock, but we will never get to change the parent. However, It's hard to tell whether it's been done on purpose or not. Since we'll start mandating a determine_rate() implementation, let's convert the round_rate() implementation to a determine_rate(), which will also make the current behavior explicit. And if it was an oversight, the clock behaviour can be adjusted later on. Signed-off-by: Maxime Ripard --- drivers/clk/clk-si5351.c | 23 +-- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c index fcf5785ba4ce..bfab05f4fe28 100644 --- a/drivers/clk/clk-si5351.c +++ b/drivers/clk/clk-si5351.c @@ -642,11 +642,12 @@ static unsigned long si5351_msynth_recalc_rate(struct clk_hw *hw, return (unsigned long)rate; } -static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate, -unsigned long *parent_rate) +static int si5351_msynth_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct si5351_hw_data *hwdata = container_of(hw, struct si5351_hw_data, hw); + unsigned long rate = req->rate; unsigned long long lltmp; unsigned long a, b, c; int divby4; @@ -681,10 +682,10 @@ static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate, b = 0; c = 1; - *parent_rate = a * rate; + req->best_parent_rate = a * rate; } else if (hwdata->num >= 6) { /* determine the closest integer divider */ - a = DIV_ROUND_CLOSEST(*parent_rate, rate); + a = DIV_ROUND_CLOSEST(req->best_parent_rate, rate); if (a < SI5351_MULTISYNTH_A_MIN) a = SI5351_MULTISYNTH_A_MIN; if (a > SI5351_MULTISYNTH67_A_MAX) @@ -702,7 +703,7 @@ static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate, } /* determine integer part of divider equation */ - a = *parent_rate / rate; + a = req->best_parent_rate / rate; if (a < SI5351_MULTISYNTH_A_MIN) a = SI5351_MULTISYNTH_A_MIN; if (a > SI5351_MULTISYNTH_A_MAX) @@ -710,7 +711,7 @@ static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate, /* find best approximation for b/c = fVCO mod fOUT */ denom = 1000 * 1000; - lltmp = (*parent_rate) % rate; + lltmp = req->best_parent_rate % rate; lltmp *= denom; do_div(lltmp, rate); rfrac = (unsigned long)lltmp; @@ -724,7 +725,7 @@ static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate, } /* recalculate rate by fOUT = fIN / (a + b/c) */ - lltmp = *parent_rate; + lltmp = req->best_parent_rate; lltmp *= c; do_div(lltmp, a * c + b); rate = (unsigned long)lltmp; @@ -749,9 +750,11 @@ static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate, dev_dbg(&hwdata->drvdata->client->dev, "%s - %s: a = %lu, b = %lu, c = %lu, divby4 = %d, parent_rate = %lu, rate = %lu\n", __func__, clk_hw_get_name(hw), a, b, c, divby4, - *parent_rate, rate); + req->best_parent_rate, rate); - return rate; + req->rate = rate; + + return 0; } static int si5351_msynth_set_rate(struct clk_hw *hw, unsigned long rate, @@ -791,7 +794,7 @@ static const struct clk_ops si5351_msynth_ops = { .set_parent = si5351_msynth_set_parent, .get_parent = si5351_msynth_get_parent, .recalc_rate = si5351_msynth_recalc_rate, - .round_rate = si5351_msynth_round_rate, + .determine_rate = si5351_msynth_determine_rate, .set_rate = si5351_msynth_set_rate, }; -- 2.39.2
Re: [RFC PATCH 00/10] Xe DRM scheduler and long running workload plans
On Tue, Apr 04, 2023 at 11:48:36AM +0200, Christian König wrote: > Am 04.04.23 um 11:43 schrieb Tvrtko Ursulin: > > > > On 04/04/2023 01:22, Matthew Brost wrote: > > > Hello, > > > > > > As a prerequisite to merging the new Intel Xe DRM driver [1] [2], we > > > have been asked to merge our common DRM scheduler patches first as well > > > as develop a common solution for long running workloads with the DRM > > > scheduler. This RFC series is our first attempt at doing this. We > > > welcome any and all feedback. > > > > > > This can we thought of as 4 parts detailed below. > > > > > > - DRM scheduler changes for 1 to 1 relationship between scheduler and > > > entity (patches 1-3) > > > > > > In Xe all of the scheduling of jobs is done by a firmware scheduler (the > > > GuC) which is a new paradigm WRT to the DRM scheduler and presents > > > severals problems as the DRM was originally designed to schedule jobs on > > > hardware queues. The main problem being that DRM scheduler expects the > > > submission order of jobs to be the completion order of jobs even across > > > multiple entities. This assumption falls apart with a firmware scheduler > > > as a firmware scheduler has no concept of jobs and jobs can complete out > > > of order. A novel solution for was originally thought of by Faith during > > > the initial prototype of Xe, create a 1 to 1 relationship between > > > scheduler > > > and entity. I believe the AGX driver [3] is using this approach and > > > Boris may use approach as well for the Mali driver [4]. > > > > > > To support a 1 to 1 relationship we move the main execution function > > > from a kthread to a work queue and add a new scheduling mode which > > > bypasses code in the DRM which isn't needed in a 1 to 1 relationship. > > > The new scheduling mode should unify all drivers usage with a 1 to 1 > > > relationship and can be thought of as using scheduler as a dependency / > > > infligt job tracker rather than a true scheduler. > > > > Once you add capability for a more proper 1:1 via > > DRM_SCHED_POLICY_SINGLE_ENTITY, do you still have further need to > > replace kthreads with a wq? > > Yeah, I fail to see the need for that as well. On the other hand it would be > really nice to get rid of the rq/priority design in general. > wrt to replacing kthread with a worker I think the idea is you don't want to tie a kthread creation directly to a uAPI as a user then could create 1000s of kthreads. fwiw in a private email about a year yoy actually suggest using a work queue Christian. > > > > Or in other words, what purpose does the offloading of a job picking > > code to a separate execution context serve? Could it be done directly in > > the 1:1 mode and leave kthread setup for N:M? > > Well moving from kthread to work item is beneficial on it's own since the > later usually follows the the source of it's queue. E.g. when this is > triggered by an interrupt we run on the CPU of the interrupt and not have > inter CPU signaling. > > > > > Apart from those design level questions, low level open IMO still is > > that default fallback of using the system_wq has the potential to affect > > latency for other drivers. But that's for those driver owners to > > approve. > > Oh, yeah that's a good point as well. This needs some high priority queue. > system_highpri_wq? Matt > Christian. > > > > > Regards, > > > > Tvrtko > > > > > - Generic messaging interface for DRM scheduler > > > > > > Idea is to be able to communicate to the submission backend with in band > > > (relative to main execution function) messages. Messages are backend > > > defined and flexable enough for any use case. In Xe we use these > > > messages to clean up entites, set properties for entites, and suspend / > > > resume execution of an entity [5]. I suspect other driver can leverage > > > this messaging concept too as it a convenient way to avoid races in the > > > backend. > > > > > > - Support for using TDR for all error paths of a scheduler / entity > > > > > > Fix a few races / bugs, add function to dynamically set the TDR timeout. > > > > > > - Annotate dma-fences for long running workloads. > > > > > > The idea here is to use dma-fences only as sync points within the > > > scheduler and never export them for long running workloads. By > > > annotating these fences as long running we ensure that these dma-fences > > > are never used in a way that breaks the dma-fence rules. A benefit of > > > thus approach is the scheduler can still safely flow control the > > > execution ring buffer via the job limit without breaking the dma-fence > > > rules. > > > > > > Again this a first draft and looking forward to feedback. > > > > > > Enjoy - Matt > > > > > > [1] https://gitlab.freedesktop.org/drm/xe/kernel > > > [2] https://patchwork.freedesktop.org/series/112188/ > > > [3] https://patchwork.freedesktop.org/series/114772/ > > > [4] https://patchwork.freedesktop.org/patch/515854/?series=112188&rev=1 > > >
Re: [PATCH v3 34/65] clk: ux500: prcmu: Add a determine_rate hook
On Tue, Apr 4, 2023 at 2:45 PM Maxime Ripard wrote: > The UX500 PRCMU "clkout" clock implements a mux with a set_parent hook, > but doesn't provide a determine_rate implementation. > > This is a bit odd, since set_parent() is there to, as its name implies, > change the parent of a clock. However, the most likely candidate to > trigger that parent change is a call to clk_set_rate(), with > determine_rate() figuring out which parent is the best suited for a > given rate. Not even that. The parent is selected from the second cell of the device tree specifier, and the divisor from the third cell. See: Documentation/devicetree/bindings/clock/stericsson,u8500-clks.yaml So this definitely does not reparent. Yours, Linus Walleij
Re: [PATCH v3 07/11] iio: core: Add new DMABUF interface infrastructure
On 4/4/23 00:55, Paul Cercueil wrote: [...] + priv = attach->importer_priv; + list_del_init(&priv->entry); + + iio_buffer_dmabuf_put(attach); + iio_buffer_dmabuf_put(attach); + Is this intended? Looks suspicious... It is intended, yes. You want to release the dma_buf_attachment that's created in iio_buffer_attach_dmabuf(), and you need to call iio_buffer_find_attachment() to get a pointer to it, which also gets a second reference - so it needs to unref twice. Let's add a comment documenting that.
Re: [RFC PATCH 00/10] Xe DRM scheduler and long running workload plans
On Tue, Apr 04, 2023 at 10:43:03AM +0100, Tvrtko Ursulin wrote: > > On 04/04/2023 01:22, Matthew Brost wrote: > > Hello, > > > > As a prerequisite to merging the new Intel Xe DRM driver [1] [2], we > > have been asked to merge our common DRM scheduler patches first as well > > as develop a common solution for long running workloads with the DRM > > scheduler. This RFC series is our first attempt at doing this. We > > welcome any and all feedback. > > > > This can we thought of as 4 parts detailed below. > > > > - DRM scheduler changes for 1 to 1 relationship between scheduler and > > entity (patches 1-3) > > > > In Xe all of the scheduling of jobs is done by a firmware scheduler (the > > GuC) which is a new paradigm WRT to the DRM scheduler and presents > > severals problems as the DRM was originally designed to schedule jobs on > > hardware queues. The main problem being that DRM scheduler expects the > > submission order of jobs to be the completion order of jobs even across > > multiple entities. This assumption falls apart with a firmware scheduler > > as a firmware scheduler has no concept of jobs and jobs can complete out > > of order. A novel solution for was originally thought of by Faith during > > the initial prototype of Xe, create a 1 to 1 relationship between scheduler > > and entity. I believe the AGX driver [3] is using this approach and > > Boris may use approach as well for the Mali driver [4]. > > > > To support a 1 to 1 relationship we move the main execution function > > from a kthread to a work queue and add a new scheduling mode which > > bypasses code in the DRM which isn't needed in a 1 to 1 relationship. > > The new scheduling mode should unify all drivers usage with a 1 to 1 > > relationship and can be thought of as using scheduler as a dependency / > > infligt job tracker rather than a true scheduler. > > Once you add capability for a more proper 1:1 via > DRM_SCHED_POLICY_SINGLE_ENTITY, do you still have further need to replace > kthreads with a wq? > > Or in other words, what purpose does the offloading of a job picking code to > a separate execution context serve? Could it be done directly in the 1:1 > mode and leave kthread setup for N:M? > Addressed the other two on my reply to Christian... For this one basically the concept of a single entity point IMO is a very good concept which I'd like to keep. But most important reason being the main execution thread (now worker) is kicked when a dependency for a job is resolved, dependencies are dma-fences signaled via a callback, and these call backs can be signaled in IRQ contexts. We absolutely do not want to enter the backend in an IRQ context for a variety of reasons. Matt > Apart from those design level questions, low level open IMO still is that > default fallback of using the system_wq has the potential to affect latency > for other drivers. But that's for those driver owners to approve. > > Regards, > > Tvrtko > > > - Generic messaging interface for DRM scheduler > > > > Idea is to be able to communicate to the submission backend with in band > > (relative to main execution function) messages. Messages are backend > > defined and flexable enough for any use case. In Xe we use these > > messages to clean up entites, set properties for entites, and suspend / > > resume execution of an entity [5]. I suspect other driver can leverage > > this messaging concept too as it a convenient way to avoid races in the > > backend. > > > > - Support for using TDR for all error paths of a scheduler / entity > > > > Fix a few races / bugs, add function to dynamically set the TDR timeout. > > > > - Annotate dma-fences for long running workloads. > > > > The idea here is to use dma-fences only as sync points within the > > scheduler and never export them for long running workloads. By > > annotating these fences as long running we ensure that these dma-fences > > are never used in a way that breaks the dma-fence rules. A benefit of > > thus approach is the scheduler can still safely flow control the > > execution ring buffer via the job limit without breaking the dma-fence > > rules. > > > > Again this a first draft and looking forward to feedback. > > > > Enjoy - Matt > > > > [1] https://gitlab.freedesktop.org/drm/xe/kernel > > [2] https://patchwork.freedesktop.org/series/112188/ > > [3] https://patchwork.freedesktop.org/series/114772/ > > [4] https://patchwork.freedesktop.org/patch/515854/?series=112188&rev=1 > > [5] > > https://gitlab.freedesktop.org/drm/xe/kernel/-/blob/drm-xe-next/drivers/gpu/drm/xe/xe_guc_submit.c#L1031 > > > > Matthew Brost (8): > >drm/sched: Convert drm scheduler to use a work queue rather than > > kthread > >drm/sched: Move schedule policy to scheduler / entity > >drm/sched: Add DRM_SCHED_POLICY_SINGLE_ENTITY scheduling policy > >drm/sched: Add generic scheduler message interface > >drm/sched: Start run wq before TDR in drm_sched_start > >drm/sched: Submit job befo
Re: [PATCH] fbdev: Don't spam dmesg on bad userspace ioctl input
Hi Daniel, CC vkmsdrm maintainer Thanks for your patch! On Tue, Apr 4, 2023 at 2:36 PM Daniel Vetter wrote: > There's a few reasons the kernel should not spam dmesg on bad > userspace ioctl input: > - at warning level it results in CI false positives > - it allows userspace to drown dmesg output, potentially hiding real > issues. > > None of the other generic EINVAL checks report in the > FBIOPUT_VSCREENINFO ioctl do this, so it's also inconsistent. > > I guess the intent of the patch which introduced this warning was that > the drivers ->fb_check_var routine should fail in that case. Reality > is that there's too many fbdev drivers and not enough people > maintaining them by far, and so over the past few years we've simply > handled all these validation gaps by tighning the checks in the core, > because that's realistically really all that will ever happen. > > Reported-by: syzbot+20dcf81733d43ddff...@syzkaller.appspotmail.com > Link: > https://syzkaller.appspot.com/bug?id=c5faf983bfa4a607de530cd3bb00bf06cefc WARNING: fbcon: Driver 'vkmsdrmfb' missed to adjust virtual screen size (0x0 vs. 64x768) This is a bug in the vkmsdrmfb driver and/or DRM helpers. The message was added to make sure the individual drivers are fixed. Perhaps it should be changed to BUG() instead, so dmesg output cannot be drown? > Fixes: 6c11df58fd1a ("fbmem: Check virtual screen sizes in fb_set_var()") > Cc: Helge Deller > Cc: Geert Uytterhoeven > Cc: sta...@vger.kernel.org # v5.4+ > Cc: Daniel Vetter > Cc: Javier Martinez Canillas > Cc: Thomas Zimmermann > Signed-off-by: Daniel Vetter NAKed-by: Geert Uytterhoeven > --- a/drivers/video/fbdev/core/fbmem.c > +++ b/drivers/video/fbdev/core/fbmem.c > @@ -1021,10 +1021,6 @@ fb_set_var(struct fb_info *info, struct > fb_var_screeninfo *var) > /* verify that virtual resolution >= physical resolution */ > if (var->xres_virtual < var->xres || > var->yres_virtual < var->yres) { > - pr_warn("WARNING: fbcon: Driver '%s' missed to adjust virtual > screen size (%ux%u vs. %ux%u)\n", > - info->fix.id, > - var->xres_virtual, var->yres_virtual, > - var->xres, var->yres); > return -EINVAL; > } Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Re: [PATCH v3 2/3] drm/bridge: tfp410: Fix logic to configured polled HPD
On Fri, Mar 31, 2023 at 5:00 AM Neil Armstrong wrote: > > Hi, > > On 20/02/2023 23:10, Jonathan Cormier wrote: > > From: Michael Williamson > > > > The logic to configure polling (vs async/irq notification) of hot-plug > > events was not correct. If the connected bridge requires polling, > > then inform the upstream bridge we also require polling. > > > > Signed-off-by: Michael Williamson > > Signed-off-by: Jonathan Cormier > > --- > > drivers/gpu/drm/bridge/ti-tfp410.c | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c > > b/drivers/gpu/drm/bridge/ti-tfp410.c > > index bb3f8d0ff207..41007d05d584 100644 > > --- a/drivers/gpu/drm/bridge/ti-tfp410.c > > +++ b/drivers/gpu/drm/bridge/ti-tfp410.c > > @@ -155,7 +155,7 @@ static int tfp410_attach(struct drm_bridge *bridge, > > return -ENODEV; > > } > > > > - if (dvi->next_bridge->ops & DRM_BRIDGE_OP_DETECT) > > + if (dvi->next_bridge->ops & DRM_BRIDGE_OP_HPD) > > dvi->connector.polled = DRM_CONNECTOR_POLL_HPD; > > else > > dvi->connector.polled = DRM_CONNECTOR_POLL_CONNECT | > > DRM_CONNECTOR_POLL_DISCONNECT; > > > > A Fixes tag is probably needed here ? Thanks will do > > With that: > Reviewed-by: Neil Armstrong -- Jonathan Cormier Software Engineer Voice: 315.425.4045 x222 http://www.CriticalLink.com 6712 Brooklawn Parkway, Syracuse, NY 13211
[PATCH v3 53/65] clk: si5351: clkout: Switch to determine_rate
The SI5351 clkout clocks implements a mux with a set_parent hook, but doesn't provide a determine_rate implementation. This is a bit odd, since set_parent() is there to, as its name implies, change the parent of a clock. However, the most likely candidate to trigger that parent change is a call to clk_set_rate(), with determine_rate() figuring out which parent is the best suited for a given rate. The other trigger would be a call to clk_set_parent(), but it's far less used, and it doesn't look like there's any obvious user for that clock. So, the set_parent hook is effectively unused, possibly because of an oversight. However, it could also be an explicit decision by the original author to avoid any reparenting but through an explicit call to clk_set_parent(). The driver does implement round_rate() though, which means that we can change the rate of the clock, but we will never get to change the parent. However, It's hard to tell whether it's been done on purpose or not. Since we'll start mandating a determine_rate() implementation, let's convert the round_rate() implementation to a determine_rate(), which will also make the current behavior explicit. And if it was an oversight, the clock behaviour can be adjusted later on. Signed-off-by: Maxime Ripard --- drivers/clk/clk-si5351.c | 18 ++ 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c index bfab05f4fe28..11aaa934da29 100644 --- a/drivers/clk/clk-si5351.c +++ b/drivers/clk/clk-si5351.c @@ -1037,11 +1037,12 @@ static unsigned long si5351_clkout_recalc_rate(struct clk_hw *hw, return parent_rate >> rdiv; } -static long si5351_clkout_round_rate(struct clk_hw *hw, unsigned long rate, -unsigned long *parent_rate) +static int si5351_clkout_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct si5351_hw_data *hwdata = container_of(hw, struct si5351_hw_data, hw); + unsigned long rate = req->rate; unsigned char rdiv; /* clkout6/7 can only handle output freqencies < 150MHz */ @@ -1063,13 +1064,13 @@ static long si5351_clkout_round_rate(struct clk_hw *hw, unsigned long rate, rdiv += 1; rate *= 2; } - *parent_rate = rate; + req->best_parent_rate = rate; } else { unsigned long new_rate, new_err, err; /* round to closed rdiv */ rdiv = SI5351_OUTPUT_CLK_DIV_1; - new_rate = *parent_rate; + new_rate = req->best_parent_rate; err = abs(new_rate - rate); do { new_rate >>= 1; @@ -1080,14 +1081,15 @@ static long si5351_clkout_round_rate(struct clk_hw *hw, unsigned long rate, err = new_err; } while (1); } - rate = *parent_rate >> rdiv; + rate = req->best_parent_rate >> rdiv; dev_dbg(&hwdata->drvdata->client->dev, "%s - %s: rdiv = %u, parent_rate = %lu, rate = %lu\n", __func__, clk_hw_get_name(hw), (1 << rdiv), - *parent_rate, rate); + req->best_parent_rate, rate); - return rate; + req->rate = rate; + return 0; } static int si5351_clkout_set_rate(struct clk_hw *hw, unsigned long rate, @@ -1147,7 +1149,7 @@ static const struct clk_ops si5351_clkout_ops = { .set_parent = si5351_clkout_set_parent, .get_parent = si5351_clkout_get_parent, .recalc_rate = si5351_clkout_recalc_rate, - .round_rate = si5351_clkout_round_rate, + .determine_rate = si5351_clkout_determine_rate, .set_rate = si5351_clkout_set_rate, }; -- 2.39.2
[PATCH v3 54/65] clk: da8xx: clk48: Switch to determine_rate
The TI DA8xx USB0 clk48 clocks implements a mux with a set_parent hook, but doesn't provide a determine_rate implementation. This is a bit odd, since set_parent() is there to, as its name implies, change the parent of a clock. However, the most likely candidate to trigger that parent change is a call to clk_set_rate(), with determine_rate() figuring out which parent is the best suited for a given rate. The other trigger would be a call to clk_set_parent(), but it's far less used, and it doesn't look like there's any obvious user for that clock. So, the set_parent hook is effectively unused, possibly because of an oversight. However, it could also be an explicit decision by the original author to avoid any reparenting but through an explicit call to clk_set_parent(). The driver does implement round_rate() though, which means that we can change the rate of the clock, but we will never get to change the parent. However, It's hard to tell whether it's been done on purpose or not. Since we'll start mandating a determine_rate() implementation, let's convert the round_rate() implementation to a determine_rate(), which will also make the current behavior explicit. And if it was an oversight, the clock behaviour can be adjusted later on. Signed-off-by: Maxime Ripard --- drivers/clk/davinci/da8xx-cfgchip.c | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/clk/davinci/da8xx-cfgchip.c b/drivers/clk/davinci/da8xx-cfgchip.c index 4c1cc59bba53..f60c97091818 100644 --- a/drivers/clk/davinci/da8xx-cfgchip.c +++ b/drivers/clk/davinci/da8xx-cfgchip.c @@ -462,10 +462,12 @@ static unsigned long da8xx_usb0_clk48_recalc_rate(struct clk_hw *hw, return 4800; } -static long da8xx_usb0_clk48_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int da8xx_usb0_clk48_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - return 4800; + req->rate = 4800; + + return 0; } static int da8xx_usb0_clk48_set_parent(struct clk_hw *hw, u8 index) @@ -494,7 +496,7 @@ static const struct clk_ops da8xx_usb0_clk48_ops = { .disable= da8xx_usb0_clk48_disable, .is_enabled = da8xx_usb0_clk48_is_enabled, .recalc_rate= da8xx_usb0_clk48_recalc_rate, - .round_rate = da8xx_usb0_clk48_round_rate, + .determine_rate = da8xx_usb0_clk48_determine_rate, .set_parent = da8xx_usb0_clk48_set_parent, .get_parent = da8xx_usb0_clk48_get_parent, }; -- 2.39.2
[PATCH v3 55/65] clk: imx: scu: Switch to determine_rate
The iMX SCU clocks implements a mux with a set_parent hook, but doesn't provide a determine_rate implementation. This is a bit odd, since set_parent() is there to, as its name implies, change the parent of a clock. However, the most likely candidate to trigger that parent change is a call to clk_set_rate(), with determine_rate() figuring out which parent is the best suited for a given rate. The other trigger would be a call to clk_set_parent(), but it's far less used, and it doesn't look like there's any obvious user for that clock. So, the set_parent hook is effectively unused, possibly because of an oversight. However, it could also be an explicit decision by the original author to avoid any reparenting but through an explicit call to clk_set_parent(). The driver does implement round_rate() though, which means that we can change the rate of the clock, but we will never get to change the parent. However, It's hard to tell whether it's been done on purpose or not. Since we'll start mandating a determine_rate() implementation, let's convert the round_rate() implementation to a determine_rate(), which will also make the current behavior explicit. The round_rate() implementation being shared with other clocks, it's not removed. And if it was an oversight, the clock behaviour can be adjusted later on. Signed-off-by: Maxime Ripard --- drivers/clk/imx/clk-scu.c | 19 ++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c index 66e49fea5f8a..bbdc1b23f6f5 100644 --- a/drivers/clk/imx/clk-scu.c +++ b/drivers/clk/imx/clk-scu.c @@ -250,6 +250,23 @@ static unsigned long clk_scu_recalc_rate(struct clk_hw *hw, return le32_to_cpu(msg.data.resp.rate); } +/* + * clk_scu_determine_rate - Returns the closest rate for a SCU clock + * @hw: clock to round rate for + * @req: clock rate request + * + * Returns 0 on success, a negative error on failure + */ +static int clk_scu_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + /* +* Assume we support all the requested rate and let the SCU firmware +* to handle the left work +*/ + return 0; +} + /* * clk_scu_round_rate - Round clock rate for a SCU clock * @hw: clock to round rate for @@ -425,7 +442,7 @@ static void clk_scu_unprepare(struct clk_hw *hw) static const struct clk_ops clk_scu_ops = { .recalc_rate = clk_scu_recalc_rate, - .round_rate = clk_scu_round_rate, + .determine_rate = clk_scu_determine_rate, .set_rate = clk_scu_set_rate, .get_parent = clk_scu_get_parent, .set_parent = clk_scu_set_parent, -- 2.39.2
[PATCH v3 56/65] clk: ingenic: cgu: Switch to determine_rate
The Ingenic CGU clocks implements a mux with a set_parent hook, but doesn't provide a determine_rate implementation. This is a bit odd, since set_parent() is there to, as its name implies, change the parent of a clock. However, the most likely candidate to trigger that parent change is a call to clk_set_rate(), with determine_rate() figuring out which parent is the best suited for a given rate. The other trigger would be a call to clk_set_parent(), but it's far less used, and it doesn't look like there's any obvious user for that clock. So, the set_parent hook is effectively unused, possibly because of an oversight. However, it could also be an explicit decision by the original author to avoid any reparenting but through an explicit call to clk_set_parent(). The driver does implement round_rate() though, which means that we can change the rate of the clock, but we will never get to change the parent. However, It's hard to tell whether it's been done on purpose or not. Since we'll start mandating a determine_rate() implementation, let's convert the round_rate() implementation to a determine_rate(), which will also make the current behavior explicit. And if it was an oversight, the clock behaviour can be adjusted later on. Signed-off-by: Maxime Ripard --- drivers/clk/ingenic/cgu.c | 15 --- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c index 1f7ba30f5a1b..0c9c8344ad11 100644 --- a/drivers/clk/ingenic/cgu.c +++ b/drivers/clk/ingenic/cgu.c @@ -491,22 +491,23 @@ ingenic_clk_calc_div(struct clk_hw *hw, return div; } -static long -ingenic_clk_round_rate(struct clk_hw *hw, unsigned long req_rate, - unsigned long *parent_rate) +static int ingenic_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw); const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk); unsigned int div = 1; if (clk_info->type & CGU_CLK_DIV) - div = ingenic_clk_calc_div(hw, clk_info, *parent_rate, req_rate); + div = ingenic_clk_calc_div(hw, clk_info, req->best_parent_rate, + req->rate); else if (clk_info->type & CGU_CLK_FIXDIV) div = clk_info->fixdiv.div; else if (clk_hw_can_set_rate_parent(hw)) - *parent_rate = req_rate; + req->best_parent_rate = req->rate; - return DIV_ROUND_UP(*parent_rate, div); + req->rate = DIV_ROUND_UP(req->best_parent_rate, div); + return 0; } static inline int ingenic_clk_check_stable(struct ingenic_cgu *cgu, @@ -626,7 +627,7 @@ static const struct clk_ops ingenic_clk_ops = { .set_parent = ingenic_clk_set_parent, .recalc_rate = ingenic_clk_recalc_rate, - .round_rate = ingenic_clk_round_rate, + .determine_rate = ingenic_clk_determine_rate, .set_rate = ingenic_clk_set_rate, .enable = ingenic_clk_enable, -- 2.39.2
[PATCH v3 57/65] clk: ingenic: tcu: Switch to determine_rate
The Ingenic TCU clocks implements a mux with a set_parent hook, but doesn't provide a determine_rate implementation. This is a bit odd, since set_parent() is there to, as its name implies, change the parent of a clock. However, the most likely candidate to trigger that parent change is a call to clk_set_rate(), with determine_rate() figuring out which parent is the best suited for a given rate. The other trigger would be a call to clk_set_parent(), but it's far less used, and it doesn't look like there's any obvious user for that clock. So, the set_parent hook is effectively unused, possibly because of an oversight. However, it could also be an explicit decision by the original author to avoid any reparenting but through an explicit call to clk_set_parent(). The driver does implement round_rate() though, which means that we can change the rate of the clock, but we will never get to change the parent. However, It's hard to tell whether it's been done on purpose or not. Since we'll start mandating a determine_rate() implementation, let's convert the round_rate() implementation to a determine_rate(), which will also make the current behavior explicit. And if it was an oversight, the clock behaviour can be adjusted later on. Signed-off-by: Maxime Ripard --- drivers/clk/ingenic/tcu.c | 19 +++ 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/clk/ingenic/tcu.c b/drivers/clk/ingenic/tcu.c index d5544cbc5c48..7d04ef40b7cf 100644 --- a/drivers/clk/ingenic/tcu.c +++ b/drivers/clk/ingenic/tcu.c @@ -178,18 +178,21 @@ static u8 ingenic_tcu_get_prescale(unsigned long rate, unsigned long req_rate) return 5; /* /1024 divider */ } -static long ingenic_tcu_round_rate(struct clk_hw *hw, unsigned long req_rate, - unsigned long *parent_rate) +static int ingenic_tcu_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - unsigned long rate = *parent_rate; + unsigned long rate = req->best_parent_rate; u8 prescale; - if (req_rate > rate) - return rate; + if (req->rate > rate) { + req->rate = rate; + return 0; + } - prescale = ingenic_tcu_get_prescale(rate, req_rate); + prescale = ingenic_tcu_get_prescale(rate, req->rate); - return rate >> (prescale * 2); + req->rate = rate >> (prescale * 2); + return 0; } static int ingenic_tcu_set_rate(struct clk_hw *hw, unsigned long req_rate, @@ -219,7 +222,7 @@ static const struct clk_ops ingenic_tcu_clk_ops = { .set_parent = ingenic_tcu_set_parent, .recalc_rate= ingenic_tcu_recalc_rate, - .round_rate = ingenic_tcu_round_rate, + .determine_rate = ingenic_tcu_determine_rate, .set_rate = ingenic_tcu_set_rate, .enable = ingenic_tcu_enable, -- 2.39.2
[PATCH v3 58/65] clk: sprd: composite: Switch to determine_rate
The Spreadtrum composite clocks implements a mux with a set_parent hook, but doesn't provide a determine_rate implementation. This is a bit odd, since set_parent() is there to, as its name implies, change the parent of a clock. However, the most likely candidate to trigger that parent change is a call to clk_set_rate(), with determine_rate() figuring out which parent is the best suited for a given rate. The other trigger would be a call to clk_set_parent(), but it's far less used, and it doesn't look like there's any obvious user for that clock. So, the set_parent hook is effectively unused, possibly because of an oversight. However, it could also be an explicit decision by the original author to avoid any reparenting but through an explicit call to clk_set_parent(). The driver does implement round_rate() though, which means that we can change the rate of the clock, but we will never get to change the parent. However, It's hard to tell whether it's been done on purpose or not. Since we'll start mandating a determine_rate() implementation, let's convert the round_rate() implementation to a determine_rate(), which will also make the current behavior explicit. And if it was an oversight, the clock behaviour can be adjusted later on. Acked-by: Chunyan Zhang Signed-off-by: Maxime Ripard --- drivers/clk/sprd/composite.c | 16 +++- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/clk/sprd/composite.c b/drivers/clk/sprd/composite.c index ebb644820b1e..d3a852720c07 100644 --- a/drivers/clk/sprd/composite.c +++ b/drivers/clk/sprd/composite.c @@ -9,13 +9,19 @@ #include "composite.h" -static long sprd_comp_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int sprd_comp_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct sprd_comp *cc = hw_to_sprd_comp(hw); + unsigned long rate; - return sprd_div_helper_round_rate(&cc->common, &cc->div, -rate, parent_rate); + rate = sprd_div_helper_round_rate(&cc->common, &cc->div, + req->rate, &req->best_parent_rate); + if (rate < 0) + return rate; + + req->rate = rate; + return 0; } static unsigned long sprd_comp_recalc_rate(struct clk_hw *hw, @@ -53,7 +59,7 @@ const struct clk_ops sprd_comp_ops = { .get_parent = sprd_comp_get_parent, .set_parent = sprd_comp_set_parent, - .round_rate = sprd_comp_round_rate, + .determine_rate = sprd_comp_determine_rate, .recalc_rate= sprd_comp_recalc_rate, .set_rate = sprd_comp_set_rate, }; -- 2.39.2
[PATCH v3 59/65] clk: st: flexgen: Switch to determine_rate
The ST Flexgen clocks implements a mux with a set_parent hook, but doesn't provide a determine_rate implementation. This is a bit odd, since set_parent() is there to, as its name implies, change the parent of a clock. However, the most likely candidate to trigger that parent change is a call to clk_set_rate(), with determine_rate() figuring out which parent is the best suited for a given rate. The other trigger would be a call to clk_set_parent(), but it's far less used, and it doesn't look like there's any obvious user for that clock. So, the set_parent hook is effectively unused, possibly because of an oversight. However, it could also be an explicit decision by the original author to avoid any reparenting but through an explicit call to clk_set_parent(). The driver does implement round_rate() though, which means that we can change the rate of the clock, but we will never get to change the parent. However, It's hard to tell whether it's been done on purpose or not. Since we'll start mandating a determine_rate() implementation, let's convert the round_rate() implementation to a determine_rate(), which will also make the current behavior explicit. And if it was an oversight, the clock behaviour can be adjusted later on. Signed-off-by: Maxime Ripard --- drivers/clk/st/clk-flexgen.c | 15 --- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/clk/st/clk-flexgen.c b/drivers/clk/st/clk-flexgen.c index 7ae4f656191e..5292208c4dd8 100644 --- a/drivers/clk/st/clk-flexgen.c +++ b/drivers/clk/st/clk-flexgen.c @@ -119,20 +119,21 @@ clk_best_div(unsigned long parent_rate, unsigned long rate) return parent_rate / rate + ((rate > (2*(parent_rate % rate))) ? 0 : 1); } -static long flexgen_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int flexgen_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { unsigned long div; /* Round div according to exact prate and wished rate */ - div = clk_best_div(*prate, rate); + div = clk_best_div(req->best_parent_rate, req->rate); if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) { - *prate = rate * div; - return rate; + req->best_parent_rate = req->rate * div; + return 0; } - return *prate / div; + req->rate = req->best_parent_rate / div; + return 0; } static unsigned long flexgen_recalc_rate(struct clk_hw *hw, @@ -197,7 +198,7 @@ static const struct clk_ops flexgen_ops = { .is_enabled = flexgen_is_enabled, .get_parent = flexgen_get_parent, .set_parent = flexgen_set_parent, - .round_rate = flexgen_round_rate, + .determine_rate = flexgen_determine_rate, .recalc_rate = flexgen_recalc_rate, .set_rate = flexgen_set_rate, }; -- 2.39.2
[PATCH v3 60/65] clk: stm32: composite: Switch to determine_rate
The STM32 composite clocks implements a mux with a set_parent hook, but doesn't provide a determine_rate implementation. This is a bit odd, since set_parent() is there to, as its name implies, change the parent of a clock. However, the most likely candidate to trigger that parent change is a call to clk_set_rate(), with determine_rate() figuring out which parent is the best suited for a given rate. The other trigger would be a call to clk_set_parent(), but it's far less used, and it doesn't look like there's any obvious user for that clock. So, the set_parent hook is effectively unused, possibly because of an oversight. However, it could also be an explicit decision by the original author to avoid any reparenting but through an explicit call to clk_set_parent(). The driver does implement round_rate() though, which means that we can change the rate of the clock, but we will never get to change the parent. However, It's hard to tell whether it's been done on purpose or not. Since we'll start mandating a determine_rate() implementation, let's convert the round_rate() implementation to a determine_rate(), which will also make the current behavior explicit. And if it was an oversight, the clock behaviour can be adjusted later on. Signed-off-by: Maxime Ripard --- drivers/clk/stm32/clk-stm32-core.c | 32 +--- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/drivers/clk/stm32/clk-stm32-core.c b/drivers/clk/stm32/clk-stm32-core.c index 3247539683c9..d5aa09e9fce4 100644 --- a/drivers/clk/stm32/clk-stm32-core.c +++ b/drivers/clk/stm32/clk-stm32-core.c @@ -426,15 +426,15 @@ static unsigned long clk_stm32_composite_recalc_rate(struct clk_hw *hw, composite->div_id, parent_rate); } -static long clk_stm32_composite_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_stm32_composite_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_stm32_composite *composite = to_clk_stm32_composite(hw); - const struct stm32_div_cfg *divider; + unsigned long rate; if (composite->div_id == NO_STM32_DIV) - return rate; + return 0; divider = &composite->clock_data->dividers[composite->div_id]; @@ -445,14 +445,24 @@ static long clk_stm32_composite_round_rate(struct clk_hw *hw, unsigned long rate val = readl(composite->base + divider->offset) >> divider->shift; val &= clk_div_mask(divider->width); - return divider_ro_round_rate(hw, rate, prate, divider->table, - divider->width, divider->flags, - val); + rate = divider_ro_round_rate(hw, req->rate, &req->best_parent_rate, +divider->table, divider->width, divider->flags, +val); + if (rate < 0) + return rate; + + req->rate = rate; + return 0; } - return divider_round_rate_parent(hw, clk_hw_get_parent(hw), -rate, prate, divider->table, -divider->width, divider->flags); + rate = divider_round_rate_parent(hw, clk_hw_get_parent(hw), +req->rate, &req->best_parent_rate, +divider->table, divider->width, divider->flags); + if (rate < 0) + return rate; + + req->rate = rate; + return 0; } static u8 clk_stm32_composite_get_parent(struct clk_hw *hw) @@ -602,7 +612,7 @@ static void clk_stm32_composite_disable_unused(struct clk_hw *hw) const struct clk_ops clk_stm32_composite_ops = { .set_rate = clk_stm32_composite_set_rate, .recalc_rate= clk_stm32_composite_recalc_rate, - .round_rate = clk_stm32_composite_round_rate, + .determine_rate = clk_stm32_composite_determine_rate, .get_parent = clk_stm32_composite_get_parent, .set_parent = clk_stm32_composite_set_parent, .enable = clk_stm32_composite_gate_enable, -- 2.39.2
[PATCH v3 61/65] clk: tegra: periph: Switch to determine_rate
The Tegra periph clocks implements a mux with a set_parent hook, but doesn't provide a determine_rate implementation. This is a bit odd, since set_parent() is there to, as its name implies, change the parent of a clock. However, the most likely candidate to trigger that parent change is a call to clk_set_rate(), with determine_rate() figuring out which parent is the best suited for a given rate. The other trigger would be a call to clk_set_parent(), but it's far less used, and it doesn't look like there's any obvious user for that clock. So, the set_parent hook is effectively unused, possibly because of an oversight. However, it could also be an explicit decision by the original author to avoid any reparenting but through an explicit call to clk_set_parent(). The driver does implement round_rate() though, which means that we can change the rate of the clock, but we will never get to change the parent. However, It's hard to tell whether it's been done on purpose or not. Since we'll start mandating a determine_rate() implementation, let's convert the round_rate() implementation to a determine_rate(), which will also make the current behavior explicit. And if it was an oversight, the clock behaviour can be adjusted later on. Signed-off-by: Maxime Ripard --- drivers/clk/tegra/clk-periph.c | 16 +++- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c index 367396c62259..ce8cab5f1978 100644 --- a/drivers/clk/tegra/clk-periph.c +++ b/drivers/clk/tegra/clk-periph.c @@ -45,16 +45,22 @@ static unsigned long clk_periph_recalc_rate(struct clk_hw *hw, return div_ops->recalc_rate(div_hw, parent_rate); } -static long clk_periph_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_periph_determine_rate(struct clk_hw *hw, +struct clk_rate_request *req) { struct tegra_clk_periph *periph = to_clk_periph(hw); const struct clk_ops *div_ops = periph->div_ops; struct clk_hw *div_hw = &periph->divider.hw; + unsigned long rate; __clk_hw_set_clk(div_hw, hw); - return div_ops->round_rate(div_hw, rate, prate); + rate = div_ops->round_rate(div_hw, req->rate, &req->best_parent_rate); + if (rate < 0) + return rate; + + req->rate = rate; + return 0; } static int clk_periph_set_rate(struct clk_hw *hw, unsigned long rate, @@ -130,7 +136,7 @@ const struct clk_ops tegra_clk_periph_ops = { .get_parent = clk_periph_get_parent, .set_parent = clk_periph_set_parent, .recalc_rate = clk_periph_recalc_rate, - .round_rate = clk_periph_round_rate, + .determine_rate = clk_periph_determine_rate, .set_rate = clk_periph_set_rate, .is_enabled = clk_periph_is_enabled, .enable = clk_periph_enable, @@ -154,7 +160,7 @@ static const struct clk_ops tegra_clk_periph_no_gate_ops = { .get_parent = clk_periph_get_parent, .set_parent = clk_periph_set_parent, .recalc_rate = clk_periph_recalc_rate, - .round_rate = clk_periph_round_rate, + .determine_rate = clk_periph_determine_rate, .set_rate = clk_periph_set_rate, .restore_context = clk_periph_restore_context, }; -- 2.39.2
[PATCH v3 62/65] clk: tegra: super: Switch to determine_rate
The Tegra super clocks implements a mux with a set_parent hook, but doesn't provide a determine_rate implementation. This is a bit odd, since set_parent() is there to, as its name implies, change the parent of a clock. However, the most likely candidate to trigger that parent change is a call to clk_set_rate(), with determine_rate() figuring out which parent is the best suited for a given rate. The other trigger would be a call to clk_set_parent(), but it's far less used, and it doesn't look like there's any obvious user for that clock. So, the set_parent hook is effectively unused, possibly because of an oversight. However, it could also be an explicit decision by the original author to avoid any reparenting but through an explicit call to clk_set_parent(). The driver does implement round_rate() though, which means that we can change the rate of the clock, but we will never get to change the parent. However, It's hard to tell whether it's been done on purpose or not. Since we'll start mandating a determine_rate() implementation, let's convert the round_rate() implementation to a determine_rate(), which will also make the current behavior explicit. And if it was an oversight, the clock behaviour can be adjusted later on. Signed-off-by: Maxime Ripard --- drivers/clk/tegra/clk-super.c | 15 +++ 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c index 8ad62e04fd8b..c035f0eb030d 100644 --- a/drivers/clk/tegra/clk-super.c +++ b/drivers/clk/tegra/clk-super.c @@ -142,15 +142,22 @@ static const struct clk_ops tegra_clk_super_mux_ops = { .restore_context = clk_super_mux_restore_context, }; -static long clk_super_round_rate(struct clk_hw *hw, unsigned long rate, -unsigned long *parent_rate) +static int clk_super_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct tegra_clk_super_mux *super = to_clk_super_mux(hw); struct clk_hw *div_hw = &super->frac_div.hw; + unsigned long rate; __clk_hw_set_clk(div_hw, hw); - return super->div_ops->round_rate(div_hw, rate, parent_rate); + rate = super->div_ops->round_rate(div_hw, req->rate, + &req->best_parent_rate); + if (rate < 0) + return rate; + + req->rate = rate; + return 0; } static unsigned long clk_super_recalc_rate(struct clk_hw *hw, @@ -193,7 +200,7 @@ const struct clk_ops tegra_clk_super_ops = { .get_parent = clk_super_get_parent, .set_parent = clk_super_set_parent, .set_rate = clk_super_set_rate, - .round_rate = clk_super_round_rate, + .determine_rate = clk_super_determine_rate, .recalc_rate = clk_super_recalc_rate, .restore_context = clk_super_restore_context, }; -- 2.39.2
Re: [PATCH] fbdev: Don't spam dmesg on bad userspace ioctl input
On Tue, Apr 04, 2023 at 03:53:09PM +0200, Geert Uytterhoeven wrote: > Hi Daniel, > > CC vkmsdrm maintainer > > Thanks for your patch! > > On Tue, Apr 4, 2023 at 2:36 PM Daniel Vetter wrote: > > There's a few reasons the kernel should not spam dmesg on bad > > userspace ioctl input: > > - at warning level it results in CI false positives > > - it allows userspace to drown dmesg output, potentially hiding real > > issues. > > > > None of the other generic EINVAL checks report in the > > FBIOPUT_VSCREENINFO ioctl do this, so it's also inconsistent. > > > > I guess the intent of the patch which introduced this warning was that > > the drivers ->fb_check_var routine should fail in that case. Reality > > is that there's too many fbdev drivers and not enough people > > maintaining them by far, and so over the past few years we've simply > > handled all these validation gaps by tighning the checks in the core, > > because that's realistically really all that will ever happen. > > > > Reported-by: syzbot+20dcf81733d43ddff...@syzkaller.appspotmail.com > > Link: > > https://syzkaller.appspot.com/bug?id=c5faf983bfa4a607de530cd3bb00bf06cefc > > WARNING: fbcon: Driver 'vkmsdrmfb' missed to adjust virtual screen > size (0x0 vs. 64x768) > > This is a bug in the vkmsdrmfb driver and/or DRM helpers. > > The message was added to make sure the individual drivers are fixed. > Perhaps it should be changed to BUG() instead, so dmesg output > cannot be drown? So you're solution is to essentially force us to replicate this check over all the drivers which cannot change the virtual size? Are you volunteering to field that audit and type all the patches? > > Fixes: 6c11df58fd1a ("fbmem: Check virtual screen sizes in fb_set_var()") > > Cc: Helge Deller > > Cc: Geert Uytterhoeven > > Cc: sta...@vger.kernel.org # v5.4+ > > Cc: Daniel Vetter > > Cc: Javier Martinez Canillas > > Cc: Thomas Zimmermann > > Signed-off-by: Daniel Vetter > > NAKed-by: Geert Uytterhoeven Yes I know it's not pretty, but realistically unless someone starts typing a _lot_ of patches this is the solution. It's exactly the same solution we've implemented for all other gaps syzcaller has find in fbdev input validation. Unless you can show that this is papering over a more severe bug somewhere, but then I guess it really should be a BUG to prevent worse things from happening. -Daniel > > > --- a/drivers/video/fbdev/core/fbmem.c > > +++ b/drivers/video/fbdev/core/fbmem.c > > @@ -1021,10 +1021,6 @@ fb_set_var(struct fb_info *info, struct > > fb_var_screeninfo *var) > > /* verify that virtual resolution >= physical resolution */ > > if (var->xres_virtual < var->xres || > > var->yres_virtual < var->yres) { > > - pr_warn("WARNING: fbcon: Driver '%s' missed to adjust > > virtual screen size (%ux%u vs. %ux%u)\n", > > - info->fix.id, > > - var->xres_virtual, var->yres_virtual, > > - var->xres, var->yres); > > return -EINVAL; > > } > > Gr{oetje,eeting}s, > > Geert > > > -- > Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- > ge...@linux-m68k.org > > In personal conversations with technical people, I call myself a hacker. But > when I'm talking to journalists I just say "programmer" or something like > that. > -- Linus Torvalds -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch
Re: [PATCH v10 2/2] drm: add kms driver for loongson display controller
Greetings Sui Jingfeng, I haven't been around drm-land for a while and this is the first driver I skim through in a few years. So take the following suggestions with a healthy pinch of salt. Hope that helps o/ On Mon, 3 Apr 2023 at 18:13, Sui Jingfeng wrote: > v7 -> v8: >1) Zero a compile warnnings on 32-bit platform, compile with W=1 >2) Revise lsdc_bo_gpu_offset() and minor cleanup >3) Pageflip tested on the virtual terminal with following commands > > modetest -M loongson -s 32:1920x1080 -v > modetest -M loongson -s 34:1920x1080 -v -F tiles > I could be wrong, but my understanding is that new drivers should be capable of running under Xorg and/or Wayland compositor. There is also the IGT test suite, which can help verify and validate the driver's behaviour: https://www.kernel.org/doc/html/latest/gpu/drm-uapi.html > +static void lsdc_crtc_reset(struct drm_crtc *crtc) > +{ > + struct lsdc_display_pipe *dispipe = crtc_to_display_pipe(crtc); > + struct drm_device *ddev = crtc->dev; > + struct lsdc_device *ldev = to_lsdc(ddev); > + struct lsdc_crtc_state *priv_crtc_state; > + unsigned int index = dispipe->index; > + u32 val; > + > + val = LSDC_PF_XRGB | CFG_RESET_N; > + if (ldev->descp->chip == CHIP_LS7A2000) > + val |= LSDC_DMA_STEP_64_BYTES; > + > + lsdc_crtc_wreg32(ldev, LSDC_CRTC0_CFG_REG, index, val); > + > + if (ldev->descp->chip == CHIP_LS7A2000) { > + val = PHY_CLOCK_EN | PHY_DATA_EN; > + lsdc_crtc_wreg32(ldev, LSDC_CRTC0_PANEL_CONF_REG, index, val); > + } > + AFAICT no other driver touches the HW in their reset callback. Should the above be moved to another callback? > +static void lsdc_crtc_atomic_enable(struct drm_crtc *crtc, > + struct drm_atomic_state *state) > +{ > + val = lsdc_crtc_rreg32(ldev, LSDC_CRTC0_CFG_REG, index); > + /* clear old dma step settings */ > + val &= ~CFG_DMA_STEP_MASK; > + > + if (descp->chip == CHIP_LS7A2000) { > + /* > +* Using large dma step as much as possible, > +* for improve hardware DMA efficiency. > +*/ > + if (width_in_bytes % 256 == 0) > + val |= LSDC_DMA_STEP_256_BYTES; > + else if (width_in_bytes % 128 == 0) > + val |= LSDC_DMA_STEP_128_BYTES; > + else if (width_in_bytes % 64 == 0) > + val |= LSDC_DMA_STEP_64_BYTES; > + else /* width_in_bytes % 32 == 0 */ > + val |= LSDC_DMA_STEP_32_BYTES; > + } > + > + clk_func->update(pixpll, &priv_state->pparms); > + Without knowing the hardware, the clk_func abstraction seems quite arbitrary and unnecessary. It should be introduced when there is a use-case for it. > + lsdc_crtc_wreg32(ldev, LSDC_CRTC0_CFG_REG, index, val | > CFG_OUTPUT_EN); > + > + drm_crtc_vblank_on(crtc); > +} > + > --- /dev/null > +++ b/drivers/gpu/drm/loongson/lsdc_debugfs.c > +void lsdc_debugfs_init(struct drm_minor *minor) > +{ > +#ifdef CONFIG_DEBUG_FS > + drm_debugfs_create_files(lsdc_debugfs_list, > +ARRAY_SIZE(lsdc_debugfs_list), > +minor->debugfs_root, > +minor); > +#endif > +} Should probably build the file when debugfs is enabled and provide no-op stub in the header. See nouveau for an example. > --- /dev/null > +++ b/drivers/gpu/drm/loongson/lsdc_drv.c > +static const struct lsdc_desc dc_in_ls7a1000 = { > + .chip = CHIP_LS7A1000, > + .num_of_crtc = LSDC_NUM_CRTC, > + .max_pixel_clk = 20, > + .max_width = 2048, > + .max_height = 2048, > + .num_of_hw_cursor = 1, > + .hw_cursor_w = 32, > + .hw_cursor_h = 32, > + .pitch_align = 256, > + .mc_bits = 40, > + .has_vblank_counter = false, > + .has_scan_pos = true, > + .has_builtin_i2c = true, > + .has_vram = true, > + .has_hpd_reg = false, > + .is_soc = false, > +}; > + > +static const struct lsdc_desc dc_in_ls7a2000 = { > + .chip = CHIP_LS7A2000, > + .num_of_crtc = LSDC_NUM_CRTC, > + .max_pixel_clk = 35, > + .max_width = 4096, > + .max_height = 4096, > + .num_of_hw_cursor = 2, > + .hw_cursor_w = 64, > + .hw_cursor_h = 64, > + .pitch_align = 64, > + .mc_bits = 40, /* support 48, but use 40 for backward compatibility */ > + .has_vblank_counter = true, > + .has_scan_pos = true, > + .has_builtin_i2c = true, > + .has_vram = true, > + .has_hpd_reg = true, > + .is_soc = false, > +}; > + Roughly a quarter of the above are identical. It might be better to drop them for now and re-introduce as needed with future code. > +const char *chip_to_str(enum loongson_chip_fami
Re: [RESEND PATCH v4 03/21] staging: media: tegra-video: fix .vidioc_enum_fmt_vid_cap to return all formats
Hello Hans, On Wed, 29 Mar 2023 13:16:22 +0200 Hans Verkuil wrote: > Hi Luca, > > I finally found the time to test this series. It looks OK, except for this > patch. Thank you very much for taking the time! > The list of supported formats really has to be the intersection of what the > tegra > supports and what the sensor supports. > > Otherwise you would advertise pixelformats that cannot be used, and the > application > would have no way of knowing that. As far as I understand, I think we should rather make this driver fully behave as an MC-centric device. It is already using MC quite successfully after all. Do you think this is correct? If you do, then I think the plan would be: - Add the V4L2_CAP_IO_MC flag - As the mbus_code in get_format appropriately - Leave the changes in this patch unmodified otherwise Best regards, Luca -- Luca Ceresoli, Bootlin Embedded Linux and Kernel engineering https://bootlin.com
Re: [PATCH] fbdev: Don't spam dmesg on bad userspace ioctl input
On Tue, Apr 04, 2023 at 03:59:12PM +0200, Daniel Vetter wrote: > On Tue, Apr 04, 2023 at 03:53:09PM +0200, Geert Uytterhoeven wrote: > > Hi Daniel, > > > > CC vkmsdrm maintainer > > > > Thanks for your patch! > > > > On Tue, Apr 4, 2023 at 2:36 PM Daniel Vetter wrote: > > > There's a few reasons the kernel should not spam dmesg on bad > > > userspace ioctl input: > > > - at warning level it results in CI false positives > > > - it allows userspace to drown dmesg output, potentially hiding real > > > issues. > > > > > > None of the other generic EINVAL checks report in the > > > FBIOPUT_VSCREENINFO ioctl do this, so it's also inconsistent. > > > > > > I guess the intent of the patch which introduced this warning was that > > > the drivers ->fb_check_var routine should fail in that case. Reality > > > is that there's too many fbdev drivers and not enough people > > > maintaining them by far, and so over the past few years we've simply > > > handled all these validation gaps by tighning the checks in the core, > > > because that's realistically really all that will ever happen. > > > > > > Reported-by: syzbot+20dcf81733d43ddff...@syzkaller.appspotmail.com > > > Link: > > > https://syzkaller.appspot.com/bug?id=c5faf983bfa4a607de530cd3bb00bf06cefc > > > > WARNING: fbcon: Driver 'vkmsdrmfb' missed to adjust virtual screen > > size (0x0 vs. 64x768) > > > > This is a bug in the vkmsdrmfb driver and/or DRM helpers. > > > > The message was added to make sure the individual drivers are fixed. > > Perhaps it should be changed to BUG() instead, so dmesg output > > cannot be drown? > > So you're solution is to essentially force us to replicate this check over > all the drivers which cannot change the virtual size? > > Are you volunteering to field that audit and type all the patches? Note that at least efifb, vesafb and offb seem to get this wrong. I didn't bother checking any of the non-fw drivers. Iow there is a _lot_ of work in your nack. -Daniel > > > Fixes: 6c11df58fd1a ("fbmem: Check virtual screen sizes in fb_set_var()") > > > Cc: Helge Deller > > > Cc: Geert Uytterhoeven > > > Cc: sta...@vger.kernel.org # v5.4+ > > > Cc: Daniel Vetter > > > Cc: Javier Martinez Canillas > > > Cc: Thomas Zimmermann > > > Signed-off-by: Daniel Vetter > > > > NAKed-by: Geert Uytterhoeven > > Yes I know it's not pretty, but realistically unless someone starts typing > a _lot_ of patches this is the solution. It's exactly the same solution > we've implemented for all other gaps syzcaller has find in fbdev input > validation. Unless you can show that this is papering over a more severe > bug somewhere, but then I guess it really should be a BUG to prevent worse > things from happening. > -Daniel > > > > > > --- a/drivers/video/fbdev/core/fbmem.c > > > +++ b/drivers/video/fbdev/core/fbmem.c > > > @@ -1021,10 +1021,6 @@ fb_set_var(struct fb_info *info, struct > > > fb_var_screeninfo *var) > > > /* verify that virtual resolution >= physical resolution */ > > > if (var->xres_virtual < var->xres || > > > var->yres_virtual < var->yres) { > > > - pr_warn("WARNING: fbcon: Driver '%s' missed to adjust > > > virtual screen size (%ux%u vs. %ux%u)\n", > > > - info->fix.id, > > > - var->xres_virtual, var->yres_virtual, > > > - var->xres, var->yres); > > > return -EINVAL; > > > } > > > > Gr{oetje,eeting}s, > > > > Geert > > > > > > -- > > Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- > > ge...@linux-m68k.org > > > > In personal conversations with technical people, I call myself a hacker. But > > when I'm talking to journalists I just say "programmer" or something like > > that. > > -- Linus Torvalds > > -- > Daniel Vetter > Software Engineer, Intel Corporation > http://blog.ffwll.ch -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch
[PATCH 2/5] drm/i915/display: Set I915_BO_ALLOC_USER for fb
Framebuffer is exposed to userspace so make sure we set proper flags for it. Set I915_BO_PREALLOC for prealloced fb so that ttm won't clear existing data. Cc: Matthew Auld Cc: Andi Shyti Cc: Andrzej Hajda Cc: Ville Syrjälä Cc: Jani Nikula Cc: Imre Deak Signed-off-by: Nirmoy Das --- drivers/gpu/drm/i915/display/intel_fbdev.c | 3 ++- drivers/gpu/drm/i915/display/intel_plane_initial.c | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 673bcdfb7ff6..f7d48d00ae4b 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -163,7 +163,8 @@ static int intelfb_alloc(struct drm_fb_helper *helper, obj = ERR_PTR(-ENODEV); if (HAS_LMEM(dev_priv)) { obj = i915_gem_object_create_lmem(dev_priv, size, - I915_BO_ALLOC_CONTIGUOUS); + I915_BO_ALLOC_CONTIGUOUS | + I915_BO_ALLOC_USER); } else { /* * If the FB is too big, just don't use it since fbdev is not very diff --git a/drivers/gpu/drm/i915/display/intel_plane_initial.c b/drivers/gpu/drm/i915/display/intel_plane_initial.c index bb6ea7de5c61..736072a8b2b0 100644 --- a/drivers/gpu/drm/i915/display/intel_plane_initial.c +++ b/drivers/gpu/drm/i915/display/intel_plane_initial.c @@ -110,7 +110,9 @@ initial_plane_vma(struct drm_i915_private *i915, size * 2 > i915->dsm.usable_size) return NULL; - obj = i915_gem_object_create_region_at(mem, phys_base, size, 0); + obj = i915_gem_object_create_region_at(mem, phys_base, size, + I915_BO_ALLOC_USER | + I915_BO_PREALLOC); if (IS_ERR(obj)) return NULL; -- 2.39.0
[PATCH 3/5] drm/i915: Add a function to mmap framebuffer obj
Implement i915_gem_fb_mmap() to enable fb_ops.fb_mmap() callback for i915's framebuffer objects. v2: add a comment why i915_gem_object_get() needed(Andi). v3: mmap also ttm objects. Cc: Matthew Auld Cc: Andi Shyti Cc: Ville Syrjälä Cc: Jani Nikula Cc: Imre Deak Signed-off-by: Nirmoy Das --- drivers/gpu/drm/i915/gem/i915_gem_mman.c | 137 +++ drivers/gpu/drm/i915/gem/i915_gem_mman.h | 2 +- 2 files changed, 93 insertions(+), 46 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c index d3c1dee16af2..3dbacdf0911a 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c @@ -927,53 +927,15 @@ static struct file *mmap_singleton(struct drm_i915_private *i915) return file; } -/* - * This overcomes the limitation in drm_gem_mmap's assignment of a - * drm_gem_object as the vma->vm_private_data. Since we need to - * be able to resolve multiple mmap offsets which could be tied - * to a single gem object. - */ -int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma) +static int +i915_gem_object_mmap(struct drm_i915_gem_object *obj, +struct i915_mmap_offset *mmo, +struct vm_area_struct *vma) { - struct drm_vma_offset_node *node; - struct drm_file *priv = filp->private_data; - struct drm_device *dev = priv->minor->dev; - struct drm_i915_gem_object *obj = NULL; - struct i915_mmap_offset *mmo = NULL; + struct drm_i915_private *i915 = to_i915(obj->base.dev); + struct drm_device *dev = &i915->drm; struct file *anon; - if (drm_dev_is_unplugged(dev)) - return -ENODEV; - - rcu_read_lock(); - drm_vma_offset_lock_lookup(dev->vma_offset_manager); - node = drm_vma_offset_exact_lookup_locked(dev->vma_offset_manager, - vma->vm_pgoff, - vma_pages(vma)); - if (node && drm_vma_node_is_allowed(node, priv)) { - /* -* Skip 0-refcnted objects as it is in the process of being -* destroyed and will be invalid when the vma manager lock -* is released. -*/ - if (!node->driver_private) { - mmo = container_of(node, struct i915_mmap_offset, vma_node); - obj = i915_gem_object_get_rcu(mmo->obj); - - GEM_BUG_ON(obj && obj->ops->mmap_ops); - } else { - obj = i915_gem_object_get_rcu - (container_of(node, struct drm_i915_gem_object, - base.vma_node)); - - GEM_BUG_ON(obj && !obj->ops->mmap_ops); - } - } - drm_vma_offset_unlock_lookup(dev->vma_offset_manager); - rcu_read_unlock(); - if (!obj) - return node ? -EACCES : -EINVAL; - if (i915_gem_object_is_readonly(obj)) { if (vma->vm_flags & VM_WRITE) { i915_gem_object_put(obj); @@ -1005,7 +967,7 @@ int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma) if (obj->ops->mmap_ops) { vma->vm_page_prot = pgprot_decrypted(vm_get_page_prot(vma->vm_flags)); vma->vm_ops = obj->ops->mmap_ops; - vma->vm_private_data = node->driver_private; + vma->vm_private_data = obj->base.vma_node.driver_private; return 0; } @@ -1043,6 +1005,91 @@ int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma) return 0; } +/* + * This overcomes the limitation in drm_gem_mmap's assignment of a + * drm_gem_object as the vma->vm_private_data. Since we need to + * be able to resolve multiple mmap offsets which could be tied + * to a single gem object. + */ +int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma) +{ + struct drm_vma_offset_node *node; + struct drm_file *priv = filp->private_data; + struct drm_device *dev = priv->minor->dev; + struct drm_i915_gem_object *obj = NULL; + struct i915_mmap_offset *mmo = NULL; + + if (drm_dev_is_unplugged(dev)) + return -ENODEV; + + rcu_read_lock(); + drm_vma_offset_lock_lookup(dev->vma_offset_manager); + node = drm_vma_offset_exact_lookup_locked(dev->vma_offset_manager, + vma->vm_pgoff, + vma_pages(vma)); + if (node && drm_vma_node_is_allowed(node, priv)) { + /* +* Skip 0-refcnted objects as it is in the process of being +* destroyed and will be invalid when the vma manager lock +* is released. +*/ + if (!node->driver_private) { +
[PATCH 1/5] drm/i915/ttm: Add I915_BO_PREALLOC
Add a mechanism to keep existing data when creating a ttm object with I915_BO_ALLOC_USER flag. Cc: Matthew Auld Cc: Andi Shyti Cc: Andrzej Hajda Cc: Ville Syrjälä Cc: Jani Nikula Cc: Imre Deak Signed-off-by: Nirmoy Das --- drivers/gpu/drm/i915/gem/i915_gem_object_types.h | 15 +++ drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c | 5 +++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h index 5dcbbef31d44..830c11431ee8 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h @@ -328,6 +328,12 @@ struct drm_i915_gem_object { */ #define I915_BO_ALLOC_GPU_ONLY BIT(6) #define I915_BO_ALLOC_CCS_AUXBIT(7) +/* + * Object is allowed to retain its initial data and will not be cleared on first + * access if used along with I915_BO_ALLOC_USER. This is mainly to keep + * preallocated framebuffer data intact while transitioning it to i915drmfb. + */ +#define I915_BO_PREALLOC BIT(8) #define I915_BO_ALLOC_FLAGS (I915_BO_ALLOC_CONTIGUOUS | \ I915_BO_ALLOC_VOLATILE | \ I915_BO_ALLOC_CPU_CLEAR | \ @@ -335,10 +341,11 @@ struct drm_i915_gem_object { I915_BO_ALLOC_PM_VOLATILE | \ I915_BO_ALLOC_PM_EARLY | \ I915_BO_ALLOC_GPU_ONLY | \ -I915_BO_ALLOC_CCS_AUX) -#define I915_BO_READONLY BIT(8) -#define I915_TILING_QUIRK_BIT 9 /* unknown swizzling; do not release! */ -#define I915_BO_PROTECTED BIT(10) +I915_BO_ALLOC_CCS_AUX | \ +I915_BO_PREALLOC) +#define I915_BO_READONLY BIT(9) +#define I915_TILING_QUIRK_BIT 10 /* unknown swizzling; do not release! */ +#define I915_BO_PROTECTED BIT(11) /** * @mem_flags - Mutable placement-related flags * diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c index dd188dfcc423..69eb20ed4d47 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c @@ -576,7 +576,7 @@ int i915_ttm_move(struct ttm_buffer_object *bo, bool evict, struct dma_fence *migration_fence = NULL; struct ttm_tt *ttm = bo->ttm; struct i915_refct_sgt *dst_rsgt; - bool clear; + bool clear, prealloc_bo; int ret; if (GEM_WARN_ON(i915_ttm_is_ghost_object(bo))) { @@ -632,7 +632,8 @@ int i915_ttm_move(struct ttm_buffer_object *bo, bool evict, return PTR_ERR(dst_rsgt); clear = !i915_ttm_cpu_maps_iomem(bo->resource) && (!ttm || !ttm_tt_is_populated(ttm)); - if (!(clear && ttm && !(ttm->page_flags & TTM_TT_FLAG_ZERO_ALLOC))) { + prealloc_bo = obj->flags & I915_BO_PREALLOC; + if (!(clear && ttm && !((ttm->page_flags & TTM_TT_FLAG_ZERO_ALLOC) && !prealloc_bo))) { struct i915_deps deps; i915_deps_init(&deps, GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN); -- 2.39.0
[PATCH 4/5] drm/i915/display: Add helper func to get intel_fbdev from drm_fb_helper
Add a helper function to retrieve struct intel_fbdev from struct drm_fb_helper. Cc: Matthew Auld Cc: Andi Shyti Cc: Ville Syrjälä Cc: Jani Nikula Cc: Imre Deak Signed-off-by: Nirmoy Das Reviewed-by: Jani Nikula Reviewed-by: Andi Shyti Reviewed-by: Andrzej Hajda --- drivers/gpu/drm/i915/display/intel_fbdev.c | 23 ++ 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index f7d48d00ae4b..2ac9e9f8a128 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -67,6 +67,11 @@ struct intel_fbdev { struct mutex hpd_lock; }; +static struct intel_fbdev *to_intel_fbdev(struct drm_fb_helper *fb_helper) +{ + return container_of(fb_helper, struct intel_fbdev, helper); +} + static struct intel_frontbuffer *to_frontbuffer(struct intel_fbdev *ifbdev) { return ifbdev->fb->frontbuffer; @@ -79,9 +84,7 @@ static void intel_fbdev_invalidate(struct intel_fbdev *ifbdev) static int intel_fbdev_set_par(struct fb_info *info) { - struct drm_fb_helper *fb_helper = info->par; - struct intel_fbdev *ifbdev = - container_of(fb_helper, struct intel_fbdev, helper); + struct intel_fbdev *ifbdev = to_intel_fbdev(info->par); int ret; ret = drm_fb_helper_set_par(info); @@ -93,9 +96,7 @@ static int intel_fbdev_set_par(struct fb_info *info) static int intel_fbdev_blank(int blank, struct fb_info *info) { - struct drm_fb_helper *fb_helper = info->par; - struct intel_fbdev *ifbdev = - container_of(fb_helper, struct intel_fbdev, helper); + struct intel_fbdev *ifbdev = to_intel_fbdev(info->par); int ret; ret = drm_fb_helper_blank(blank, info); @@ -108,9 +109,7 @@ static int intel_fbdev_blank(int blank, struct fb_info *info) static int intel_fbdev_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { - struct drm_fb_helper *fb_helper = info->par; - struct intel_fbdev *ifbdev = - container_of(fb_helper, struct intel_fbdev, helper); + struct intel_fbdev *ifbdev = to_intel_fbdev(info->par); int ret; ret = drm_fb_helper_pan_display(var, info); @@ -136,8 +135,7 @@ static const struct fb_ops intelfb_ops = { static int intelfb_alloc(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes) { - struct intel_fbdev *ifbdev = - container_of(helper, struct intel_fbdev, helper); + struct intel_fbdev *ifbdev = to_intel_fbdev(helper); struct drm_framebuffer *fb; struct drm_device *dev = helper->dev; struct drm_i915_private *dev_priv = to_i915(dev); @@ -194,8 +192,7 @@ static int intelfb_alloc(struct drm_fb_helper *helper, static int intelfb_create(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes) { - struct intel_fbdev *ifbdev = - container_of(helper, struct intel_fbdev, helper); + struct intel_fbdev *ifbdev = to_intel_fbdev(helper); struct intel_framebuffer *intel_fb = ifbdev->fb; struct drm_device *dev = helper->dev; struct drm_i915_private *dev_priv = to_i915(dev); -- 2.39.0
[PATCH 5/5] drm/i915/display: Implement fb_mmap callback function
If stolen memory allocation fails for fbdev, the driver will fallback to system memory. Calculation of smem_start is wrong for such framebuffer objs if the platform comes with no gmadr or no aperture. Solve this by adding fb_mmap callback which will use GTT if aperture is available otherwise will use cpu to access the framebuffer. v2: Use to_intel_fbdev() function(Jani) Cc: Matthew Auld Cc: Andi Shyti Cc: Ville Syrjälä Cc: Jani Nikula Cc: Imre Deak Signed-off-by: Nirmoy Das Reviewed-by: Andi Shyti Reviewed-by: Andrzej Hajda --- drivers/gpu/drm/i915/display/intel_fbdev.c | 12 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 2ac9e9f8a128..aab1ae74a8f7 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -40,8 +40,10 @@ #include #include #include +#include #include "gem/i915_gem_lmem.h" +#include "gem/i915_gem_mman.h" #include "i915_drv.h" #include "intel_display_types.h" @@ -119,6 +121,15 @@ static int intel_fbdev_pan_display(struct fb_var_screeninfo *var, return ret; } +static int intel_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma) +{ + struct intel_fbdev *fbdev = to_intel_fbdev(info->par); + struct drm_gem_object *bo = drm_gem_fb_get_obj(&fbdev->fb->base, 0); + struct drm_i915_gem_object *obj = to_intel_bo(bo); + + return i915_gem_fb_mmap(obj, vma); +} + static const struct fb_ops intelfb_ops = { .owner = THIS_MODULE, DRM_FB_HELPER_DEFAULT_OPS, @@ -130,6 +141,7 @@ static const struct fb_ops intelfb_ops = { .fb_imageblit = drm_fb_helper_cfb_imageblit, .fb_pan_display = intel_fbdev_pan_display, .fb_blank = intel_fbdev_blank, + .fb_mmap = intel_fbdev_mmap, }; static int intelfb_alloc(struct drm_fb_helper *helper, -- 2.39.0
Re: [PATCH] fbdev: Don't spam dmesg on bad userspace ioctl input
Hi Am 04.04.23 um 16:19 schrieb Daniel Vetter: On Tue, Apr 04, 2023 at 03:59:12PM +0200, Daniel Vetter wrote: On Tue, Apr 04, 2023 at 03:53:09PM +0200, Geert Uytterhoeven wrote: Hi Daniel, CC vkmsdrm maintainer Thanks for your patch! On Tue, Apr 4, 2023 at 2:36 PM Daniel Vetter wrote: There's a few reasons the kernel should not spam dmesg on bad userspace ioctl input: - at warning level it results in CI false positives - it allows userspace to drown dmesg output, potentially hiding real issues. None of the other generic EINVAL checks report in the FBIOPUT_VSCREENINFO ioctl do this, so it's also inconsistent. I guess the intent of the patch which introduced this warning was that the drivers ->fb_check_var routine should fail in that case. Reality is that there's too many fbdev drivers and not enough people maintaining them by far, and so over the past few years we've simply handled all these validation gaps by tighning the checks in the core, because that's realistically really all that will ever happen. Reported-by: syzbot+20dcf81733d43ddff...@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?id=c5faf983bfa4a607de530cd3bb00bf06cefc WARNING: fbcon: Driver 'vkmsdrmfb' missed to adjust virtual screen size (0x0 vs. 64x768) This is a bug in the vkmsdrmfb driver and/or DRM helpers. The message was added to make sure the individual drivers are fixed. Perhaps it should be changed to BUG() instead, so dmesg output cannot be drown? So you're solution is to essentially force us to replicate this check over all the drivers which cannot change the virtual size? Are you volunteering to field that audit and type all the patches? Note that at least efifb, vesafb and offb seem to get this wrong. I didn't bother checking any of the non-fw drivers. Iow there is a _lot_ of work in your nack. As most of us really only care about DRM, we can add this test to drm_fb_helper_check_var() [1] and that's it. No need to fix all of the fbdev drivers. Having said that, I think the few remaining fbdev devs should decide if they want to actually put effort into fbdev, or accept it to bitrot away. The current state of 'non-maintenance' is the worst situation. I've been working on the console emulation and it is hard to get qualified reviews of the related fbdev code. At the same time, it's also not possible to get Ack-bys rubber-stamped. Best regards Thomas [1] https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/drm_fb_helper.c#L1514 -Daniel Fixes: 6c11df58fd1a ("fbmem: Check virtual screen sizes in fb_set_var()") Cc: Helge Deller Cc: Geert Uytterhoeven Cc: sta...@vger.kernel.org # v5.4+ Cc: Daniel Vetter Cc: Javier Martinez Canillas Cc: Thomas Zimmermann Signed-off-by: Daniel Vetter NAKed-by: Geert Uytterhoeven Yes I know it's not pretty, but realistically unless someone starts typing a _lot_ of patches this is the solution. It's exactly the same solution we've implemented for all other gaps syzcaller has find in fbdev input validation. Unless you can show that this is papering over a more severe bug somewhere, but then I guess it really should be a BUG to prevent worse things from happening. -Daniel --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -1021,10 +1021,6 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) /* verify that virtual resolution >= physical resolution */ if (var->xres_virtual < var->xres || var->yres_virtual < var->yres) { - pr_warn("WARNING: fbcon: Driver '%s' missed to adjust virtual screen size (%ux%u vs. %ux%u)\n", - info->fix.id, - var->xres_virtual, var->yres_virtual, - var->xres, var->yres); return -EINVAL; } Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Ivo Totev OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH 01/11] drm/ast: Use drm_aperture_remove_conflicting_pci_framebuffers
Hi, FYI I have merged patches 1, 6 and 7 of this patchset. They look fine and are worthwhile fixes on their own. Best regards Thomas Am 11.01.23 um 16:41 schrieb Daniel Vetter: It's just open coded and matches. Note that Thomas said that his version apparently failed for some reason, but hey maybe we should try again. Signed-off-by: Daniel Vetter Cc: Dave Airlie Cc: Thomas Zimmermann Cc: Javier Martinez Canillas Cc: Helge Deller Cc: linux-fb...@vger.kernel.org --- drivers/gpu/drm/ast/ast_drv.c | 16 +--- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index 420fc75c240e..3ac24a780f50 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c @@ -90,27 +90,13 @@ static const struct pci_device_id ast_pciidlist[] = { MODULE_DEVICE_TABLE(pci, ast_pciidlist); -static int ast_remove_conflicting_framebuffers(struct pci_dev *pdev) -{ - bool primary = false; - resource_size_t base, size; - - base = pci_resource_start(pdev, 0); - size = pci_resource_len(pdev, 0); -#ifdef CONFIG_X86 - primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; -#endif - - return drm_aperture_remove_conflicting_framebuffers(base, size, primary, &ast_driver); -} - static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct ast_private *ast; struct drm_device *dev; int ret; - ret = ast_remove_conflicting_framebuffers(pdev); + ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &ast_driver); if (ret) return ret; -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Ivo Totev OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH] fbdev: Don't spam dmesg on bad userspace ioctl input
CC linux-fbdev On Tue, Apr 4, 2023 at 4:19 PM Daniel Vetter wrote: > On Tue, Apr 04, 2023 at 03:59:12PM +0200, Daniel Vetter wrote: > > On Tue, Apr 04, 2023 at 03:53:09PM +0200, Geert Uytterhoeven wrote: > > > On Tue, Apr 4, 2023 at 2:36 PM Daniel Vetter > > > wrote: > > > > There's a few reasons the kernel should not spam dmesg on bad > > > > userspace ioctl input: > > > > - at warning level it results in CI false positives > > > > - it allows userspace to drown dmesg output, potentially hiding real > > > > issues. > > > > > > > > None of the other generic EINVAL checks report in the > > > > FBIOPUT_VSCREENINFO ioctl do this, so it's also inconsistent. > > > > > > > > I guess the intent of the patch which introduced this warning was that > > > > the drivers ->fb_check_var routine should fail in that case. Reality > > > > is that there's too many fbdev drivers and not enough people > > > > maintaining them by far, and so over the past few years we've simply > > > > handled all these validation gaps by tighning the checks in the core, > > > > because that's realistically really all that will ever happen. > > > > > > > > Reported-by: syzbot+20dcf81733d43ddff...@syzkaller.appspotmail.com > > > > Link: > > > > https://syzkaller.appspot.com/bug?id=c5faf983bfa4a607de530cd3bb00bf06cefc > > > > > > WARNING: fbcon: Driver 'vkmsdrmfb' missed to adjust virtual screen > > > size (0x0 vs. 64x768) > > > > > > This is a bug in the vkmsdrmfb driver and/or DRM helpers. > > > > > > The message was added to make sure the individual drivers are fixed. > > > Perhaps it should be changed to BUG() instead, so dmesg output > > > cannot be drown? > > > > So you're solution is to essentially force us to replicate this check over > > all the drivers which cannot change the virtual size? > > > > Are you volunteering to field that audit and type all the patches? > > Note that at least efifb, vesafb and offb seem to get this wrong. I didn't > bother checking any of the non-fw drivers. Iow there is a _lot_ of work in > your nack. Please don't spread FUD: efifb, vesafb and offb do not implement fb_ops.fb_check_var(), so they are not affected. Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Re: [PATCH] fbdev: Don't spam dmesg on bad userspace ioctl input
CC linux-fbdev On Tue, Apr 4, 2023 at 4:41 PM Thomas Zimmermann wrote: > Am 04.04.23 um 16:19 schrieb Daniel Vetter: > > On Tue, Apr 04, 2023 at 03:59:12PM +0200, Daniel Vetter wrote: > >> On Tue, Apr 04, 2023 at 03:53:09PM +0200, Geert Uytterhoeven wrote: > >>> CC vkmsdrm maintainer > >>> > >>> Thanks for your patch! > >>> > >>> On Tue, Apr 4, 2023 at 2:36 PM Daniel Vetter > >>> wrote: > There's a few reasons the kernel should not spam dmesg on bad > userspace ioctl input: > - at warning level it results in CI false positives > - it allows userspace to drown dmesg output, potentially hiding real > issues. > > None of the other generic EINVAL checks report in the > FBIOPUT_VSCREENINFO ioctl do this, so it's also inconsistent. > > I guess the intent of the patch which introduced this warning was that > the drivers ->fb_check_var routine should fail in that case. Reality > is that there's too many fbdev drivers and not enough people > maintaining them by far, and so over the past few years we've simply > handled all these validation gaps by tighning the checks in the core, > because that's realistically really all that will ever happen. > > Reported-by: syzbot+20dcf81733d43ddff...@syzkaller.appspotmail.com > Link: > https://syzkaller.appspot.com/bug?id=c5faf983bfa4a607de530cd3bb00bf06cefc > >>> > >>> WARNING: fbcon: Driver 'vkmsdrmfb' missed to adjust virtual screen > >>> size (0x0 vs. 64x768) > >>> > >>> This is a bug in the vkmsdrmfb driver and/or DRM helpers. > >>> > >>> The message was added to make sure the individual drivers are fixed. > >>> Perhaps it should be changed to BUG() instead, so dmesg output > >>> cannot be drown? > >> > >> So you're solution is to essentially force us to replicate this check over > >> all the drivers which cannot change the virtual size? > >> > >> Are you volunteering to field that audit and type all the patches? The message is there to invite people to look at .fb_check_var() implementations, and fix the issues. > As most of us really only care about DRM, we can add this test to > drm_fb_helper_check_var() [1] and that's it. No need to fix all of the > fbdev drivers. Either drm_fb_helper_check_var() (which is the most used buggy implementation) has to be fixed, or it should be removed, cfr. https://lore.kernel.org/all/20220629105658.1373770-1-ge...@linux-m68k.org > Having said that, I think the few remaining fbdev devs should decide if > they want to actually put effort into fbdev, or accept it to bitrot > away. The current state of 'non-maintenance' is the worst situation. > I've been working on the console emulation and it is hard to get > qualified reviews of the related fbdev code. At the same time, it's also > not possible to get Ack-bys rubber-stamped. > > Best regards > Thomas > > [1] > https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/drm_fb_helper.c#L1514 > > > -Daniel > > > Fixes: 6c11df58fd1a ("fbmem: Check virtual screen sizes in fb_set_var()") > Cc: Helge Deller > Cc: Geert Uytterhoeven > Cc: sta...@vger.kernel.org # v5.4+ > Cc: Daniel Vetter > Cc: Javier Martinez Canillas > Cc: Thomas Zimmermann > Signed-off-by: Daniel Vetter > >>> > >>> NAKed-by: Geert Uytterhoeven > >> > >> Yes I know it's not pretty, but realistically unless someone starts typing > >> a _lot_ of patches this is the solution. It's exactly the same solution > >> we've implemented for all other gaps syzcaller has find in fbdev input > >> validation. Unless you can show that this is papering over a more severe > >> bug somewhere, but then I guess it really should be a BUG to prevent worse > >> things from happening. > >> -Daniel > >> > >>> > --- a/drivers/video/fbdev/core/fbmem.c > +++ b/drivers/video/fbdev/core/fbmem.c > @@ -1021,10 +1021,6 @@ fb_set_var(struct fb_info *info, struct > fb_var_screeninfo *var) > /* verify that virtual resolution >= physical resolution */ > if (var->xres_virtual < var->xres || > var->yres_virtual < var->yres) { > - pr_warn("WARNING: fbcon: Driver '%s' missed to adjust > virtual screen size (%ux%u vs. %ux%u)\n", > - info->fix.id, > - var->xres_virtual, var->yres_virtual, > - var->xres, var->yres); > return -EINVAL; > } Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Re: [PATCH] misc: sram: Add dma-heap-export reserved SRAM area type
> > Hi Andrew > > > >> > >> > >> Okay, will split for v2. > >> > >> > > > > Was there a follow-up v2 of this patchset? AFAICT this series did not > > make it into the mainline kernel. > > Do you have any plans to work on it? If not I would like to help out > > as we have a use case where we want to > > use a dma-buf sram exporter. > > > > > > Sure, I've been keeping it alive in our evil vendor tree, but if > there is interest upstream now I'll post a v2 and CC you. That would be great! -- greets -- Christian Gmeiner, MSc https://christian-gmeiner.info/privacypolicy
Re: [PATCH 0/3] Revert lima fdinfo patchset
On Tue, 4 Apr 2023 at 08:13, wrote: > > From: Qiang Yu > > Upstream has reverted the dependant commit > df622729ddbf ("drm/scheduler: track GPU active time per entity""), > but this patchset has been pushed to drm-misc-next which still > has that commit. To avoid other branch build fail after merge > drm-misc-next, just revert the lima patchset on drm-misc-next too. > The bug/revert is unfortunate, although we better keep the build clean or Linus will go bananas ^_^ Fwiw for the series: Acked-by: Emil Velikov HTH -Emil
Re: [PATCH] drm/fb-helper: Remove helpers to change frame buffer config
Hi Daniel, On Tue, Aug 9, 2022 at 5:03 PM Daniel Vetter wrote: > On Sat, Jul 02, 2022 at 08:05:54PM +0200, Helge Deller wrote: > > On 6/29/22 12:56, Geert Uytterhoeven wrote: > > > The DRM fbdev emulation layer does not support pushing back > > > changes to fb_var_screeninfo to KMS. > > > > > > However, drm_fb_helper still implements the fb_ops.fb_check_var() and > > > fb_ops.fb_set_par() callbacks, but the former fails to validate various > > > parameters passed from userspace. Hence unsanitized and possible > > > invaled values are passed up through the fbdev, fbcon, and console > > > stack, which has become an endless source of security issues reported > > > against fbdev. > > > > > > Fix this by not populating the fb_ops.fb_check_var() and > > > fb_ops.fb_set_par() callbacks, as there is no point in providing them if > > > the frame buffer config cannot be changed anyway. This makes the fbdev > > > core aware that making changes to the frame buffer config is not > > > supported, so it will always return the current config. > > > > > > Signed-off-by: Geert Uytterhoeven > > > > It's unfortunate that DRM currently isn't able to switch resolutions > > at runtime. > > > > With that in mind I agree with Geert that it's probably better to > > disable (or drop) that code until DRM can cope with fbdev's > > interface to switch resolutions. > > > > Furthermore, with the upcoming patches to fbcon (which prevents crashes on > > invalid userspace input), you will face a kernel WARNING if you call fbset > > to switch screen resolutions with DRM drivers. > > > > So, from my side (although I'd prefer a better fix for DRM): > > > > Acked-by: Helge Deller > > So maybe I'm missing something, but I think this breaks a lot of stuff. > The issue is that fbdev is only a subordinate owner of the kms device, if > there's a real drm kms owner around that wins. > > Which means when you switch back then set_par needs to restore the fbdev > framebuffer. So that might break some recovery/use-cases. Upon closer look, I think I was a bit too over-eager, and we can keep the implementation of fb_ops.fb_set_par(). > The other thing is that I think this also breaks the scanout offset, and > people do use that for double-buffering on top of fbdev on top of drm > drivers. So we can't just nuke it completely. You mean panning? That does not need fb_ops.fb_check_var(), as it should be done through fb_ops.fb_pan_display(). > For better or worse I think we need to keep playing the whack-a-mole game. > Or do I miss something here? With the above fixed, we can continue whacking the drm bugs in implementing the fbdev API? Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Re: [PATCH v3 43/65] ASoC: tlv320aic32x4: Add a determine_rate hook
On Tue, Apr 04, 2023 at 12:11:33PM +0200, Maxime Ripard wrote: > The tlv320aic32x4 clkin clock implements a mux with a set_parent hook, > but doesn't provide a determine_rate implementation. > This is a bit odd, since set_parent() is there to, as its name implies, > change the parent of a clock. However, the most likely candidate to > trigger that parent change is a call to clk_set_rate(), with > determine_rate() figuring out which parent is the best suited for a > given rate. > The other trigger would be a call to clk_set_parent(), but it's far less > used, and it doesn't look like there's any obvious user for that clock. It could be configured from device tree as well couldn't it? > So, the set_parent hook is effectively unused, possibly because of an > oversight. However, it could also be an explicit decision by the > original author to avoid any reparenting but through an explicit call to > clk_set_parent(). Historically clk_set_rate() wouldn't reparent IIRC. > The latter case would be equivalent to setting the flag > CLK_SET_RATE_NO_REPARENT, together with setting our determine_rate hook > to __clk_mux_determine_rate(). Indeed, if no determine_rate > implementation is provided, clk_round_rate() (through > clk_core_round_rate_nolock()) will call itself on the parent if > CLK_SET_RATE_PARENT is set, and will not change the clock rate > otherwise. __clk_mux_determine_rate() has the exact same behavior when > CLK_SET_RATE_NO_REPARENT is set. > And if it was an oversight, then we are at least explicit about our > behavior now and it can be further refined down the line. To be honest it's surprising that we'd have to manually specify this, I would expect to be able to reparent. I suspect it'd be better to go the other way here and allow reparenting. signature.asc Description: PGP signature