Re: [Intel-gfx] [PATCH 15/18] vfio/gvt: Make DRM_I915_GVT depend on VFIO_MDEV
On 2021.03.23 16:39:36 -0300, Jason Gunthorpe wrote: > On Tue, Mar 23, 2021 at 08:26:30PM +0100, Christoph Hellwig wrote: > > On Tue, Mar 23, 2021 at 02:55:32PM -0300, Jason Gunthorpe wrote: > > > Ideally all of this would be moved to kvmgt.c, but it is entangled with > > > the rest of the "generic" code in an odd way. Thus put in a kconfig > > > dependency so we don't get randconfig failures when the next patch creates > > > a link time dependency related to the use of MDEV_TYPE. > > > > Ideally that weird struct intel_gvt_mpt would go away entirely. But > > that is clearly out of scope for this patchset.. > > Yes.. Maybe someone from Intel will take that on, along with that > other note you had. Compared to all the others this driver is quite > twisty! > It was there for other hypervisor support, although XenGT support was never upstream, but there's also some third-party hypervisor using GVT device model. For vGPU type, it planned to be used for XenGT as well, but it turned out not to be true, yeah, I agree that should be in kvmgt.c and mdev only. Thanks to point out this. Until to clean up this, I may pick this one first. Thanks signature.asc Description: PGP signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 1/2] iommu/arm-smmu-qcom: Skip the TTBR1 quirk for db820c.
On Mon, Mar 29, 2021 at 7:47 AM Will Deacon wrote: > > On Fri, Mar 26, 2021 at 04:13:02PM -0700, Eric Anholt wrote: > > db820c wants to use the qcom smmu path to get HUPCF set (which keeps > > the GPU from wedging and then sometimes wedging the kernel after a > > page fault), but it doesn't have separate pagetables support yet in > > drm/msm so we can't go all the way to the TTBR1 path. > > What do you mean by "doesn't have separate pagetables support yet"? The > compatible string doesn't feel like the right way to determine this. the compatible string identifies what it is, not what the sw limitations are, so in that regard it seems right to me.. BR, -R ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Freedreno] [PATCH v3 19/25] drm/msm/dsi: drop msm_dsi_pll abstracton
On 2021-03-29 20:13, abhin...@codeaurora.org wrote: On 2021-03-27 04:02, Dmitry Baryshkov wrote: Drop the struct msm_dsi_pll abstraction, by including vco's clk_hw directly into struct msm_dsi_phy. Signed-off-by: Dmitry Baryshkov Forgot to mention, please fix the typo "abstraction" in the subject line. With that fixed: Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/Kconfig | 8 -- drivers/gpu/drm/msm/Makefile | 2 - drivers/gpu/drm/msm/dsi/phy/dsi_phy.h | 36 +--- drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c| 66 --- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c| 78 - drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c| 83 ++- .../gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c | 65 --- drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 74 + drivers/gpu/drm/msm/dsi/phy/dsi_pll.c | 23 - drivers/gpu/drm/msm/dsi/phy/dsi_pll.h | 44 -- 10 files changed, 221 insertions(+), 258 deletions(-) delete mode 100644 drivers/gpu/drm/msm/dsi/phy/dsi_pll.c delete mode 100644 drivers/gpu/drm/msm/dsi/phy/dsi_pll.h diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index dabb4a1ccdcf..1f0b3f0e7149 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -76,14 +76,6 @@ config DRM_MSM_DSI Choose this option if you have a need for MIPI DSI connector support. -config DRM_MSM_DSI_PLL - bool "Enable DSI PLL driver in MSM DRM" - depends on DRM_MSM_DSI && COMMON_CLK - default y - help - Choose this option to enable DSI PLL driver which provides DSI - source clocks under common clock framework. - config DRM_MSM_DSI_28NM_PHY bool "Enable DSI 28nm PHY driver in MSM DRM" depends on DRM_MSM_DSI diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 1be6996b80b7..610d630326bb 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -136,6 +136,4 @@ msm-$(CONFIG_DRM_MSM_DSI_14NM_PHY) += dsi/phy/dsi_phy_14nm.o msm-$(CONFIG_DRM_MSM_DSI_10NM_PHY) += dsi/phy/dsi_phy_10nm.o msm-$(CONFIG_DRM_MSM_DSI_7NM_PHY) += dsi/phy/dsi_phy_7nm.o -msm-$(CONFIG_DRM_MSM_DSI_PLL) += dsi/phy/dsi_pll.o - obj-$(CONFIG_DRM_MSM) += msm.o diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h index fa09f4c2c071..4fe410c97d3a 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h @@ -7,6 +7,7 @@ #define __DSI_PHY_H__ #include +#include #include #include "dsi.h" @@ -14,15 +15,6 @@ #define dsi_phy_read(offset) msm_readl((offset)) #define dsi_phy_write(offset, data) msm_writel((data), (offset)) -struct msm_dsi_pll { - struct clk_hw clk_hw; - boolpll_on; - - const struct msm_dsi_phy_cfg *cfg; -}; - -#define hw_clk_to_pll(x) container_of(x, struct msm_dsi_pll, clk_hw) - struct msm_dsi_phy_ops { int (*pll_init)(struct msm_dsi_phy *phy); int (*enable)(struct msm_dsi_phy *phy, int src_pll_id, @@ -107,7 +99,8 @@ struct msm_dsi_phy { enum msm_dsi_phy_usecase usecase; bool regulator_ldo_mode; - struct msm_dsi_pll *pll; + struct clk_hw *vco_hw; + bool pll_on; struct clk_hw_onecell_data *provided_clocks; @@ -127,6 +120,27 @@ int msm_dsi_dphy_timing_calc_v4(struct msm_dsi_dphy_timing *timing, struct msm_dsi_phy_clk_request *clk_req); void msm_dsi_phy_set_src_pll(struct msm_dsi_phy *phy, int pll_id, u32 reg, u32 bit_mask); +/* PLL accessors */ +static inline void pll_write(void __iomem *reg, u32 data) +{ + msm_writel(data, reg); +} + +static inline u32 pll_read(const void __iomem *reg) +{ + return msm_readl(reg); +} + +static inline void pll_write_udelay(void __iomem *reg, u32 data, u32 delay_us) +{ + pll_write(reg, data); + udelay(delay_us); +} + +static inline void pll_write_ndelay(void __iomem *reg, u32 data, u32 delay_ns) +{ + pll_write((reg), data); + ndelay(delay_ns); +} #endif /* __DSI_PHY_H__ */ - diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c index 25fd4d860c4d..dec9beadddaa 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c @@ -7,7 +7,6 @@ #include #include -#include "dsi_pll.h" #include "dsi_phy.h" #include "dsi.xml.h" @@ -85,11 +84,13 @@ struct pll_10nm_cached_state { }; struct dsi_pll_10nm { - struct msm_dsi_pll base; + struct clk_hw clk_hw; int id; struct platform_device *pdev; + struct msm_dsi_phy *phy; + void __iomem *phy_cmn_mmio; void __iomem *mmio; @@ -104,11 +105,10 @@ struct dsi_pll_10nm { struct pll_10nm_cached_state cached_state; - enum msm_dsi_phy_usecase
Re: [Freedreno] [PATCH v3 24/25] drm/msm/dsi: inline msm_dsi_phy_set_src_pll
On 2021-03-27 04:03, Dmitry Baryshkov wrote: The src_truthtable config is not used for some of phys, which use other means of configuring the master/slave usecases. Inline this function with the goal of removing src_pll_id argument in the next commit. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 17 - drivers/gpu/drm/msm/dsi/phy/dsi_phy.h | 8 drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c | 2 -- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 13 +++-- drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c | 11 +++ drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c | 13 +++-- drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c | 1 - drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 2 -- 8 files changed, 21 insertions(+), 46 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c index 74cc11c84d71..56f5134e3933 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c @@ -461,23 +461,6 @@ int msm_dsi_dphy_timing_calc_v4(struct msm_dsi_dphy_timing *timing, return 0; } -void msm_dsi_phy_set_src_pll(struct msm_dsi_phy *phy, int pll_id, u32 reg, - u32 bit_mask) -{ - int phy_id = phy->id; - u32 val; - - if ((phy_id >= DSI_MAX) || (pll_id >= DSI_MAX)) - return; - - val = dsi_phy_read(phy->base + reg); - - if (phy->cfg->src_pll_truthtable[phy_id][pll_id]) - dsi_phy_write(phy->base + reg, val | bit_mask); - else - dsi_phy_write(phy->base + reg, val & (~bit_mask)); -} - static int dsi_phy_regulator_init(struct msm_dsi_phy *phy) { struct regulator_bulk_data *s = phy->supplies; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h index 8e828c5ca8f4..3b207cf9f6b4 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h @@ -33,12 +33,6 @@ struct msm_dsi_phy_cfg { unsigned long min_pll_rate; unsigned long max_pll_rate; - /* -* Each cell {phy_id, pll_id} of the truth table indicates -* if the source PLL selection bit should be set for each PHY. -* Fill default H/W values in illegal cells, eg. cell {0, 1}. -*/ - bool src_pll_truthtable[DSI_MAX][DSI_MAX]; const resource_size_t io_start[DSI_MAX]; const int num_dsi_phy; const int quirks; @@ -121,7 +115,5 @@ int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing, struct msm_dsi_phy_clk_request *clk_req); int msm_dsi_dphy_timing_calc_v4(struct msm_dsi_dphy_timing *timing, struct msm_dsi_phy_clk_request *clk_req); -void msm_dsi_phy_set_src_pll(struct msm_dsi_phy *phy, int pll_id, u32 reg, - u32 bit_mask); #endif /* __DSI_PHY_H__ */ diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c index 1fbb54f4df98..04535ccd11ef 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c @@ -919,7 +919,6 @@ static void dsi_10nm_phy_disable(struct msm_dsi_phy *phy) } const struct msm_dsi_phy_cfg dsi_phy_10nm_cfgs = { - .src_pll_truthtable = { {false, false}, {true, false} }, .has_phy_lane = true, .reg_cfg = { .num = 1, @@ -941,7 +940,6 @@ const struct msm_dsi_phy_cfg dsi_phy_10nm_cfgs = { }; const struct msm_dsi_phy_cfg dsi_phy_10nm_8998_cfgs = { - .src_pll_truthtable = { {false, false}, {true, false} }, .has_phy_lane = true, .reg_cfg = { .num = 1, diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c index d08ad0c632b4..7a87bed71e36 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c @@ -947,6 +947,7 @@ static int dsi_14nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, int ret; void __iomem *base = phy->base; void __iomem *lane_base = phy->lane_base; + u32 glbl_test_ctrl; if (msm_dsi_dphy_timing_calc_v2(timing, clk_req)) { DRM_DEV_ERROR(>pdev->dev, @@ -994,10 +995,12 @@ static int dsi_14nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, udelay(100); dsi_phy_write(base + REG_DSI_14nm_PHY_CMN_CTRL_1, 0x00); - msm_dsi_phy_set_src_pll(phy, src_pll_id, - REG_DSI_14nm_PHY_CMN_GLBL_TEST_CTRL, - DSI_14nm_PHY_CMN_GLBL_TEST_CTRL_BITCLK_HS_SEL); - + glbl_test_ctrl = dsi_phy_read(base + REG_DSI_14nm_PHY_CMN_GLBL_TEST_CTRL); + if (phy->id == DSI_1 && src_pll_id == DSI_0) + glbl_test_ctrl |= DSI_14nm_PHY_CMN_GLBL_TEST_CTRL_BITCLK_HS_SEL; + else + glbl_test_ctrl
Re: [Freedreno] [PATCH v3 23/25] drm/msm/dsi: remove temp data from global pll structure
On 2021-03-27 04:03, Dmitry Baryshkov wrote: The 7nm, 10nm and 14nm drivers would store interim data used during VCO/PLL rate setting in the global dsi_pll_Nnm structure. Move this data structures to the onstack storage. While we are at it, drop unused/static 'config' data, unused config fields, etc. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c | 167 --- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 334 +++-- drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 166 -- 3 files changed, 220 insertions(+), 447 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c index b937e77b3c37..1fbb54f4df98 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c @@ -36,43 +36,25 @@ */ #define VCO_REF_CLK_RATE 1920 - -struct dsi_pll_regs { - u32 pll_prop_gain_rate; - u32 pll_lockdet_rate; - u32 decimal_div_start; - u32 frac_div_start_low; - u32 frac_div_start_mid; - u32 frac_div_start_high; - u32 pll_clock_inverters; - u32 ssc_stepsize_low; - u32 ssc_stepsize_high; - u32 ssc_div_per_low; - u32 ssc_div_per_high; - u32 ssc_adjper_low; - u32 ssc_adjper_high; - u32 ssc_control; -}; +#define FRAC_BITS 18 /* v3.0.0 10nm implementation that requires the old timings settings */ #define DSI_PHY_10NM_QUIRK_OLD_TIMINGS BIT(0) struct dsi_pll_config { - u32 ref_freq; - bool div_override; - u32 output_div; - bool ignore_frac; - bool disable_prescaler; bool enable_ssc; bool ssc_center; - u32 dec_bits; - u32 frac_bits; - u32 lock_timer; u32 ssc_freq; u32 ssc_offset; u32 ssc_adj_per; - u32 thresh_cycles; - u32 refclk_cycles; + + /* out */ + u32 pll_prop_gain_rate; + u32 decimal_div_start; + u32 frac_div_start; + u32 pll_clock_inverters; + u32 ssc_stepsize; + u32 ssc_div_per; }; struct pll_10nm_cached_state { @@ -88,15 +70,11 @@ struct dsi_pll_10nm { struct msm_dsi_phy *phy; - u64 vco_ref_clk_rate; u64 vco_current_rate; /* protects REG_DSI_10nm_PHY_CMN_CLK_CFG0 register */ spinlock_t postdiv_lock; - struct dsi_pll_config pll_configuration; - struct dsi_pll_regs reg_setup; - struct pll_10nm_cached_state cached_state; struct dsi_pll_10nm *slave; @@ -110,34 +88,19 @@ struct dsi_pll_10nm { */ static struct dsi_pll_10nm *pll_10nm_list[DSI_MAX]; -static void dsi_pll_setup_config(struct dsi_pll_10nm *pll) +static void dsi_pll_setup_config(struct dsi_pll_config *config) { - struct dsi_pll_config *config = >pll_configuration; - - config->ref_freq = pll->vco_ref_clk_rate; - config->output_div = 1; - config->dec_bits = 8; - config->frac_bits = 18; - config->lock_timer = 64; config->ssc_freq = 31500; config->ssc_offset = 5000; config->ssc_adj_per = 2; - config->thresh_cycles = 32; - config->refclk_cycles = 256; - - config->div_override = false; - config->ignore_frac = false; - config->disable_prescaler = false; config->enable_ssc = false; - config->ssc_center = 0; + config->ssc_center = false; } -static void dsi_pll_calc_dec_frac(struct dsi_pll_10nm *pll) +static void dsi_pll_calc_dec_frac(struct dsi_pll_10nm *pll, struct dsi_pll_config *config) { - struct dsi_pll_config *config = >pll_configuration; - struct dsi_pll_regs *regs = >reg_setup; - u64 fref = pll->vco_ref_clk_rate; + u64 fref = VCO_REF_CLK_RATE; u64 pll_freq; u64 divider; u64 dec, dec_multiple; @@ -146,40 +109,32 @@ static void dsi_pll_calc_dec_frac(struct dsi_pll_10nm *pll) pll_freq = pll->vco_current_rate; - if (config->disable_prescaler) - divider = fref; - else - divider = fref * 2; + divider = fref * 2; - multiplier = 1 << config->frac_bits; + multiplier = 1 << FRAC_BITS; dec_multiple = div_u64(pll_freq * multiplier, divider); dec = div_u64_rem(dec_multiple, multiplier, ); if (pll_freq <= 19UL) - regs->pll_prop_gain_rate = 8; + config->pll_prop_gain_rate = 8; else if (pll_freq <= 30UL) - regs->pll_prop_gain_rate = 10; + config->pll_prop_gain_rate = 10; else - regs->pll_prop_gain_rate = 12; + config->pll_prop_gain_rate = 12; if (pll_freq < 11UL) - regs->pll_clock_inverters = 8; + config->pll_clock_inverters = 8; else - regs->pll_clock_inverters = 0; + config->pll_clock_inverters = 0; -
Re: [PATCH 2/2] arm64: dts: msm8996: Mark the GPU's SMMU as an adreno one.
On Fri 26 Mar 18:13 CDT 2021, Eric Anholt wrote: > This enables the adreno-specific SMMU path that sets HUPCF so > (user-managed) page faults don't wedge the GPU. > > Signed-off-by: Eric Anholt Acked-by: Bjorn Andersson @Will, can you pick this together with the driver patch? (So that they land in order) Regards, Bjorn > --- > > We've been seeing a flaky test per day or so in Mesa CI where the > kernel gets wedged after an iommu fault turns into CP errors. With > this patch, the CI isn't throwing the string of CP errors on the > faults in any of the ~10 jobs I've run so far. > > arch/arm64/boot/dts/qcom/msm8996.dtsi | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi > b/arch/arm64/boot/dts/qcom/msm8996.dtsi > index 6de136e3add9..432b87ec9c5e 100644 > --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi > +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi > @@ -1127,7 +1127,7 @@ cci_i2c1: i2c-bus@1 { > }; > > adreno_smmu: iommu@b4 { > - compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2"; > + compatible = "qcom,msm8996-smmu-v2", > "qcom,adreno-smmu", "qcom,smmu-v2"; > reg = <0x00b4 0x1>; > > #global-interrupts = <1>; > -- > 2.31.0 > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 22/25] drm/msm/dsi: remove duplicate fields from dsi_pll_Nnm instances
On 2021-03-27 04:03, Dmitry Baryshkov wrote: Drop duplicate fields pdev and id from dsi_pll_Nnm instances. Reuse those fields from the provided msm_dsi_phy. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c| 72 +-- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c| 54 +++--- drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c| 48 ++--- .../gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c | 26 +++ drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 68 -- 5 files changed, 119 insertions(+), 149 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c index 8a15ae91d44b..b937e77b3c37 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c @@ -86,9 +86,6 @@ struct pll_10nm_cached_state { struct dsi_pll_10nm { struct clk_hw clk_hw; - int id; - struct platform_device *pdev; - struct msm_dsi_phy *phy; u64 vco_ref_clk_rate; @@ -301,7 +298,7 @@ static int dsi_pll_10nm_vco_set_rate(struct clk_hw *hw, unsigned long rate, { struct dsi_pll_10nm *pll_10nm = to_pll_10nm(hw); - DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_10nm->id, rate, + DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_10nm->phy->id, rate, parent_rate); pll_10nm->vco_current_rate = rate; @@ -327,7 +324,7 @@ static int dsi_pll_10nm_vco_set_rate(struct clk_hw *hw, unsigned long rate, static int dsi_pll_10nm_lock_status(struct dsi_pll_10nm *pll) { - struct device *dev = >pdev->dev; + struct device *dev = >phy->pdev->dev; int rc; u32 status = 0; u32 const delay_us = 100; @@ -341,7 +338,7 @@ static int dsi_pll_10nm_lock_status(struct dsi_pll_10nm *pll) timeout_us); if (rc) DRM_DEV_ERROR(dev, "DSI PLL(%d) lock failed, status=0x%08x\n", - pll->id, status); + pll->phy->id, status); return rc; } @@ -387,7 +384,7 @@ static void dsi_pll_enable_global_clk(struct dsi_pll_10nm *pll) static int dsi_pll_10nm_vco_prepare(struct clk_hw *hw) { struct dsi_pll_10nm *pll_10nm = to_pll_10nm(hw); - struct device *dev = _10nm->pdev->dev; + struct device *dev = _10nm->phy->pdev->dev; int rc; dsi_pll_enable_pll_bias(pll_10nm); @@ -413,7 +410,7 @@ static int dsi_pll_10nm_vco_prepare(struct clk_hw *hw) /* Check for PLL lock */ rc = dsi_pll_10nm_lock_status(pll_10nm); if (rc) { - DRM_DEV_ERROR(dev, "PLL(%d) lock failed\n", pll_10nm->id); + DRM_DEV_ERROR(dev, "PLL(%d) lock failed\n", pll_10nm->phy->id); goto error; } @@ -494,7 +491,7 @@ static unsigned long dsi_pll_10nm_vco_recalc_rate(struct clk_hw *hw, vco_rate = pll_freq; DBG("DSI PLL%d returning vco rate = %lu, dec = %x, frac = %x", - pll_10nm->id, (unsigned long)vco_rate, dec, frac); + pll_10nm->phy->id, (unsigned long)vco_rate, dec, frac); return (unsigned long)vco_rate; } @@ -543,7 +540,7 @@ static void dsi_10nm_save_state(struct msm_dsi_phy *phy) cached->pll_mux = cmn_clk_cfg1 & 0x3; DBG("DSI PLL%d outdiv %x bit_clk_div %x pix_clk_div %x pll_mux %x", - pll_10nm->id, cached->pll_out_div, cached->bit_clk_div, + pll_10nm->phy->id, cached->pll_out_div, cached->bit_clk_div, cached->pix_clk_div, cached->pll_mux); } @@ -570,12 +567,12 @@ static int dsi_10nm_restore_state(struct msm_dsi_phy *phy) ret = dsi_pll_10nm_vco_set_rate(phy->vco_hw, pll_10nm->vco_current_rate, pll_10nm->vco_ref_clk_rate); if (ret) { - DRM_DEV_ERROR(_10nm->pdev->dev, + DRM_DEV_ERROR(_10nm->phy->pdev->dev, "restore vco rate failed. ret=%d\n", ret); return ret; } - DBG("DSI PLL%d", pll_10nm->id); + DBG("DSI PLL%d", pll_10nm->phy->id); return 0; } @@ -586,13 +583,13 @@ static int dsi_10nm_set_usecase(struct msm_dsi_phy *phy) void __iomem *base = phy->base; u32 data = 0x0; /* internal PLL */ - DBG("DSI PLL%d", pll_10nm->id); + DBG("DSI PLL%d", pll_10nm->phy->id); switch (phy->usecase) { case MSM_DSI_PHY_STANDALONE: break; case MSM_DSI_PHY_MASTER: - pll_10nm->slave = pll_10nm_list[(pll_10nm->id + 1) % DSI_MAX]; + pll_10nm->slave = pll_10nm_list[(pll_10nm->phy->id + 1) % DSI_MAX]; break; case MSM_DSI_PHY_SLAVE: data = 0x1; /* external PLL */ @@ -624,21 +621,21 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm, struct clk_hw **prov .flags = CLK_IGNORE_UNUSED, .ops = _ops_dsi_pll_10nm_vco, }; -
Re: [PATCH 1/2] iommu/arm-smmu-qcom: Skip the TTBR1 quirk for db820c.
On Fri 26 Mar 18:13 CDT 2021, Eric Anholt wrote: > db820c wants to use the qcom smmu path to get HUPCF set (which keeps > the GPU from wedging and then sometimes wedging the kernel after a > page fault), but it doesn't have separate pagetables support yet in > drm/msm so we can't go all the way to the TTBR1 path. > > Signed-off-by: Eric Anholt Reviewed-by: Bjorn Andersson Regards, Bjorn > --- > > We've been seeing a flaky test per day or so in Mesa CI where the > kernel gets wedged after an iommu fault turns into CP errors. With > this patch, the CI isn't throwing the string of CP errors on the > faults in any of the ~10 jobs I've run so far. > > drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 13 - > 1 file changed, 12 insertions(+), 1 deletion(-) > > diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c > b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c > index bcda17012aee..51f22193e456 100644 > --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c > +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c > @@ -130,6 +130,16 @@ static int qcom_adreno_smmu_alloc_context_bank(struct > arm_smmu_domain *smmu_doma > return __arm_smmu_alloc_bitmap(smmu->context_map, start, count); > } > > +static bool qcom_adreno_can_do_ttbr1(struct arm_smmu_device *smmu) > +{ > + const struct device_node *np = smmu->dev->of_node; > + > + if (of_device_is_compatible(np, "qcom,msm8996-smmu-v2")) > + return false; > + > + return true; > +} > + > static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain, > struct io_pgtable_cfg *pgtbl_cfg, struct device *dev) > { > @@ -144,7 +154,8 @@ static int qcom_adreno_smmu_init_context(struct > arm_smmu_domain *smmu_domain, >* be AARCH64 stage 1 but double check because the arm-smmu code assumes >* that is the case when the TTBR1 quirk is enabled >*/ > - if ((smmu_domain->stage == ARM_SMMU_DOMAIN_S1) && > + if (qcom_adreno_can_do_ttbr1(smmu_domain->smmu) && > + (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) && > (smmu_domain->cfg.fmt == ARM_SMMU_CTX_FMT_AARCH64)) > pgtbl_cfg->quirks |= IO_PGTABLE_QUIRK_ARM_TTBR1; > > -- > 2.31.0 > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 3/3] drm/bridge: ti-sn65dsi86: Properly get the EDID, but only if refclk
Hi Doug, On Mon, Mar 29, 2021 at 07:57:05PM -0700, Doug Anderson wrote: > On Tue, Mar 16, 2021 at 5:44 PM Doug Anderson wrote: > > On Tue, Mar 16, 2021 at 2:46 PM Laurent Pinchart wrote: > > > On Mon, Mar 15, 2021 at 09:25:37AM -0700, Doug Anderson wrote: > > > > On Sat, Mar 13, 2021 at 1:17 PM Laurent Pinchart wrote: > > > > > On Thu, Mar 04, 2021 at 03:52:01PM -0800, Douglas Anderson wrote: > > > > > > In commit 58074b08c04a ("drm/bridge: ti-sn65dsi86: Read EDID blob > > > > > > over > > > > > > DDC") we attempted to make the ti-sn65dsi86 bridge properly read the > > > > > > EDID from the panel. That commit kinda worked but it had some > > > > > > serious > > > > > > problems. > > > > > > > > > > > > The problems all stem from the fact that userspace wants to be able > > > > > > to > > > > > > read the EDID before it explicitly enables the panel. For eDP > > > > > > panels, > > > > > > though, we don't actually power the panel up until the pre-enable > > > > > > stage and the pre-enable call happens right before the enable call > > > > > > with no way to interject in-between. For eDP panels, you can't read > > > > > > the EDID until you power the panel. The result was that > > > > > > ti_sn_bridge_connector_get_modes() was always failing to read the > > > > > > EDID > > > > > > (falling back to what drm_panel_get_modes() returned) until _after_ > > > > > > the EDID was needed. > > > > > > > > > > > > To make it concrete, on my system I saw this happen: > > > > > > 1. We'd attach the bridge. > > > > > > 2. Userspace would ask for the EDID (several times). We'd try but > > > > > > fail > > > > > >to read the EDID over and over again and fall back to the > > > > > > hardcoded > > > > > >modes. > > > > > > 3. Userspace would decide on a mode based only on the hardcoded > > > > > > modes. > > > > > > 4. Userspace would ask to turn the panel on. > > > > > > 5. Userspace would (eventually) check the modes again (in Chrome OS > > > > > >this happens on the handoff from the boot splash screen to the > > > > > >browser). Now we'd read them properly and, if they were > > > > > > different, > > > > > >userspace would request to change the mode. > > > > > > > > > > > > The fact that userspace would always end up using the hardcoded > > > > > > modes > > > > > > at first significantly decreases the benefit of the EDID > > > > > > reading. Also: if the modes were even a tiny bit different we'd end > > > > > > up > > > > > > doing a wasteful modeset and at boot. > > > > > > > > > > s/and at/at/ ? > > > > > > > > Sure, I can correct if/when I respin or it can be corrected when landed. > > > > > > > > > > diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c > > > > > > b/drivers/gpu/drm/bridge/ti-sn65dsi86.c > > > > > > index 491c9c4f32d1..af3fb4657af6 100644 > > > > > > --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c > > > > > > +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c > > > > > > @@ -16,6 +16,7 @@ > > > > > > #include > > > > > > #include > > > > > > #include > > > > > > +#include > > > > > > > > > > > > #include > > > > > > > > > > > > @@ -130,6 +131,12 @@ > > > > > > * @ln_assign:Value to program to the LN_ASSIGN register. > > > > > > * @ln_polrs: Value for the 4-bit LN_POLRS field of > > > > > > SN_ENH_FRAME_REG. > > > > > > * > > > > > > + * @pre_enabled_early: If true we did an early pre_enable at > > > > > > attach. > > > > > > + * @pre_enable_timeout_work: Delayed work to undo the pre_enable > > > > > > from attach > > > > > > + * if a normal pre_enable never came. > > > > > > > > > > Could we simplify this by using the runtime PM autosuspend feature ? > > > > > The > > > > > configuration of the bridge would be moved from pre_enable to the PM > > > > > runtime resume handler, the clk_disable_unprepare() call moved from > > > > > post_disable to the runtime suspend handler, and the work queue > > > > > replaced > > > > > by usage of pm_runtime_put_autosuspend(). > > > > > > > > It's an interesting idea but I don't think I can make it work, at > > > > least not in a generic enough way. Specifically we can also use this > > > > bridge chip as a generic GPIO provider in Linux. When someone asks us > > > > to read a GPIO then we have to power the bridge on > > > > (pm_runtime_get_sync()) and when someone asks us to configure a GPIO > > > > as an output then we actually leave the bridge powered until they stop > > > > requesting it as an output. At the moment the only user of this > > > > functionality (that I know of) is for the HPD pin on trogdor boards > > > > (long story about why we don't use the dedicated HPD) but the API > > > > supports using these GPIOs for anything and I've tested that it works. > > > > It wouldn't be great to have to keep the panel on in order to access > > > > the GPIOs. > > > > > > The issue you're trying to fix doesn't seem specific to this bridge, so > > > handling it in the bridge driver bothers me :-S
Re: [PATCH v4 3/4] drm/msm: add compatibles for sm8150/sm8250 display
On Mon 29 Mar 07:00 CDT 2021, Dmitry Baryshkov wrote: > From: Jonathan Marek > > The driver already has support for sm8150/sm8250, but the compatibles were > never added. > > Also inverse the non-mdp4 condition in add_display_components() to avoid > having to check every new compatible in the condition. > > Signed-off-by: Jonathan Marek > Signed-off-by: Dmitry Baryshkov Rob, will you pick patch 2 and 3 for 5.13? I've picked patch 1 and would like to pick patch 4 through my tree... Regards, Bjorn > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 2 ++ > drivers/gpu/drm/msm/msm_drv.c | 6 +++--- > 2 files changed, 5 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c > index 5a8e3e1fc48c..fff12a4c8bfc 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c > @@ -1219,6 +1219,8 @@ static const struct dev_pm_ops dpu_pm_ops = { > static const struct of_device_id dpu_dt_match[] = { > { .compatible = "qcom,sdm845-dpu", }, > { .compatible = "qcom,sc7180-dpu", }, > + { .compatible = "qcom,sm8150-dpu", }, > + { .compatible = "qcom,sm8250-dpu", }, > {} > }; > MODULE_DEVICE_TABLE(of, dpu_dt_match); > diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c > index 94525ac76d4e..928f13d4bfbc 100644 > --- a/drivers/gpu/drm/msm/msm_drv.c > +++ b/drivers/gpu/drm/msm/msm_drv.c > @@ -1185,9 +1185,7 @@ static int add_display_components(struct device *dev, >* Populate the children devices, find the MDP5/DPU node, and then add >* the interfaces to our components list. >*/ > - if (of_device_is_compatible(dev->of_node, "qcom,mdss") || > - of_device_is_compatible(dev->of_node, "qcom,sdm845-mdss") || > - of_device_is_compatible(dev->of_node, "qcom,sc7180-mdss")) { > + if (!of_device_is_compatible(dev->of_node, "qcom,mdp4")) { > ret = of_platform_populate(dev->of_node, NULL, NULL, dev); > if (ret) { > DRM_DEV_ERROR(dev, "failed to populate children > devices\n"); > @@ -1320,6 +1318,8 @@ static const struct of_device_id dt_match[] = { > { .compatible = "qcom,mdss", .data = (void *)KMS_MDP5 }, > { .compatible = "qcom,sdm845-mdss", .data = (void *)KMS_DPU }, > { .compatible = "qcom,sc7180-mdss", .data = (void *)KMS_DPU }, > + { .compatible = "qcom,sm8150-mdss", .data = (void *)KMS_DPU }, > + { .compatible = "qcom,sm8250-mdss", .data = (void *)KMS_DPU }, > {} > }; > MODULE_DEVICE_TABLE(of, dt_match); > -- > 2.30.2 > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Freedreno] [PATCH v3 21/25] drm/msm/dsi: move ioremaps to dsi_phy_driver_probe
On 2021-03-27 04:03, Dmitry Baryshkov wrote: All PHY drivers would map dsi_pll area. Some PHY drivers would also map dsi_phy area again (a leftover from old PHY/PLL separation). Move all ioremaps to the common dsi_phy driver code and drop individual ioremapped areas from PHY drivers. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 7 ++ drivers/gpu/drm/msm/dsi/phy/dsi_phy.h | 1 + drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c| 75 +++--- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c| 49 drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c| 33 +++- .../gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c | 27 +++ drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 79 --- 7 files changed, 108 insertions(+), 163 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c index f21f3babec68..74cc11c84d71 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c @@ -682,6 +682,13 @@ static int dsi_phy_driver_probe(struct platform_device *pdev) goto fail; } + phy->pll_base = msm_ioremap(pdev, "dsi_pll", "DSI_PLL"); + if (IS_ERR(phy->pll_base)) { + DRM_DEV_ERROR(>dev, "%s: failed to map pll base\n", __func__); + ret = -ENOMEM; + goto fail; + } + if (phy->cfg->has_phy_lane) { phy->lane_base = msm_ioremap(pdev, "dsi_phy_lane", "DSI_PHY_LANE"); if (IS_ERR(phy->lane_base)) { diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h index d7031a35e2da..8e828c5ca8f4 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h @@ -88,6 +88,7 @@ struct msm_dsi_dphy_timing { struct msm_dsi_phy { struct platform_device *pdev; void __iomem *base; + void __iomem *pll_base; void __iomem *reg_base; void __iomem *lane_base; int id; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c index 73afbb597a9f..8a15ae91d44b 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c @@ -91,9 +91,6 @@ struct dsi_pll_10nm { struct msm_dsi_phy *phy; - void __iomem *phy_cmn_mmio; - void __iomem *mmio; - u64 vco_ref_clk_rate; u64 vco_current_rate; @@ -228,7 +225,7 @@ static void dsi_pll_calc_ssc(struct dsi_pll_10nm *pll) static void dsi_pll_ssc_commit(struct dsi_pll_10nm *pll) { - void __iomem *base = pll->mmio; + void __iomem *base = pll->phy->pll_base; struct dsi_pll_regs *regs = >reg_setup; if (pll->pll_configuration.enable_ssc) { @@ -253,7 +250,7 @@ static void dsi_pll_ssc_commit(struct dsi_pll_10nm *pll) static void dsi_pll_config_hzindep_reg(struct dsi_pll_10nm *pll) { - void __iomem *base = pll->mmio; + void __iomem *base = pll->phy->pll_base; dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_ONE, 0x80); dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_TWO, 0x03); @@ -279,7 +276,7 @@ static void dsi_pll_config_hzindep_reg(struct dsi_pll_10nm *pll) static void dsi_pll_commit(struct dsi_pll_10nm *pll) { - void __iomem *base = pll->mmio; + void __iomem *base = pll->phy->pll_base; struct dsi_pll_regs *reg = >reg_setup; dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_CORE_INPUT_OVERRIDE, 0x12); @@ -336,7 +333,7 @@ static int dsi_pll_10nm_lock_status(struct dsi_pll_10nm *pll) u32 const delay_us = 100; u32 const timeout_us = 5000; - rc = readl_poll_timeout_atomic(pll->mmio + + rc = readl_poll_timeout_atomic(pll->phy->pll_base + REG_DSI_10nm_PHY_PLL_COMMON_STATUS_ONE, status, ((status & BIT(0)) > 0), @@ -351,21 +348,21 @@ static int dsi_pll_10nm_lock_status(struct dsi_pll_10nm *pll) static void dsi_pll_disable_pll_bias(struct dsi_pll_10nm *pll) { - u32 data = dsi_phy_read(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CTRL_0); + u32 data = dsi_phy_read(pll->phy->base + REG_DSI_10nm_PHY_CMN_CTRL_0); - dsi_phy_write(pll->mmio + REG_DSI_10nm_PHY_PLL_SYSTEM_MUXES, 0); - dsi_phy_write(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CTRL_0, + dsi_phy_write(pll->phy->pll_base + REG_DSI_10nm_PHY_PLL_SYSTEM_MUXES, 0); + dsi_phy_write(pll->phy->base + REG_DSI_10nm_PHY_CMN_CTRL_0, data & ~BIT(5)); ndelay(250); } static void dsi_pll_enable_pll_bias(struct dsi_pll_10nm *pll) { - u32 data = dsi_phy_read(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CTRL_0); + u32 data = dsi_phy_read(pll->phy->base + REG_DSI_10nm_PHY_CMN_CTRL_0); - dsi_phy_write(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CTRL_0, +
Re: [Freedreno] [PATCH v3 20/25] drm/msm/dsi: drop PLL accessor functions
On 2021-03-27 04:03, Dmitry Baryshkov wrote: Replace PLL accessor functions (pll_read/pll_write*) with the DSI PHY accessors, reducing duplication. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/dsi/phy/dsi_phy.h | 24 +-- drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c| 124 drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c| 126 drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c| 118 +++ .../gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c | 54 +++ drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 140 +- 6 files changed, 283 insertions(+), 303 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h index 4fe410c97d3a..d7031a35e2da 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h @@ -14,6 +14,8 @@ #define dsi_phy_read(offset) msm_readl((offset)) #define dsi_phy_write(offset, data) msm_writel((data), (offset)) +#define dsi_phy_write_udelay(offset, data, delay_us) { msm_writel((data), (offset)); udelay(delay_us); } +#define dsi_phy_write_ndelay(offset, data, delay_ns) { msm_writel((data), (offset)); ndelay(delay_ns); } struct msm_dsi_phy_ops { int (*pll_init)(struct msm_dsi_phy *phy); @@ -120,27 +122,5 @@ int msm_dsi_dphy_timing_calc_v4(struct msm_dsi_dphy_timing *timing, struct msm_dsi_phy_clk_request *clk_req); void msm_dsi_phy_set_src_pll(struct msm_dsi_phy *phy, int pll_id, u32 reg, u32 bit_mask); -/* PLL accessors */ -static inline void pll_write(void __iomem *reg, u32 data) -{ - msm_writel(data, reg); -} - -static inline u32 pll_read(const void __iomem *reg) -{ - return msm_readl(reg); -} - -static inline void pll_write_udelay(void __iomem *reg, u32 data, u32 delay_us) -{ - pll_write(reg, data); - udelay(delay_us); -} - -static inline void pll_write_ndelay(void __iomem *reg, u32 data, u32 delay_ns) -{ - pll_write((reg), data); - ndelay(delay_ns); -} #endif /* __DSI_PHY_H__ */ diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c index dec9beadddaa..73afbb597a9f 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c @@ -234,19 +234,19 @@ static void dsi_pll_ssc_commit(struct dsi_pll_10nm *pll) if (pll->pll_configuration.enable_ssc) { pr_debug("SSC is enabled\n"); - pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_STEPSIZE_LOW_1, + dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_SSC_STEPSIZE_LOW_1, regs->ssc_stepsize_low); - pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_STEPSIZE_HIGH_1, + dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_SSC_STEPSIZE_HIGH_1, regs->ssc_stepsize_high); - pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_PER_LOW_1, + dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_PER_LOW_1, regs->ssc_div_per_low); - pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_PER_HIGH_1, + dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_PER_HIGH_1, regs->ssc_div_per_high); - pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_ADJPER_LOW_1, + dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_ADJPER_LOW_1, regs->ssc_adjper_low); - pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_ADJPER_HIGH_1, + dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_ADJPER_HIGH_1, regs->ssc_adjper_high); - pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_CONTROL, + dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_SSC_CONTROL, SSC_EN | regs->ssc_control); } } @@ -255,26 +255,26 @@ static void dsi_pll_config_hzindep_reg(struct dsi_pll_10nm *pll) { void __iomem *base = pll->mmio; - pll_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_ONE, 0x80); - pll_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_TWO, 0x03); - pll_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_THREE, 0x00); - pll_write(base + REG_DSI_10nm_PHY_PLL_DSM_DIVIDER, 0x00); - pll_write(base + REG_DSI_10nm_PHY_PLL_FEEDBACK_DIVIDER, 0x4e); - pll_write(base + REG_DSI_10nm_PHY_PLL_CALIBRATION_SETTINGS, 0x40); - pll_write(base + REG_DSI_10nm_PHY_PLL_BAND_SEL_CAL_SETTINGS_THREE, + dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_ONE, 0x80); + dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_TWO, 0x03); + dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_THREE, 0x00); + dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_DSM_DIVIDER, 0x00); + dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_FEEDBACK_DIVIDER,
Re: [PATCH v4 3/4] drm/msm: add compatibles for sm8150/sm8250 display
On Mon 29 Mar 07:00 CDT 2021, Dmitry Baryshkov wrote: > From: Jonathan Marek > > The driver already has support for sm8150/sm8250, but the compatibles were > never added. > > Also inverse the non-mdp4 condition in add_display_components() to avoid > having to check every new compatible in the condition. > > Signed-off-by: Jonathan Marek > Signed-off-by: Dmitry Baryshkov > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 2 ++ > drivers/gpu/drm/msm/msm_drv.c | 6 +++--- > 2 files changed, 5 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c > index 5a8e3e1fc48c..fff12a4c8bfc 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c > @@ -1219,6 +1219,8 @@ static const struct dev_pm_ops dpu_pm_ops = { > static const struct of_device_id dpu_dt_match[] = { > { .compatible = "qcom,sdm845-dpu", }, > { .compatible = "qcom,sc7180-dpu", }, > + { .compatible = "qcom,sm8150-dpu", }, > + { .compatible = "qcom,sm8250-dpu", }, > {} > }; > MODULE_DEVICE_TABLE(of, dpu_dt_match); > diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c > index 94525ac76d4e..928f13d4bfbc 100644 > --- a/drivers/gpu/drm/msm/msm_drv.c > +++ b/drivers/gpu/drm/msm/msm_drv.c > @@ -1185,9 +1185,7 @@ static int add_display_components(struct device *dev, >* Populate the children devices, find the MDP5/DPU node, and then add >* the interfaces to our components list. >*/ > - if (of_device_is_compatible(dev->of_node, "qcom,mdss") || > - of_device_is_compatible(dev->of_node, "qcom,sdm845-mdss") || > - of_device_is_compatible(dev->of_node, "qcom,sc7180-mdss")) { > + if (!of_device_is_compatible(dev->of_node, "qcom,mdp4")) { Please consider reviewing my proposed alternative solution for this hunk: https://lore.kernel.org/linux-arm-msm/20210317025634.3987908-1-bjorn.anders...@linaro.org/ For the rest Reviewed-by: Bjorn Andersson Regards, Bjorn > ret = of_platform_populate(dev->of_node, NULL, NULL, dev); > if (ret) { > DRM_DEV_ERROR(dev, "failed to populate children > devices\n"); > @@ -1320,6 +1318,8 @@ static const struct of_device_id dt_match[] = { > { .compatible = "qcom,mdss", .data = (void *)KMS_MDP5 }, > { .compatible = "qcom,sdm845-mdss", .data = (void *)KMS_DPU }, > { .compatible = "qcom,sc7180-mdss", .data = (void *)KMS_DPU }, > + { .compatible = "qcom,sm8150-mdss", .data = (void *)KMS_DPU }, > + { .compatible = "qcom,sm8250-mdss", .data = (void *)KMS_DPU }, > {} > }; > MODULE_DEVICE_TABLE(of, dt_match); > -- > 2.30.2 > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Freedreno] [PATCH v3 19/25] drm/msm/dsi: drop msm_dsi_pll abstracton
On 2021-03-27 04:02, Dmitry Baryshkov wrote: Drop the struct msm_dsi_pll abstraction, by including vco's clk_hw directly into struct msm_dsi_phy. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/Kconfig | 8 -- drivers/gpu/drm/msm/Makefile | 2 - drivers/gpu/drm/msm/dsi/phy/dsi_phy.h | 36 +--- drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c| 66 --- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c| 78 - drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c| 83 ++- .../gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c | 65 --- drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 74 + drivers/gpu/drm/msm/dsi/phy/dsi_pll.c | 23 - drivers/gpu/drm/msm/dsi/phy/dsi_pll.h | 44 -- 10 files changed, 221 insertions(+), 258 deletions(-) delete mode 100644 drivers/gpu/drm/msm/dsi/phy/dsi_pll.c delete mode 100644 drivers/gpu/drm/msm/dsi/phy/dsi_pll.h diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index dabb4a1ccdcf..1f0b3f0e7149 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -76,14 +76,6 @@ config DRM_MSM_DSI Choose this option if you have a need for MIPI DSI connector support. -config DRM_MSM_DSI_PLL - bool "Enable DSI PLL driver in MSM DRM" - depends on DRM_MSM_DSI && COMMON_CLK - default y - help - Choose this option to enable DSI PLL driver which provides DSI - source clocks under common clock framework. - config DRM_MSM_DSI_28NM_PHY bool "Enable DSI 28nm PHY driver in MSM DRM" depends on DRM_MSM_DSI diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 1be6996b80b7..610d630326bb 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -136,6 +136,4 @@ msm-$(CONFIG_DRM_MSM_DSI_14NM_PHY) += dsi/phy/dsi_phy_14nm.o msm-$(CONFIG_DRM_MSM_DSI_10NM_PHY) += dsi/phy/dsi_phy_10nm.o msm-$(CONFIG_DRM_MSM_DSI_7NM_PHY) += dsi/phy/dsi_phy_7nm.o -msm-$(CONFIG_DRM_MSM_DSI_PLL) += dsi/phy/dsi_pll.o - obj-$(CONFIG_DRM_MSM) += msm.o diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h index fa09f4c2c071..4fe410c97d3a 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h @@ -7,6 +7,7 @@ #define __DSI_PHY_H__ #include +#include #include #include "dsi.h" @@ -14,15 +15,6 @@ #define dsi_phy_read(offset) msm_readl((offset)) #define dsi_phy_write(offset, data) msm_writel((data), (offset)) -struct msm_dsi_pll { - struct clk_hw clk_hw; - boolpll_on; - - const struct msm_dsi_phy_cfg *cfg; -}; - -#define hw_clk_to_pll(x) container_of(x, struct msm_dsi_pll, clk_hw) - struct msm_dsi_phy_ops { int (*pll_init)(struct msm_dsi_phy *phy); int (*enable)(struct msm_dsi_phy *phy, int src_pll_id, @@ -107,7 +99,8 @@ struct msm_dsi_phy { enum msm_dsi_phy_usecase usecase; bool regulator_ldo_mode; - struct msm_dsi_pll *pll; + struct clk_hw *vco_hw; + bool pll_on; struct clk_hw_onecell_data *provided_clocks; @@ -127,6 +120,27 @@ int msm_dsi_dphy_timing_calc_v4(struct msm_dsi_dphy_timing *timing, struct msm_dsi_phy_clk_request *clk_req); void msm_dsi_phy_set_src_pll(struct msm_dsi_phy *phy, int pll_id, u32 reg, u32 bit_mask); +/* PLL accessors */ +static inline void pll_write(void __iomem *reg, u32 data) +{ + msm_writel(data, reg); +} + +static inline u32 pll_read(const void __iomem *reg) +{ + return msm_readl(reg); +} + +static inline void pll_write_udelay(void __iomem *reg, u32 data, u32 delay_us) +{ + pll_write(reg, data); + udelay(delay_us); +} + +static inline void pll_write_ndelay(void __iomem *reg, u32 data, u32 delay_ns) +{ + pll_write((reg), data); + ndelay(delay_ns); +} #endif /* __DSI_PHY_H__ */ - diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c index 25fd4d860c4d..dec9beadddaa 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c @@ -7,7 +7,6 @@ #include #include -#include "dsi_pll.h" #include "dsi_phy.h" #include "dsi.xml.h" @@ -85,11 +84,13 @@ struct pll_10nm_cached_state { }; struct dsi_pll_10nm { - struct msm_dsi_pll base; + struct clk_hw clk_hw; int id; struct platform_device *pdev; + struct msm_dsi_phy *phy; + void __iomem *phy_cmn_mmio; void __iomem *mmio; @@ -104,11 +105,10 @@ struct dsi_pll_10nm { struct pll_10nm_cached_state cached_state; - enum msm_dsi_phy_usecase uc; struct dsi_pll_10nm *slave; }; -#define to_pll_10nm(x) container_of(x, struct dsi_pll_10nm, base) +#define to_pll_10nm(x)
RE: 回复: [PATCH v3] drm/scheduler re-insert Bailing job to avoid memleak
[AMD Official Use Only - Internal Distribution Only] Hi Christian, We don't need to debate on the design's topic, each of us have our own opinion, it is hard to persuade others sometimes, again with more and more features and requirements it is pretty normal that an old design need to Refine and or even rework to satisfy all those needs, so I'm not trying to argue with you that we don't need a better rework, that's also pleasure me . In the moment, the more important thing I care is the solution because SRIOV project still try best to put all changes into upstreaming tree, we don't want to fork another tree unless no choice ... Let's have a sync in another thread Thanks for you help on this -- Monk Liu | Cloud-GPU Core team -- -Original Message- From: Koenig, Christian Sent: Friday, March 26, 2021 10:51 PM To: Liu, Monk ; Zhang, Jack (Jian) ; Grodzovsky, Andrey ; Christian König ; dri-devel@lists.freedesktop.org; amd-...@lists.freedesktop.org; Deng, Emily ; Rob Herring ; Tomeu Vizoso ; Steven Price Cc: Zhang, Andy ; Jiang, Jerry (SW) Subject: Re: 回复: [PATCH v3] drm/scheduler re-insert Bailing job to avoid memleak Hi Monk, I can't disagree more. The fundamental problem here is that we have pushed a design without validating if it really fits into the concepts the Linux kernel mandates here. My mistake was that I haven't pushed back hard enough on the initial design resulting in numerous cycles of trying to save the design while band aiding the flaws which became obvious after a while. I haven't counted them but I think we are now already had over 10 patches which try to work around lifetime issues of the job object because I wasn't able to properly explain why this isn't going to work like this. Because of this I will hard reject any attempt to band aid this issue even more which isn't starting over again with a design which looks like it is going to work. Regards, Christian. Am 26.03.21 um 12:21 schrieb Liu, Monk: > [AMD Official Use Only - Internal Distribution Only] > > Hi Christian > > This is not correct or correct perspective, any design comes with its > pros and cons, otherwise it wouldn't comes to kernel tree in the very > beginning , it is just with time passed we have more and more > requirement and feature need to implement And those new requirement > drags many new solution or idea, and some idea you prefer need to > based on a new infrastructure, that's all > > I don't why the job "should be" or not "should be" in the scheduler, > honestly speaking I can argue with you that the "scheduler" and the TDR > feature which invented by AMD developer "should" never escalate to drm layer > at all and by that assumption Those vendor's compatibilities headache right > now won't happen at all. > > Let's just focus on the issue so far. > > The solution Andrey and Jack doing right now looks good to me, and it > can solve our problems without introducing regression from a surface > look, but it is fine if you need a neat solution, since we have our > project pressure (which we always have) Either we implement the first > version with Jack's patch and do the revise in another series of > patches (that also my initial suggestion) or we rework anything you > mentioned, but since looks to me you are from time to time asking > people to rework Something in the stage that people already have a > solution, which frustrated people a lot, > > I would like you do prepare a solution for us, which solves our > headaches ... I really don't want to see you asked Jack to rework again and > again If you are out of bandwidth or no interest in doing this ,please at > least make your solution/proposal very detail and clear, jack told me he > couldn't understand your point here. > > Thanks very much, and please understand our painful here > > /Monk > > > -邮件原件- > 发件人: Koenig, Christian > 发送时间: 2021年3月26日 17:06 > 收件人: Zhang, Jack (Jian) ; Grodzovsky, Andrey > ; Christian König > ; dri-devel@lists.freedesktop.org; > amd-...@lists.freedesktop.org; Liu, Monk ; Deng, > Emily ; Rob Herring ; Tomeu > Vizoso ; Steven Price > > 主题: Re: [PATCH v3] drm/scheduler re-insert Bailing job to avoid > memleak > > Hi guys, > > Am 26.03.21 um 03:23 schrieb Zhang, Jack (Jian): >> [AMD Official Use Only - Internal Distribution Only] >> >> Hi, Andrey, >> how u handle non guilty singnaled jobs in drm_sched_stop, currently looks like you don't call put for them and just explicitly free them as before >> Good point, I missed that place. Will cover that in my next patch. >> Also sched->free_guilty seems useless with the new approach. >> Yes, I agree. >> Do we even need the cleanup mechanism at drm_sched_get_cleanup_job with this approach... >> I am not quite sure about that for now, let me think about this topic today. >> >> Hi, Christian, >> should I add a
Re: [PATCH v3 18/25] drm/msm/dsi: make save_state/restore_state callbacks accept msm_dsi_phy
On 2021-03-27 04:02, Dmitry Baryshkov wrote: Make save_state/restore callbacks accept struct msm_dsi_phy rather than struct msm_dsi_pll. This moves them to struct msm_dsi_phy_ops, allowing us to drop struct msm_dsi_pll_ops. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 12 +++ drivers/gpu/drm/msm/dsi/phy/dsi_phy.h | 11 +++--- drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c| 22 +--- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c| 24 ++--- drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c| 34 --- .../gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c | 18 +- drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 22 +--- 7 files changed, 60 insertions(+), 83 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c index 176930800082..f21f3babec68 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c @@ -858,9 +858,9 @@ int msm_dsi_phy_get_clk_provider(struct msm_dsi_phy *phy, void msm_dsi_phy_save_state(struct msm_dsi_phy *phy) { - if (phy->cfg->pll_ops.save_state) { - phy->cfg->pll_ops.save_state(phy->pll); - phy->pll->state_saved = true; + if (phy->cfg->ops.save_state) { + phy->cfg->ops.save_state(phy); + phy->state_saved = true; } } @@ -868,12 +868,12 @@ int msm_dsi_phy_restore_state(struct msm_dsi_phy *phy) { int ret; - if (phy->cfg->pll_ops.restore_state && phy->pll->state_saved) { - ret = phy->cfg->pll_ops.restore_state(phy->pll); + if (phy->cfg->ops.restore_state && phy->state_saved) { + ret = phy->cfg->ops.restore_state(phy); if (ret) return ret; - phy->pll->state_saved = false; + phy->state_saved = false; } return 0; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h index b477d21804c8..fa09f4c2c071 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h @@ -17,7 +17,6 @@ struct msm_dsi_pll { struct clk_hw clk_hw; boolpll_on; - boolstate_saved; const struct msm_dsi_phy_cfg *cfg; }; @@ -29,17 +28,13 @@ struct msm_dsi_phy_ops { int (*enable)(struct msm_dsi_phy *phy, int src_pll_id, struct msm_dsi_phy_clk_request *clk_req); void (*disable)(struct msm_dsi_phy *phy); -}; - -struct msm_dsi_pll_ops { - void (*save_state)(struct msm_dsi_pll *pll); - int (*restore_state)(struct msm_dsi_pll *pll); + void (*save_state)(struct msm_dsi_phy *phy); + int (*restore_state)(struct msm_dsi_phy *phy); I think that naming these save_pll_state/restore_pll_state would be more appropriate. }; struct msm_dsi_phy_cfg { struct dsi_reg_config reg_cfg; struct msm_dsi_phy_ops ops; - const struct msm_dsi_pll_ops pll_ops; unsigned long min_pll_rate; unsigned long max_pll_rate; @@ -115,6 +110,8 @@ struct msm_dsi_phy { struct msm_dsi_pll *pll; struct clk_hw_onecell_data *provided_clocks; + + bool state_saved; }; /* diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c index bfb96d87d1d7..25fd4d860c4d 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c @@ -518,9 +518,9 @@ static const struct clk_ops clk_ops_dsi_pll_10nm_vco = { * PLL Callbacks */ -static void dsi_pll_10nm_save_state(struct msm_dsi_pll *pll) +static void dsi_10nm_save_state(struct msm_dsi_phy *phy) { - struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); + struct dsi_pll_10nm *pll_10nm = to_pll_10nm(phy->pll); struct pll_10nm_cached_state *cached = _10nm->cached_state; void __iomem *phy_base = pll_10nm->phy_cmn_mmio; u32 cmn_clk_cfg0, cmn_clk_cfg1; @@ -541,9 +541,9 @@ static void dsi_pll_10nm_save_state(struct msm_dsi_pll *pll) cached->pix_clk_div, cached->pll_mux); } -static int dsi_pll_10nm_restore_state(struct msm_dsi_pll *pll) +static int dsi_10nm_restore_state(struct msm_dsi_phy *phy) { - struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); + struct dsi_pll_10nm *pll_10nm = to_pll_10nm(phy->pll); struct pll_10nm_cached_state *cached = _10nm->cached_state; void __iomem *phy_base = pll_10nm->phy_cmn_mmio; u32 val; @@ -562,7 +562,7 @@ static int dsi_pll_10nm_restore_state(struct msm_dsi_pll *pll) val |= cached->pll_mux; pll_write(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1, val); - ret = dsi_pll_10nm_vco_set_rate(>clk_hw, pll_10nm->vco_current_rate, pll_10nm->vco_ref_clk_rate); + ret = dsi_pll_10nm_vco_set_rate(>pll->clk_hw, pll_10nm->vco_current_rate, pll_10nm->vco_ref_clk_rate); if
Re: [PATCH 3/3] drm/bridge: ti-sn65dsi86: Properly get the EDID, but only if refclk
Hi, On Tue, Mar 16, 2021 at 5:44 PM Doug Anderson wrote: > > Hi, > > On Tue, Mar 16, 2021 at 2:46 PM Laurent Pinchart > wrote: > > > > Hi Doug, > > > > On Mon, Mar 15, 2021 at 09:25:37AM -0700, Doug Anderson wrote: > > > On Sat, Mar 13, 2021 at 1:17 PM Laurent Pinchart wrote: > > > > On Thu, Mar 04, 2021 at 03:52:01PM -0800, Douglas Anderson wrote: > > > > > In commit 58074b08c04a ("drm/bridge: ti-sn65dsi86: Read EDID blob over > > > > > DDC") we attempted to make the ti-sn65dsi86 bridge properly read the > > > > > EDID from the panel. That commit kinda worked but it had some serious > > > > > problems. > > > > > > > > > > The problems all stem from the fact that userspace wants to be able to > > > > > read the EDID before it explicitly enables the panel. For eDP panels, > > > > > though, we don't actually power the panel up until the pre-enable > > > > > stage and the pre-enable call happens right before the enable call > > > > > with no way to interject in-between. For eDP panels, you can't read > > > > > the EDID until you power the panel. The result was that > > > > > ti_sn_bridge_connector_get_modes() was always failing to read the EDID > > > > > (falling back to what drm_panel_get_modes() returned) until _after_ > > > > > the EDID was needed. > > > > > > > > > > To make it concrete, on my system I saw this happen: > > > > > 1. We'd attach the bridge. > > > > > 2. Userspace would ask for the EDID (several times). We'd try but fail > > > > >to read the EDID over and over again and fall back to the hardcoded > > > > >modes. > > > > > 3. Userspace would decide on a mode based only on the hardcoded modes. > > > > > 4. Userspace would ask to turn the panel on. > > > > > 5. Userspace would (eventually) check the modes again (in Chrome OS > > > > >this happens on the handoff from the boot splash screen to the > > > > >browser). Now we'd read them properly and, if they were different, > > > > >userspace would request to change the mode. > > > > > > > > > > The fact that userspace would always end up using the hardcoded modes > > > > > at first significantly decreases the benefit of the EDID > > > > > reading. Also: if the modes were even a tiny bit different we'd end up > > > > > doing a wasteful modeset and at boot. > > > > > > > > s/and at/at/ ? > > > > > > Sure, I can correct if/when I respin or it can be corrected when landed. > > > > > > > > diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c > > > > > b/drivers/gpu/drm/bridge/ti-sn65dsi86.c > > > > > index 491c9c4f32d1..af3fb4657af6 100644 > > > > > --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c > > > > > +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c > > > > > @@ -16,6 +16,7 @@ > > > > > #include > > > > > #include > > > > > #include > > > > > +#include > > > > > > > > > > #include > > > > > > > > > > @@ -130,6 +131,12 @@ > > > > > * @ln_assign:Value to program to the LN_ASSIGN register. > > > > > * @ln_polrs: Value for the 4-bit LN_POLRS field of > > > > > SN_ENH_FRAME_REG. > > > > > * > > > > > + * @pre_enabled_early: If true we did an early pre_enable at attach. > > > > > + * @pre_enable_timeout_work: Delayed work to undo the pre_enable > > > > > from attach > > > > > + * if a normal pre_enable never came. > > > > > > > > Could we simplify this by using the runtime PM autosuspend feature ? The > > > > configuration of the bridge would be moved from pre_enable to the PM > > > > runtime resume handler, the clk_disable_unprepare() call moved from > > > > post_disable to the runtime suspend handler, and the work queue replaced > > > > by usage of pm_runtime_put_autosuspend(). > > > > > > It's an interesting idea but I don't think I can make it work, at > > > least not in a generic enough way. Specifically we can also use this > > > bridge chip as a generic GPIO provider in Linux. When someone asks us > > > to read a GPIO then we have to power the bridge on > > > (pm_runtime_get_sync()) and when someone asks us to configure a GPIO > > > as an output then we actually leave the bridge powered until they stop > > > requesting it as an output. At the moment the only user of this > > > functionality (that I know of) is for the HPD pin on trogdor boards > > > (long story about why we don't use the dedicated HPD) but the API > > > supports using these GPIOs for anything and I've tested that it works. > > > It wouldn't be great to have to keep the panel on in order to access > > > the GPIOs. > > > > The issue you're trying to fix doesn't seem specific to this bridge, so > > handling it in the bridge driver bothers me :-S Is there any way we > > could handle this in the DRM core ? I don't want to see similar > > implementations duplicated in all HDMI/DP bridges. > > Yes, it is true that this problem could affect other drivers. ...and > in full disclosure I think there are other similar workarounds already > present. I haven't personally worked on those chips, but in > ps8640_bridge_get_edid()
[PATCH v2 12/14] drm/bridge: ti-sn65dsi86: Read the EDID only if refclk was provided
Though I don't have access to any hardware that uses ti-sn65dsi86 and _doesn't_ provide a "refclk", I believe that we'll have trouble reading the EDID at bootup in that case. Specifically I believe that if there's no "refclk" we need the MIPI source clock to be active before we can successfully read the EDID. My evidence here is that, in testing, I couldn't read the EDID until I turned on the DPPLL in the bridge chip and that the DPPLL needs the input clock to be active. Since this is hard to support, let's punt trying to read the EDID if there's no "refclk". I don't believe there are any users of the ti-sn65dsi86 bridge chip that _don't_ use "refclk". The bridge chip is _very_ inflexible in that mode. The only time I've seen that mode used was for some really early prototype hardware that was thrown in the e-waste bin years ago when we realized how inflexible it was. Even if someone is using the bridge chip without the "refclk" they're in no worse shape than they were before the (fairly recent) commit 58074b08c04a ("drm/bridge: ti-sn65dsi86: Read EDID blob over DDC"). Signed-off-by: Douglas Anderson --- (no changes since v1) drivers/gpu/drm/bridge/ti-sn65dsi86.c | 13 + 1 file changed, 13 insertions(+) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index 673c9f1c2d8e..92498900c58d 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -273,6 +273,18 @@ static int ti_sn_bridge_connector_get_modes(struct drm_connector *connector) bool was_enabled; int num = 0; + /* +* Don't try to read the EDID if no refclk. In theory it is possible +* to make this work but it's tricky. I believe that we need to get +* our upstream MIPI source to provide a pixel clock before we can +* do AUX transations but we need to be able to read the EDID before +* we've picked a display mode. The bridge is already super limited +* if you try to use it without a refclk so presumably limiting to +* the fixed modes our downstream panel reports is fine. +*/ + if (!pdata->refclk) + goto exit; + /* * Try to get the EDID first without anything special. There are * three things that could happen with this call. @@ -306,6 +318,7 @@ static int ti_sn_bridge_connector_get_modes(struct drm_connector *connector) return num; } +exit: return drm_panel_get_modes(pdata->panel, connector); } -- 2.31.0.291.g576ba9dcdaf-goog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 10/14] drm/bridge: ti-sn65dsi86: Stop caching the EDID ourselves
Now that we have the patch ("drm/edid: Use the cached EDID in drm_get_edid() if eDP") we no longer need to maintain our own cache. Drop this code. Signed-off-by: Douglas Anderson --- (no changes since v1) drivers/gpu/drm/bridge/ti-sn65dsi86.c | 22 +- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index 9577ebd58c4c..c0398daaa4a6 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -121,7 +121,6 @@ * @debugfs: Used for managing our debugfs. * @host_node:Remote DSI node. * @dsi: Our MIPI DSI source. - * @edid: Detected EDID of eDP panel. * @refclk: Our reference clock. * @panel:Our panel. * @enable_gpio: The GPIO we toggle to enable the bridge. @@ -147,7 +146,6 @@ struct ti_sn_bridge { struct drm_bridge bridge; struct drm_connectorconnector; struct dentry *debugfs; - struct edid *edid; struct device_node *host_node; struct mipi_dsi_device *dsi; struct clk *refclk; @@ -269,17 +267,17 @@ connector_to_ti_sn_bridge(struct drm_connector *connector) static int ti_sn_bridge_connector_get_modes(struct drm_connector *connector) { struct ti_sn_bridge *pdata = connector_to_ti_sn_bridge(connector); - struct edid *edid = pdata->edid; - int num; + struct edid *edid; + int num = 0; - if (!edid) { - pm_runtime_get_sync(pdata->dev); - edid = pdata->edid = drm_get_edid(connector, >aux.ddc); - pm_runtime_put(pdata->dev); - } + pm_runtime_get_sync(pdata->dev); + edid = drm_get_edid(connector, >aux.ddc); + pm_runtime_put(pdata->dev); - if (edid && drm_edid_is_valid(edid)) { - num = drm_add_edid_modes(connector, edid); + if (edid) { + if (drm_edid_is_valid(edid)) + num = drm_add_edid_modes(connector, edid); + kfree(edid); if (num) return num; } @@ -1308,8 +1306,6 @@ static int ti_sn_bridge_remove(struct i2c_client *client) if (!pdata) return -EINVAL; - kfree(pdata->edid); - ti_sn_debugfs_remove(pdata); drm_bridge_remove(>bridge); -- 2.31.0.291.g576ba9dcdaf-goog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 14/14] drm/panel: panel-simple: Use runtime pm to avoid excessive unprepare / prepare
Unpreparing and re-preparing a panel can be a really heavy operation. Panels datasheets often specify something on the order of 500ms as the delay you should insert after turning off the panel before turning it on again. In addition, turning on a panel can have delays on the order of 100ms - 200ms before the panel will assert HPD (AKA "panel ready"). The above means that we should avoid turning a panel off if we're going to turn it on again shortly. The above becomes a problem when we want to read the EDID of a panel. The way that ordering works is that userspace wants to read the EDID of the panel _before_ fully enabling it so that it can set the initial mode correctly. However, we can't read the EDID until we power it up. This leads to code that does this dance (like ps8640_bridge_get_edid()): 1. When userspace requests EDID / the panel modes (through an ioctl), we power on the panel just enough to read the EDID and then power it off. 2. Userspace then turns the panel on. There's likely not much time between step #1 and #2 and so we want to avoid powering the panel off and on again between those two steps. Let's use Runtime PM to help us. We'll move the existing prepare() and unprepare() to be runtime resume() and runtime suspend(). Now when we want to prepare() or unprepare() we just increment or decrement the refcount. We'll default to a 1 second autosuspend delay which seems sane given the typical delays we see for panels. A few notes: - It seems the existing unprepare() and prepare() are defined to be no-ops if called extra times. We'll preserve that behavior. - This is a slight change in the ABI of simple panel. If something was absolutely relying on the unprepare() to happen instantly that simply won't be the case anymore. I'm not aware of anyone relying on that behavior, but if there is someone then we'll need to figure out how to enable (or disable) this new delayed behavior selectively. - In order for this to work we now have a hard dependency on "PM". From memory this is a legit thing to assume these days and we don't have to find some fallback to keep working if someone wants to build their system without "PM". Signed-off-by: Douglas Anderson --- (no changes since v1) drivers/gpu/drm/panel/Kconfig| 1 + drivers/gpu/drm/panel/panel-simple.c | 93 +--- 2 files changed, 73 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index 4894913936e9..ef87d92cdf49 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -80,6 +80,7 @@ config DRM_PANEL_SIMPLE tristate "support for simple panels" depends on OF depends on BACKLIGHT_CLASS_DEVICE + depends on PM select VIDEOMODE_HELPERS help DRM panel driver for dumb panels that need at most a regulator and diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index be312b5c04dd..6b22872b3281 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -175,6 +176,8 @@ struct panel_simple { bool enabled; bool no_hpd; + bool prepared; + ktime_t prepared_time; ktime_t unprepared_time; @@ -334,19 +337,31 @@ static int panel_simple_disable(struct drm_panel *panel) return 0; } +static int panel_simple_suspend(struct device *dev) +{ + struct panel_simple *p = dev_get_drvdata(dev); + + gpiod_set_value_cansleep(p->enable_gpio, 0); + regulator_disable(p->supply); + p->unprepared_time = ktime_get(); + + return 0; +} + static int panel_simple_unprepare(struct drm_panel *panel) { struct panel_simple *p = to_panel_simple(panel); + int ret; - if (p->prepared_time == 0) + /* Unpreparing when already unprepared is a no-op */ + if (!p->prepared) return 0; - gpiod_set_value_cansleep(p->enable_gpio, 0); - - regulator_disable(p->supply); - - p->prepared_time = 0; - p->unprepared_time = ktime_get(); + pm_runtime_mark_last_busy(panel->dev); + ret = pm_runtime_put_autosuspend(panel->dev); + if (ret < 0) + return ret; + p->prepared = false; return 0; } @@ -376,22 +391,19 @@ static int panel_simple_get_hpd_gpio(struct device *dev, return 0; } -static int panel_simple_prepare_once(struct drm_panel *panel) +static int panel_simple_prepare_once(struct panel_simple *p) { - struct panel_simple *p = to_panel_simple(panel); + struct device *dev = p->base.dev; unsigned int delay; int err; int hpd_asserted; unsigned long hpd_wait_us; - if (p->prepared_time != 0) - return 0; - panel_simple_wait(p->unprepared_time, p->desc->delay.unprepare);
[PATCH v2 13/14] drm/bridge: ti-sn65dsi86: Print an error if we fallback to panel modes
Now that we can properly read the EDID for modes there should be no reason to fallback to the fixed modes that our downstream panel driver provides us. Let's make that clear by: - Putting an error message in the logs if we fall back. - Putting a comment in saying what's going on. Signed-off-by: Douglas Anderson --- (no changes since v1) drivers/gpu/drm/bridge/ti-sn65dsi86.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index 92498900c58d..20c3b13939c2 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -318,6 +318,13 @@ static int ti_sn_bridge_connector_get_modes(struct drm_connector *connector) return num; } + /* +* Ideally this should never happen and we could remove the fallback +* but let's preserve old behavior. +*/ + DRM_DEV_ERROR(pdata->dev, + "Failed to read EDID; falling back to panel modes"); + exit: return drm_panel_get_modes(pdata->panel, connector); } -- 2.31.0.291.g576ba9dcdaf-goog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 11/14] drm/bridge: ti-sn65dsi86: Power things properly for reading the EDID
eDP panels won't provide their EDID unless they're powered on. Let's chain a power-on before we read the EDID. This roughly matches what was done in 'parade-ps8640.c'. NOTE: The old code attempted to call pm_runtime_get_sync() before reading the EDID. While that was enough to power the bridge chip on, it wasn't enough to talk to the panel for two reasons: 1. Since we never ran the bridge chip's pre-enable then we never set the bit to ignore HPD. This meant the bridge chip didn't even _try_ to go out on the bus and communicate with the panel. 2. Even if we fixed things to ignore HPD, the EDID still wouldn't read if the panel wasn't on. One thing that's a bit odd here is taking advantage of the EDID that the core might have cached for us. See the patch ("drm/edid: Use the cached EDID in drm_get_edid() if eDP"). We manage to get at the cache by: - Instantly failing aux transfers if we're not powered. - If the first read of the EDID fails we try again after powering. Fixes: 58074b08c04a ("drm/bridge: ti-sn65dsi86: Read EDID blob over DDC") Signed-off-by: Douglas Anderson --- Depending on what people think of the other patches in this series, some of this could change. - If everyone loves the "runtime PM" in the panel driver then we could, in theory, put the pre-enable chaining straight in the "aux transfer" function. - If everyone hates the EDID cache moving to the core then we can avoid some of the awkward flow of things and keep the EDID cache in the sn65dsi86 driver. (no changes since v1) drivers/gpu/drm/bridge/ti-sn65dsi86.c | 39 +-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index c0398daaa4a6..673c9f1c2d8e 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -128,6 +128,7 @@ * @dp_lanes: Count of dp_lanes we're using. * @ln_assign:Value to program to the LN_ASSIGN register. * @ln_polrs: Value for the 4-bit LN_POLRS field of SN_ENH_FRAME_REG. + * @pre_enabled: If true then pre_enable() has run. * * @gchip:If we expose our GPIOs, this is used. * @gchip_output: A cache of whether we've set GPIOs to output. This @@ -155,6 +156,7 @@ struct ti_sn_bridge { int dp_lanes; u8 ln_assign; u8 ln_polrs; + boolpre_enabled; #if defined(CONFIG_OF_GPIO) struct gpio_chipgchip; @@ -268,11 +270,33 @@ static int ti_sn_bridge_connector_get_modes(struct drm_connector *connector) { struct ti_sn_bridge *pdata = connector_to_ti_sn_bridge(connector); struct edid *edid; + bool was_enabled; int num = 0; - pm_runtime_get_sync(pdata->dev); + /* +* Try to get the EDID first without anything special. There are +* three things that could happen with this call. +* a) It might just return from its cache. +* b) It might try to initiate an AUX transfer which might work. +* c) It might try to initiate an AUX transfer which might fail because +*we're not powered up. +* +* If we get a failure we'll assume case c) and try again. NOTE: we +* don't want to power up every time because that's slow and we don't +* have visibility into whether the data has already been cached. +*/ edid = drm_get_edid(connector, >aux.ddc); - pm_runtime_put(pdata->dev); + if (!edid) { + was_enabled = pdata->pre_enabled; + + if (!was_enabled) + drm_bridge_chain_pre_enable(>bridge); + + edid = drm_get_edid(connector, >aux.ddc); + + if (!was_enabled) + drm_bridge_chain_post_disable(>bridge); + } if (edid) { if (drm_edid_is_valid(edid)) @@ -852,12 +876,16 @@ static void ti_sn_bridge_pre_enable(struct drm_bridge *bridge) HPD_DISABLE); drm_panel_prepare(pdata->panel); + + pdata->pre_enabled = true; } static void ti_sn_bridge_post_disable(struct drm_bridge *bridge) { struct ti_sn_bridge *pdata = bridge_to_ti_sn_bridge(bridge); + pdata->pre_enabled = false; + drm_panel_unprepare(pdata->panel); clk_disable_unprepare(pdata->refclk); @@ -891,6 +919,13 @@ static ssize_t ti_sn_aux_transfer(struct drm_dp_aux *aux, int ret; u8 addr_len[SN_AUX_LENGTH_REG + 1 - SN_AUX_ADDR_19_16_REG]; + /* +* Things just won't work if the panel isn't powered. Return failure +* right away. +*/ + if (!pdata->pre_enabled) + return -EIO; + if (len > SN_AUX_MAX_PAYLOAD_BYTES) return -EINVAL; -- 2.31.0.291.g576ba9dcdaf-goog
[PATCH v2 09/14] drm/edid: Use the cached EDID in drm_get_edid() if eDP
Each time we call drm_get_edid() we: 1. Go out to the bus and ask for the EDID. 2. Cache the EDID. We can improve this to actually use the cached EDID so that if drm_get_edid() is called multiple times then we don't need to go out to the bus over and over again. In normal DP/HDMI cases reading the EDID over and over again isn't _that_ expensive so, presumably, this wasn't that critical in the past. However for eDP going out to the bus can be expensive. This is because eDP panels might be powered off before the EDID was requested so we need to do power sequencing in addition to the transfer. In theory we should be able to cache the EDID for all types of displays. There is already code throwing the cache away when we detect that a display was unplugged. However, it can be noted that it's _extra_ safe to cache the EDID for eDP since eDP isn't a hot-pluggable interface. If we get the EDID once then we've got the EDID and we should never need to read it again. For now we'll only use the cache for eDP both because it's more important and extra safe. Signed-off-by: Douglas Anderson --- (no changes since v1) drivers/gpu/drm/drm_edid.c | 32 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index c2bbe7bee7b6..fcbf468d73c9 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -2049,15 +2049,39 @@ struct edid *drm_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) { struct edid *edid; + size_t old_edid_size; + const struct edid *old_edid; if (connector->force == DRM_FORCE_OFF) return NULL; - if (connector->force == DRM_FORCE_UNSPECIFIED && !drm_probe_ddc(adapter)) - return NULL; + if (connector->connector_type == DRM_MODE_CONNECTOR_eDP && + connector->edid_blob_ptr) { + /* +* eDP devices are non-removable, or at least not something +* that's expected to be hot-pluggable. We can freely use +* the cached EDID. +* +* NOTE: technically we could probably even use the cached +* EDID even for non-eDP because the cached EDID should be +* cleared if we ever notice a display is not connected, but +* we'll use an abundance of caution and only do it for eDP. +* It's more important for eDP anyway because the EDID may not +* always be readable, like when the panel is powered down. +*/ + old_edid = (const struct edid *)connector->edid_blob_ptr->data; + old_edid_size = ksize(old_edid); + edid = kmalloc(old_edid_size, GFP_KERNEL); + if (edid) + memcpy(edid, old_edid, old_edid_size); + } else { + if (connector->force == DRM_FORCE_UNSPECIFIED && !drm_probe_ddc(adapter)) + return NULL; + + edid = drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter); + drm_connector_update_edid_property(connector, edid); + } - edid = drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter); - drm_connector_update_edid_property(connector, edid); return edid; } EXPORT_SYMBOL(drm_get_edid); -- 2.31.0.291.g576ba9dcdaf-goog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 08/14] drm/bridge: ti-sn65dsi86: Remove extra call: drm_connector_update_edid_property()
As of commit 5186421cbfe2 ("drm: Introduce epoch counter to drm_connector") the drm_get_edid() function calls drm_connector_update_edid_property() for us. There's no reason for us to call it again. Signed-off-by: Douglas Anderson --- (no changes since v1) drivers/gpu/drm/bridge/ti-sn65dsi86.c | 11 --- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index a0a00dd1187c..9577ebd58c4c 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -270,7 +270,7 @@ static int ti_sn_bridge_connector_get_modes(struct drm_connector *connector) { struct ti_sn_bridge *pdata = connector_to_ti_sn_bridge(connector); struct edid *edid = pdata->edid; - int num, ret; + int num; if (!edid) { pm_runtime_get_sync(pdata->dev); @@ -279,12 +279,9 @@ static int ti_sn_bridge_connector_get_modes(struct drm_connector *connector) } if (edid && drm_edid_is_valid(edid)) { - ret = drm_connector_update_edid_property(connector, edid); - if (!ret) { - num = drm_add_edid_modes(connector, edid); - if (num) - return num; - } + num = drm_add_edid_modes(connector, edid); + if (num) + return num; } return drm_panel_get_modes(pdata->panel, connector); -- 2.31.0.291.g576ba9dcdaf-goog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 06/14] drm/bridge: ti-sn65dsi86: Move drm_panel_unprepare() to post_disable()
We prepared the panel in pre_enable() so we should unprepare it in post_disable() to match. This becomes important once we start using pre_enable() and post_disable() to make sure things are powered on (and then off again) when reading the EDID. Signed-off-by: Douglas Anderson --- (no changes since v1) drivers/gpu/drm/bridge/ti-sn65dsi86.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index e8e523b3a16b..50a52af8e39f 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -460,8 +460,6 @@ static void ti_sn_bridge_disable(struct drm_bridge *bridge) regmap_write(pdata->regmap, SN_ML_TX_MODE_REG, 0); /* disable DP PLL */ regmap_write(pdata->regmap, SN_PLL_ENABLE_REG, 0); - - drm_panel_unprepare(pdata->panel); } static u32 ti_sn_bridge_get_dsi_freq(struct ti_sn_bridge *pdata) @@ -877,6 +875,8 @@ static void ti_sn_bridge_post_disable(struct drm_bridge *bridge) { struct ti_sn_bridge *pdata = bridge_to_ti_sn_bridge(bridge); + drm_panel_unprepare(pdata->panel); + clk_disable_unprepare(pdata->refclk); pm_runtime_put_sync(pdata->dev); -- 2.31.0.291.g576ba9dcdaf-goog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 07/14] drm/bridge: ti-sn65dsi86: Get rid of the useless detect() function
If we just leave the detect() function as NULL then the upper layers assume we're always connected. There's no reason for a stub. Signed-off-by: Douglas Anderson --- (no changes since v1) drivers/gpu/drm/bridge/ti-sn65dsi86.c | 12 1 file changed, 12 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index 50a52af8e39f..a0a00dd1187c 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -306,20 +306,8 @@ static struct drm_connector_helper_funcs ti_sn_bridge_connector_helper_funcs = { .mode_valid = ti_sn_bridge_connector_mode_valid, }; -static enum drm_connector_status -ti_sn_bridge_connector_detect(struct drm_connector *connector, bool force) -{ - /** -* TODO: Currently if drm_panel is present, then always -* return the status as connected. Need to add support to detect -* device state for hot pluggable scenarios. -*/ - return connector_status_connected; -} - static const struct drm_connector_funcs ti_sn_bridge_connector_funcs = { .fill_modes = drm_helper_probe_single_connector_modes, - .detect = ti_sn_bridge_connector_detect, .destroy = drm_connector_cleanup, .reset = drm_atomic_helper_connector_reset, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, -- 2.31.0.291.g576ba9dcdaf-goog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 03/14] drm/bridge: ti-sn65dsi86: Remove incorrectly tagged kerneldoc comment
A random comment inside a function had "/**" in front of it. That doesn't make sense. Remove. Signed-off-by: Douglas Anderson --- (no changes since v1) drivers/gpu/drm/bridge/ti-sn65dsi86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index 96fe8f2c0ea9..76f43af6735d 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -788,7 +788,7 @@ static void ti_sn_bridge_enable(struct drm_bridge *bridge) /* set dsi clk frequency value */ ti_sn_bridge_set_dsi_rate(pdata); - /** + /* * The SN65DSI86 only supports ASSR Display Authentication method and * this method is enabled by default. An eDP panel must support this * authentication method. We need to enable this method in the eDP panel -- 2.31.0.291.g576ba9dcdaf-goog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 04/14] drm/bridge: ti-sn65dsi86: Reorder remove()
Let's make the remove() function strictly the reverse of the probe() function so it's easier to reason about. NOTES: - The MIPI calls probably belong in detach() but will be moved in a separate patch. - The cached EDID freeing isn't actually part of probe but needs to be in remove to avoid orphaning memory until better handling of the EDID happens. This patch was created by code inspection and should move us closer to a proper remove. Signed-off-by: Douglas Anderson --- (no changes since v1) drivers/gpu/drm/bridge/ti-sn65dsi86.c | 15 --- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index 76f43af6735d..c006678c9921 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -1315,20 +1315,21 @@ static int ti_sn_bridge_remove(struct i2c_client *client) if (!pdata) return -EINVAL; - kfree(pdata->edid); - ti_sn_debugfs_remove(pdata); - - of_node_put(pdata->host_node); - - pm_runtime_disable(pdata->dev); - if (pdata->dsi) { mipi_dsi_detach(pdata->dsi); mipi_dsi_device_unregister(pdata->dsi); } + kfree(pdata->edid); + + ti_sn_debugfs_remove(pdata); + drm_bridge_remove(>bridge); + pm_runtime_disable(pdata->dev); + + of_node_put(pdata->host_node); + return 0; } -- 2.31.0.291.g576ba9dcdaf-goog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 05/14] drm/bridge: ti-sn65dsi86: Move MIPI detach() / unregister() to detach()
The register() / attach() for MIPI happen in the bridge's attach(). That means that the inverse belongs in the bridge's detach(). Signed-off-by: Douglas Anderson --- (no changes since v1) drivers/gpu/drm/bridge/ti-sn65dsi86.c | 15 +-- 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index c006678c9921..e8e523b3a16b 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -437,7 +437,15 @@ static int ti_sn_bridge_attach(struct drm_bridge *bridge, static void ti_sn_bridge_detach(struct drm_bridge *bridge) { - drm_dp_aux_unregister(_to_ti_sn_bridge(bridge)->aux); + struct ti_sn_bridge *pdata = bridge_to_ti_sn_bridge(bridge); + + + if (pdata->dsi) { + mipi_dsi_detach(pdata->dsi); + mipi_dsi_device_unregister(pdata->dsi); + } + + drm_dp_aux_unregister(>aux); } static void ti_sn_bridge_disable(struct drm_bridge *bridge) @@ -1315,11 +1323,6 @@ static int ti_sn_bridge_remove(struct i2c_client *client) if (!pdata) return -EINVAL; - if (pdata->dsi) { - mipi_dsi_detach(pdata->dsi); - mipi_dsi_device_unregister(pdata->dsi); - } - kfree(pdata->edid); ti_sn_debugfs_remove(pdata); -- 2.31.0.291.g576ba9dcdaf-goog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 02/14] drm/bridge: ti-sn65dsi86: Simplify refclk handling
The clock framework makes it simple to deal with an optional clock. You can call clk_get_optional() and if the clock isn't specified it'll just return NULL without complaint. It's valid to pass NULL to enable/disable/prepare/unprepare. Let's make use of this to simplify things a tiny bit. Signed-off-by: Douglas Anderson Reviewed-by: Robert Foss Reviewed-by: Bjorn Andersson Reviewed-by: Stephen Boyd Reviewed-by: Laurent Pinchart --- Changes in v2: - Removed 2nd paragraph in commit message. drivers/gpu/drm/bridge/ti-sn65dsi86.c | 11 +++ 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index 88df4dd0f39d..96fe8f2c0ea9 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -1275,14 +1275,9 @@ static int ti_sn_bridge_probe(struct i2c_client *client, return ret; } - pdata->refclk = devm_clk_get(pdata->dev, "refclk"); - if (IS_ERR(pdata->refclk)) { - ret = PTR_ERR(pdata->refclk); - if (ret == -EPROBE_DEFER) - return ret; - DRM_DEBUG_KMS("refclk not found\n"); - pdata->refclk = NULL; - } + pdata->refclk = devm_clk_get_optional(pdata->dev, "refclk"); + if (IS_ERR(pdata->refclk)) + return PTR_ERR(pdata->refclk); ret = ti_sn_bridge_parse_dsi_host(pdata); if (ret) -- 2.31.0.291.g576ba9dcdaf-goog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 01/14] drm/bridge: Fix the stop condition of drm_bridge_chain_pre_enable()
The drm_bridge_chain_pre_enable() is not the proper opposite of drm_bridge_chain_post_disable(). It continues along the chain to _before_ the starting bridge. Let's fix that. Fixes: 05193dc38197 ("drm/bridge: Make the bridge chain a double-linked list") Signed-off-by: Douglas Anderson --- (no changes since v1) drivers/gpu/drm/drm_bridge.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index 64f0effb52ac..044acd07c153 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -522,6 +522,9 @@ void drm_bridge_chain_pre_enable(struct drm_bridge *bridge) list_for_each_entry_reverse(iter, >bridge_chain, chain_node) { if (iter->funcs->pre_enable) iter->funcs->pre_enable(iter); + + if (iter == bridge) + break; } } EXPORT_SYMBOL(drm_bridge_chain_pre_enable); -- 2.31.0.291.g576ba9dcdaf-goog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 00/14] drm: Fix EDID reading on ti-sn65dsi86
The primary goal of this series is to try to properly fix EDID reading for eDP panels using the ti-sn65dsi86 bridge. Previously we had a patch that added EDID reading but it turned out not to work at bootup. This caused some extra churn at bootup as we tried (and failed) to read the EDID several times and also ended up forcing us to use the hardcoded mode at boot. With this patch series I believe EDID reading is reliable at boot now and we never use the hardcoded mode. This series is the logical successor to the 3-part series containing the patch ("drm/bridge: ti-sn65dsi86: Properly get the EDID, but only if refclk") [1] though only one actual patch is the same between the two. This series starts out with some general / obvious fixes and moves on to some more specific and maybe controversial ones. I wouldn't object to some of the earlier ones landing if they look ready. This patch was developed against drm-misc-next on a sc7180-trogdor-lazor device. To get things booting for me, I had to use Stephen's patch [2] to keep from crashing but otherwise all the patches I needed were here. [1] https://lore.kernel.org/r/20210304155144.3.I60a7fb23ce4589006bc95c64ab8d15c74b876e68@changeid/ [2] https://lore.kernel.org/r/161706912161.3012082.17313817257247946...@swboyd.mtv.corp.google.com/ Changes in v2: - Removed 2nd paragraph in commit message. Douglas Anderson (14): drm/bridge: Fix the stop condition of drm_bridge_chain_pre_enable() drm/bridge: ti-sn65dsi86: Simplify refclk handling drm/bridge: ti-sn65dsi86: Remove incorrectly tagged kerneldoc comment drm/bridge: ti-sn65dsi86: Reorder remove() drm/bridge: ti-sn65dsi86: Move MIPI detach() / unregister() to detach() drm/bridge: ti-sn65dsi86: Move drm_panel_unprepare() to post_disable() drm/bridge: ti-sn65dsi86: Get rid of the useless detect() function drm/bridge: ti-sn65dsi86: Remove extra call: drm_connector_update_edid_property() drm/edid: Use the cached EDID in drm_get_edid() if eDP drm/bridge: ti-sn65dsi86: Stop caching the EDID ourselves drm/bridge: ti-sn65dsi86: Power things properly for reading the EDID drm/bridge: ti-sn65dsi86: Read the EDID only if refclk was provided drm/bridge: ti-sn65dsi86: Print an error if we fallback to panel modes drm/panel: panel-simple: Use runtime pm to avoid excessive unprepare / prepare drivers/gpu/drm/bridge/ti-sn65dsi86.c | 125 -- drivers/gpu/drm/drm_bridge.c | 3 + drivers/gpu/drm/drm_edid.c| 32 ++- drivers/gpu/drm/panel/Kconfig | 1 + drivers/gpu/drm/panel/panel-simple.c | 93 ++- 5 files changed, 184 insertions(+), 70 deletions(-) -- 2.31.0.291.g576ba9dcdaf-goog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm/panel: Convert sysfs sprintf/snprintf family to sysfs_emit
Fix the following coccicheck warning: drivers/gpu/drm/panel//panel-tpo-td043mtea1.c:217:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/panel//panel-tpo-td043mtea1.c:189:8-16: WARNING: use scnprintf or sprintf Signed-off-by: Tian Tao --- drivers/gpu/drm/panel/panel-tpo-td043mtea1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-tpo-td043mtea1.c b/drivers/gpu/drm/panel/panel-tpo-td043mtea1.c index 49e6c93..bacaf1b 100644 --- a/drivers/gpu/drm/panel/panel-tpo-td043mtea1.c +++ b/drivers/gpu/drm/panel/panel-tpo-td043mtea1.c @@ -186,7 +186,7 @@ static ssize_t vmirror_show(struct device *dev, struct device_attribute *attr, { struct td043mtea1_panel *lcd = dev_get_drvdata(dev); - return snprintf(buf, PAGE_SIZE, "%d\n", lcd->vmirror); + return sysfs_emit(buf, "%d\n", lcd->vmirror); } static ssize_t vmirror_store(struct device *dev, struct device_attribute *attr, @@ -214,7 +214,7 @@ static ssize_t mode_show(struct device *dev, struct device_attribute *attr, { struct td043mtea1_panel *lcd = dev_get_drvdata(dev); - return snprintf(buf, PAGE_SIZE, "%d\n", lcd->mode); + return sysfs_emit(buf, "%d\n", lcd->mode); } static ssize_t mode_store(struct device *dev, struct device_attribute *attr, -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 10/11] drm: Use state helper instead of the plane state pointer
Trimming Cc list way down, sorry if that's too much. Quoting Maxime Ripard (2021-02-19 04:00:30) > Many drivers reference the plane->state pointer in order to get the > current plane state in their atomic_update or atomic_disable hooks, > which would be the new plane state in the global atomic state since > _swap_state happened when those hooks are run. Does this mean drm_atomic_helper_swap_state()? > > Use the drm_atomic_get_new_plane_state helper to get that state to make it > more obvious. > > This was made using the coccinelle script below: > > @ plane_atomic_func @ > identifier helpers; > identifier func; > @@ > > ( > static const struct drm_plane_helper_funcs helpers = { > ..., > .atomic_disable = func, > ..., > }; > | > static const struct drm_plane_helper_funcs helpers = { > ..., > .atomic_update = func, > ..., > }; > ) > > @ adds_new_state @ > identifier plane_atomic_func.func; > identifier plane, state; > identifier new_state; > @@ > > func(struct drm_plane *plane, struct drm_atomic_state *state) > { > ... > - struct drm_plane_state *new_state = plane->state; > + struct drm_plane_state *new_state = > drm_atomic_get_new_plane_state(state, plane); > ... > } > > @ include depends on adds_new_state @ > @@ > > #include > > @ no_include depends on !include && adds_new_state @ > @@ > > + #include > #include > > drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 3 ++- > drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c | 4 +++- > drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 3 ++- > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c > index 31071f9e21d7..e8ce72fe54a4 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c > @@ -1244,7 +1244,8 @@ static void dpu_plane_atomic_update(struct drm_plane > *plane, > struct drm_atomic_state *state) > { > struct dpu_plane *pdpu = to_dpu_plane(plane); > - struct drm_plane_state *new_state = plane->state; > + struct drm_plane_state *new_state = > drm_atomic_get_new_plane_state(state, > + > plane); > > pdpu->is_error = false; > This is oopsing for me. It turns out that 'new_state' is NULL. According to the comments drm_atomic_get_new_plane_state() can return NULL if the plane isn't part of the global state. I haven't looked much further but wanted to report it here in case that type of return value makes sense. If I revert this patch from linux-next my display works and doesn't crash the system. Or I can check for NULL in the if below and it also works. diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index df7f3d3afd8b..f31b89531f6a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -1251,7 +1251,7 @@ static void dpu_plane_atomic_update(struct drm_plane *plane, DPU_DEBUG_PLANE(pdpu, "\n"); - if (!new_state->visible) { + if (new_state && !new_state->visible) { _dpu_plane_atomic_disable(plane); } else { dpu_plane_sspp_atomic_update(plane); ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v6 04/10] gpu: host1x: Remove cancelled waiters immediately
30.03.2021 00:36, Mikko Perttunen пишет: > On 3/29/21 11:27 PM, Dmitry Osipenko wrote: >> 29.03.2021 16:38, Mikko Perttunen пишет: >>> Before this patch, cancelled waiters would only be cleaned up >>> once their threshold value was reached. Make host1x_intr_put_ref >>> process the cancellation immediately to fix this. >>> >>> Signed-off-by: Mikko Perttunen >>> --- >>> v6: >>> * Call schedule instead of cpu_relax while waiting for pending >>> interrupt processing >>> v5: >>> * Add parameter to flush, i.e. wait for all pending waiters to >>> complete before returning. The reason this is not always true >>> is that the pending waiter might be the place that is calling >>> the put_ref. >>> --- >>> drivers/gpu/host1x/intr.c | 23 +-- >>> drivers/gpu/host1x/intr.h | 4 +++- >>> drivers/gpu/host1x/syncpt.c | 2 +- >>> 3 files changed, 21 insertions(+), 8 deletions(-) >>> >>> diff --git a/drivers/gpu/host1x/intr.c b/drivers/gpu/host1x/intr.c >>> index 9245add23b5d..69b0e8e41466 100644 >>> --- a/drivers/gpu/host1x/intr.c >>> +++ b/drivers/gpu/host1x/intr.c >>> @@ -242,18 +242,29 @@ int host1x_intr_add_action(struct host1x *host, >>> struct host1x_syncpt *syncpt, >>> return 0; >>> } >>> -void host1x_intr_put_ref(struct host1x *host, unsigned int id, >>> void *ref) >>> +void host1x_intr_put_ref(struct host1x *host, unsigned int id, void >>> *ref, >>> + bool flush) >>> { >>> struct host1x_waitlist *waiter = ref; >>> struct host1x_syncpt *syncpt; >>> - while (atomic_cmpxchg(>state, WLS_PENDING, >>> WLS_CANCELLED) == >>> - WLS_REMOVED) >>> - schedule(); >>> + atomic_cmpxchg(>state, WLS_PENDING, WLS_CANCELLED); >>> syncpt = host->syncpt + id; >>> - (void)process_wait_list(host, syncpt, >>> - host1x_syncpt_load(host->syncpt + id)); >>> + >>> + spin_lock(>intr.lock); >>> + if (atomic_cmpxchg(>state, WLS_CANCELLED, WLS_HANDLED) == >>> + WLS_CANCELLED) { >>> + list_del(>list); >>> + kref_put(>refcount, waiter_release); >>> + } >>> + spin_unlock(>intr.lock); >> >> Looks like we need to use IRQ-safe version of the locking here in order >> not to race with the interrupt handler(?), preventing lockup. > > The potential contention is with the syncpt_thresh_work scheduled work, > and not the actual interrupt handler, so there is no issue. I see now, thanks. >> But what real bug is fixed by this patch? If no real problem is fixed, >> then maybe will be better to defer touching this code till we will just >> replace it all with a proper dma-fence handlers? >> > > It improves things in that we won't litter the waiter data structures > with unbounded waiter entries when waits are cancelled. Also, I prefer > working in steps when possible - next is writing dma_fences on top of > this (which is already done) and then eventually phasing/refactoring > code from intr.c to fence.c so eventually only dma_fences remain. In my > experience that works better than big rewrites. So this change is a cleanup and not a bugfix, which wasn't clear from the commit description. In my experience it usually tends to help with a review if commit message explicitly states whether it is a minor cleanup or a critical bugfix. The small cleanups should be okay. It could be better if you could explicitly separate the fixes from cleanups since there is a better chance that fixes will be picked up immediately. I'd also suggest to try to group the cleanup changes with the new features that benefit from them, where possible. This should make patches to look more logical, not like it's some random change, helping with a review. I'll try to give a test to this series later today. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re:Re: [PATCH] amd: display: dc: struct dc_state is declared twice
>On Sat, Mar 27, 2021 at 3:28 AM Wan Jiabing wrote: >> >> struct dc_state has been declared at 273rd line. >> Remove the duplicate. >> Delete duplicate blank lines. > >Can you split these into separate patches? > >Alex OK. But in fact, what I did is simple. The most important thing is removing the duplicate struct dc_state declaration at 585th line. Others are all deleting duplicate blank lines. So maybe I should send two patchs, one is removing duplicate declaration, the other is deleting blank lines? >> >> Signed-off-by: Wan Jiabing >> --- >> drivers/gpu/drm/amd/display/dc/dc.h | 10 -- >> 1 file changed, 10 deletions(-) >> >> diff --git a/drivers/gpu/drm/amd/display/dc/dc.h >> b/drivers/gpu/drm/amd/display/dc/dc.h >> index 18ed0d3f247e..dc667298ab5b 100644 >> --- a/drivers/gpu/drm/amd/display/dc/dc.h >> +++ b/drivers/gpu/drm/amd/display/dc/dc.h >> @@ -234,7 +234,6 @@ struct dc_static_screen_params { >> unsigned int num_frames; >> }; >> >> - >> /* Surface update type is used by dc_update_surfaces_and_stream >> * The update type is determined at the very beginning of the function based >> * on parameters passed in and decides how much programming (or updating) is >> @@ -272,7 +271,6 @@ struct dc; >> struct dc_plane_state; >> struct dc_state; >> >> - >> struct dc_cap_funcs { >> bool (*get_dcc_compression_cap)(const struct dc *dc, >> const struct dc_dcc_surface_param *input, >> @@ -281,7 +279,6 @@ struct dc_cap_funcs { >> >> struct link_training_settings; >> >> - >> /* Structure to hold configuration flags set by dm at dc creation. */ >> struct dc_config { >> bool gpu_vm_support; >> @@ -581,7 +578,6 @@ struct dc_bounding_box_overrides { >> int min_dcfclk_mhz; >> }; >> >> -struct dc_state; Removing the duplicate is here. And others are all deleting duplicate blank line. I think they are in the same file. I want to remove the declaration first. By the way, I deleted the blank line. Yours, Wan Jiabing >> struct resource_pool; >> struct dce_hwseq; >> struct gpu_info_soc_bounding_box_v1_0; >> @@ -757,7 +753,6 @@ enum dc_transfer_func_predefined { >> TRANSFER_FUNCTION_GAMMA26 >> }; >> >> - >> struct dc_transfer_func { >> struct kref refcount; >> enum dc_transfer_func_type type; >> @@ -770,7 +765,6 @@ struct dc_transfer_func { >> }; >> }; >> >> - >> union dc_3dlut_state { >> struct { >> uint32_t initialized:1; /*if 3dlut is went through >> color module for initialization */ >> @@ -784,7 +778,6 @@ union dc_3dlut_state { >> uint32_t raw; >> }; >> >> - >> struct dc_3dlut { >> struct kref refcount; >> struct tetrahedral_params lut_3d; >> @@ -1014,7 +1007,6 @@ enum dc_status dc_validate_global_state( >> struct dc_state *new_ctx, >> bool fast_validate); >> >> - >> void dc_resource_state_construct( >> const struct dc *dc, >> struct dc_state *dst_ctx); >> @@ -1167,7 +1159,6 @@ struct dc_container_id { >> unsigned short productCode; >> }; >> >> - >> struct dc_sink_dsc_caps { >> // 'true' if these are virtual DPCD's DSC caps (immediately upstream >> of sink in MST topology), >> // 'false' if they are sink's DSC caps >> @@ -1229,7 +1220,6 @@ struct dc_cursor { >> struct dc_cursor_attributes attributes; >> }; >> >> - >> >> /*** >> * Interrupt interfaces >> >> **/ >> -- >> 2.25.1 >> >> ___ >> dri-devel mailing list >> dri-devel@lists.freedesktop.org >> https://lists.freedesktop.org/mailman/listinfo/dri-devel ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 00/25] drm/msm/dsi: refactor MSM DSI PHY/PLL drivers
Quoting Dmitry Baryshkov (2021-03-27 04:02:40) > Restructure MSM DSI PHY drivers. What started as an attempt to grok the > overcomplicated PHY drivers, has lead up to the idea of merging PHY and > PLL code, reducing abstractions, code duplication, dropping dead code, > etc. > > The patches were mainly tested on RB5 (sm8250, 7nm) and DB410c (apq8016, > 28nm-lp) and lightly tested on RB3 (sdm845, 10nm). > > The patch 'clk: fixed: add devm helper for clk_hw_register_fixed_factor()' > is already a part of mainline as of 5.12-rc1, but is included here for > completeness to fix compilation issues (as msm-next is based on 5.11-rc5). > > Changes since v2: > - Drop the 'stop setting clock parents manually' patch for now together >with the dtsi changes. Unlike the rest of patchset it provides >functional changes and might require additional discussion. >The patchset will be resubmitted later. > > Changes since v1: > - Rebase on top of msm/msm-next > - Reorder patches to follow logical sequence > - Add sc7180 clocks assignment > - Drop sm8250 clocks assignment, as respective file is not updated in >msm/msm-next > > Changes since RFC: > - Reorder patches to move global clock patches in the beginning and >dtsi patches where they are required. > - remove msm_dsi_phy_set_src_pll() and guess src_pll_id using PHY usecase. > > The following changes since commit 627dc55c273dab308303a5217bd3e767d7083ddb: > > drm/msm/disp/dpu1: icc path needs to be set before dpu runtime resume > (2021-03-22 18:52:34 -0700) > > are available in the Git repository at: > > https://git.linaro.org/people/dmitry.baryshkov/kernel.git dsi-phy-3 I tested this on sc7180 lazor and the display comes up Tested-by: Stephen Boyd ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm/komeda: Convert sysfs sprintf/snprintf family to sysfs_emit
Fix the following coccicheck warning: drivers/gpu/drm/arm/display/komeda/komeda_dev.c:97:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/arm/display/komeda/komeda_dev.c:88:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/arm/display/komeda/komeda_dev.c:65:8-16: WARNING: use scnprintf or sprintf Signed-off-by: Tian Tao --- drivers/gpu/drm/arm/display/komeda/komeda_dev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c index ca891ae..cc7664c 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c @@ -62,7 +62,7 @@ core_id_show(struct device *dev, struct device_attribute *attr, char *buf) { struct komeda_dev *mdev = dev_to_mdev(dev); - return snprintf(buf, PAGE_SIZE, "0x%08x\n", mdev->chip.core_id); + return sysfs_emit(buf, "0x%08x\n", mdev->chip.core_id); } static DEVICE_ATTR_RO(core_id); @@ -85,7 +85,7 @@ config_id_show(struct device *dev, struct device_attribute *attr, char *buf) if (pipe->layers[i]->layer_type == KOMEDA_FMT_RICH_LAYER) config_id.n_richs++; } - return snprintf(buf, PAGE_SIZE, "0x%08x\n", config_id.value); + return sysfs_emit(buf, "0x%08x\n", config_id.value); } static DEVICE_ATTR_RO(config_id); @@ -94,7 +94,7 @@ aclk_hz_show(struct device *dev, struct device_attribute *attr, char *buf) { struct komeda_dev *mdev = dev_to_mdev(dev); - return snprintf(buf, PAGE_SIZE, "%lu\n", clk_get_rate(mdev->aclk)); + return sysfs_emit(buf, "%lu\n", clk_get_rate(mdev->aclk)); } static DEVICE_ATTR_RO(aclk_hz); -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 13/25] drm/msm/dsi: use devm_of_clk_add_hw_provider
Would make it devm_of_clk_add_hw_provider() in the subject Quoting Dmitry Baryshkov (2021-03-27 04:02:53) > Use devm_of_clk_add_hw_provider() to register provided clocks. This > allows dropping the remove function alltogether. > > Signed-off-by: Dmitry Baryshkov > --- Reviewed-by: Stephen Boyd ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Freedreno] [PATCH v3 17/25] drm/msi/dsi: inline msm_dsi_pll_helper_clk_prepare/unprepare
On 2021-03-27 04:02, Dmitry Baryshkov wrote: 10nm and 7nm already do not use these helpers, as they handle setting slave DSI clocks after enabling VCO. Modify the rest of PHY drivers to remove unnecessary indirection and drop enable_seq/disable_seq PLL callbacks. Signed-off-by: Dmitry Baryshkov There is some amount of duplication of code when we inline the vco ops to the respective PLL files. Diff stats have infact more additions than removal, however in terms of the bigger interest of removing the dsi_pll.c/dsi_pll.h in the coming patchsets https://patchwork.freedesktop.org/patch/426369/?series=88517=2 I am okay with this change. Hence, Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/dsi/phy/dsi_phy.h | 2 - drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c| 87 +++-- drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c| 86 - .../gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c | 120 ++ drivers/gpu/drm/msm/dsi/phy/dsi_pll.c | 35 - drivers/gpu/drm/msm/dsi/phy/dsi_pll.h | 2 - 6 files changed, 171 insertions(+), 161 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h index 8133732e0c7f..b477d21804c8 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h @@ -32,8 +32,6 @@ struct msm_dsi_phy_ops { }; struct msm_dsi_pll_ops { - int (*enable_seq)(struct msm_dsi_pll *pll); - void (*disable_seq)(struct msm_dsi_pll *pll); void (*save_state)(struct msm_dsi_pll *pll); int (*restore_state)(struct msm_dsi_pll *pll); }; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c index 434d02ffa7fe..91c5bb2fd169 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c @@ -652,12 +652,58 @@ static unsigned long dsi_pll_14nm_vco_recalc_rate(struct clk_hw *hw, return (unsigned long)vco_rate; } +static int dsi_pll_14nm_vco_prepare(struct clk_hw *hw) +{ + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); + void __iomem *base = pll_14nm->mmio; + void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; + bool locked; + + DBG(""); + + if (unlikely(pll->pll_on)) + return 0; + + pll_write(base + REG_DSI_14nm_PHY_PLL_VREF_CFG1, 0x10); + pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 1); + + locked = pll_14nm_poll_for_ready(pll_14nm, POLL_MAX_READS, +POLL_TIMEOUT_US); + + if (unlikely(!locked)) { + DRM_DEV_ERROR(_14nm->pdev->dev, "DSI PLL lock failed\n"); + return -EINVAL; + } + + DBG("DSI PLL lock success"); + pll->pll_on = true; + + return 0; +} + +static void dsi_pll_14nm_vco_unprepare(struct clk_hw *hw) +{ + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); + void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; + + DBG(""); + + if (unlikely(!pll->pll_on)) + return; + + pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 0); + + pll->pll_on = false; +} + static const struct clk_ops clk_ops_dsi_pll_14nm_vco = { .round_rate = msm_dsi_pll_helper_clk_round_rate, .set_rate = dsi_pll_14nm_vco_set_rate, .recalc_rate = dsi_pll_14nm_vco_recalc_rate, - .prepare = msm_dsi_pll_helper_clk_prepare, - .unprepare = msm_dsi_pll_helper_clk_unprepare, + .prepare = dsi_pll_14nm_vco_prepare, + .unprepare = dsi_pll_14nm_vco_unprepare, }; /* @@ -749,39 +795,6 @@ static const struct clk_ops clk_ops_dsi_pll_14nm_postdiv = { * PLL Callbacks */ -static int dsi_pll_14nm_enable_seq(struct msm_dsi_pll *pll) -{ - struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); - void __iomem *base = pll_14nm->mmio; - void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; - bool locked; - - DBG(""); - - pll_write(base + REG_DSI_14nm_PHY_PLL_VREF_CFG1, 0x10); - pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 1); - - locked = pll_14nm_poll_for_ready(pll_14nm, POLL_MAX_READS, -POLL_TIMEOUT_US); - - if (unlikely(!locked)) - DRM_DEV_ERROR(_14nm->pdev->dev, "DSI PLL lock failed\n"); - else - DBG("DSI PLL lock success"); - - return locked ? 0 : -EINVAL; -} - -static void dsi_pll_14nm_disable_seq(struct msm_dsi_pll *pll) -{ - struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); - void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; - - DBG(""); - - pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 0); -} - static void dsi_pll_14nm_save_state(struct msm_dsi_pll *pll) { struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); @@ -1157,8 +1170,6 @@ const struct
Re: [PATCH v3 12/25] drm/msm/dsi: use devm_clk_*register to registe DSI PHY clocks
Subject should say register instead of registe Quoting Dmitry Baryshkov (2021-03-27 04:02:52) > Use devres-enabled version of clock registration functions. This lets us > remove dsi_pll destroy callbacks completely. > > Signed-off-by: Dmitry Baryshkov > --- > drivers/gpu/drm/msm/dsi/dsi.h | 4 - > drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 2 - > drivers/gpu/drm/msm/dsi/phy/dsi_phy.h | 1 - > drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c| 84 --- > drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c| 35 +--- > drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c| 50 +-- > .../gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c | 39 +++-- > drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 84 --- > drivers/gpu/drm/msm/dsi/phy/dsi_pll.c | 17 > drivers/gpu/drm/msm/dsi/phy/dsi_pll.h | 4 - > 10 files changed, 71 insertions(+), 249 deletions(-) Awesome diffstat! ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 03/25] clk: divider: add devm_clk_hw_register_divider
Quoting Dmitry Baryshkov (2021-03-27 04:02:43) > Add devm_clk_hw_register_divider() - devres version of > clk_hw_register_divider(). > > Signed-off-by: Dmitry Baryshkov > Reviewed-by: Abhinav Kumar > --- Acked-by: Stephen Boyd ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 02/25] clk: mux: provide devm_clk_hw_register_mux()
Quoting Dmitry Baryshkov (2021-03-27 04:02:42) > Add devm_clk_hw_register_mux() - devres-managed version of > clk_hw_register_mux(). > > Signed-off-by: Dmitry Baryshkov > Reviewed-by: Abhinav Kumar > --- Acked-by: Stephen Boyd ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 3/3] drm/mediatek: in struct mtk_hdmi, replace conn field with curr_conn ptr
Hi Dafna, Thank you for the patch. On Mon, Mar 29, 2021 at 05:36:32PM +0200, Dafna Hirschfeld wrote: > The mtk_hdmi does not support creating a bridge with a connector. > Therefore the field 'conn' should be removed from the mtk_hdmi struct. > It is replaced with a pointer curr_conn that points to the current > connector which can be access through the global state. > > Signed-off-by: Dafna Hirschfeld The patch looks good to me, but I'd squash it with 2/3 otherwise I think you'll break bisection. On the other hand, given that the HDMI support is already broken... :-) Reviewed-by: Laurent Pinchart But you need to make sure this patch will get backported to stable along 2/3, probably by adding a fixes tag. Or squashing it with 2/3, up to you. > --- > drivers/gpu/drm/mediatek/mtk_hdmi.c | 19 ++- > 1 file changed, 14 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c > b/drivers/gpu/drm/mediatek/mtk_hdmi.c > index 1eeb211b1536..0d95d2cfe3de 100644 > --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c > +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c > @@ -153,7 +153,7 @@ struct mtk_hdmi_conf { > struct mtk_hdmi { > struct drm_bridge bridge; > struct drm_bridge *next_bridge; > - struct drm_connector conn; > + struct drm_connector *curr_conn;/* current connector (only valid when > 'enabled') */ > struct device *dev; > const struct mtk_hdmi_conf *conf; > struct phy *phy; > @@ -969,7 +969,7 @@ static int mtk_hdmi_setup_avi_infoframe(struct mtk_hdmi > *hdmi, > ssize_t err; > > err = drm_hdmi_avi_infoframe_from_display_mode(, > ->conn, mode); > +hdmi->curr_conn, mode); > if (err < 0) { > dev_err(hdmi->dev, > "Failed to get AVI infoframe from mode: %zd\n", err); > @@ -1049,7 +1049,7 @@ static int > mtk_hdmi_setup_vendor_specific_infoframe(struct mtk_hdmi *hdmi, > ssize_t err; > > err = drm_hdmi_vendor_infoframe_from_display_mode(, > - >conn, mode); > + hdmi->curr_conn, > mode); > if (err) { > dev_err(hdmi->dev, > "Failed to get vendor infoframe from mode: %zd\n", err); > @@ -1322,6 +1322,8 @@ static void mtk_hdmi_bridge_atomic_disable(struct > drm_bridge *bridge, > clk_disable_unprepare(hdmi->clk[MTK_HDMI_CLK_HDMI_PIXEL]); > clk_disable_unprepare(hdmi->clk[MTK_HDMI_CLK_HDMI_PLL]); > > + hdmi->curr_conn = NULL; > + > hdmi->enabled = false; > } > > @@ -1385,8 +1387,13 @@ static void mtk_hdmi_send_infoframe(struct mtk_hdmi > *hdmi, > static void mtk_hdmi_bridge_atomic_enable(struct drm_bridge *bridge, > struct drm_bridge_state *old_state) > { > + struct drm_atomic_state *state = old_state->base.state; > struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); > > + /* Retrieve the connector through the atomic state. */ > + hdmi->curr_conn = drm_atomic_get_new_connector_for_encoder(state, > + > bridge->encoder); > + > mtk_hdmi_output_set_display_mode(hdmi, >mode); > clk_prepare_enable(hdmi->clk[MTK_HDMI_CLK_HDMI_PLL]); > clk_prepare_enable(hdmi->clk[MTK_HDMI_CLK_HDMI_PIXEL]); > @@ -1625,8 +1632,10 @@ static int mtk_hdmi_audio_get_eld(struct device *dev, > void *data, uint8_t *buf, > { > struct mtk_hdmi *hdmi = dev_get_drvdata(dev); > > - memcpy(buf, hdmi->conn.eld, min(sizeof(hdmi->conn.eld), len)); > - > + if (hdmi->enabled) > + memcpy(buf, hdmi->curr_conn->eld, > min(sizeof(hdmi->curr_conn->eld), len)); > + else > + memset(buf, 0, len); > return 0; > } > -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 2/3] drm/mediatek: Don't support hdmi connector creation
Hi Dafna, Thank you for the patch. On Mon, Mar 29, 2021 at 05:36:31PM +0200, Dafna Hirschfeld wrote: > commit f01195148967 ("drm/mediatek: mtk_dpi: Create connector for bridges") > broke the display support for elm device since mtk_dpi calls > drm_bridge_attach with the flag DRM_BRIDGE_ATTACH_NO_CONNECTOR > while mtk_hdmi does not yet support this flag. > > Fix this by accepting DRM_BRIDGE_ATTACH_NO_CONNECTOR in bridge attachment. > Implement the drm_bridge_funcs .detect() and .get_edid() operations, and > call drm_bridge_hpd_notify() to report HPD. This provides the > necessary API to support disabling connector creation. > > This patch is inspired by a similar patch for bridge/synopsys/dw-hdmi.c: > commit ec971aaa6775 ("drm: bridge: dw-hdmi: Make connector creation optional") > But with the difference that in mtk-hdmi only the option of not creating > a connector is supported. > > Fixes: f01195148967 ("drm/mediatek: mtk_dpi: Create connector for bridges") > Signed-off-by: Dafna Hirschfeld > --- > drivers/gpu/drm/mediatek/mtk_hdmi.c | 129 ++-- > 1 file changed, 44 insertions(+), 85 deletions(-) > > diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c > b/drivers/gpu/drm/mediatek/mtk_hdmi.c > index f2c810b767ef..1eeb211b1536 100644 > --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c > +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c > @@ -186,11 +186,6 @@ static inline struct mtk_hdmi > *hdmi_ctx_from_bridge(struct drm_bridge *b) > return container_of(b, struct mtk_hdmi, bridge); > } > > -static inline struct mtk_hdmi *hdmi_ctx_from_conn(struct drm_connector *c) > -{ > - return container_of(c, struct mtk_hdmi, conn); > -} > - > static u32 mtk_hdmi_read(struct mtk_hdmi *hdmi, u32 offset) > { > return readl(hdmi->regs + offset); > @@ -1201,48 +1196,30 @@ mtk_hdmi_update_plugged_status(struct mtk_hdmi *hdmi) > connector_status_connected : connector_status_disconnected; > } > > -static enum drm_connector_status hdmi_conn_detect(struct drm_connector *conn, > - bool force) > -{ > - struct mtk_hdmi *hdmi = hdmi_ctx_from_conn(conn); > - return mtk_hdmi_update_plugged_status(hdmi); > -} > - > -static void hdmi_conn_destroy(struct drm_connector *conn) > +static struct edid *mtk_hdmi_get_edid(struct mtk_hdmi *hdmi, > + struct drm_connector *connector) > { > - struct mtk_hdmi *hdmi = hdmi_ctx_from_conn(conn); > - > - mtk_cec_set_hpd_event(hdmi->cec_dev, NULL, NULL); > - > - drm_connector_cleanup(conn); > -} > - > -static int mtk_hdmi_conn_get_modes(struct drm_connector *conn) > -{ > - struct mtk_hdmi *hdmi = hdmi_ctx_from_conn(conn); > struct edid *edid; > - int ret; > > if (!hdmi->ddc_adpt) > - return -ENODEV; > - > - edid = drm_get_edid(conn, hdmi->ddc_adpt); > + return NULL; > + edid = drm_get_edid(connector, hdmi->ddc_adpt); > if (!edid) > - return -ENODEV; > - > + return NULL; > hdmi->dvi_mode = !drm_detect_monitor_audio(edid); > + return edid; > +} > > - drm_connector_update_edid_property(conn, edid); > - > - ret = drm_add_edid_modes(conn, edid); > - kfree(edid); > - return ret; > +static enum drm_connector_status mtk_hdmi_detect(struct mtk_hdmi *hdmi) > +{ > + return mtk_hdmi_update_plugged_status(hdmi); > } > > -static int mtk_hdmi_conn_mode_valid(struct drm_connector *conn, > - struct drm_display_mode *mode) > +static int mtk_hdmi_bridge_mode_valid(struct drm_bridge *bridge, > + const struct drm_display_info *info, > + const struct drm_display_mode *mode) > { > - struct mtk_hdmi *hdmi = hdmi_ctx_from_conn(conn); > + struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); > struct drm_bridge *next_bridge; > > dev_dbg(hdmi->dev, "xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n", > @@ -1267,74 +1244,50 @@ static int mtk_hdmi_conn_mode_valid(struct > drm_connector *conn, > return drm_mode_validate_size(mode, 0x1fff, 0x1fff); > } > > -static struct drm_encoder *mtk_hdmi_conn_best_enc(struct drm_connector *conn) > -{ > - struct mtk_hdmi *hdmi = hdmi_ctx_from_conn(conn); > - > - return hdmi->bridge.encoder; > -} > - > -static const struct drm_connector_funcs mtk_hdmi_connector_funcs = { > - .detect = hdmi_conn_detect, > - .fill_modes = drm_helper_probe_single_connector_modes, > - .destroy = hdmi_conn_destroy, > - .reset = drm_atomic_helper_connector_reset, > - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, > - .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, > -}; > - > -static const struct drm_connector_helper_funcs > - mtk_hdmi_connector_helper_funcs = { > - .get_modes = mtk_hdmi_conn_get_modes, > - .mode_valid =
Re: [Freedreno] [PATCH v3 16/25] drm/msm/dpu: simplify vco_delay handling in dsi_phy_28nm driver
On 2021-03-27 04:02, Dmitry Baryshkov wrote: Instead of setting the variable and then using it just in the one place, determine vco_delay directly at the PLL configuration time. Signed-off-by: Dmitry Baryshkov The subject line should still be "drm/msm/dsi" and not "drm/msm/dpu". Once thats fixed, please apply Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c | 12 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c index 3e9b7949b038..ed369eb18e9d 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c @@ -72,8 +72,6 @@ struct dsi_pll_28nm { struct platform_device *pdev; void __iomem *mmio; - int vco_delay; - struct pll_28nm_cached_state cached_state; }; @@ -212,8 +210,10 @@ static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate, pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG4, 0x00); /* Add hardware recommended delay for correct PLL configuration */ - if (pll_28nm->vco_delay) - udelay(pll_28nm->vco_delay); + if (pll->cfg->quirks & DSI_PHY_28NM_QUIRK_PHY_LP) + udelay(1000); + else + udelay(1); pll_write(base + REG_DSI_28nm_PHY_PLL_REFCLK_CFG, refclk_cfg); pll_write(base + REG_DSI_28nm_PHY_PLL_PWRGEN_CFG, 0x00); @@ -580,10 +580,6 @@ static int dsi_pll_28nm_init(struct msm_dsi_phy *phy) pll = _28nm->base; pll->cfg = phy->cfg; - if (phy->cfg->quirks & DSI_PHY_28NM_QUIRK_PHY_LP) - pll_28nm->vco_delay = 1000; - else - pll_28nm->vco_delay = 1; ret = pll_28nm_register(pll_28nm, phy->provided_clocks->hws); if (ret) { ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 1/3] drm/mediatek: Switch the hdmi bridge ops to the atomic versions
Hi Dafna, Thank you for the patch. On Mon, Mar 29, 2021 at 05:36:30PM +0200, Dafna Hirschfeld wrote: > The bridge operation '.enable' and the audio cb '.get_eld' > access hdmi->conn. In the future we will want to support > the flag DRM_BRIDGE_ATTACH_NO_CONNECTOR and then we will > not have direct access to the connector. > The atomic version '.atomic_enable' allows accessing the > current connector from the state. > This patch switches the bridge to the atomic version to > prepare access to the connector in later patches. > > Signed-off-by: Dafna Hirschfeld Reviewed-by: Laurent Pinchart > --- > drivers/gpu/drm/mediatek/mtk_hdmi.c | 23 +++ > 1 file changed, 15 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c > b/drivers/gpu/drm/mediatek/mtk_hdmi.c > index 8ee55f9e2954..f2c810b767ef 100644 > --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c > +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c > @@ -1357,7 +1357,8 @@ static bool mtk_hdmi_bridge_mode_fixup(struct > drm_bridge *bridge, > return true; > } > > -static void mtk_hdmi_bridge_disable(struct drm_bridge *bridge) > +static void mtk_hdmi_bridge_atomic_disable(struct drm_bridge *bridge, > +struct drm_bridge_state > *old_bridge_state) > { > struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); > > @@ -1371,7 +1372,8 @@ static void mtk_hdmi_bridge_disable(struct drm_bridge > *bridge) > hdmi->enabled = false; > } > > -static void mtk_hdmi_bridge_post_disable(struct drm_bridge *bridge) > +static void mtk_hdmi_bridge_atomic_post_disable(struct drm_bridge *bridge, > + struct drm_bridge_state > *old_state) > { > struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); > > @@ -1406,7 +1408,8 @@ static void mtk_hdmi_bridge_mode_set(struct drm_bridge > *bridge, > drm_mode_copy(>mode, adjusted_mode); > } > > -static void mtk_hdmi_bridge_pre_enable(struct drm_bridge *bridge) > +static void mtk_hdmi_bridge_atomic_pre_enable(struct drm_bridge *bridge, > + struct drm_bridge_state > *old_state) > { > struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); > > @@ -1426,7 +1429,8 @@ static void mtk_hdmi_send_infoframe(struct mtk_hdmi > *hdmi, > mtk_hdmi_setup_vendor_specific_infoframe(hdmi, mode); > } > > -static void mtk_hdmi_bridge_enable(struct drm_bridge *bridge) > +static void mtk_hdmi_bridge_atomic_enable(struct drm_bridge *bridge, > + struct drm_bridge_state *old_state) > { > struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); > > @@ -1440,13 +1444,16 @@ static void mtk_hdmi_bridge_enable(struct drm_bridge > *bridge) > } > > static const struct drm_bridge_funcs mtk_hdmi_bridge_funcs = { > + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, > + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, > + .atomic_reset = drm_atomic_helper_bridge_reset, > .attach = mtk_hdmi_bridge_attach, > .mode_fixup = mtk_hdmi_bridge_mode_fixup, > - .disable = mtk_hdmi_bridge_disable, > - .post_disable = mtk_hdmi_bridge_post_disable, > + .atomic_disable = mtk_hdmi_bridge_atomic_disable, > + .atomic_post_disable = mtk_hdmi_bridge_atomic_post_disable, > .mode_set = mtk_hdmi_bridge_mode_set, > - .pre_enable = mtk_hdmi_bridge_pre_enable, > - .enable = mtk_hdmi_bridge_enable, > + .atomic_pre_enable = mtk_hdmi_bridge_atomic_pre_enable, > + .atomic_enable = mtk_hdmi_bridge_atomic_enable, > }; > > static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Freedreno] [PATCH v3 15/25] drm/msm/dsi: drop vco_delay setting from 7nm, 10nm, 14nm drivers
On 2021-03-27 04:02, Dmitry Baryshkov wrote: These drivers do not use vco_delay variable, so drop it from all of them. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c | 3 --- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 4 drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 3 --- 3 files changed, 10 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c index e0df12a841b2..bfb96d87d1d7 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c @@ -99,7 +99,6 @@ struct dsi_pll_10nm { /* protects REG_DSI_10nm_PHY_CMN_CLK_CFG0 register */ spinlock_t postdiv_lock; - int vco_delay; struct dsi_pll_config pll_configuration; struct dsi_pll_regs reg_setup; @@ -771,8 +770,6 @@ static int dsi_pll_10nm_init(struct msm_dsi_phy *phy) pll = _10nm->base; pll->cfg = phy->cfg; - pll_10nm->vco_delay = 1; - ret = pll_10nm_register(pll_10nm, phy->provided_clocks->hws); if (ret) { DRM_DEV_ERROR(>dev, "failed to register PLL: %d\n", ret); diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c index 7fe7c8348b42..434d02ffa7fe 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c @@ -122,8 +122,6 @@ struct dsi_pll_14nm { void __iomem *phy_cmn_mmio; void __iomem *mmio; - int vco_delay; - struct dsi_pll_input in; struct dsi_pll_output out; @@ -1012,8 +1010,6 @@ static int dsi_pll_14nm_init(struct msm_dsi_phy *phy) pll = _14nm->base; pll->cfg = phy->cfg; - pll_14nm->vco_delay = 1; - ret = pll_14nm_register(pll_14nm, phy->provided_clocks->hws); if (ret) { DRM_DEV_ERROR(>dev, "failed to register PLL: %d\n", ret); diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c index e6c8040e1bd3..f760904efac9 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c @@ -99,7 +99,6 @@ struct dsi_pll_7nm { /* protects REG_DSI_7nm_PHY_CMN_CLK_CFG0 register */ spinlock_t postdiv_lock; - int vco_delay; struct dsi_pll_config pll_configuration; struct dsi_pll_regs reg_setup; @@ -796,8 +795,6 @@ static int dsi_pll_7nm_init(struct msm_dsi_phy *phy) pll = _7nm->base; pll->cfg = phy->cfg; - pll_7nm->vco_delay = 1; - ret = pll_7nm_register(pll_7nm, phy->provided_clocks->hws); if (ret) { DRM_DEV_ERROR(>dev, "failed to register PLL: %d\n", ret); ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Freedreno] [PATCH v3 14/25] drm/msm/dsi: make save/restore_state phy-level functions
On 2021-03-27 04:02, Dmitry Baryshkov wrote: Morph msm_dsi_pll_save/restore_state() into msm_dsi_phy_save/restore_state(), thus removing last bits of knowledge about msm_dsi_pll from dsi_manager. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dsi/dsi.h | 18 ++- drivers/gpu/drm/msm/dsi/dsi_manager.c | 6 ++-- drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 35 +++--- drivers/gpu/drm/msm/dsi/phy/dsi_phy.h | 11 +++ drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c | 2 +- drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 2 +- drivers/gpu/drm/msm/dsi/phy/dsi_pll.c | 26 drivers/gpu/drm/msm/dsi/phy/dsi_pll.h | 11 --- 8 files changed, 42 insertions(+), 69 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h index 0970f05cd47f..53feea9d30c0 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.h +++ b/drivers/gpu/drm/msm/dsi/dsi.h @@ -92,21 +92,6 @@ static inline bool msm_dsi_device_connected(struct msm_dsi *msm_dsi) struct drm_encoder *msm_dsi_get_encoder(struct msm_dsi *msm_dsi); -/* dsi pll */ -struct msm_dsi_pll; -#ifdef CONFIG_DRM_MSM_DSI_PLL -void msm_dsi_pll_save_state(struct msm_dsi_pll *pll); -int msm_dsi_pll_restore_state(struct msm_dsi_pll *pll); -#else -static inline void msm_dsi_pll_save_state(struct msm_dsi_pll *pll) -{ -} -static inline int msm_dsi_pll_restore_state(struct msm_dsi_pll *pll) -{ - return 0; -} -#endif - /* dsi host */ struct msm_dsi_host; int msm_dsi_host_xfer_prepare(struct mipi_dsi_host *host, @@ -182,11 +167,12 @@ int msm_dsi_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, void msm_dsi_phy_disable(struct msm_dsi_phy *phy); void msm_dsi_phy_get_shared_timings(struct msm_dsi_phy *phy, struct msm_dsi_phy_shared_timings *shared_timing); -struct msm_dsi_pll *msm_dsi_phy_get_pll(struct msm_dsi_phy *phy); void msm_dsi_phy_set_usecase(struct msm_dsi_phy *phy, enum msm_dsi_phy_usecase uc); int msm_dsi_phy_get_clk_provider(struct msm_dsi_phy *phy, struct clk **byte_clk_provider, struct clk **pixel_clk_provider); +void msm_dsi_phy_save_state(struct msm_dsi_phy *phy); +int msm_dsi_phy_restore_state(struct msm_dsi_phy *phy); I think renaming these to msm_dsi_phy_pll_save_state()/msm_dsi_phy_pll_restore_state() will be better because internally they are only saving/restoring PLL states, Once thats fixed, please feel free to add : Reviewed-by: Abhinav Kumar #endif /* __DSI_CONNECTOR_H__ */ diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c index 86e36be58701..0c47c5fb1ab3 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c @@ -498,7 +498,6 @@ static void dsi_mgr_bridge_post_disable(struct drm_bridge *bridge) struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1); struct mipi_dsi_host *host = msm_dsi->host; struct drm_panel *panel = msm_dsi->panel; - struct msm_dsi_pll *src_pll; bool is_dual_dsi = IS_DUAL_DSI(); int ret; @@ -532,9 +531,8 @@ static void dsi_mgr_bridge_post_disable(struct drm_bridge *bridge) id, ret); } - /* Save PLL status if it is a clock source */ - src_pll = msm_dsi_phy_get_pll(msm_dsi->phy); - msm_dsi_pll_save_state(src_pll); + /* Save PHY status if it is a clock source */ + msm_dsi_phy_save_state(msm_dsi->phy); ret = msm_dsi_host_power_off(host); if (ret) diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c index 46561435a27d..176930800082 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c @@ -799,9 +799,9 @@ int msm_dsi_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, * source. */ if (phy->usecase != MSM_DSI_PHY_SLAVE) { - ret = msm_dsi_pll_restore_state(phy->pll); + ret = msm_dsi_phy_restore_state(phy); if (ret) { - DRM_DEV_ERROR(dev, "%s: failed to restore pll state, %d\n", + DRM_DEV_ERROR(dev, "%s: failed to restore phy state, %d\n", __func__, ret); goto pll_restor_fail; } @@ -838,14 +838,6 @@ void msm_dsi_phy_get_shared_timings(struct msm_dsi_phy *phy, sizeof(*shared_timings)); } -struct msm_dsi_pll *msm_dsi_phy_get_pll(struct msm_dsi_phy *phy) -{ - if (!phy) - return NULL; - - return phy->pll; -} - void msm_dsi_phy_set_usecase(struct msm_dsi_phy *phy, enum msm_dsi_phy_usecase uc) { @@ -863,3 +855,26 @@ int msm_dsi_phy_get_clk_provider(struct msm_dsi_phy *phy, return -EINVAL; } + +void msm_dsi_phy_save_state(struct msm_dsi_phy *phy) +{ + if
Re: [Freedreno] [PATCH v3 13/25] drm/msm/dsi: use devm_of_clk_add_hw_provider
On 2021-03-27 04:02, Dmitry Baryshkov wrote: Use devm_of_clk_add_hw_provider() to register provided clocks. This allows dropping the remove function alltogether. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 22 +- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c index df3b91b0ea88..46561435a27d 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c @@ -728,7 +728,7 @@ static int dsi_phy_driver_probe(struct platform_device *pdev) } } - ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, phy->provided_clocks); if (ret) { DRM_DEV_ERROR(dev, "%s: failed to register clk provider: %d\n", __func__, ret); @@ -742,31 +742,11 @@ static int dsi_phy_driver_probe(struct platform_device *pdev) return 0; fail: - if (phy->pll) { - of_clk_del_provider(dev->of_node); - phy->pll = NULL; - } - return ret; } -static int dsi_phy_driver_remove(struct platform_device *pdev) -{ - struct msm_dsi_phy *phy = platform_get_drvdata(pdev); - - if (phy && phy->pll) { - of_clk_del_provider(pdev->dev.of_node); - phy->pll = NULL; - } - - platform_set_drvdata(pdev, NULL); - - return 0; -} - static struct platform_driver dsi_phy_platform_driver = { .probe = dsi_phy_driver_probe, - .remove = dsi_phy_driver_remove, .driver = { .name = "msm_dsi_phy", .of_match_table = dsi_phy_dt_match, ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Freedreno] [PATCH v3 12/25] drm/msm/dsi: use devm_clk_*register to registe DSI PHY clocks
On 2021-03-27 04:02, Dmitry Baryshkov wrote: Use devres-enabled version of clock registration functions. This lets us remove dsi_pll destroy callbacks completely. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/dsi/dsi.h | 4 - drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 2 - drivers/gpu/drm/msm/dsi/phy/dsi_phy.h | 1 - drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c| 84 --- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c| 35 +--- drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c| 50 +-- .../gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c | 39 +++-- drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 84 --- drivers/gpu/drm/msm/dsi/phy/dsi_pll.c | 17 drivers/gpu/drm/msm/dsi/phy/dsi_pll.h | 4 - 10 files changed, 71 insertions(+), 249 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h index 43590f338d20..0970f05cd47f 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.h +++ b/drivers/gpu/drm/msm/dsi/dsi.h @@ -95,13 +95,9 @@ struct drm_encoder *msm_dsi_get_encoder(struct msm_dsi *msm_dsi); /* dsi pll */ struct msm_dsi_pll; #ifdef CONFIG_DRM_MSM_DSI_PLL -void msm_dsi_pll_destroy(struct msm_dsi_pll *pll); void msm_dsi_pll_save_state(struct msm_dsi_pll *pll); int msm_dsi_pll_restore_state(struct msm_dsi_pll *pll); #else -static inline void msm_dsi_pll_destroy(struct msm_dsi_pll *pll) -{ -} static inline void msm_dsi_pll_save_state(struct msm_dsi_pll *pll) { } diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c index 69214447f757..df3b91b0ea88 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c @@ -744,7 +744,6 @@ static int dsi_phy_driver_probe(struct platform_device *pdev) fail: if (phy->pll) { of_clk_del_provider(dev->of_node); - msm_dsi_pll_destroy(phy->pll); phy->pll = NULL; } @@ -757,7 +756,6 @@ static int dsi_phy_driver_remove(struct platform_device *pdev) if (phy && phy->pll) { of_clk_del_provider(pdev->dev.of_node); - msm_dsi_pll_destroy(phy->pll); phy->pll = NULL; } diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h index c3099629fa3b..2c5196844ba9 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h @@ -23,7 +23,6 @@ struct msm_dsi_phy_ops { struct msm_dsi_pll_ops { int (*enable_seq)(struct msm_dsi_pll *pll); void (*disable_seq)(struct msm_dsi_pll *pll); - void (*destroy)(struct msm_dsi_pll *pll); void (*save_state)(struct msm_dsi_pll *pll); int (*restore_state)(struct msm_dsi_pll *pll); }; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c index 8666da1c29e5..6300b92c65eb 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c @@ -103,15 +103,6 @@ struct dsi_pll_10nm { struct dsi_pll_config pll_configuration; struct dsi_pll_regs reg_setup; - /* private clocks: */ - struct clk_hw *out_div_clk_hw; - struct clk_hw *bit_clk_hw; - struct clk_hw *byte_clk_hw; - struct clk_hw *by_2_bit_clk_hw; - struct clk_hw *post_out_div_clk_hw; - struct clk_hw *pclk_mux_hw; - struct clk_hw *out_dsiclk_hw; - struct pll_10nm_cached_state cached_state; enum msm_dsi_phy_usecase uc; @@ -614,22 +605,6 @@ static int dsi_pll_10nm_set_usecase(struct msm_dsi_pll *pll, return 0; } -static void dsi_pll_10nm_destroy(struct msm_dsi_pll *pll) -{ - struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); - - DBG("DSI PLL%d", pll_10nm->id); - - clk_hw_unregister_divider(pll_10nm->out_dsiclk_hw); - clk_hw_unregister_mux(pll_10nm->pclk_mux_hw); - clk_hw_unregister_fixed_factor(pll_10nm->post_out_div_clk_hw); - clk_hw_unregister_fixed_factor(pll_10nm->by_2_bit_clk_hw); - clk_hw_unregister_fixed_factor(pll_10nm->byte_clk_hw); - clk_hw_unregister_divider(pll_10nm->bit_clk_hw); - clk_hw_unregister_divider(pll_10nm->out_div_clk_hw); - clk_hw_unregister(_10nm->base.clk_hw); -} - /* * The post dividers and mux clocks are created using the standard divider and * mux API. Unlike the 14nm PHY, the slave PLL doesn't need its dividers/mux @@ -656,30 +631,28 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm, struct clk_hw **prov snprintf(vco_name, 32, "dsi%dvco_clk", pll_10nm->id); pll_10nm->base.clk_hw.init = _init; - ret = clk_hw_register(dev, _10nm->base.clk_hw); + ret = devm_clk_hw_register(dev, _10nm->base.clk_hw); if (ret) return ret; snprintf(clk_name, 32, "dsi%d_pll_out_div_clk", pll_10nm->id); snprintf(parent, 32,
[PATCH AUTOSEL 4.9 05/10] drm/msm: Ratelimit invalid-fence message
From: Rob Clark [ Upstream commit 7ad48d27a2846bfda29214fb454d001c3e02b9e7 ] We have seen a couple cases where low memory situations cause something bad to happen, followed by a flood of these messages obscuring the root cause. Lets ratelimit the dmesg spam so that next time it happens we don't lose the kernel traces leading up to this. Signed-off-by: Rob Clark Reviewed-by: Douglas Anderson Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/msm_fence.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_fence.c b/drivers/gpu/drm/msm/msm_fence.c index a9b9b1c95a2e..9dbd17be51f7 100644 --- a/drivers/gpu/drm/msm/msm_fence.c +++ b/drivers/gpu/drm/msm/msm_fence.c @@ -56,7 +56,7 @@ int msm_wait_fence(struct msm_fence_context *fctx, uint32_t fence, int ret; if (fence > fctx->last_fence) { - DRM_ERROR("%s: waiting on invalid fence: %u (of %u)\n", + DRM_ERROR_RATELIMITED("%s: waiting on invalid fence: %u (of %u)\n", fctx->name, fence, fctx->last_fence); return -EINVAL; } -- 2.30.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH AUTOSEL 4.14 06/12] drm/msm: Ratelimit invalid-fence message
From: Rob Clark [ Upstream commit 7ad48d27a2846bfda29214fb454d001c3e02b9e7 ] We have seen a couple cases where low memory situations cause something bad to happen, followed by a flood of these messages obscuring the root cause. Lets ratelimit the dmesg spam so that next time it happens we don't lose the kernel traces leading up to this. Signed-off-by: Rob Clark Reviewed-by: Douglas Anderson Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/msm_fence.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_fence.c b/drivers/gpu/drm/msm/msm_fence.c index a2f89bac9c16..4c0ac0360b93 100644 --- a/drivers/gpu/drm/msm/msm_fence.c +++ b/drivers/gpu/drm/msm/msm_fence.c @@ -56,7 +56,7 @@ int msm_wait_fence(struct msm_fence_context *fctx, uint32_t fence, int ret; if (fence > fctx->last_fence) { - DRM_ERROR("%s: waiting on invalid fence: %u (of %u)\n", + DRM_ERROR_RATELIMITED("%s: waiting on invalid fence: %u (of %u)\n", fctx->name, fence, fctx->last_fence); return -EINVAL; } -- 2.30.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH AUTOSEL 4.19 08/15] drm/msm: Ratelimit invalid-fence message
From: Rob Clark [ Upstream commit 7ad48d27a2846bfda29214fb454d001c3e02b9e7 ] We have seen a couple cases where low memory situations cause something bad to happen, followed by a flood of these messages obscuring the root cause. Lets ratelimit the dmesg spam so that next time it happens we don't lose the kernel traces leading up to this. Signed-off-by: Rob Clark Reviewed-by: Douglas Anderson Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/msm_fence.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_fence.c b/drivers/gpu/drm/msm/msm_fence.c index 349c12f670eb..6c11be79574e 100644 --- a/drivers/gpu/drm/msm/msm_fence.c +++ b/drivers/gpu/drm/msm/msm_fence.c @@ -56,7 +56,7 @@ int msm_wait_fence(struct msm_fence_context *fctx, uint32_t fence, int ret; if (fence > fctx->last_fence) { - DRM_ERROR("%s: waiting on invalid fence: %u (of %u)\n", + DRM_ERROR_RATELIMITED("%s: waiting on invalid fence: %u (of %u)\n", fctx->name, fence, fctx->last_fence); return -EINVAL; } -- 2.30.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH AUTOSEL 5.4 11/19] drm/msm: Ratelimit invalid-fence message
From: Rob Clark [ Upstream commit 7ad48d27a2846bfda29214fb454d001c3e02b9e7 ] We have seen a couple cases where low memory situations cause something bad to happen, followed by a flood of these messages obscuring the root cause. Lets ratelimit the dmesg spam so that next time it happens we don't lose the kernel traces leading up to this. Signed-off-by: Rob Clark Reviewed-by: Douglas Anderson Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/msm_fence.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_fence.c b/drivers/gpu/drm/msm/msm_fence.c index ad2703698b05..cd59a5918038 100644 --- a/drivers/gpu/drm/msm/msm_fence.c +++ b/drivers/gpu/drm/msm/msm_fence.c @@ -45,7 +45,7 @@ int msm_wait_fence(struct msm_fence_context *fctx, uint32_t fence, int ret; if (fence > fctx->last_fence) { - DRM_ERROR("%s: waiting on invalid fence: %u (of %u)\n", + DRM_ERROR_RATELIMITED("%s: waiting on invalid fence: %u (of %u)\n", fctx->name, fence, fctx->last_fence); return -EINVAL; } -- 2.30.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH AUTOSEL 5.4 10/19] drm/msm/adreno: a5xx_power: Don't apply A540 lm_setup to other GPUs
From: Konrad Dybcio [ Upstream commit 4a9d36b0610aa7034340e976652e5b43320dd7c5 ] While passing the A530-specific lm_setup func to A530 and A540 to !A530 was fine back when only these two were supported, it certainly is not a good idea to send A540 specifics to smaller GPUs like A508 and friends. Signed-off-by: Konrad Dybcio Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/adreno/a5xx_power.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_power.c b/drivers/gpu/drm/msm/adreno/a5xx_power.c index a3a06db675ba..ee3ff32da004 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_power.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_power.c @@ -300,7 +300,7 @@ int a5xx_power_init(struct msm_gpu *gpu) /* Set up the limits management */ if (adreno_is_a530(adreno_gpu)) a530_lm_setup(gpu); - else + else if (adreno_is_a540(adreno_gpu)) a540_lm_setup(gpu); /* Set up SP/TP power collpase */ -- 2.30.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH AUTOSEL 5.10 21/33] drm/msm/disp/dpu1: icc path needs to be set before dpu runtime resume
From: Kalyan Thota [ Upstream commit 627dc55c273dab308303a5217bd3e767d7083ddb ] DPU runtime resume will request for a min vote on the AXI bus as it is a necessary step before turning ON the AXI clock. The change does below 1) Move the icc path set before requesting runtime get_sync. 2) remove the dependency of hw catalog for min ib vote as it is initialized at a later point. Signed-off-by: Kalyan Thota Tested-by: Matthias Kaehlcke Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 12 +++- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index d93c44f6996d..e69ea810e18d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -43,6 +43,8 @@ #define DPU_DEBUGFS_DIR "msm_dpu" #define DPU_DEBUGFS_HWMASKNAME "hw_log_mask" +#define MIN_IB_BW 4ULL /* Min ib vote 400MB */ + static int dpu_kms_hw_init(struct msm_kms *kms); static void _dpu_kms_mmu_destroy(struct dpu_kms *dpu_kms); @@ -929,6 +931,9 @@ static int dpu_kms_hw_init(struct msm_kms *kms) DPU_DEBUG("REG_DMA is not defined"); } + if (of_device_is_compatible(dev->dev->of_node, "qcom,sc7180-mdss")) + dpu_kms_parse_data_bus_icc_path(dpu_kms); + pm_runtime_get_sync(_kms->pdev->dev); dpu_kms->core_rev = readl_relaxed(dpu_kms->mmio + 0x0); @@ -1030,9 +1035,6 @@ static int dpu_kms_hw_init(struct msm_kms *kms) dpu_vbif_init_memtypes(dpu_kms); - if (of_device_is_compatible(dev->dev->of_node, "qcom,sc7180-mdss")) - dpu_kms_parse_data_bus_icc_path(dpu_kms); - pm_runtime_put_sync(_kms->pdev->dev); return 0; @@ -1189,10 +1191,10 @@ static int __maybe_unused dpu_runtime_resume(struct device *dev) ddev = dpu_kms->dev; + WARN_ON(!(dpu_kms->num_paths)); /* Min vote of BW is required before turning on AXI clk */ for (i = 0; i < dpu_kms->num_paths; i++) - icc_set_bw(dpu_kms->path[i], 0, - dpu_kms->catalog->perf.min_dram_ib); + icc_set_bw(dpu_kms->path[i], 0, Bps_to_icc(MIN_IB_BW)); rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, true); if (rc) { -- 2.30.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH AUTOSEL 5.10 15/33] drm/msm: Ratelimit invalid-fence message
From: Rob Clark [ Upstream commit 7ad48d27a2846bfda29214fb454d001c3e02b9e7 ] We have seen a couple cases where low memory situations cause something bad to happen, followed by a flood of these messages obscuring the root cause. Lets ratelimit the dmesg spam so that next time it happens we don't lose the kernel traces leading up to this. Signed-off-by: Rob Clark Reviewed-by: Douglas Anderson Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/msm_fence.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_fence.c b/drivers/gpu/drm/msm/msm_fence.c index ad2703698b05..cd59a5918038 100644 --- a/drivers/gpu/drm/msm/msm_fence.c +++ b/drivers/gpu/drm/msm/msm_fence.c @@ -45,7 +45,7 @@ int msm_wait_fence(struct msm_fence_context *fctx, uint32_t fence, int ret; if (fence > fctx->last_fence) { - DRM_ERROR("%s: waiting on invalid fence: %u (of %u)\n", + DRM_ERROR_RATELIMITED("%s: waiting on invalid fence: %u (of %u)\n", fctx->name, fence, fctx->last_fence); return -EINVAL; } -- 2.30.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH AUTOSEL 5.10 14/33] drm/msm/adreno: a5xx_power: Don't apply A540 lm_setup to other GPUs
From: Konrad Dybcio [ Upstream commit 4a9d36b0610aa7034340e976652e5b43320dd7c5 ] While passing the A530-specific lm_setup func to A530 and A540 to !A530 was fine back when only these two were supported, it certainly is not a good idea to send A540 specifics to smaller GPUs like A508 and friends. Signed-off-by: Konrad Dybcio Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/adreno/a5xx_power.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_power.c b/drivers/gpu/drm/msm/adreno/a5xx_power.c index f176a6f3eff6..e58670a61df4 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_power.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_power.c @@ -304,7 +304,7 @@ int a5xx_power_init(struct msm_gpu *gpu) /* Set up the limits management */ if (adreno_is_a530(adreno_gpu)) a530_lm_setup(gpu); - else + else if (adreno_is_a540(adreno_gpu)) a540_lm_setup(gpu); /* Set up SP/TP power collpase */ -- 2.30.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH AUTOSEL 5.10 13/33] drm/msm/dsi_pll_7nm: Fix variable usage for pll_lockdet_rate
From: Dmitry Baryshkov [ Upstream commit 9daaf31307856defb1070685418ce5a484ecda3a ] The PLL_LOCKDET_RATE_1 was being programmed with a hardcoded value directly, but the same value was also being specified in the dsi_pll_regs struct pll_lockdet_rate variable: let's use it! Based on 362cadf34b9f ("drm/msm/dsi_pll_10nm: Fix variable usage for pll_lockdet_rate") Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/dsi/pll/dsi_pll_7nm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_7nm.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_7nm.c index 93bf142e4a4e..901e8b8819d3 100644 --- a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_7nm.c +++ b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_7nm.c @@ -325,7 +325,7 @@ static void dsi_pll_commit(struct dsi_pll_7nm *pll) pll_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_LOW_1, reg->frac_div_start_low); pll_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_MID_1, reg->frac_div_start_mid); pll_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_HIGH_1, reg->frac_div_start_high); - pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCKDET_RATE_1, 0x40); + pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCKDET_RATE_1, reg->pll_lockdet_rate); pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCK_DELAY, 0x06); pll_write(base + REG_DSI_7nm_PHY_PLL_CMODE_1, 0x10); /* TODO: 0x00 for CPHY */ pll_write(base + REG_DSI_7nm_PHY_PLL_CLOCK_INVERTERS, reg->pll_clock_inverters); -- 2.30.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH AUTOSEL 5.11 24/38] drm/msm/disp/dpu1: icc path needs to be set before dpu runtime resume
From: Kalyan Thota [ Upstream commit 627dc55c273dab308303a5217bd3e767d7083ddb ] DPU runtime resume will request for a min vote on the AXI bus as it is a necessary step before turning ON the AXI clock. The change does below 1) Move the icc path set before requesting runtime get_sync. 2) remove the dependency of hw catalog for min ib vote as it is initialized at a later point. Signed-off-by: Kalyan Thota Tested-by: Matthias Kaehlcke Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 12 +++- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 374b0e8471e6..0f1b04ef61f2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -43,6 +43,8 @@ #define DPU_DEBUGFS_DIR "msm_dpu" #define DPU_DEBUGFS_HWMASKNAME "hw_log_mask" +#define MIN_IB_BW 4ULL /* Min ib vote 400MB */ + static int dpu_kms_hw_init(struct msm_kms *kms); static void _dpu_kms_mmu_destroy(struct dpu_kms *dpu_kms); @@ -931,6 +933,9 @@ static int dpu_kms_hw_init(struct msm_kms *kms) DPU_DEBUG("REG_DMA is not defined"); } + if (of_device_is_compatible(dev->dev->of_node, "qcom,sc7180-mdss")) + dpu_kms_parse_data_bus_icc_path(dpu_kms); + pm_runtime_get_sync(_kms->pdev->dev); dpu_kms->core_rev = readl_relaxed(dpu_kms->mmio + 0x0); @@ -1032,9 +1037,6 @@ static int dpu_kms_hw_init(struct msm_kms *kms) dpu_vbif_init_memtypes(dpu_kms); - if (of_device_is_compatible(dev->dev->of_node, "qcom,sc7180-mdss")) - dpu_kms_parse_data_bus_icc_path(dpu_kms); - pm_runtime_put_sync(_kms->pdev->dev); return 0; @@ -1191,10 +1193,10 @@ static int __maybe_unused dpu_runtime_resume(struct device *dev) ddev = dpu_kms->dev; + WARN_ON(!(dpu_kms->num_paths)); /* Min vote of BW is required before turning on AXI clk */ for (i = 0; i < dpu_kms->num_paths; i++) - icc_set_bw(dpu_kms->path[i], 0, - dpu_kms->catalog->perf.min_dram_ib); + icc_set_bw(dpu_kms->path[i], 0, Bps_to_icc(MIN_IB_BW)); rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, true); if (rc) { -- 2.30.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH AUTOSEL 5.11 17/38] drm/msm/adreno: a5xx_power: Don't apply A540 lm_setup to other GPUs
From: Konrad Dybcio [ Upstream commit 4a9d36b0610aa7034340e976652e5b43320dd7c5 ] While passing the A530-specific lm_setup func to A530 and A540 to !A530 was fine back when only these two were supported, it certainly is not a good idea to send A540 specifics to smaller GPUs like A508 and friends. Signed-off-by: Konrad Dybcio Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/adreno/a5xx_power.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_power.c b/drivers/gpu/drm/msm/adreno/a5xx_power.c index f176a6f3eff6..e58670a61df4 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_power.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_power.c @@ -304,7 +304,7 @@ int a5xx_power_init(struct msm_gpu *gpu) /* Set up the limits management */ if (adreno_is_a530(adreno_gpu)) a530_lm_setup(gpu); - else + else if (adreno_is_a540(adreno_gpu)) a540_lm_setup(gpu); /* Set up SP/TP power collpase */ -- 2.30.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH AUTOSEL 5.11 18/38] drm/msm: Ratelimit invalid-fence message
From: Rob Clark [ Upstream commit 7ad48d27a2846bfda29214fb454d001c3e02b9e7 ] We have seen a couple cases where low memory situations cause something bad to happen, followed by a flood of these messages obscuring the root cause. Lets ratelimit the dmesg spam so that next time it happens we don't lose the kernel traces leading up to this. Signed-off-by: Rob Clark Reviewed-by: Douglas Anderson Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/msm_fence.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_fence.c b/drivers/gpu/drm/msm/msm_fence.c index ad2703698b05..cd59a5918038 100644 --- a/drivers/gpu/drm/msm/msm_fence.c +++ b/drivers/gpu/drm/msm/msm_fence.c @@ -45,7 +45,7 @@ int msm_wait_fence(struct msm_fence_context *fctx, uint32_t fence, int ret; if (fence > fctx->last_fence) { - DRM_ERROR("%s: waiting on invalid fence: %u (of %u)\n", + DRM_ERROR_RATELIMITED("%s: waiting on invalid fence: %u (of %u)\n", fctx->name, fence, fctx->last_fence); return -EINVAL; } -- 2.30.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH AUTOSEL 5.11 16/38] drm/msm/dsi_pll_7nm: Fix variable usage for pll_lockdet_rate
From: Dmitry Baryshkov [ Upstream commit 9daaf31307856defb1070685418ce5a484ecda3a ] The PLL_LOCKDET_RATE_1 was being programmed with a hardcoded value directly, but the same value was also being specified in the dsi_pll_regs struct pll_lockdet_rate variable: let's use it! Based on 362cadf34b9f ("drm/msm/dsi_pll_10nm: Fix variable usage for pll_lockdet_rate") Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/dsi/pll/dsi_pll_7nm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_7nm.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_7nm.c index 93bf142e4a4e..901e8b8819d3 100644 --- a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_7nm.c +++ b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_7nm.c @@ -325,7 +325,7 @@ static void dsi_pll_commit(struct dsi_pll_7nm *pll) pll_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_LOW_1, reg->frac_div_start_low); pll_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_MID_1, reg->frac_div_start_mid); pll_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_HIGH_1, reg->frac_div_start_high); - pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCKDET_RATE_1, 0x40); + pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCKDET_RATE_1, reg->pll_lockdet_rate); pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCK_DELAY, 0x06); pll_write(base + REG_DSI_7nm_PHY_PLL_CMODE_1, 0x10); /* TODO: 0x00 for CPHY */ pll_write(base + REG_DSI_7nm_PHY_PLL_CLOCK_INVERTERS, reg->pll_clock_inverters); -- 2.30.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH AUTOSEL 5.11 03/38] drm/msm: a6xx: Make sure the SQE microcode is safe
From: Jordan Crouse [ Upstream commit 8490f02a3ca45fd1bbcadc243b4db9b69d0e3450 ] Most a6xx targets have security issues that were fixed with new versions of the microcode(s). Make sure that we are booting with a safe version of the microcode for the target and print a message and error if not. v2: Add more informative error messages and fix typos Signed-off-by: Jordan Crouse Reviewed-by: Akhil P Oommen Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 77 ++- 1 file changed, 64 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 0366419d8bfe..e7a8442b59af 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -521,28 +521,73 @@ static int a6xx_cp_init(struct msm_gpu *gpu) return a6xx_idle(gpu, ring) ? 0 : -EINVAL; } -static void a6xx_ucode_check_version(struct a6xx_gpu *a6xx_gpu, +/* + * Check that the microcode version is new enough to include several key + * security fixes. Return true if the ucode is safe. + */ +static bool a6xx_ucode_check_version(struct a6xx_gpu *a6xx_gpu, struct drm_gem_object *obj) { + struct adreno_gpu *adreno_gpu = _gpu->base; + struct msm_gpu *gpu = _gpu->base; u32 *buf = msm_gem_get_vaddr(obj); + bool ret = false; if (IS_ERR(buf)) - return; + return false; /* -* If the lowest nibble is 0xa that is an indication that this microcode -* has been patched. The actual version is in dword [3] but we only care -* about the patchlevel which is the lowest nibble of dword [3] -* -* Otherwise check that the firmware is greater than or equal to 1.90 -* which was the first version that had this fix built in +* Targets up to a640 (a618, a630 and a640) need to check for a +* microcode version that is patched to support the whereami opcode or +* one that is new enough to include it by default. */ - if (((buf[0] & 0xf) == 0xa) && (buf[2] & 0xf) >= 1) - a6xx_gpu->has_whereami = true; - else if ((buf[0] & 0xfff) > 0x190) - a6xx_gpu->has_whereami = true; + if (adreno_is_a618(adreno_gpu) || adreno_is_a630(adreno_gpu) || + adreno_is_a640(adreno_gpu)) { + /* +* If the lowest nibble is 0xa that is an indication that this +* microcode has been patched. The actual version is in dword +* [3] but we only care about the patchlevel which is the lowest +* nibble of dword [3] +* +* Otherwise check that the firmware is greater than or equal +* to 1.90 which was the first version that had this fix built +* in +*/ + if buf[0] & 0xf) == 0xa) && (buf[2] & 0xf) >= 1) || + (buf[0] & 0xfff) >= 0x190) { + a6xx_gpu->has_whereami = true; + ret = true; + goto out; + } + DRM_DEV_ERROR(>pdev->dev, + "a630 SQE ucode is too old. Have version %x need at least %x\n", + buf[0] & 0xfff, 0x190); + } else { + /* +* a650 tier targets don't need whereami but still need to be +* equal to or newer than 1.95 for other security fixes +*/ + if (adreno_is_a650(adreno_gpu)) { + if ((buf[0] & 0xfff) >= 0x195) { + ret = true; + goto out; + } + + DRM_DEV_ERROR(>pdev->dev, + "a650 SQE ucode is too old. Have version %x need at least %x\n", + buf[0] & 0xfff, 0x195); + } + + /* +* When a660 is added those targets should return true here +* since those have all the critical security fixes built in +* from the start +*/ + } +out: msm_gem_put_vaddr(obj); + return ret; } static int a6xx_ucode_init(struct msm_gpu *gpu) @@ -565,7 +610,13 @@ static int a6xx_ucode_init(struct msm_gpu *gpu) } msm_gem_object_set_name(a6xx_gpu->sqe_bo, "sqefw"); - a6xx_ucode_check_version(a6xx_gpu, a6xx_gpu->sqe_bo); + if (!a6xx_ucode_check_version(a6xx_gpu, a6xx_gpu->sqe_bo)) { + msm_gem_unpin_iova(a6xx_gpu->sqe_bo, gpu->aspace); + drm_gem_object_put(a6xx_gpu->sqe_bo); + + a6xx_gpu->sqe_bo = NULL; + return -EPERM; + } } gpu_write64(gpu,
Re: [Freedreno] [PATCH v3 11/25] drm/msm/dsi: push provided clocks handling into a generic code
On 2021-03-27 04:02, Dmitry Baryshkov wrote: All MSM DSI PHYs provide two clocks: byte and pixel ones. Register/unregister provided clocks from the generic place, removing boilerplate code from all MSM DSI PHY drivers. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/dsi/dsi.h | 11 +--- drivers/gpu/drm/msm/dsi/dsi_host.c| 4 +- drivers/gpu/drm/msm/dsi/dsi_manager.c | 13 +--- drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 34 ++ drivers/gpu/drm/msm/dsi/phy/dsi_phy.h | 9 ++- drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c| 55 ++-- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c| 53 ++-- drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c| 63 +++ .../gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c | 57 +++-- drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 55 ++-- drivers/gpu/drm/msm/dsi/phy/dsi_pll.c | 16 + drivers/gpu/drm/msm/dsi/phy/dsi_pll.h | 3 +- 12 files changed, 78 insertions(+), 295 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h index b310cf344ed4..43590f338d20 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.h +++ b/drivers/gpu/drm/msm/dsi/dsi.h @@ -96,19 +96,12 @@ struct drm_encoder *msm_dsi_get_encoder(struct msm_dsi *msm_dsi); struct msm_dsi_pll; #ifdef CONFIG_DRM_MSM_DSI_PLL void msm_dsi_pll_destroy(struct msm_dsi_pll *pll); -int msm_dsi_pll_get_clk_provider(struct msm_dsi_pll *pll, - struct clk **byte_clk_provider, struct clk **pixel_clk_provider); void msm_dsi_pll_save_state(struct msm_dsi_pll *pll); int msm_dsi_pll_restore_state(struct msm_dsi_pll *pll); #else static inline void msm_dsi_pll_destroy(struct msm_dsi_pll *pll) { } -static inline int msm_dsi_pll_get_clk_provider(struct msm_dsi_pll *pll, - struct clk **byte_clk_provider, struct clk **pixel_clk_provider) -{ - return -ENODEV; -} static inline void msm_dsi_pll_save_state(struct msm_dsi_pll *pll) { } @@ -144,7 +137,7 @@ struct drm_bridge *msm_dsi_host_get_bridge(struct mipi_dsi_host *host); int msm_dsi_host_register(struct mipi_dsi_host *host, bool check_defer); void msm_dsi_host_unregister(struct mipi_dsi_host *host); int msm_dsi_host_set_src_pll(struct mipi_dsi_host *host, - struct msm_dsi_pll *src_pll); + struct msm_dsi_phy *src_phy); void msm_dsi_host_reset_phy(struct mipi_dsi_host *host); void msm_dsi_host_get_phy_clk_req(struct mipi_dsi_host *host, struct msm_dsi_phy_clk_request *clk_req, @@ -196,6 +189,8 @@ void msm_dsi_phy_get_shared_timings(struct msm_dsi_phy *phy, struct msm_dsi_pll *msm_dsi_phy_get_pll(struct msm_dsi_phy *phy); void msm_dsi_phy_set_usecase(struct msm_dsi_phy *phy, enum msm_dsi_phy_usecase uc); +int msm_dsi_phy_get_clk_provider(struct msm_dsi_phy *phy, + struct clk **byte_clk_provider, struct clk **pixel_clk_provider); #endif /* __DSI_CONNECTOR_H__ */ diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index ab281cba0f08..41e1d0f7ab6e 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -2226,13 +2226,13 @@ void msm_dsi_host_cmd_xfer_commit(struct mipi_dsi_host *host, u32 dma_base, } int msm_dsi_host_set_src_pll(struct mipi_dsi_host *host, - struct msm_dsi_pll *src_pll) + struct msm_dsi_phy *src_phy) { struct msm_dsi_host *msm_host = to_msm_dsi_host(host); struct clk *byte_clk_provider, *pixel_clk_provider; int ret; - ret = msm_dsi_pll_get_clk_provider(src_pll, + ret = msm_dsi_phy_get_clk_provider(src_phy, _clk_provider, _clk_provider); if (ret) { pr_info("%s: can't get provider from pll, don't set parent\n", diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c index 1d28dfba2c9b..86e36be58701 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c @@ -70,7 +70,6 @@ static int dsi_mgr_setup_components(int id) struct msm_dsi *other_dsi = dsi_mgr_get_other_dsi(id); struct msm_dsi *clk_master_dsi = dsi_mgr_get_dsi(DSI_CLOCK_MASTER); struct msm_dsi *clk_slave_dsi = dsi_mgr_get_dsi(DSI_CLOCK_SLAVE); - struct msm_dsi_pll *src_pll; int ret; if (!IS_DUAL_DSI()) { @@ -79,10 +78,7 @@ static int dsi_mgr_setup_components(int id) return ret; msm_dsi_phy_set_usecase(msm_dsi->phy, MSM_DSI_PHY_STANDALONE); - src_pll = msm_dsi_phy_get_pll(msm_dsi->phy); - if (IS_ERR(src_pll)) - return PTR_ERR(src_pll); - ret = msm_dsi_host_set_src_pll(msm_dsi->host, src_pll); + ret = msm_dsi_host_set_src_pll(msm_dsi->host, msm_dsi->phy); } else if (!other_dsi) {
Re: [PATCH v3 01/25] clk: fixed: add devm helper for clk_hw_register_fixed_factor()
On 2021-03-27 04:02, Dmitry Baryshkov wrote: From: Daniel Palmer Add a devm helper for clk_hw_register_fixed_factor() so that drivers that internally register fixed factor clocks for things like dividers don't need to manually unregister them on remove or if probe fails. Signed-off-by: Daniel Palmer Link: https://lore.kernel.org/r/20210211052206.2955988-4-dan...@0x0f.com Signed-off-by: Stephen Boyd Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/clk/clk-fixed-factor.c | 39 -- include/linux/clk-provider.h | 4 +++- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c index 910e6e74ae90..4f7bf3929d6d 100644 --- a/drivers/clk/clk-fixed-factor.c +++ b/drivers/clk/clk-fixed-factor.c @@ -64,10 +64,16 @@ const struct clk_ops clk_fixed_factor_ops = { }; EXPORT_SYMBOL_GPL(clk_fixed_factor_ops); +static void devm_clk_hw_register_fixed_factor_release(struct device *dev, void *res) +{ + clk_hw_unregister_fixed_factor(&((struct clk_fixed_factor *)res)->hw); +} + static struct clk_hw * __clk_hw_register_fixed_factor(struct device *dev, struct device_node *np, const char *name, const char *parent_name, int index, - unsigned long flags, unsigned int mult, unsigned int div) + unsigned long flags, unsigned int mult, unsigned int div, + bool devm) { struct clk_fixed_factor *fix; struct clk_init_data init = { }; @@ -75,7 +81,15 @@ __clk_hw_register_fixed_factor(struct device *dev, struct device_node *np, struct clk_hw *hw; int ret; - fix = kmalloc(sizeof(*fix), GFP_KERNEL); + /* You can't use devm without a dev */ + if (devm && !dev) + return ERR_PTR(-EINVAL); + + if (devm) + fix = devres_alloc(devm_clk_hw_register_fixed_factor_release, + sizeof(*fix), GFP_KERNEL); + else + fix = kmalloc(sizeof(*fix), GFP_KERNEL); if (!fix) return ERR_PTR(-ENOMEM); @@ -99,9 +113,13 @@ __clk_hw_register_fixed_factor(struct device *dev, struct device_node *np, else ret = of_clk_hw_register(np, hw); if (ret) { - kfree(fix); + if (devm) + devres_free(fix); + else + kfree(fix); hw = ERR_PTR(ret); - } + } else if (devm) + devres_add(dev, fix); return hw; } @@ -111,7 +129,7 @@ struct clk_hw *clk_hw_register_fixed_factor(struct device *dev, unsigned int mult, unsigned int div) { return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, -1, - flags, mult, div); + flags, mult, div, false); } EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor); @@ -153,6 +171,15 @@ void clk_hw_unregister_fixed_factor(struct clk_hw *hw) } EXPORT_SYMBOL_GPL(clk_hw_unregister_fixed_factor); +struct clk_hw *devm_clk_hw_register_fixed_factor(struct device *dev, + const char *name, const char *parent_name, unsigned long flags, + unsigned int mult, unsigned int div) +{ + return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, -1, + flags, mult, div, true); +} +EXPORT_SYMBOL_GPL(devm_clk_hw_register_fixed_factor); + #ifdef CONFIG_OF static const struct of_device_id set_rate_parent_matches[] = { { .compatible = "allwinner,sun4i-a10-pll3-2x-clk" }, @@ -185,7 +212,7 @@ static struct clk_hw *_of_fixed_factor_clk_setup(struct device_node *node) flags |= CLK_SET_RATE_PARENT; hw = __clk_hw_register_fixed_factor(NULL, node, clk_name, NULL, 0, - flags, mult, div); + flags, mult, div, false); if (IS_ERR(hw)) { /* * Clear OF_POPULATED flag so that clock registration can be diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index e4316890661a..58f6fe866ae9 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -941,7 +941,9 @@ struct clk_hw *clk_hw_register_fixed_factor(struct device *dev, const char *name, const char *parent_name, unsigned long flags, unsigned int mult, unsigned int div); void clk_hw_unregister_fixed_factor(struct clk_hw *hw); - +struct clk_hw *devm_clk_hw_register_fixed_factor(struct device *dev, + const char *name, const char *parent_name, unsigned long flags, + unsigned int mult, unsigned int div); /** * struct clk_fractional_divider - adjustable fractional divider clock * ___ dri-devel mailing list dri-devel@lists.freedesktop.org
Re: [PATCH v6 04/10] gpu: host1x: Remove cancelled waiters immediately
On 3/29/21 11:27 PM, Dmitry Osipenko wrote: 29.03.2021 16:38, Mikko Perttunen пишет: Before this patch, cancelled waiters would only be cleaned up once their threshold value was reached. Make host1x_intr_put_ref process the cancellation immediately to fix this. Signed-off-by: Mikko Perttunen --- v6: * Call schedule instead of cpu_relax while waiting for pending interrupt processing v5: * Add parameter to flush, i.e. wait for all pending waiters to complete before returning. The reason this is not always true is that the pending waiter might be the place that is calling the put_ref. --- drivers/gpu/host1x/intr.c | 23 +-- drivers/gpu/host1x/intr.h | 4 +++- drivers/gpu/host1x/syncpt.c | 2 +- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/host1x/intr.c b/drivers/gpu/host1x/intr.c index 9245add23b5d..69b0e8e41466 100644 --- a/drivers/gpu/host1x/intr.c +++ b/drivers/gpu/host1x/intr.c @@ -242,18 +242,29 @@ int host1x_intr_add_action(struct host1x *host, struct host1x_syncpt *syncpt, return 0; } -void host1x_intr_put_ref(struct host1x *host, unsigned int id, void *ref) +void host1x_intr_put_ref(struct host1x *host, unsigned int id, void *ref, +bool flush) { struct host1x_waitlist *waiter = ref; struct host1x_syncpt *syncpt; - while (atomic_cmpxchg(>state, WLS_PENDING, WLS_CANCELLED) == - WLS_REMOVED) - schedule(); + atomic_cmpxchg(>state, WLS_PENDING, WLS_CANCELLED); syncpt = host->syncpt + id; - (void)process_wait_list(host, syncpt, - host1x_syncpt_load(host->syncpt + id)); + + spin_lock(>intr.lock); + if (atomic_cmpxchg(>state, WLS_CANCELLED, WLS_HANDLED) == + WLS_CANCELLED) { + list_del(>list); + kref_put(>refcount, waiter_release); + } + spin_unlock(>intr.lock); Looks like we need to use IRQ-safe version of the locking here in order not to race with the interrupt handler(?), preventing lockup. The potential contention is with the syncpt_thresh_work scheduled work, and not the actual interrupt handler, so there is no issue. But what real bug is fixed by this patch? If no real problem is fixed, then maybe will be better to defer touching this code till we will just replace it all with a proper dma-fence handlers? It improves things in that we won't litter the waiter data structures with unbounded waiter entries when waits are cancelled. Also, I prefer working in steps when possible - next is writing dma_fences on top of this (which is already done) and then eventually phasing/refactoring code from intr.c to fence.c so eventually only dma_fences remain. In my experience that works better than big rewrites. Mikko ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v6 04/10] gpu: host1x: Remove cancelled waiters immediately
29.03.2021 16:38, Mikko Perttunen пишет: > Before this patch, cancelled waiters would only be cleaned up > once their threshold value was reached. Make host1x_intr_put_ref > process the cancellation immediately to fix this. > > Signed-off-by: Mikko Perttunen > --- > v6: > * Call schedule instead of cpu_relax while waiting for pending > interrupt processing > v5: > * Add parameter to flush, i.e. wait for all pending waiters to > complete before returning. The reason this is not always true > is that the pending waiter might be the place that is calling > the put_ref. > --- > drivers/gpu/host1x/intr.c | 23 +-- > drivers/gpu/host1x/intr.h | 4 +++- > drivers/gpu/host1x/syncpt.c | 2 +- > 3 files changed, 21 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/host1x/intr.c b/drivers/gpu/host1x/intr.c > index 9245add23b5d..69b0e8e41466 100644 > --- a/drivers/gpu/host1x/intr.c > +++ b/drivers/gpu/host1x/intr.c > @@ -242,18 +242,29 @@ int host1x_intr_add_action(struct host1x *host, struct > host1x_syncpt *syncpt, > return 0; > } > > -void host1x_intr_put_ref(struct host1x *host, unsigned int id, void *ref) > +void host1x_intr_put_ref(struct host1x *host, unsigned int id, void *ref, > + bool flush) > { > struct host1x_waitlist *waiter = ref; > struct host1x_syncpt *syncpt; > > - while (atomic_cmpxchg(>state, WLS_PENDING, WLS_CANCELLED) == > -WLS_REMOVED) > - schedule(); > + atomic_cmpxchg(>state, WLS_PENDING, WLS_CANCELLED); > > syncpt = host->syncpt + id; > - (void)process_wait_list(host, syncpt, > - host1x_syncpt_load(host->syncpt + id)); > + > + spin_lock(>intr.lock); > + if (atomic_cmpxchg(>state, WLS_CANCELLED, WLS_HANDLED) == > + WLS_CANCELLED) { > + list_del(>list); > + kref_put(>refcount, waiter_release); > + } > + spin_unlock(>intr.lock); Looks like we need to use IRQ-safe version of the locking here in order not to race with the interrupt handler(?), preventing lockup. But what real bug is fixed by this patch? If no real problem is fixed, then maybe will be better to defer touching this code till we will just replace it all with a proper dma-fence handlers? ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 8/8] drm/displayid: rename displayid_hdr to displayid_header
On Mon, Mar 29, 2021 at 04:37:22PM +0300, Jani Nikula wrote: > Avoid any confusion with High Dynamic Range. No functional changes. > > Signed-off-by: Jani Nikula Reviewed-by: Ville Syrjälä > --- > drivers/gpu/drm/drm_displayid.c | 10 +- > include/drm/drm_displayid.h | 2 +- > 2 files changed, 6 insertions(+), 6 deletions(-) > > diff --git a/drivers/gpu/drm/drm_displayid.c b/drivers/gpu/drm/drm_displayid.c > index e0b9e58a9dc8..32da557b960f 100644 > --- a/drivers/gpu/drm/drm_displayid.c > +++ b/drivers/gpu/drm/drm_displayid.c > @@ -11,9 +11,9 @@ static int validate_displayid(const u8 *displayid, int > length, int idx) > { > int i, dispid_length; > u8 csum = 0; > - const struct displayid_hdr *base; > + const struct displayid_header *base; > > - base = (const struct displayid_hdr *)[idx]; > + base = (const struct displayid_header *)[idx]; > > DRM_DEBUG_KMS("base revision 0x%x, length %d, %d %d\n", > base->rev, base->bytes, base->prod_id, base->ext_count); > @@ -38,7 +38,7 @@ static const u8 *drm_find_displayid_extension(const struct > edid *edid, > int *ext_index) > { > const u8 *displayid = drm_find_edid_extension(edid, DISPLAYID_EXT, > ext_index); > - const struct displayid_hdr *base; > + const struct displayid_header *base; > int ret; > > if (!displayid) > @@ -52,7 +52,7 @@ static const u8 *drm_find_displayid_extension(const struct > edid *edid, > if (ret) > return NULL; > > - base = (const struct displayid_hdr *)[*idx]; > + base = (const struct displayid_header *)[*idx]; > *length = *idx + sizeof(*base) + base->bytes; > > return displayid; > @@ -118,7 +118,7 @@ __displayid_iter_next(struct displayid_iter *iter) > return NULL; > } > > - iter->idx += sizeof(struct displayid_hdr); > + iter->idx += sizeof(struct displayid_header); > > block = displayid_iter_block(iter); > if (block) > diff --git a/include/drm/drm_displayid.h b/include/drm/drm_displayid.h > index 10ee863f1734..ec64d141f578 100644 > --- a/include/drm/drm_displayid.h > +++ b/include/drm/drm_displayid.h > @@ -56,7 +56,7 @@ struct edid; > #define PRODUCT_TYPE_REPEATER 5 > #define PRODUCT_TYPE_DIRECT_DRIVE 6 > > -struct displayid_hdr { > +struct displayid_header { > u8 rev; > u8 bytes; > u8 prod_id; > -- > 2.20.1 -- Ville Syrjälä Intel ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 7/8] drm/displayid: allow data blocks with 0 payload length
On Mon, Mar 29, 2021 at 04:37:21PM +0300, Jani Nikula wrote: > The DisplayID specifications explicitly call out 0 as a valid payload > length for data blocks. The mere presence of a data block, or the > information coded in the block specific data (bits 7:3 in offset 1), may > be enough to convey the necessary information. > > Signed-off-by: Jani Nikula Reviewed-by: Ville Syrjälä Though after looking at the current users it looks to me like we're missing some block length checks. In particular drm_parse_tiled_block() looks suspect. Judging by what I wrote in cea_db_offsets() I think I once convinced myself that the CEA ext block stuff is safe. And add_displayid_detailed_1_modes() looks OK as well. > --- > drivers/gpu/drm/drm_displayid.c | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/drm_displayid.c b/drivers/gpu/drm/drm_displayid.c > index 902ff6114b68..e0b9e58a9dc8 100644 > --- a/drivers/gpu/drm/drm_displayid.c > +++ b/drivers/gpu/drm/drm_displayid.c > @@ -77,8 +77,7 @@ displayid_iter_block(const struct displayid_iter *iter) > block = (const struct displayid_block *)>section[iter->idx]; > > if (iter->idx + sizeof(*block) <= iter->length && > - iter->idx + sizeof(*block) + block->num_bytes <= iter->length && > - block->num_bytes > 0) > + iter->idx + sizeof(*block) + block->num_bytes <= iter->length) > return block; > > return NULL; > -- > 2.20.1 -- Ville Syrjälä Intel ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/amdgpu: fix an underflow on non-4KB-page systems
Am 29.03.21 um 21:27 schrieb Xi Ruoyao: Hi Christian, I don't think there is any constraint implemented to ensure `num_entries % AMDGPU_GPU_PAGES_IN_CPU_PAGE == 0`. For example, in `amdgpu_vm_bo_map()`: /* validate the parameters */ if (saddr & AMDGPU_GPU_PAGE_MASK || offset & AMDGPU_GPU_PAGE_MASK || size == 0 || size & AMDGPU_GPU_PAGE_MASK) return -EINVAL; /* snip */ saddr /= AMDGPU_GPU_PAGE_SIZE; eaddr /= AMDGPU_GPU_PAGE_SIZE; /* snip */ mapping->start = saddr; mapping->last = eaddr; If we really want to ensure (mapping->last - mapping->start + 1) % AMDGPU_GPU_PAGES_IN_CPU_PAGE == 0, then we should replace "AMDGPU_GPU_PAGE_MASK" in "validate the parameters" with "PAGE_MASK". Yeah, good point. I tried it and it broke userspace: Xorg startup fails with EINVAL with this change. Well in theory it is possible that we always fill the GPUVM on a 4k basis while the native page size of the CPU is larger. Let me double check the code. BTW: What code base are you based on? The code your post here is quite outdated. Christian. On 2021-03-30 02:30 +0800, Xi Ruoyao wrote: On 2021-03-30 02:21 +0800, Xi Ruoyao wrote: On 2021-03-29 20:10 +0200, Christian König wrote: You need to identify the root cause of this, most likely start or last are not a multiple of AMDGPU_GPU_PAGES_IN_CPU_PAGE. I printk'ed the value of start & last, they are all a multiple of 4 (AMDGPU_GPU_PAGES_IN_CPU_PAGE). However... `num_entries = last - start + 1` so it became some irrational thing... Either this line is wrong, or someone called amdgpu_vm_bo_update_mapping with [start, last) instead of [start, last], which is unexpected. I added BUG_ON(num_entries % AMDGPU_GPU_PAGES_IN_CPU_PAGE != 0), get: Mar 30 02:28:27 xry111-A1901 kernel: [] amdgpu_vm_bo_update_mapping.constprop.0+0x218/0xae8 Mar 30 02:28:27 xry111-A1901 kernel: [] amdgpu_vm_bo_update+0x270/0x4c0 Mar 30 02:28:27 xry111-A1901 kernel: [] amdgpu_gem_va_ioctl+0x40c/0x430 Mar 30 02:28:27 xry111-A1901 kernel: [] drm_ioctl_kernel+0xcc/0x120 Mar 30 02:28:27 xry111-A1901 kernel: [] drm_ioctl+0x220/0x408 Mar 30 02:28:27 xry111-A1901 kernel: [] amdgpu_drm_ioctl+0x58/0x98 Mar 30 02:28:27 xry111-A1901 kernel: [] sys_ioctl+0xcc/0xe8 Mar 30 02:28:27 xry111-A1901 kernel: [] syscall_common+0x34/0x58 BugLink: https://gitlab.freedesktop.org/drm/amd/-/issues/1549 Fixes: a39f2a8d7066 ("drm/amdgpu: nuke amdgpu_vm_bo_split_mapping v2") Reported-by: Xi Ruoyao Reported-by: Dan Horák Cc: sta...@vger.kernel.org Signed-off-by: Xi Ruoyao --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index ad91c0c3c423..cee0cc9c8085 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -1707,7 +1707,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, } start = tmp; - } while (unlikely(start != last + 1)); + } while (unlikely(start < last + 1)); r = vm->update_funcs->commit(, fence); base-commit: a5e13c6df0e41702d2b2c77c8ad41677ebb065b3 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v4 4/4] arm64: dts: qcom: sm8250: fix display nodes
Quoting Dmitry Baryshkov (2021-03-29 05:00:51) > From: Jonathan Marek > > - Use sm8250 compatibles instead of sdm845 compatibles > Does it need the " - " prefix? > Signed-off-by: Jonathan Marek > Signed-off-by: Dmitry Baryshkov > --- Reviewed-by: Stephen Boyd ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v4 2/4] dt-bindings: msm/disp: add compatibles for sm8150/sm8250 display
Quoting Dmitry Baryshkov (2021-03-29 05:00:49) > From: Jonathan Marek > > The driver already has support for sm8150/sm8250, but the compatibles were > never added. > > Signed-off-by: Jonathan Marek > Acked-by: Rob Herring > [DB: split dt-bindings into separate patch] > Signed-off-by: Dmitry Baryshkov > --- Reviewed-by: Stephen Boyd This will conflict with the yaml changes to this file that are also in flight. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v4 3/4] drm/msm: add compatibles for sm8150/sm8250 display
Quoting Dmitry Baryshkov (2021-03-29 05:00:50) > From: Jonathan Marek > > The driver already has support for sm8150/sm8250, but the compatibles were > never added. > > Also inverse the non-mdp4 condition in add_display_components() to avoid > having to check every new compatible in the condition. > > Signed-off-by: Jonathan Marek > Signed-off-by: Dmitry Baryshkov > --- Reviewed-by: Stephen Boyd ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v7 2/2] drm/tiny: add driver for newhaven,1.8-128160EF
This patch adds support for Newhaven's NHD-1.8-128160EF display, featuring an Ilitek ILI9163 controller. Signed-off-by: Daniel Mack Acked-by: Daniel Vetter --- drivers/gpu/drm/tiny/Kconfig | 13 ++ drivers/gpu/drm/tiny/Makefile | 1 + drivers/gpu/drm/tiny/ili9163.c | 224 + 3 files changed, 238 insertions(+) create mode 100644 drivers/gpu/drm/tiny/ili9163.c diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index 2b6414f0fa759..9de0c0eeea6f5 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -41,6 +41,19 @@ config TINYDRM_HX8357D If M is selected the module will be called hx8357d. +config TINYDRM_ILI9163 + tristate "DRM support for ILI9163 display panels" + depends on DRM && SPI + select DRM_KMS_HELPER + select DRM_KMS_CMA_HELPER + select DRM_MIPI_DBI + select BACKLIGHT_CLASS_DEVICE + help + DRM driver for the following Ilitek ILI9163 panels: + * NHD-1.8-128160EF 128x160 TFT + + If M is selected the module will be called ili9163. + config TINYDRM_ILI9225 tristate "DRM support for ILI9225 display panels" depends on DRM && SPI diff --git a/drivers/gpu/drm/tiny/Makefile b/drivers/gpu/drm/tiny/Makefile index 6ae4e9e5a35fb..78016b2ed11b5 100644 --- a/drivers/gpu/drm/tiny/Makefile +++ b/drivers/gpu/drm/tiny/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus.o obj-$(CONFIG_DRM_GM12U320) += gm12u320.o obj-$(CONFIG_TINYDRM_HX8357D) += hx8357d.o +obj-$(CONFIG_TINYDRM_ILI9163) += ili9163.o obj-$(CONFIG_TINYDRM_ILI9225) += ili9225.o obj-$(CONFIG_TINYDRM_ILI9341) += ili9341.o obj-$(CONFIG_TINYDRM_ILI9486) += ili9486.o diff --git a/drivers/gpu/drm/tiny/ili9163.c b/drivers/gpu/drm/tiny/ili9163.c new file mode 100644 index 0..6fa9e59b69321 --- /dev/null +++ b/drivers/gpu/drm/tiny/ili9163.c @@ -0,0 +1,224 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define ILI9163_FRMCTR10xb1 + +#define ILI9163_PWCTRL10xc0 +#define ILI9163_PWCTRL20xc1 +#define ILI9163_VMCTRL10xc5 +#define ILI9163_VMCTRL20xc7 +#define ILI9163_PWCTRLA0xcb +#define ILI9163_PWCTRLB0xcf + +#define ILI9163_EN3GAM 0xf2 + +#define ILI9163_MADCTL_BGR BIT(3) +#define ILI9163_MADCTL_MV BIT(5) +#define ILI9163_MADCTL_MX BIT(6) +#define ILI9163_MADCTL_MY BIT(7) + +static void yx240qv29_enable(struct drm_simple_display_pipe *pipe, +struct drm_crtc_state *crtc_state, +struct drm_plane_state *plane_state) +{ + struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(pipe->crtc.dev); + struct mipi_dbi *dbi = >dbi; + u8 addr_mode; + int ret, idx; + + if (!drm_dev_enter(pipe->crtc.dev, )) + return; + + drm_dbg_kms(>drm, "\n"); + + ret = mipi_dbi_poweron_conditional_reset(dbidev); + if (ret < 0) + goto out_exit; + if (ret == 1) + goto out_enable; + + /* Gamma */ + mipi_dbi_command(dbi, MIPI_DCS_SET_GAMMA_CURVE, 0x04); + mipi_dbi_command(dbi, ILI9163_EN3GAM, 0x00); + + /* Frame Rate */ + mipi_dbi_command(dbi, ILI9163_FRMCTR1, 0x0a, 0x14); + + /* Power Control */ + mipi_dbi_command(dbi, ILI9163_PWCTRL1, 0x0a, 0x00); + mipi_dbi_command(dbi, ILI9163_PWCTRL2, 0x02); + + /* VCOM */ + mipi_dbi_command(dbi, ILI9163_VMCTRL1, 0x2f, 0x3e); + mipi_dbi_command(dbi, ILI9163_VMCTRL2, 0x40); + + /* Memory Access Control */ + mipi_dbi_command(dbi, MIPI_DCS_SET_PIXEL_FORMAT, MIPI_DCS_PIXEL_FMT_16BIT); + + mipi_dbi_command(dbi, MIPI_DCS_EXIT_SLEEP_MODE); + msleep(100); + + mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_ON); + msleep(100); + +out_enable: + switch (dbidev->rotation) { + default: + addr_mode = 0; + break; + case 90: + addr_mode = ILI9163_MADCTL_MV | ILI9163_MADCTL_MX; + break; + case 180: + addr_mode = ILI9163_MADCTL_MX | ILI9163_MADCTL_MY; + break; + case 270: + addr_mode = ILI9163_MADCTL_MV | ILI9163_MADCTL_MY; + break; + } + addr_mode |= ILI9163_MADCTL_BGR; + mipi_dbi_command(dbi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode); + mipi_dbi_enable_flush(dbidev, crtc_state, plane_state); +out_exit: + drm_dev_exit(idx); +} + +static const struct drm_simple_display_pipe_funcs ili9163_pipe_funcs = { + .enable = yx240qv29_enable, + .disable = mipi_dbi_pipe_disable, + .update =
[PATCH v7 0/2] gpu: drm: add driver for ili9361 panel
This is v3 of the series. Changelog: v2 -> v3: * Turn Documentation into yaml format v3 -> v4: * Fix reference error in yaml file v4 -> v5: * More yaml file documentation fixes v5 -> v6: * More yaml file documentation fixes v6 -> v7: * Fix ordering of patches Daniel Mack (2): dt-bindings: display: add bindings for newhaven,1.8-128160EF drm/tiny: add driver for newhaven,1.8-128160EF .../display/panel/ilitek,ili9163.yaml | 69 +++ drivers/gpu/drm/tiny/Kconfig | 13 + drivers/gpu/drm/tiny/Makefile | 1 + drivers/gpu/drm/tiny/ili9163.c| 224 ++ 4 files changed, 307 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/ilitek,ili9163.yaml create mode 100644 drivers/gpu/drm/tiny/ili9163.c -- 2.29.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v7 1/2] dt-bindings: display: add bindings for newhaven, 1.8-128160EF
This adds documentation for a new ILI9163 based, SPI connected display. Signed-off-by: Daniel Mack --- .../display/panel/ilitek,ili9163.yaml | 69 +++ 1 file changed, 69 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/ilitek,ili9163.yaml diff --git a/Documentation/devicetree/bindings/display/panel/ilitek,ili9163.yaml b/Documentation/devicetree/bindings/display/panel/ilitek,ili9163.yaml new file mode 100644 index 0..fe612851e399a --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/ilitek,ili9163.yaml @@ -0,0 +1,69 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/ilitek,ili9163.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Ilitek ILI9163 display panels device tree bindings + +maintainers: + - Daniel Mack + +description: + This binding is for display panels using an Ilitek ILI9163 controller in SPI + mode. + +allOf: + - $ref: panel/panel-common.yaml# + +properties: + compatible: +items: + - enum: + - newhaven,1.8-128160EF + - const: ilitek,ili9163 + + spi-max-frequency: +maximum: 3200 + + dc-gpios: +maxItems: 1 +description: Display data/command selection (D/CX) + + backlight: true + reg: true + reset-gpios: true + rotation: true + +required: + - compatible + - reg + - dc-gpios + - reset-gpios + +additionalProperties: false + +examples: + - | +#include + +backlight: backlight { +compatible = "gpio-backlight"; +gpios = < 22 GPIO_ACTIVE_HIGH>; +}; +spi { +#address-cells = <1>; +#size-cells = <0>; + +display@0 { +compatible = "newhaven,1.8-128160EF", "ilitek,ili9163"; +reg = <0>; +spi-max-frequency = <3200>; +dc-gpios = < 24 GPIO_ACTIVE_HIGH>; +reset-gpios = < 25 GPIO_ACTIVE_HIGH>; +rotation = <180>; +backlight = <>; +}; +}; + +... -- 2.30.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 2/2] drm/tiny: add driver for newhaven,1.8-128160EF
This patch adds support for Newhaven's NHD-1.8-128160EF display, featuring an Ilitek ILI9163 controller. Signed-off-by: Daniel Mack Acked-by: Daniel Vetter --- drivers/gpu/drm/tiny/Kconfig | 13 ++ drivers/gpu/drm/tiny/Makefile | 1 + drivers/gpu/drm/tiny/ili9163.c | 224 + 3 files changed, 238 insertions(+) create mode 100644 drivers/gpu/drm/tiny/ili9163.c diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index 2b6414f0fa759..9de0c0eeea6f5 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -41,6 +41,19 @@ config TINYDRM_HX8357D If M is selected the module will be called hx8357d. +config TINYDRM_ILI9163 + tristate "DRM support for ILI9163 display panels" + depends on DRM && SPI + select DRM_KMS_HELPER + select DRM_KMS_CMA_HELPER + select DRM_MIPI_DBI + select BACKLIGHT_CLASS_DEVICE + help + DRM driver for the following Ilitek ILI9163 panels: + * NHD-1.8-128160EF 128x160 TFT + + If M is selected the module will be called ili9163. + config TINYDRM_ILI9225 tristate "DRM support for ILI9225 display panels" depends on DRM && SPI diff --git a/drivers/gpu/drm/tiny/Makefile b/drivers/gpu/drm/tiny/Makefile index 6ae4e9e5a35fb..78016b2ed11b5 100644 --- a/drivers/gpu/drm/tiny/Makefile +++ b/drivers/gpu/drm/tiny/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus.o obj-$(CONFIG_DRM_GM12U320) += gm12u320.o obj-$(CONFIG_TINYDRM_HX8357D) += hx8357d.o +obj-$(CONFIG_TINYDRM_ILI9163) += ili9163.o obj-$(CONFIG_TINYDRM_ILI9225) += ili9225.o obj-$(CONFIG_TINYDRM_ILI9341) += ili9341.o obj-$(CONFIG_TINYDRM_ILI9486) += ili9486.o diff --git a/drivers/gpu/drm/tiny/ili9163.c b/drivers/gpu/drm/tiny/ili9163.c new file mode 100644 index 0..6fa9e59b69321 --- /dev/null +++ b/drivers/gpu/drm/tiny/ili9163.c @@ -0,0 +1,224 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define ILI9163_FRMCTR10xb1 + +#define ILI9163_PWCTRL10xc0 +#define ILI9163_PWCTRL20xc1 +#define ILI9163_VMCTRL10xc5 +#define ILI9163_VMCTRL20xc7 +#define ILI9163_PWCTRLA0xcb +#define ILI9163_PWCTRLB0xcf + +#define ILI9163_EN3GAM 0xf2 + +#define ILI9163_MADCTL_BGR BIT(3) +#define ILI9163_MADCTL_MV BIT(5) +#define ILI9163_MADCTL_MX BIT(6) +#define ILI9163_MADCTL_MY BIT(7) + +static void yx240qv29_enable(struct drm_simple_display_pipe *pipe, +struct drm_crtc_state *crtc_state, +struct drm_plane_state *plane_state) +{ + struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(pipe->crtc.dev); + struct mipi_dbi *dbi = >dbi; + u8 addr_mode; + int ret, idx; + + if (!drm_dev_enter(pipe->crtc.dev, )) + return; + + drm_dbg_kms(>drm, "\n"); + + ret = mipi_dbi_poweron_conditional_reset(dbidev); + if (ret < 0) + goto out_exit; + if (ret == 1) + goto out_enable; + + /* Gamma */ + mipi_dbi_command(dbi, MIPI_DCS_SET_GAMMA_CURVE, 0x04); + mipi_dbi_command(dbi, ILI9163_EN3GAM, 0x00); + + /* Frame Rate */ + mipi_dbi_command(dbi, ILI9163_FRMCTR1, 0x0a, 0x14); + + /* Power Control */ + mipi_dbi_command(dbi, ILI9163_PWCTRL1, 0x0a, 0x00); + mipi_dbi_command(dbi, ILI9163_PWCTRL2, 0x02); + + /* VCOM */ + mipi_dbi_command(dbi, ILI9163_VMCTRL1, 0x2f, 0x3e); + mipi_dbi_command(dbi, ILI9163_VMCTRL2, 0x40); + + /* Memory Access Control */ + mipi_dbi_command(dbi, MIPI_DCS_SET_PIXEL_FORMAT, MIPI_DCS_PIXEL_FMT_16BIT); + + mipi_dbi_command(dbi, MIPI_DCS_EXIT_SLEEP_MODE); + msleep(100); + + mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_ON); + msleep(100); + +out_enable: + switch (dbidev->rotation) { + default: + addr_mode = 0; + break; + case 90: + addr_mode = ILI9163_MADCTL_MV | ILI9163_MADCTL_MX; + break; + case 180: + addr_mode = ILI9163_MADCTL_MX | ILI9163_MADCTL_MY; + break; + case 270: + addr_mode = ILI9163_MADCTL_MV | ILI9163_MADCTL_MY; + break; + } + addr_mode |= ILI9163_MADCTL_BGR; + mipi_dbi_command(dbi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode); + mipi_dbi_enable_flush(dbidev, crtc_state, plane_state); +out_exit: + drm_dev_exit(idx); +} + +static const struct drm_simple_display_pipe_funcs ili9163_pipe_funcs = { + .enable = yx240qv29_enable, + .disable = mipi_dbi_pipe_disable, + .update =
[PATCH v6 0/2] gpu: drm: add driver for ili9361 panel
This is v3 of the series. Changelog: v2 -> v3: * Turn Documentation into yaml format v3 -> v4: * Fix reference error in yaml file v4 -> v5: * More yaml file documentation fixes v5 -> v6: * More yaml file documentation fixes Daniel Mack (2): dt-bindings: display: add bindings for newhaven,1.8-128160EF drm/tiny: add driver for newhaven,1.8-128160EF .../display/panel/ilitek,ili9163.yaml | 69 +++ drivers/gpu/drm/tiny/Kconfig | 13 + drivers/gpu/drm/tiny/Makefile | 1 + drivers/gpu/drm/tiny/ili9163.c| 224 ++ 4 files changed, 307 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/ilitek,ili9163.yaml create mode 100644 drivers/gpu/drm/tiny/ili9163.c -- 2.29.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v6 2/2] dt-bindings: display: add bindings for newhaven, 1.8-128160EF
This adds documentation for a new ILI9163 based, SPI connected display. Signed-off-by: Daniel Mack --- .../display/panel/ilitek,ili9163.yaml | 69 +++ 1 file changed, 69 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/ilitek,ili9163.yaml diff --git a/Documentation/devicetree/bindings/display/panel/ilitek,ili9163.yaml b/Documentation/devicetree/bindings/display/panel/ilitek,ili9163.yaml new file mode 100644 index 0..fe612851e399a --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/ilitek,ili9163.yaml @@ -0,0 +1,69 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/ilitek,ili9163.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Ilitek ILI9163 display panels device tree bindings + +maintainers: + - Daniel Mack + +description: + This binding is for display panels using an Ilitek ILI9163 controller in SPI + mode. + +allOf: + - $ref: panel/panel-common.yaml# + +properties: + compatible: +items: + - enum: + - newhaven,1.8-128160EF + - const: ilitek,ili9163 + + spi-max-frequency: +maximum: 3200 + + dc-gpios: +maxItems: 1 +description: Display data/command selection (D/CX) + + backlight: true + reg: true + reset-gpios: true + rotation: true + +required: + - compatible + - reg + - dc-gpios + - reset-gpios + +additionalProperties: false + +examples: + - | +#include + +backlight: backlight { +compatible = "gpio-backlight"; +gpios = < 22 GPIO_ACTIVE_HIGH>; +}; +spi { +#address-cells = <1>; +#size-cells = <0>; + +display@0 { +compatible = "newhaven,1.8-128160EF", "ilitek,ili9163"; +reg = <0>; +spi-max-frequency = <3200>; +dc-gpios = < 24 GPIO_ACTIVE_HIGH>; +reset-gpios = < 25 GPIO_ACTIVE_HIGH>; +rotation = <180>; +backlight = <>; +}; +}; + +... -- 2.30.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v6 1/2] drm/tiny: add driver for newhaven,1.8-128160EF
This patch adds support for Newhaven's NHD-1.8-128160EF display, featuring an Ilitek ILI9163 controller. Signed-off-by: Daniel Mack Acked-by: Daniel Vetter --- drivers/gpu/drm/tiny/Kconfig | 13 ++ drivers/gpu/drm/tiny/Makefile | 1 + drivers/gpu/drm/tiny/ili9163.c | 224 + 3 files changed, 238 insertions(+) create mode 100644 drivers/gpu/drm/tiny/ili9163.c diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index 2b6414f0fa759..9de0c0eeea6f5 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -41,6 +41,19 @@ config TINYDRM_HX8357D If M is selected the module will be called hx8357d. +config TINYDRM_ILI9163 + tristate "DRM support for ILI9163 display panels" + depends on DRM && SPI + select DRM_KMS_HELPER + select DRM_KMS_CMA_HELPER + select DRM_MIPI_DBI + select BACKLIGHT_CLASS_DEVICE + help + DRM driver for the following Ilitek ILI9163 panels: + * NHD-1.8-128160EF 128x160 TFT + + If M is selected the module will be called ili9163. + config TINYDRM_ILI9225 tristate "DRM support for ILI9225 display panels" depends on DRM && SPI diff --git a/drivers/gpu/drm/tiny/Makefile b/drivers/gpu/drm/tiny/Makefile index 6ae4e9e5a35fb..78016b2ed11b5 100644 --- a/drivers/gpu/drm/tiny/Makefile +++ b/drivers/gpu/drm/tiny/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus.o obj-$(CONFIG_DRM_GM12U320) += gm12u320.o obj-$(CONFIG_TINYDRM_HX8357D) += hx8357d.o +obj-$(CONFIG_TINYDRM_ILI9163) += ili9163.o obj-$(CONFIG_TINYDRM_ILI9225) += ili9225.o obj-$(CONFIG_TINYDRM_ILI9341) += ili9341.o obj-$(CONFIG_TINYDRM_ILI9486) += ili9486.o diff --git a/drivers/gpu/drm/tiny/ili9163.c b/drivers/gpu/drm/tiny/ili9163.c new file mode 100644 index 0..6fa9e59b69321 --- /dev/null +++ b/drivers/gpu/drm/tiny/ili9163.c @@ -0,0 +1,224 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define ILI9163_FRMCTR10xb1 + +#define ILI9163_PWCTRL10xc0 +#define ILI9163_PWCTRL20xc1 +#define ILI9163_VMCTRL10xc5 +#define ILI9163_VMCTRL20xc7 +#define ILI9163_PWCTRLA0xcb +#define ILI9163_PWCTRLB0xcf + +#define ILI9163_EN3GAM 0xf2 + +#define ILI9163_MADCTL_BGR BIT(3) +#define ILI9163_MADCTL_MV BIT(5) +#define ILI9163_MADCTL_MX BIT(6) +#define ILI9163_MADCTL_MY BIT(7) + +static void yx240qv29_enable(struct drm_simple_display_pipe *pipe, +struct drm_crtc_state *crtc_state, +struct drm_plane_state *plane_state) +{ + struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(pipe->crtc.dev); + struct mipi_dbi *dbi = >dbi; + u8 addr_mode; + int ret, idx; + + if (!drm_dev_enter(pipe->crtc.dev, )) + return; + + drm_dbg_kms(>drm, "\n"); + + ret = mipi_dbi_poweron_conditional_reset(dbidev); + if (ret < 0) + goto out_exit; + if (ret == 1) + goto out_enable; + + /* Gamma */ + mipi_dbi_command(dbi, MIPI_DCS_SET_GAMMA_CURVE, 0x04); + mipi_dbi_command(dbi, ILI9163_EN3GAM, 0x00); + + /* Frame Rate */ + mipi_dbi_command(dbi, ILI9163_FRMCTR1, 0x0a, 0x14); + + /* Power Control */ + mipi_dbi_command(dbi, ILI9163_PWCTRL1, 0x0a, 0x00); + mipi_dbi_command(dbi, ILI9163_PWCTRL2, 0x02); + + /* VCOM */ + mipi_dbi_command(dbi, ILI9163_VMCTRL1, 0x2f, 0x3e); + mipi_dbi_command(dbi, ILI9163_VMCTRL2, 0x40); + + /* Memory Access Control */ + mipi_dbi_command(dbi, MIPI_DCS_SET_PIXEL_FORMAT, MIPI_DCS_PIXEL_FMT_16BIT); + + mipi_dbi_command(dbi, MIPI_DCS_EXIT_SLEEP_MODE); + msleep(100); + + mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_ON); + msleep(100); + +out_enable: + switch (dbidev->rotation) { + default: + addr_mode = 0; + break; + case 90: + addr_mode = ILI9163_MADCTL_MV | ILI9163_MADCTL_MX; + break; + case 180: + addr_mode = ILI9163_MADCTL_MX | ILI9163_MADCTL_MY; + break; + case 270: + addr_mode = ILI9163_MADCTL_MV | ILI9163_MADCTL_MY; + break; + } + addr_mode |= ILI9163_MADCTL_BGR; + mipi_dbi_command(dbi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode); + mipi_dbi_enable_flush(dbidev, crtc_state, plane_state); +out_exit: + drm_dev_exit(idx); +} + +static const struct drm_simple_display_pipe_funcs ili9163_pipe_funcs = { + .enable = yx240qv29_enable, + .disable = mipi_dbi_pipe_disable, + .update =
[PATCH v5 1/2] dt-bindings: display: add bindings for newhaven, 1.8-128160EF
This adds documentation for a new ILI9163 based, SPI connected display. Signed-off-by: Daniel Mack --- .../display/panel/ilitek,ili9163.yaml | 69 +++ 1 file changed, 69 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/ilitek,ili9163.yaml diff --git a/Documentation/devicetree/bindings/display/panel/ilitek,ili9163.yaml b/Documentation/devicetree/bindings/display/panel/ilitek,ili9163.yaml new file mode 100644 index 0..fbb12e46493b2 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/ilitek,ili9163.yaml @@ -0,0 +1,69 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/ilitek,ili9163.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Ilitek ILI9163 display panels device tree bindings + +maintainers: + - Daniel Mack + +description: + This binding is for display panels using an Ilitek ILI9163 controller in SPI + mode. + +allOf: + - $ref: panel/panel-common.yaml# + +properties: + compatible: +items: + - enum: + - newhaven,1.8-128160EF + - const: ilitek,ili9163 + + spi-max-frequency: +maximum: 3200 + + dc-gpios: +maxItems: 1 +description: Display data/command selection (D/CX) + + backlight: true + reg: true + reset-gpios: true + rotation: true + +required: + - compatible + - reg + - dc-gpios + - reset-gpios + +additionalProperties: false + +examples: + - | +#include + +backlight: backlight { +compatible = "gpio-backlight"; +gpios = < 22 GPIO_ACTIVE_HIGH>; +}; +spi { +#address-cells = <1>; +#size-cells = <0>; + +display@0 { +compatible = "newhaven,1.8-128160EF", "ilitek,ili9163"; +reg = <0>; +spi-max-frequency = <3200>; +dc-gpios = < 24 GPIO_ACTIVE_HIGH>; +reset-gpios = < 25 GPIO_ACTIVE_HIGH>; +rotation = <180>; +backlight = <>; +}; +}; + +... -- 2.30.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: linux-next: build warning after merge of the drm-intel-fixes tree
Hi Stephen, thanks for the report. On Mon, Mar 29, 2021 at 09:01:17AM +1100, Stephen Rothwell wrote: > Hi all, > > On Fri, 26 Mar 2021 19:58:38 +1100 Stephen Rothwell > wrote: > > > > After merging the drm-intel-fixes tree, today's linux-next build > > (htmldocs) produced this warning: > > > > Documentation/gpu/i915:22: /drivers/gpu/drm/i915/intel_runtime_pm.c:423: > > WARNING: Inline strong start-string without end-string. The problem seems to be the @ignore_usecount=true part in __intel_runtime_pm_get_if_active()'s docbook documentation. I can't see the problem with it, it was meant as a reference to the function parameter, granted I'm not sure what's the proper markup syntax for this. I will follow up with the following change which suppresses the warning and renders the html as expected unless someone can suggest a better way: - * If @ignore_usecount=true, a reference will be acquired even if there is no + * If @ignore_usecount is true, a reference will be acquired even if there is no --Imre > > > > Introduced by commit > > > > 8840e3bd981f ("drm/i915: Fix the GT fence revocation runtime PM logic") > > This warning now exists in Linus' tree. > > -- > Cheers, > Stephen Rothwell ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/amdgpu: fix an underflow on non-4KB-page systems
Am 29.03.21 um 20:08 schrieb Xi Ruoyao: On 2021-03-29 20:04 +0200, Christian König wrote: Am 29.03.21 um 19:53 schrieb Xℹ Ruoyao: If the initial value of `num_entires` (calculated at line 1654) is not an integral multiple of `AMDGPU_GPU_PAGES_IN_CPU_PAGE`, in line 1681 a value greater than the initial value will be assigned to it. That causes `start > last + 1` after line 1708. Then in the next iteration an underflow happens at line 1654. It causes message *ERROR* Couldn't update BO_VA (-12) printed in kernel log, and GPU hanging. Fortify the criteria of the loop to fix this issue. NAK the value of num_entries must always be a multiple of AMDGPU_GPU_PAGES_IN_CPU_PAGE or otherwise we corrupt the page tables. How do you trigger that? Simply run "OpenGL area" from gtk3-demo (which just renders a triangle with GL) under Xorg, on MIPS64. See the BugLink. You need to identify the root cause of this, most likely start or last are not a multiple of AMDGPU_GPU_PAGES_IN_CPU_PAGE. Christian. Christian. BugLink: https://gitlab.freedesktop.org/drm/amd/-/issues/1549 Fixes: a39f2a8d7066 ("drm/amdgpu: nuke amdgpu_vm_bo_split_mapping v2") Reported-by: Xi Ruoyao Reported-by: Dan Horák Cc: sta...@vger.kernel.org Signed-off-by: Xi Ruoyao --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index ad91c0c3c423..cee0cc9c8085 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -1707,7 +1707,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, } start = tmp; - } while (unlikely(start != last + 1)); + } while (unlikely(start < last + 1)); r = vm->update_funcs->commit(, fence); base-commit: a5e13c6df0e41702d2b2c77c8ad41677ebb065b3 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/amdgpu: fix an underflow on non-4KB-page systems
Am 29.03.21 um 19:53 schrieb Xℹ Ruoyao: If the initial value of `num_entires` (calculated at line 1654) is not an integral multiple of `AMDGPU_GPU_PAGES_IN_CPU_PAGE`, in line 1681 a value greater than the initial value will be assigned to it. That causes `start > last + 1` after line 1708. Then in the next iteration an underflow happens at line 1654. It causes message *ERROR* Couldn't update BO_VA (-12) printed in kernel log, and GPU hanging. Fortify the criteria of the loop to fix this issue. NAK the value of num_entries must always be a multiple of AMDGPU_GPU_PAGES_IN_CPU_PAGE or otherwise we corrupt the page tables. How do you trigger that? Christian. BugLink: https://gitlab.freedesktop.org/drm/amd/-/issues/1549 Fixes: a39f2a8d7066 ("drm/amdgpu: nuke amdgpu_vm_bo_split_mapping v2") Reported-by: Xi Ruoyao Reported-by: Dan Horák Cc: sta...@vger.kernel.org Signed-off-by: Xi Ruoyao --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index ad91c0c3c423..cee0cc9c8085 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -1707,7 +1707,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, } start = tmp; - } while (unlikely(start != last + 1)); + } while (unlikely(start < last + 1)); r = vm->update_funcs->commit(, fence); base-commit: a5e13c6df0e41702d2b2c77c8ad41677ebb065b3 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v6 4/5] drm/bridge: anx7625: add HDCP support
On Mon, Mar 29, 2021 at 6:27 AM Xin Ji wrote: > > On Thu, Mar 25, 2021 at 02:19:23PM -0400, Sean Paul wrote: > > On Fri, Mar 19, 2021 at 2:35 AM Xin Ji wrote: > > > > > > Add HDCP feature, enable HDCP function through chip internal key > > > and downstream's capability. > > > > > > Signed-off-by: Xin Ji > > > --- /snip > > > static void anx7625_dp_start(struct anx7625_data *ctx) > > > { > > > int ret; > > > @@ -643,6 +787,9 @@ static void anx7625_dp_start(struct anx7625_data *ctx) > > > return; > > > } > > > > > > + /* HDCP config */ > > > + anx7625_hdcp_setting(ctx); > > > > You should really use the "Content Protection" property to > > enable/disable HDCP instead of force-enabling it at all times. > > > > Sean > Hi Sean, it's hard to implement "Content Protection" property, we have > implemented HDCP in firmware, it is not compatible with it. We don't > have interface to get Downstream Cert. > Thanks, > Xin Hi Xin, I'm sorry, I don't understand what you mean when you say you don't have an interface to get Downstream Cert. The Content Protection property is just a means through which userspace can turn on and turn off HDCP when it needs. As far as I can tell, your patch turns on HDCP when the display is enabled and leaves it on until it is disabled. This is undesirable since it forces HDCP on the user. Is it impossible to enable/disable HDCP outside of display enable/disable on your hardware? Thanks, Sean > > > > > + > > > if (ctx->pdata.is_dpi) > > > ret = anx7625_dpi_config(ctx); > > > else /snip ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 2/2] drm/gud: Use scatter-gather USB bulk transfer
There'a limit to how big a kmalloc buffer can be, and as memory gets fragmented it becomes more difficult to get big buffers. The downside of smaller buffers is that the driver has to split the transfer up which hampers performance. Compression might also take a hit because of the splitting. Solve this by allocating the transfer buffer using vmalloc and create a SG table to be passed on to the USB subsystem. vmalloc_32() is used to avoid DMA bounce buffers on USB controllers that can only access 32-bit addresses. This also solves the problem that split transfers can give host side tearing since flushing is decoupled from rendering. Signed-off-by: Noralf Trønnes --- drivers/gpu/drm/gud/gud_drv.c | 49 +- drivers/gpu/drm/gud/gud_internal.h | 2 ++ drivers/gpu/drm/gud/gud_pipe.c | 47 3 files changed, 77 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/gud/gud_drv.c b/drivers/gpu/drm/gud/gud_drv.c index 820c7331b3b3..8f9bcf6561e8 100644 --- a/drivers/gpu/drm/gud/gud_drv.c +++ b/drivers/gpu/drm/gud/gud_drv.c @@ -394,13 +394,40 @@ static const struct drm_driver gud_drm_driver = { .minor = 0, }; +static int gud_alloc_bulk_buffer(struct gud_device *gdrm) +{ + unsigned int i, num_pages; + struct page **pages; + void *ptr; + int ret; + + gdrm->bulk_buf = vmalloc_32(gdrm->bulk_len); + if (!gdrm->bulk_buf) + return -ENOMEM; + + num_pages = PAGE_ALIGN(gdrm->bulk_len) >> PAGE_SHIFT; + pages = kmalloc_array(num_pages, sizeof(struct page *), GFP_KERNEL); + if (!pages) + return -ENOMEM; + + for (i = 0, ptr = gdrm->bulk_buf; i < num_pages; i++, ptr += PAGE_SIZE) + pages[i] = vmalloc_to_page(ptr); + + ret = sg_alloc_table_from_pages(>bulk_sgt, pages, num_pages, + 0, gdrm->bulk_len, GFP_KERNEL); + kfree(pages); + + return ret; +} + static void gud_free_buffers_and_mutex(void *data) { struct gud_device *gdrm = data; vfree(gdrm->compress_buf); gdrm->compress_buf = NULL; - kfree(gdrm->bulk_buf); + sg_free_table(>bulk_sgt); + vfree(gdrm->bulk_buf); gdrm->bulk_buf = NULL; mutex_destroy(>ctrl_lock); mutex_destroy(>damage_lock); @@ -538,24 +565,16 @@ static int gud_probe(struct usb_interface *intf, const struct usb_device_id *id) if (desc.max_buffer_size) max_buffer_size = le32_to_cpu(desc.max_buffer_size); -retry: - /* -* Use plain kmalloc here since devm_kmalloc() places struct devres at the beginning -* of the buffer it allocates. This wastes a lot of memory when allocating big buffers. -* Asking for 2M would actually allocate 4M. This would also prevent getting the biggest -* possible buffer potentially leading to split transfers. -*/ - gdrm->bulk_buf = kmalloc(max_buffer_size, GFP_KERNEL | __GFP_NOWARN); - if (!gdrm->bulk_buf) { - max_buffer_size = roundup_pow_of_two(max_buffer_size) / 2; - if (max_buffer_size < SZ_512K) - return -ENOMEM; - goto retry; - } + if (max_buffer_size > SZ_64M) + max_buffer_size = SZ_64M; /* safeguard */ gdrm->bulk_pipe = usb_sndbulkpipe(interface_to_usbdev(intf), usb_endpoint_num(bulk_out)); gdrm->bulk_len = max_buffer_size; + ret = gud_alloc_bulk_buffer(gdrm); + if (ret) + return ret; + if (gdrm->compression & GUD_COMPRESSION_LZ4) { gdrm->lz4_comp_mem = devm_kmalloc(dev, LZ4_MEM_COMPRESS, GFP_KERNEL); if (!gdrm->lz4_comp_mem) diff --git a/drivers/gpu/drm/gud/gud_internal.h b/drivers/gpu/drm/gud/gud_internal.h index de2f2d2dbc60..1bb65a46c347 100644 --- a/drivers/gpu/drm/gud/gud_internal.h +++ b/drivers/gpu/drm/gud/gud_internal.h @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -26,6 +27,7 @@ struct gud_device { unsigned int bulk_pipe; void *bulk_buf; size_t bulk_len; + struct sg_table bulk_sgt; u8 compression; void *lz4_comp_mem; diff --git a/drivers/gpu/drm/gud/gud_pipe.c b/drivers/gpu/drm/gud/gud_pipe.c index 2f83ab6b8e61..7dd63a8c7c2d 100644 --- a/drivers/gpu/drm/gud/gud_pipe.c +++ b/drivers/gpu/drm/gud/gud_pipe.c @@ -220,13 +220,51 @@ static int gud_prep_flush(struct gud_device *gdrm, struct drm_framebuffer *fb, return ret; } +struct gud_usb_bulk_context { + struct timer_list timer; + struct usb_sg_request sgr; +}; + +static void gud_usb_bulk_timeout(struct timer_list *t) +{ + struct gud_usb_bulk_context *timer = from_timer(timer, t, timer); + + usb_sg_cancel(>sgr); +} + +static int gud_usb_bulk(struct gud_device *gdrm, size_t len) +{ + struct gud_usb_bulk_context ctx; +
[PATCH 1/2] drm/gud: Free buffers on device removal
Free transfer and compression buffers on device removal instead of at DRM device removal time. This ensures that the usual 2x8MB buffers are released when the device is unplugged and not kept around should userspace keep the DRM device fd open. At least Ubuntu 20.04 doesn't release the DRM device on unplug. Signed-off-by: Noralf Trønnes --- drivers/gpu/drm/gud/gud_drv.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/gud/gud_drv.c b/drivers/gpu/drm/gud/gud_drv.c index e8b672dc9832..820c7331b3b3 100644 --- a/drivers/gpu/drm/gud/gud_drv.c +++ b/drivers/gpu/drm/gud/gud_drv.c @@ -394,12 +394,14 @@ static const struct drm_driver gud_drm_driver = { .minor = 0, }; -static void gud_free_buffers_and_mutex(struct drm_device *drm, void *unused) +static void gud_free_buffers_and_mutex(void *data) { - struct gud_device *gdrm = to_gud_device(drm); + struct gud_device *gdrm = data; vfree(gdrm->compress_buf); + gdrm->compress_buf = NULL; kfree(gdrm->bulk_buf); + gdrm->bulk_buf = NULL; mutex_destroy(>ctrl_lock); mutex_destroy(>damage_lock); } @@ -455,7 +457,7 @@ static int gud_probe(struct usb_interface *intf, const struct usb_device_id *id) INIT_WORK(>work, gud_flush_work); gud_clear_damage(gdrm); - ret = drmm_add_action_or_reset(drm, gud_free_buffers_and_mutex, NULL); + ret = devm_add_action(dev, gud_free_buffers_and_mutex, gdrm); if (ret) return ret; -- 2.23.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 1/2] iommu/arm-smmu-qcom: Skip the TTBR1 quirk for db820c.
On Mon, Mar 29, 2021 at 7:47 AM Will Deacon wrote: > > On Fri, Mar 26, 2021 at 04:13:02PM -0700, Eric Anholt wrote: > > db820c wants to use the qcom smmu path to get HUPCF set (which keeps > > the GPU from wedging and then sometimes wedging the kernel after a > > page fault), but it doesn't have separate pagetables support yet in > > drm/msm so we can't go all the way to the TTBR1 path. > > What do you mean by "doesn't have separate pagetables support yet"? The > compatible string doesn't feel like the right way to determine this. In my past experience with DT, software looking at the (existing) board-specific compatibles has been a typical mechanism used to resolve something like this "ok, but you need to actually get down to what board is involved here to figure out how to play along with the rest of Linux that later attaches to other DT nodes". Do you have a preferred mechanism here? ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 2/2] drm/ingenic: Don't request full modeset if property is not modified
Avoid requesting a full modeset if the sharpness property is not modified, because then we don't actually need it. Fixes: fc1acf317b01 ("drm/ingenic: Add support for the IPU") Cc: # 5.8+ Signed-off-by: Paul Cercueil --- drivers/gpu/drm/ingenic/ingenic-ipu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/ingenic/ingenic-ipu.c b/drivers/gpu/drm/ingenic/ingenic-ipu.c index 3b1091e7c0cd..95b665c4a7b0 100644 --- a/drivers/gpu/drm/ingenic/ingenic-ipu.c +++ b/drivers/gpu/drm/ingenic/ingenic-ipu.c @@ -640,10 +640,12 @@ ingenic_ipu_plane_atomic_set_property(struct drm_plane *plane, { struct ingenic_ipu *ipu = plane_to_ingenic_ipu(plane); struct drm_crtc_state *crtc_state; + bool mode_changed; if (property != ipu->sharpness_prop) return -EINVAL; + mode_changed = val != ipu->sharpness; ipu->sharpness = val; if (state->crtc) { @@ -651,7 +653,7 @@ ingenic_ipu_plane_atomic_set_property(struct drm_plane *plane, if (WARN_ON(!crtc_state)) return -EINVAL; - crtc_state->mode_changed = true; + crtc_state->mode_changed |= mode_changed; } return 0; -- 2.30.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 1/2] drm/ingenic: Switch IPU plane to type OVERLAY
It should have been an OVERLAY from the beginning. The documentation stipulates that there should be an unique PRIMARY plane per CRTC. Fixes: fc1acf317b01 ("drm/ingenic: Add support for the IPU") Cc: # 5.8+ Signed-off-by: Paul Cercueil --- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 11 +-- drivers/gpu/drm/ingenic/ingenic-ipu.c | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index 29742ec5ab95..09225b770bb8 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -419,7 +419,7 @@ static void ingenic_drm_plane_enable(struct ingenic_drm *priv, unsigned int en_bit; if (priv->soc_info->has_osd) { - if (plane->type == DRM_PLANE_TYPE_PRIMARY) + if (plane != >f0) en_bit = JZ_LCD_OSDC_F1EN; else en_bit = JZ_LCD_OSDC_F0EN; @@ -434,7 +434,7 @@ void ingenic_drm_plane_disable(struct device *dev, struct drm_plane *plane) unsigned int en_bit; if (priv->soc_info->has_osd) { - if (plane->type == DRM_PLANE_TYPE_PRIMARY) + if (plane != >f0) en_bit = JZ_LCD_OSDC_F1EN; else en_bit = JZ_LCD_OSDC_F0EN; @@ -461,8 +461,7 @@ void ingenic_drm_plane_config(struct device *dev, ingenic_drm_plane_enable(priv, plane); - if (priv->soc_info->has_osd && - plane->type == DRM_PLANE_TYPE_PRIMARY) { + if (priv->soc_info->has_osd && plane != >f0) { switch (fourcc) { case DRM_FORMAT_XRGB1555: ctrl |= JZ_LCD_OSDCTRL_RGB555; @@ -510,7 +509,7 @@ void ingenic_drm_plane_config(struct device *dev, } if (priv->soc_info->has_osd) { - if (plane->type == DRM_PLANE_TYPE_PRIMARY) { + if (plane != >f0) { xy_reg = JZ_REG_LCD_XYP1; size_reg = JZ_REG_LCD_SIZE1; } else { @@ -561,7 +560,7 @@ static void ingenic_drm_plane_atomic_update(struct drm_plane *plane, height = newstate->src_h >> 16; cpp = newstate->fb->format->cpp[0]; - if (!priv->soc_info->has_osd || plane->type == DRM_PLANE_TYPE_OVERLAY) + if (!priv->soc_info->has_osd || plane == >f0) hwdesc = >dma_hwdescs->hwdesc_f0; else hwdesc = >dma_hwdescs->hwdesc_f1; diff --git a/drivers/gpu/drm/ingenic/ingenic-ipu.c b/drivers/gpu/drm/ingenic/ingenic-ipu.c index 5ae6adab8306..3b1091e7c0cd 100644 --- a/drivers/gpu/drm/ingenic/ingenic-ipu.c +++ b/drivers/gpu/drm/ingenic/ingenic-ipu.c @@ -767,7 +767,7 @@ static int ingenic_ipu_bind(struct device *dev, struct device *master, void *d) err = drm_universal_plane_init(drm, plane, 1, _ipu_plane_funcs, soc_info->formats, soc_info->num_formats, - NULL, DRM_PLANE_TYPE_PRIMARY, NULL); + NULL, DRM_PLANE_TYPE_OVERLAY, NULL); if (err) { dev_err(dev, "Failed to init plane: %i\n", err); return err; -- 2.30.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 0/2] drm/ingenic: IPU plane fixes
Hi, A set of two fixes for the IPU plane of the ingenic-drm driver. Patch [1/2] changes the type of the IPU plane from PRIMARY to OVERLAY, since there can only be one PRIMARY plane per CRTC. Patch [2/2] enforces that a full modeset is only performed when the "sharpness" property is modified. Cheers, -Paul Paul Cercueil (2): drm/ingenic: Switch IPU plane to type OVERLAY drm/ingenic: Don't request full modeset if property is not modified drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 11 +-- drivers/gpu/drm/ingenic/ingenic-ipu.c | 6 -- 2 files changed, 9 insertions(+), 8 deletions(-) -- 2.30.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/amd/display: dual cursors are seen if scaling is enabled
On 2021-03-29 3:54 a.m., Louis Li wrote: [Why] This issue is found when scaling is not equal to one from src to dest. When issue happens, there are offsets in both axis x and y between two cursors. Users cannot control APP under such a condition. What's the use case? I don't think we support two cursors on a screen. Does this pass IGT cursor tests? Nick, I thought we don't allow cursor on anything but the top, unscaled pipe. Harry [How] For dual cursors, cursor should be disabled if there is a visible pipe on top of the current pipe at the current cursor position. For offsets between two cursors, need translate cursor position from stream space to plane space with scaling into consideration. Tested-by: Louis Li Signed-off-by: Louis Li Change-Id: Ic19e4f3b9225736f037f5ade10b68e8afe5f9ab7 --- .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 40 ++- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 83212ea40077..1ce5e58e3a9e 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -2999,6 +2999,10 @@ static bool dcn10_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx) const struct rect *r1 = _ctx->plane_res.scl_data.recout, *r2; int r1_r = r1->x + r1->width, r1_b = r1->y + r1->height, r2_r, r2_b; + struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position; + int cp_x = pos_cpy.x; + int cp_y = pos_cpy.y; + /** * Disable the cursor if there's another pipe above this with a * plane that contains this pipe's viewport to prevent double cursor @@ -3013,7 +3017,8 @@ static bool dcn10_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx) r2_r = r2->x + r2->width; r2_b = r2->y + r2->height; - if (r1->x >= r2->x && r1->y >= r2->y && r1_r <= r2_r && r1_b <= r2_b) + if ((cp_x >= r1->x && cp_y >= r1->y && cp_x <= r1_r && cp_y <= r1_b) + && (cp_x >= r2->x && cp_y >= r2->y && cp_x <= r2_r && cp_y <= r2_b)) return true; } @@ -3034,15 +3039,30 @@ static void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx) .rotation = pipe_ctx->plane_state->rotation, .mirror = pipe_ctx->plane_state->horizontal_mirror }; - uint32_t x_plane = pipe_ctx->plane_state->dst_rect.x; - uint32_t y_plane = pipe_ctx->plane_state->dst_rect.y; - uint32_t x_offset = min(x_plane, pos_cpy.x); - uint32_t y_offset = min(y_plane, pos_cpy.y); - - pos_cpy.x -= x_offset; - pos_cpy.y -= y_offset; - pos_cpy.x_hotspot += (x_plane - x_offset); - pos_cpy.y_hotspot += (y_plane - y_offset); + + int x_plane = pipe_ctx->plane_state->dst_rect.x; + int y_plane = pipe_ctx->plane_state->dst_rect.y; + int x_pos = pos_cpy.x; + int y_pos = pos_cpy.y; + + // translate cursor from stream space to plane space + x_pos = (x_pos - x_plane) * pipe_ctx->plane_state->src_rect.width / + pipe_ctx->plane_state->dst_rect.width; + y_pos = (y_pos - y_plane) * pipe_ctx->plane_state->src_rect.height / + pipe_ctx->plane_state->dst_rect.height; + + if (x_pos < 0) { + pos_cpy.x_hotspot -= x_pos; + x_pos = 0; + } + + if (y_pos < 0) { + pos_cpy.y_hotspot -= y_pos; + y_pos = 0; + } + + pos_cpy.x = (uint32_t)x_pos; + pos_cpy.y = (uint32_t)y_pos; if (pipe_ctx->plane_state->address.type == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] amd: display: dc: struct dc_state is declared twice
On Sat, Mar 27, 2021 at 3:28 AM Wan Jiabing wrote: > > struct dc_state has been declared at 273rd line. > Remove the duplicate. > Delete duplicate blank lines. Can you split these into separate patches? Alex > > Signed-off-by: Wan Jiabing > --- > drivers/gpu/drm/amd/display/dc/dc.h | 10 -- > 1 file changed, 10 deletions(-) > > diff --git a/drivers/gpu/drm/amd/display/dc/dc.h > b/drivers/gpu/drm/amd/display/dc/dc.h > index 18ed0d3f247e..dc667298ab5b 100644 > --- a/drivers/gpu/drm/amd/display/dc/dc.h > +++ b/drivers/gpu/drm/amd/display/dc/dc.h > @@ -234,7 +234,6 @@ struct dc_static_screen_params { > unsigned int num_frames; > }; > > - > /* Surface update type is used by dc_update_surfaces_and_stream > * The update type is determined at the very beginning of the function based > * on parameters passed in and decides how much programming (or updating) is > @@ -272,7 +271,6 @@ struct dc; > struct dc_plane_state; > struct dc_state; > > - > struct dc_cap_funcs { > bool (*get_dcc_compression_cap)(const struct dc *dc, > const struct dc_dcc_surface_param *input, > @@ -281,7 +279,6 @@ struct dc_cap_funcs { > > struct link_training_settings; > > - > /* Structure to hold configuration flags set by dm at dc creation. */ > struct dc_config { > bool gpu_vm_support; > @@ -581,7 +578,6 @@ struct dc_bounding_box_overrides { > int min_dcfclk_mhz; > }; > > -struct dc_state; > struct resource_pool; > struct dce_hwseq; > struct gpu_info_soc_bounding_box_v1_0; > @@ -757,7 +753,6 @@ enum dc_transfer_func_predefined { > TRANSFER_FUNCTION_GAMMA26 > }; > > - > struct dc_transfer_func { > struct kref refcount; > enum dc_transfer_func_type type; > @@ -770,7 +765,6 @@ struct dc_transfer_func { > }; > }; > > - > union dc_3dlut_state { > struct { > uint32_t initialized:1; /*if 3dlut is went through > color module for initialization */ > @@ -784,7 +778,6 @@ union dc_3dlut_state { > uint32_t raw; > }; > > - > struct dc_3dlut { > struct kref refcount; > struct tetrahedral_params lut_3d; > @@ -1014,7 +1007,6 @@ enum dc_status dc_validate_global_state( > struct dc_state *new_ctx, > bool fast_validate); > > - > void dc_resource_state_construct( > const struct dc *dc, > struct dc_state *dst_ctx); > @@ -1167,7 +1159,6 @@ struct dc_container_id { > unsigned short productCode; > }; > > - > struct dc_sink_dsc_caps { > // 'true' if these are virtual DPCD's DSC caps (immediately upstream > of sink in MST topology), > // 'false' if they are sink's DSC caps > @@ -1229,7 +1220,6 @@ struct dc_cursor { > struct dc_cursor_attributes attributes; > }; > > - > > /*** > * Interrupt interfaces > > **/ > -- > 2.25.1 > > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC PATCH 1/3] dt-bindings: display: simple: Add the panel on sc7180-trogdor-pompom
Hi, On Thu, Mar 25, 2021 at 5:09 PM Rob Herring wrote: > > On Tue, Mar 16, 2021 at 02:08:19PM -0700, Douglas Anderson wrote: > > The sc7180-trogdor-pompom board might be attached to any number of a > > pile of eDP panels. At the moment I'm told that the list might include: > > - KD KD116N21-30NV-A010 > > - KD KD116N09-30NH-A016 > > - Starry 2081116HHD028001-51D > > - Sharp LQ116M1JW10 > > > > It should be noted that while the EDID programmed in the first 3 > > panels indicates that they should run with exactly the same timing (to > > keep things simple), the 4th panel not only needs different timing but > > has a different resolution. > > > > As is true in general with eDP panels, we can figure out which panel > > we have and all the info needed to drive its pixel clock by reading > > the EDID. However, we can do this only after we've powered the panel > > on. Powering on the panels requires following the timing diagram in > > each panel's datasheet which specifies delays between certain > > actions. This means that, while we can be quite dynamic about handling > > things we can't just totally skip out on describing the panel like we > > could do if it was connected to an external-facing DP port. > > Is this a 'standard' eDP connector? AFAICT, there does seem to be > such a thing. To answer this one: there's not any "standard" physical plug as far as I can tell. There's a connector on the board side for the LCD that has a whole hodgepodge of signals on it. Maybe USB for a camera. Some power signals. Maybe a PWM for a backlight. Maybe some DMIC signals. eDP signals which might be anywhere from 1 to 4 lanes. HPD (which is really a "panel ready" signal for eDP). The size / style of connector and the exact set of signals (and their ordering) is board specific. You then get a board-specific cable that splits things out. Some might go to a camera/MIC sub board. Some go to the panel and hook onto a panel-specific connector which has pin count and orderings defined by that panel. :-P > I've said in the past I'd be okay with a edp-connector > node. If that needs just the "HPD absent delay" property, I think that > would be okay. It's just a never ending stream of new properties with > each new panel that I don't want to see. Thinking about this we'd need at least one other property right now which is an enable delay. Specifically at least one panel I've supported recently lied about HPD for a short period after bootup. Specifically see commit 667d73d72f31 ("drm: panel: simple: Delay HPD checking on boe_nv133fhm_n61 for 15 ms"). ...and, of course, the existing power supply / enable signals that "simple-panel" already has. Also: if we weren't going to add the other delay properties in the device tree, we'd have to add the code right away that used the EDID to set other delays. That wouldn't be the end of the world, but it would be code to write. One last thought to add: I've looked at ~10 panels specs recently. Though they are all a little different from each other, I will say that almost every one of them seems to have the exact same timing diagram in it just with different numbers filled in. To me that backs up the idea that you can/should do the power sequence with a fairly standard (parameterized) driver. I can't link the datasheets I have but searching for "edp panel datasheet" finds me this random datasheet: https://www.data-modul.com/sites/default/files/products/NV156QUM-N72_specification_12039472.pdf See "8.0 POWER SEQUENCE" in that document. All the panels have a nearly identical diagram with different numbers filled in. You can kinda tell it was copied from some other panel since some numbers (like T4) aren't even defined. -Doug ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/mediatek: crtc: Make config-updating atomic
Applied to mediatek-drm-next [1]. [1] https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux.git/log/?h=mediatek-drm-next Regards, Chun-Kuang. Chun-Kuang Hu 於 2021年3月13日 週六 下午5:43寫道: > > While updating config, the irq would occur and get the partial > config, so use variable config_updating to make updating atomic. > > Signed-off-by: Chun-Kuang Hu > --- > drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 19 --- > 1 file changed, 12 insertions(+), 7 deletions(-) > > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c > b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c > index 8b0de90156c6..870f66210848 100644 > --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c > +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c > @@ -61,6 +61,7 @@ struct mtk_drm_crtc { > > /* lock for display hardware access */ > struct mutexhw_lock; > + boolconfig_updating; > }; > > struct mtk_crtc_state { > @@ -97,7 +98,7 @@ static void mtk_drm_crtc_finish_page_flip(struct > mtk_drm_crtc *mtk_crtc) > static void mtk_drm_finish_page_flip(struct mtk_drm_crtc *mtk_crtc) > { > drm_crtc_handle_vblank(_crtc->base); > - if (mtk_crtc->pending_needs_vblank) { > + if (!mtk_crtc->config_updating && mtk_crtc->pending_needs_vblank) { > mtk_drm_crtc_finish_page_flip(mtk_crtc); > mtk_crtc->pending_needs_vblank = false; > } > @@ -425,7 +426,8 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc, > } > } > > -static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc *mtk_crtc) > +static void mtk_drm_crtc_update_config(struct mtk_drm_crtc *mtk_crtc, > + bool needs_vblank) > { > #if IS_REACHABLE(CONFIG_MTK_CMDQ) > struct cmdq_pkt *cmdq_handle; > @@ -436,6 +438,10 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc > *mtk_crtc) > int i; > > mutex_lock(_crtc->hw_lock); > + mtk_crtc->config_updating = true; > + if (needs_vblank) > + mtk_crtc->pending_needs_vblank = true; > + > for (i = 0; i < mtk_crtc->layer_nr; i++) { > struct drm_plane *plane = _crtc->planes[i]; > struct mtk_plane_state *plane_state; > @@ -472,6 +478,7 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc > *mtk_crtc) > cmdq_pkt_flush_async(cmdq_handle, ddp_cmdq_cb, cmdq_handle); > } > #endif > + mtk_crtc->config_updating = false; > mutex_unlock(_crtc->hw_lock); > } > > @@ -532,7 +539,7 @@ void mtk_drm_crtc_async_update(struct drm_crtc *crtc, > struct drm_plane *plane, > return; > > plane_helper_funcs->atomic_update(plane, new_state); > - mtk_drm_crtc_hw_config(mtk_crtc); > + mtk_drm_crtc_update_config(mtk_crtc, false); > } > > static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc, > @@ -582,7 +589,7 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc > *crtc, > } > mtk_crtc->pending_planes = true; > > - mtk_drm_crtc_hw_config(mtk_crtc); > + mtk_drm_crtc_update_config(mtk_crtc, false); > /* Wait for planes to be disabled */ > drm_crtc_wait_one_vblank(crtc); > > @@ -618,14 +625,12 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc > *crtc, > struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); > int i; > > - if (mtk_crtc->event) > - mtk_crtc->pending_needs_vblank = true; > if (crtc->state->color_mgmt_changed) > for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) { > mtk_ddp_gamma_set(mtk_crtc->ddp_comp[i], crtc->state); > mtk_ddp_ctm_set(mtk_crtc->ddp_comp[i], crtc->state); > } > - mtk_drm_crtc_hw_config(mtk_crtc); > + mtk_drm_crtc_update_config(mtk_crtc, !!mtk_crtc->event); > } > > static const struct drm_crtc_funcs mtk_crtc_funcs = { > -- > 2.17.1 > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v4 2/3] drm/encoder: Add macro drmm_plain_encoder_alloc()
Le dim. 28 mars 2021 à 1:05, Laurent Pinchart a écrit : Hi Paul, Thank you for the patch. On Sat, Mar 27, 2021 at 11:57:41AM +, Paul Cercueil wrote: This performs the same operation as drmm_encoder_alloc(), but only allocates and returns a struct drm_encoder instance. v4: Rename macro drmm_plain_encoder_alloc() and move to . Since it's not "simple" anymore it will now take funcs/name arguments as well. Signed-off-by: Paul Cercueil Reviewed-by: Laurent Pinchart Patchset applied to drm-misc-next. Thanks! -Paul --- include/drm/drm_encoder.h | 18 ++ 1 file changed, 18 insertions(+) diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h index 5bf78b5bcb2b..6e91a0280f31 100644 --- a/include/drm/drm_encoder.h +++ b/include/drm/drm_encoder.h @@ -224,6 +224,24 @@ void *__drmm_encoder_alloc(struct drm_device *dev, offsetof(type, member), funcs, \ encoder_type, name, ##__VA_ARGS__)) +/** + * drmm_plain_encoder_alloc - Allocate and initialize an encoder + * @dev: drm device + * @funcs: callbacks for this encoder (optional) + * @encoder_type: user visible type of the encoder + * @name: printf style format string for the encoder name, or NULL for default name + * + * This is a simplified version of drmm_encoder_alloc(), which only allocates + * and returns a struct drm_encoder instance, with no subclassing. + * + * Returns: + * Pointer to the new drm_encoder struct, or ERR_PTR on failure. + */ +#define drmm_plain_encoder_alloc(dev, funcs, encoder_type, name, ...) \ + ((struct drm_encoder *) \ + __drmm_encoder_alloc(dev, sizeof(struct drm_encoder), \ +0, funcs, encoder_type, name, ##__VA_ARGS__)) + /** * drm_encoder_index - find the index of a registered encoder * @encoder: encoder to find index for -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm: DON'T require each CRTC to have a unique primary plane
Le lun. 29 mars 2021 à 15:42, Simon Ser a écrit : On Monday, March 29th, 2021 at 5:39 PM, Paul Cercueil wrote: Ok, I read that as "all drivers should provide AT LEAST one primary plane per CRTC", and not as "all drivers should provide ONE AND ONLY ONE primary plane per CRTC". My bad. Yeah, it's a little complicated to document, because it's possible for a primary plane to be compatible with multiple CRTCs… We tried to improve this [1] recently. [1]: https://dri.freedesktop.org/docs/drm/gpu/drm-kms.html#plane-abstraction Ok, that is definitely much clearer :) -Paul ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC PATCH 1/3] dt-bindings: display: simple: Add the panel on sc7180-trogdor-pompom
Hi, On Fri, Mar 26, 2021 at 5:38 AM Thierry Reding wrote: > > The point remains that unless we describe exactly which panel we're > dealing with, we ultimately have no way of properly quirking anything if > we ever have to. Just to clarify here: with my initial proposal we actually could still quirk things if we had to. If the quirk needed to be applied before power on we'd just have to apply the quirk to the whole board (which we'd have to do anyway). After the panel was powered on then we could read the EDID and apply a quirk based on what the EDID tells us, right? > Also, once we allow this kind of wildcard we can > suddenly get into a situation where people might want to reuse this on > something that's not at all a google-pompom board because the same > particular power sequence happens to work on on some other board. That's a legit concern. Of course, people could already do that with existing panels right? One would also hope that if they reused this they also used the "more specific to least specific" rule, so someone could reuse (without any problems) with: compatible = "some-other-company,some-other-board-panel", "google,pompom-panel" That doesn't seem like it would be terrible. > Similarly I can imagine a situation where we could now have the same > panel supported by multiple different wildcard compatible strings. How > is that supposed to be any cleaner than what we have now? I'm tempted to call this (same panel supported by multiple different compatible strings) a feature, actually. Specifically: Even if the exact same hardware is shipped with more than one board, it may have a different EDID programmed into it. From what I've seen the timings used on a panel may need to be adjusted based on the SoC used (and what clock rates it can provide / features of the underlying display driver), EMI concerns, and power consumption concerns. Once a different EDID is programmed in it then it sorta becomes a "different" panel, right? I think sometimes (?) panel vendors assign a slightly different model number per board, but I'm not sure. -Doug ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel