Re: [PATCH RFC PKS/PMEM 05/58] kmap: Introduce k[un]map_thread
On Mon, Nov 09 2020 at 20:59, Ira Weiny wrote: > On Tue, Nov 10, 2020 at 02:13:56AM +0100, Thomas Gleixner wrote: > Also, we can convert the new memcpy_*_page() calls to kmap_local() as well. > [For now my patch just uses kmap_atomic().] > > I've not looked at all of the patches in your latest version. Have you > included converting any of the kmap() call sites? I thought you were more > focused on converting the kmap_atomic() to kmap_local()? I did not touch any of those yet, but it's a logical consequence to convert all kmap() instances which are _not_ creating a global mapping over to it. Thanks, tglx ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v1 11/30] drm/tegra: dc: Support OPP and SoC core voltage scaling
10.11.2020 23:32, Mark Brown пишет: > On Tue, Nov 10, 2020 at 09:29:45PM +0100, Thierry Reding wrote: >> On Thu, Nov 05, 2020 at 02:44:08AM +0300, Dmitry Osipenko wrote: > >>> + /* >>> +* Voltage scaling is optional and trying to set voltage for a dummy >>> +* regulator will error out. >>> +*/ >>> + if (!device_property_present(dc->dev, "core-supply")) >>> + return; > >> This is a potentially heavy operation, so I think we should avoid that >> here. How about you use devm_regulator_get_optional() in ->probe()? That >> returns -ENODEV if no regulator was specified, in which case you can set >> dc->core_reg = NULL and use that as the condition here. > > Or enumerate the configurable voltages after getting the regulator and > handle that appropriately which would be more robust in case there's > missing or unusual constraints. > I already changed that code to use regulator_get_optional() for v2. Regarding the enumerating supported voltage.. I think this should be done by the OPP core, but regulator core doesn't work well if regulator_get() is invoked more than one time for the same device, at least there is a loud debugfs warning about an already existing directory for a regulator. It's easy to check whether the debug directory exists before creating it, like thermal framework does it for example, but then there were some other more difficult issues.. I don't recall what they were right now. Perhaps will be easier to simply get a error from regulator_set_voltage() for now because it shouldn't ever happen in practice, unless device-tree has wrong constraints. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v8 09/26] memory: tegra30: Support interconnect framework
11.11.2020 08:53, Viresh Kumar пишет: >> +static int tegra_emc_opp_table_init(struct tegra_emc *emc) >> +{ >> +struct opp_table *reg_opp_table = NULL, *clk_opp_table, *hw_opp_table; >> +u32 hw_version = BIT(tegra_sku_info.soc_speedo_id); >> +const char *rname = "core"; >> +int err; >> + >> +/* >> + * Legacy device-trees don't have OPP table and EMC driver isn't >> + * useful in this case. >> + */ >> +if (!device_property_present(emc->dev, "operating-points-v2")) { > I don't understand why you want to check this ? The below call to > dev_pm_opp_of_add_table() will fail anyway and that should be good for > you. > The dev_pm_opp_of_add_table() will produce a error message which doesn't give a clue about what's wrong, i.e. that device-tree needs to be updated. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
RE: [PATCH v2 6/6] drm/bridge: cdns-mhdp8546: Fix the interrupt enable/disable
> -Original Message- > From: Nikhil Devshatwar > Sent: Tuesday, November 10, 2020 7:23 PM > To: Tomi Valkeinen ; Swapnil Kashinath Jakhade > ; Yuti Suresh Amonkar > Cc: dri-devel@lists.freedesktop.org; Swapnil Kashinath Jakhade > ; Sekhar Nori ; Laurent Pinchart > ; Yuti Suresh Amonkar > > Subject: Re: [PATCH v2 6/6] drm/bridge: cdns-mhdp8546: Fix the interrupt > enable/disable > > EXTERNAL MAIL > > > On 14:27-20201110, Tomi Valkeinen wrote: > > On 10/11/2020 12:27, Nikhil Devshatwar wrote: > > > On 11:21-20201110, Tomi Valkeinen wrote: > > >> On 09/11/2020 19:06, Nikhil Devshatwar wrote: > > >>> When removing the tidss driver, there is a warning reported by > > >>> kernel about an unhandled interrupt for mhdp driver. > > >>> > > >>> [ 43.238895] irq 31: nobody cared (try booting with the "irqpoll" > option) > > >>> ... [snipped backtrace] > > >>> [ 43.330735] handlers: > > >>> [ 43.333020] [<5367c4f9>] irq_default_primary_handler > threaded [<7e02b601>] > > >>> cdns_mhdp_irq_handler [cdns_mhdp8546] > > >>> [ 43.344607] Disabling IRQ #31 > > >>> > > >>> This happens because as part of cdns_mhdp_bridge_hpd_disable, > > >>> driver tries to disable the interrupts. While disabling the > > >>> SW_EVENT interrupts, it accidentally enables the MBOX interrupts, > > >>> which are not handled by the driver. > > >>> > > >>> Fix this with a read-modify-write to update only required bits. > > >>> Do the same for enabling interrupts as well. > > >>> > > >>> Signed-off-by: Nikhil Devshatwar > > >>> --- > > >>> drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c | 7 +-- > > >>> 1 file changed, 5 insertions(+), 2 deletions(-) > > >>> > > >>> diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c > > >>> b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c > > >>> index 2cd809eed827..6beccd2a408e 100644 > > >>> --- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c > > >>> +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c > > >>> @@ -2146,7 +2146,8 @@ static void > > >>> cdns_mhdp_bridge_hpd_enable(struct drm_bridge *bridge) > > >>> > > >>> /* Enable SW event interrupts */ > > >>> if (mhdp->bridge_attached) > > >>> - writel(~(u32)CDNS_APB_INT_MASK_SW_EVENT_INT, > > >>> + writel(readl(mhdp->regs + CDNS_APB_INT_MASK) & > > >>> + ~CDNS_APB_INT_MASK_SW_EVENT_INT, > > >>>mhdp->regs + CDNS_APB_INT_MASK); } > > >>> > > >>> @@ -2154,7 +2155,9 @@ static void > > >>> cdns_mhdp_bridge_hpd_disable(struct drm_bridge *bridge) { > > >>> struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge); > > >>> > > >>> - writel(CDNS_APB_INT_MASK_SW_EVENT_INT, mhdp->regs + > CDNS_APB_INT_MASK); > > >>> + writel(readl(mhdp->regs + CDNS_APB_INT_MASK) | > > >>> + CDNS_APB_INT_MASK_SW_EVENT_INT, > > >>> + mhdp->regs + CDNS_APB_INT_MASK); > > >>> } > > >>> > > >>> static const struct drm_bridge_funcs cdns_mhdp_bridge_funcs = { > > >> > > >> Good catch. I wonder why we need the above functions... We already > > >> enable and disable the interrupts when attaching/detaching the > > >> driver. And I think we want to get the interrupt even if we won't report > HPD (but I think we always do report it), as we need the interrupts to track > the link status. > > >> > > > > > > I read from the code that there is TODO for handling the mailbox > > > interrupts in the driver. Once that is supported, you will be able > > > to explictily enable/disable interrupts for SW_EVENTS (like hotplug) > > > as well as mailbox events. This enabling specific bits in the > > > interrupt status. > > > > But SW_EVENTS is not the same as HPD, at least in theory. If we > > disable SW_EVENT_INT in hpd_disable(), we lose all SW_EVENT interrupts. > > I am not sure, what exactly is covered in the SW events apart from the > hotplug. > > Swapnil, Yuti, Please fill in.. hpd_enable/hpd_disable callbacks were implemented as a part of supporting DRM_BRIDGE_OP_HPD bridge operation. The existing implementation could work with current features set supported by MHDP driver. But Tomi's point is valid, as there are some HDCP interrupts which are part of SW_EVENT interrupts and this might not be the control to just enable/disable HPD. Swapnil > > Nikhil D > > > > Tomi > > > > -- > > Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. > > Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm/amd/pm: Use kmemdup instead of kmalloc and memcpy
Fixes coccicheck warning: drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_processpptables.c:255: 36-43: WARNING opportunity for kmemdup Signed-off-by: Tian Tao --- drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_processpptables.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_processpptables.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_processpptables.c index 740e2fc..1e79baa 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_processpptables.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_processpptables.c @@ -252,12 +252,11 @@ static int init_powerplay_table_information( phm_copy_clock_limits_array(hwmgr, &pptable_information->power_saving_clock_max, powerplay_table->PowerSavingClockMax, ATOM_VEGA12_PPCLOCK_COUNT); phm_copy_clock_limits_array(hwmgr, &pptable_information->power_saving_clock_min, powerplay_table->PowerSavingClockMin, ATOM_VEGA12_PPCLOCK_COUNT); - pptable_information->smc_pptable = kmalloc(sizeof(PPTable_t), GFP_KERNEL); + pptable_information->smc_pptable = kmemdup(&(powerplay_table->smcPPTable), + sizeof(PPTable_t), GFP_KERNEL); if (pptable_information->smc_pptable == NULL) return -ENOMEM; - memcpy(pptable_information->smc_pptable, &(powerplay_table->smcPPTable), sizeof(PPTable_t)); - result = append_vbios_pptable(hwmgr, (pptable_information->smc_pptable)); return result; -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v8 21/26] ARM: tegra: Add interconnect properties to Tegra30 device-tree
Add interconnect properties to the Memory Controller, External Memory Controller and the Display Controller nodes in order to describe hardware interconnection. Signed-off-by: Dmitry Osipenko --- arch/arm/boot/dts/tegra30.dtsi | 27 ++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi index aeae8c092d41..2caf6cc6f4b1 100644 --- a/arch/arm/boot/dts/tegra30.dtsi +++ b/arch/arm/boot/dts/tegra30.dtsi @@ -210,6 +210,17 @@ dc@5420 { nvidia,head = <0>; + interconnects = <&mc TEGRA30_MC_DISPLAY0A &emc>, + <&mc TEGRA30_MC_DISPLAY0B &emc>, + <&mc TEGRA30_MC_DISPLAY1B &emc>, + <&mc TEGRA30_MC_DISPLAY0C &emc>, + <&mc TEGRA30_MC_DISPLAYHC &emc>; + interconnect-names = "wina", +"winb", +"winb-vfilter", +"winc", +"cursor"; + rgb { status = "disabled"; }; @@ -229,6 +240,17 @@ dc@5424 { nvidia,head = <1>; + interconnects = <&mc TEGRA30_MC_DISPLAY0AB &emc>, + <&mc TEGRA30_MC_DISPLAY0BB &emc>, + <&mc TEGRA30_MC_DISPLAY1BB &emc>, + <&mc TEGRA30_MC_DISPLAY0CB &emc>, + <&mc TEGRA30_MC_DISPLAYHCB &emc>; + interconnect-names = "wina", +"winb", +"winb-vfilter", +"winc", +"cursor"; + rgb { status = "disabled"; }; @@ -748,15 +770,18 @@ mc: memory-controller@7000f000 { #iommu-cells = <1>; #reset-cells = <1>; + #interconnect-cells = <1>; }; - memory-controller@7000f400 { + emc: memory-controller@7000f400 { compatible = "nvidia,tegra30-emc"; reg = <0x7000f400 0x400>; interrupts = ; clocks = <&tegra_car TEGRA30_CLK_EMC>; nvidia,memory-controller = <&mc>; + + #interconnect-cells = <0>; }; fuse@7000f800 { -- 2.29.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v8 03/26] memory: tegra20-emc: Factor out clk initialization
Factor out clk initialization and make it resource-managed. This makes easier to follow code and will help to make further changes cleaner. Signed-off-by: Dmitry Osipenko --- drivers/memory/tegra/tegra20-emc.c | 70 -- 1 file changed, 47 insertions(+), 23 deletions(-) diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c index bb3f315c9587..d01b556a6d06 100644 --- a/drivers/memory/tegra/tegra20-emc.c +++ b/drivers/memory/tegra/tegra20-emc.c @@ -960,6 +960,49 @@ static int tegra_emc_opp_table_init(struct tegra_emc *emc) return err; } +static void devm_tegra_emc_unset_callback(void *data) +{ + tegra20_clk_set_emc_round_callback(NULL, NULL); +} + +static void devm_tegra_emc_unreg_clk_notifier(void *data) +{ + struct tegra_emc *emc = data; + + clk_notifier_unregister(emc->clk, &emc->clk_nb); +} + +static int tegra_emc_init_clk(struct tegra_emc *emc) +{ + int err; + + tegra20_clk_set_emc_round_callback(emc_round_rate, emc); + + err = devm_add_action_or_reset(emc->dev, devm_tegra_emc_unset_callback, + NULL); + if (err) + return err; + + emc->clk = devm_clk_get(emc->dev, NULL); + if (IS_ERR(emc->clk)) { + dev_err(emc->dev, "failed to get EMC clock: %pe\n", emc->clk); + return PTR_ERR(emc->clk); + } + + err = clk_notifier_register(emc->clk, &emc->clk_nb); + if (err) { + dev_err(emc->dev, "failed to register clk notifier: %d\n", err); + return err; + } + + err = devm_add_action_or_reset(emc->dev, + devm_tegra_emc_unreg_clk_notifier, emc); + if (err) + return err; + + return 0; +} + static int tegra_emc_probe(struct platform_device *pdev) { struct device_node *np; @@ -1003,25 +1046,13 @@ static int tegra_emc_probe(struct platform_device *pdev) return err; } - tegra20_clk_set_emc_round_callback(emc_round_rate, emc); - - emc->clk = devm_clk_get(&pdev->dev, "emc"); - if (IS_ERR(emc->clk)) { - err = PTR_ERR(emc->clk); - dev_err(&pdev->dev, "failed to get emc clock: %d\n", err); - goto unset_cb; - } - - err = clk_notifier_register(emc->clk, &emc->clk_nb); - if (err) { - dev_err(&pdev->dev, "failed to register clk notifier: %d\n", - err); - goto unset_cb; - } + err = tegra_emc_init_clk(emc); + if (err) + return err; err = tegra_emc_opp_table_init(emc); if (err) - goto unreg_notifier; + return err; platform_set_drvdata(pdev, emc); tegra_emc_rate_requests_init(emc); @@ -1036,13 +1067,6 @@ static int tegra_emc_probe(struct platform_device *pdev) try_module_get(THIS_MODULE); return 0; - -unreg_notifier: - clk_notifier_unregister(emc->clk, &emc->clk_nb); -unset_cb: - tegra20_clk_set_emc_round_callback(NULL, NULL); - - return err; } static const struct of_device_id tegra_emc_of_match[] = { -- 2.29.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v1 07/30] soc/tegra: Add sync state API
10.11.2020 23:47, Thierry Reding пишет: ... > tegra_soc_for_each_device > > I wonder if you copy/pasted this or if you got really lucky to mistype > this all three times. Copied of course :) I added a special spell checking rule for this typo, but it does help reliably. ... >> +terga_soc_for_each_device(soc_dev) { >> +do { >> +/* >> + * Devices like display controller have multiple >> + * instances with the same compatible. Hence we need >> + * to walk up the whole tree in order to account those >> + * multiple instances. >> + */ >> +np = of_find_compatible_node(prev_np, NULL, >> + soc_dev->compatible); >> +of_node_put(prev_np); >> +prev_np = np; >> + >> +if (of_device_is_available(np)) { >> +pr_debug("added %s\n", soc_dev->compatible); >> +soc_dev->sync_count++; >> +} >> +} while (np); > > Maybe use for_each_compatible_node() for that inside loop? Good point! I think there is actually an of_node_put() bug in current variant, which for_each_compatible_node() would safe from. >> +} >> + >> +return 0; >> } >> +postcore_initcall_sync(tegra_soc_devices_init); > > This is unfortunate. I recall having this discussion multiple times and > one idea that has been floating around for a while was to let a driver > bind against the top-level "bus" node. That has the advantage that it > both anchors the code somewhere, so we don't have to play this game of > checking for the SoC with soc_is_tegra(), and it properly orders this > with respect to the child devices, so we wouldn't have to make this a > postcore_initcall. > > Might be worth looking at that again, but for now this seems okay. Thanks ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v8 17/26] PM / devfreq: tegra30: Separate configurations per-SoC generation
Previously we were using count-weight of the T124 for T30 in order to get EMC clock rate that was reasonable for T30. In fact the count-weight should be x2 times smaller on T30, but then devfreq was producing a bit too low EMC clock rate for ISO memory clients, like display controller for example. Now both Tegra ACTMON and Tegra DRM display drivers support interconnect framework and display driver tells to ICC what a minimum memory bandwidth is needed, preventing FIFO underflows. Thus, now we can use a proper count-weight value for Tegra30 and MC_ALL device config needs a bit more aggressive boosting. Add a separate ACTMON driver configuration that is specific to Tegra30. Tested-by: Peter Geis Tested-by: Nicolas Chauvet Acked-by: Chanwoo Choi Signed-off-by: Dmitry Osipenko --- drivers/devfreq/tegra30-devfreq.c | 68 --- 1 file changed, 54 insertions(+), 14 deletions(-) diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c index ed6d4469c8c7..36ba82c3898c 100644 --- a/drivers/devfreq/tegra30-devfreq.c +++ b/drivers/devfreq/tegra30-devfreq.c @@ -57,13 +57,6 @@ #define ACTMON_BELOW_WMARK_WINDOW 3 #define ACTMON_BOOST_FREQ_STEP 16000 -/* - * Activity counter is incremented every 256 memory transactions, and each - * transaction takes 4 EMC clocks for Tegra124; So the COUNT_WEIGHT is - * 4 * 256 = 1024. - */ -#define ACTMON_COUNT_WEIGHT0x400 - /* * ACTMON_AVERAGE_WINDOW_LOG2: default value for @DEV_CTRL_K_VAL, which * translates to 2 ^ (K_VAL + 1). ex: 2 ^ (6 + 1) = 128 @@ -111,7 +104,7 @@ enum tegra_actmon_device { MCCPU, }; -static const struct tegra_devfreq_device_config actmon_device_configs[] = { +static const struct tegra_devfreq_device_config tegra124_device_configs[] = { { /* MCALL: All memory accesses (including from the CPUs) */ .offset = 0x1c0, @@ -133,6 +126,28 @@ static const struct tegra_devfreq_device_config actmon_device_configs[] = { }, }; +static const struct tegra_devfreq_device_config tegra30_device_configs[] = { + { + /* MCALL: All memory accesses (including from the CPUs) */ + .offset = 0x1c0, + .irq_mask = 1 << 26, + .boost_up_coeff = 200, + .boost_down_coeff = 50, + .boost_up_threshold = 20, + .boost_down_threshold = 10, + }, + { + /* MCCPU: memory accesses from the CPUs */ + .offset = 0x200, + .irq_mask = 1 << 25, + .boost_up_coeff = 800, + .boost_down_coeff = 40, + .boost_up_threshold = 27, + .boost_down_threshold = 10, + .avg_dependency_threshold = 16000, /* 16MHz in kHz units */ + }, +}; + /** * struct tegra_devfreq_device - state specific to an ACTMON device * @@ -155,6 +170,12 @@ struct tegra_devfreq_device { unsigned long target_freq; }; +struct tegra_devfreq_soc_data { + const struct tegra_devfreq_device_config *configs; + /* Weight value for count measurements */ + unsigned int count_weight; +}; + struct tegra_devfreq { struct devfreq *devfreq; struct opp_table*opp_table; @@ -171,11 +192,13 @@ struct tegra_devfreq { struct delayed_work cpufreq_update_work; struct notifier_block cpu_rate_change_nb; - struct tegra_devfreq_device devices[ARRAY_SIZE(actmon_device_configs)]; + struct tegra_devfreq_device devices[2]; unsigned intirq; boolstarted; + + const struct tegra_devfreq_soc_data *soc; }; struct tegra_actmon_emc_ratio { @@ -488,7 +511,7 @@ static void tegra_actmon_configure_device(struct tegra_devfreq *tegra, tegra_devfreq_update_avg_wmark(tegra, dev); tegra_devfreq_update_wmark(tegra, dev); - device_writel(dev, ACTMON_COUNT_WEIGHT, ACTMON_DEV_COUNT_WEIGHT); + device_writel(dev, tegra->soc->count_weight, ACTMON_DEV_COUNT_WEIGHT); device_writel(dev, ACTMON_INTR_STATUS_CLEAR, ACTMON_DEV_INTR_STATUS); val |= ACTMON_DEV_CTRL_ENB_PERIODIC; @@ -786,6 +809,8 @@ static int tegra_devfreq_probe(struct platform_device *pdev) if (!tegra) return -ENOMEM; + tegra->soc = of_device_get_match_data(&pdev->dev); + tegra->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(tegra->regs)) return PTR_ERR(tegra->regs); @@ -859,9 +884,9 @@ static int tegra_devfreq_probe(struct platform_device *pdev) tegra->max_freq = rate / KHZ; - for (i = 0; i < ARRAY_SIZE(actmon_device_configs); i++) { + for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) { dev = tegra->devices + i; - dev->config = actmon_device_configs + i; +
Re: [PATCH v8 1/5] RDMA/umem: Support importing dma-buf as user memory region
On Tue, Nov 10, 2020 at 03:14:45PM +0100, Daniel Vetter wrote: > On Fri, Nov 06, 2020 at 12:39:53PM -0400, Jason Gunthorpe wrote: > > On Fri, Nov 06, 2020 at 04:34:07PM +, Xiong, Jianxin wrote: > > > > > > The user could specify a length that is beyond the dma buf, can > > > > the dma buf length be checked during get? > > > > > > In order to check the length, the buffer needs to be mapped. That can be > > > done. > > > > Do DMA bufs even have definitate immutable lengths? Going to be a > > probelm if they can shrink > > Yup. Unfortunately that's not document in the structures themselves, > there's just some random comments sprinkled all over that dma-buf size is > invariant, e.g. see the @mmap kerneldoc in dma_buf_ops: > > https://dri.freedesktop.org/docs/drm/driver-api/dma-buf.html?highlight=dma_buf_ops#c.dma_buf_ops > > "Because dma-buf buffers have invariant size over their lifetime, ..." > > Jianxin, can you pls do a kerneldoc patch which updates the comment for > dma_buf.size and dma_buf_export_info.size? So we can check the size without doing an attachment? That means the flow should be put back to how it was a series or two ago where the SGL is only attached during page fault with the entire programming sequence under the resv lock Jason ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v8 09/26] memory: tegra30: Support interconnect framework
On 11-11-20, 09:14, Dmitry Osipenko wrote: > 11.11.2020 08:53, Viresh Kumar пишет: > >> +static int tegra_emc_opp_table_init(struct tegra_emc *emc) > >> +{ > >> + struct opp_table *reg_opp_table = NULL, *clk_opp_table, *hw_opp_table; > >> + u32 hw_version = BIT(tegra_sku_info.soc_speedo_id); > >> + const char *rname = "core"; > >> + int err; > >> + > >> + /* > >> + * Legacy device-trees don't have OPP table and EMC driver isn't > >> + * useful in this case. > >> + */ > >> + if (!device_property_present(emc->dev, "operating-points-v2")) { > > I don't understand why you want to check this ? The below call to > > dev_pm_opp_of_add_table() will fail anyway and that should be good for > > you. > > > > The dev_pm_opp_of_add_table() will produce a error message which doesn't > give a clue about what's wrong, i.e. that device-tree needs to be updated. If you think that you need to print something more, then you can do that in the error message you print when dev_pm_opp_of_add_table() fails. I would suggest to drop this redundant check here. -- viresh ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v8 09/26] memory: tegra30: Support interconnect framework
On 11-11-20, 04:14, Dmitry Osipenko wrote: > +static int tegra_emc_opp_table_init(struct tegra_emc *emc) > +{ > + struct opp_table *reg_opp_table = NULL, *clk_opp_table, *hw_opp_table; > + u32 hw_version = BIT(tegra_sku_info.soc_speedo_id); > + const char *rname = "core"; > + int err; > + > + /* > + * Legacy device-trees don't have OPP table and EMC driver isn't > + * useful in this case. > + */ > + if (!device_property_present(emc->dev, "operating-points-v2")) { I don't understand why you want to check this ? The below call to dev_pm_opp_of_add_table() will fail anyway and that should be good for you. > + dev_err(emc->dev, > + "OPP table not found, please update your device > tree\n"); > + return -ENODEV; > + } > + > + /* voltage scaling is optional */ > + if (device_property_present(emc->dev, "core-supply")) { > + reg_opp_table = dev_pm_opp_set_regulators(emc->dev, &rname, 1); > + if (IS_ERR(reg_opp_table)) > + return dev_err_probe(emc->dev, PTR_ERR(reg_opp_table), > + "failed to set OPP regulator\n"); > + } > + > + clk_opp_table = dev_pm_opp_set_clkname(emc->dev, NULL); I think there is still some misunderstanding here. This call with a NULL connection id is useful only if the DT OPP table is optional for your platform and you want the same driver to work with and without the DT OPP table. Clearly in your case you want the OPP table in the DT to be there and so this call is not required at all. > + err = PTR_ERR_OR_ZERO(clk_opp_table); > + if (err) { > + dev_err(emc->dev, "failed to set OPP clk: %d\n", err); > + goto put_reg_table; > + } > + > + hw_opp_table = dev_pm_opp_set_supported_hw(emc->dev, &hw_version, 1); > + err = PTR_ERR_OR_ZERO(hw_opp_table); > + if (err) { > + dev_err(emc->dev, "failed to set OPP supported HW: %d\n", err); > + goto put_clk_table; > + } > + > + err = dev_pm_opp_of_add_table(emc->dev); > + if (err) { > + dev_err(emc->dev, "failed to add OPP table: %d\n", err); > + goto put_hw_table; > + } > + > + dev_info(emc->dev, "OPP HW ver. 0x%x, current clock rate %lu MHz\n", > + hw_version, clk_get_rate(emc->clk) / 100); > + > + /* first dummy rate-set initializes voltage state */ > + err = dev_pm_opp_set_rate(emc->dev, clk_get_rate(emc->clk)); > + if (err) { > + dev_err(emc->dev, "failed to initialize OPP clock: %d\n", err); > + goto remove_table; > + } > + > + return 0; > + > +remove_table: > + dev_pm_opp_of_remove_table(emc->dev); > +put_hw_table: > + dev_pm_opp_put_supported_hw(hw_opp_table); > +put_clk_table: > + dev_pm_opp_put_clkname(clk_opp_table); > +put_reg_table: > + if (reg_opp_table) > + dev_pm_opp_put_regulators(reg_opp_table); > + > + return err; > +} -- viresh ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm: rcar-du: Fix the return check of of_parse_phandle and of_find_device_by_node
of_parse_phandle and of_find_device_by_node may return NULL which cannot be checked by IS_ERR. Signed-off-by: Wang Xiaojun Reported-by: Hulk Robot --- drivers/gpu/drm/rcar-du/rcar_du_kms.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c index 72dda446355f..fcfddf7ad3f3 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c @@ -700,10 +700,10 @@ static int rcar_du_cmm_init(struct rcar_du_device *rcdu) int ret; cmm = of_parse_phandle(np, "renesas,cmms", i); - if (IS_ERR(cmm)) { + if (!cmm) { dev_err(rcdu->dev, "Failed to parse 'renesas,cmms' property\n"); - return PTR_ERR(cmm); + return -ENODEV; } if (!of_device_is_available(cmm)) { @@ -713,10 +713,10 @@ static int rcar_du_cmm_init(struct rcar_du_device *rcdu) } pdev = of_find_device_by_node(cmm); - if (IS_ERR(pdev)) { + if (!pdev) { dev_err(rcdu->dev, "No device found for CMM%u\n", i); of_node_put(cmm); - return PTR_ERR(pdev); + return -ENODEV; } of_node_put(cmm); -- 2.25.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 3/4] drm/omap: hdmi4: fix reference leak in hdmi_runtime_get
pm_runtime_get_sync will increment pm usage counter even it failed. Forgetting to pm_runtime_put_noidle will result in reference leak in hdmi_runtime_get, so we should fix it. Fixes: ac7674567c620 ("drm: omapdrm: hdmi4: Allocate the omap_hdmi data structure dynamically") Signed-off-by: Zhang Qilong --- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index a14fbf06cb30..33f12c351b08 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c @@ -44,8 +44,10 @@ static int hdmi_runtime_get(struct omap_hdmi *hdmi) r = pm_runtime_get_sync(&hdmi->pdev->dev); WARN_ON(r < 0); - if (r < 0) + if (r < 0) { + pm_runtime_put_noidle(&hdmi->pdev->dev); return r; + } return 0; } -- 2.25.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCHv7 2/7] iommu/arm-smmu: Add domain attribute for system cache
On 2020-11-10 17:48, Will Deacon wrote: On Fri, Oct 30, 2020 at 02:53:09PM +0530, Sai Prakash Ranjan wrote: Add iommu domain attribute for using system cache aka last level cache by client drivers like GPU to set right attributes for caching the hardware pagetables into the system cache. Signed-off-by: Sai Prakash Ranjan --- drivers/iommu/arm/arm-smmu/arm-smmu.c | 17 + drivers/iommu/arm/arm-smmu/arm-smmu.h | 1 + include/linux/iommu.h | 1 + 3 files changed, 19 insertions(+) diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c index b1cf8f0abc29..070d13f80c7e 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -789,6 +789,9 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, if (smmu_domain->non_strict) pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_NON_STRICT; + if (smmu_domain->sys_cache) + pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_SYS_CACHE; + pgtbl_ops = alloc_io_pgtable_ops(fmt, &pgtbl_cfg, smmu_domain); if (!pgtbl_ops) { ret = -ENOMEM; @@ -1520,6 +1523,9 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain, case DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE: *(int *)data = smmu_domain->non_strict; return 0; + case DOMAIN_ATTR_SYS_CACHE: + *((int *)data) = smmu_domain->sys_cache; + return 0; default: return -ENODEV; } @@ -1551,6 +1557,17 @@ static int arm_smmu_domain_set_attr(struct iommu_domain *domain, else smmu_domain->stage = ARM_SMMU_DOMAIN_S1; break; + case DOMAIN_ATTR_SYS_CACHE: + if (smmu_domain->smmu) { + ret = -EPERM; + goto out_unlock; + } + + if (*((int *)data)) + smmu_domain->sys_cache = true; + else + smmu_domain->sys_cache = false; + break; default: ret = -ENODEV; } diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h index 885840f3bec8..dfc44d806671 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h @@ -373,6 +373,7 @@ struct arm_smmu_domain { struct mutexinit_mutex; /* Protects smmu pointer */ spinlock_t cb_lock; /* Serialises ATS1* ops and TLB syncs */ struct iommu_domain domain; + boolsys_cache; }; struct arm_smmu_master_cfg { diff --git a/include/linux/iommu.h b/include/linux/iommu.h index b95a6f8db6ff..4f4bb9c6f8f6 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -118,6 +118,7 @@ enum iommu_attr { DOMAIN_ATTR_FSL_PAMUV1, DOMAIN_ATTR_NESTING,/* two stages of translation */ DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE, + DOMAIN_ATTR_SYS_CACHE, I think you're trying to make this look generic, but it's really not. If we need to funnel io-pgtable quirks through domain attributes, then I think we should be open about that and add something like DOMAIN_ATTR_IO_PGTABLE_CFG which could take a struct of page-table configuration data for the domain (this could just be quirks initially, but maybe it's worth extending to take ias, oas and page size) Actually the initial versions used DOMAIN_ATTR_QCOM_SYS_CACHE to make it QCOM specific and not generic, I don't see anyone else using this attribute, would that work? Thanks, Sai -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCHv7 1/7] iommu/io-pgtable-arm: Add support to use system cache
On 2020-11-10 17:48, Will Deacon wrote: On Fri, Oct 30, 2020 at 02:53:08PM +0530, Sai Prakash Ranjan wrote: Add a quirk IO_PGTABLE_QUIRK_SYS_CACHE to override the attributes set in TCR for the page table walker when using system cache. Signed-off-by: Sai Prakash Ranjan --- drivers/iommu/io-pgtable-arm.c | 7 ++- include/linux/io-pgtable.h | 4 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index a7a9bc08dcd1..a356caf1683a 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -761,7 +761,8 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie) if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS | IO_PGTABLE_QUIRK_NON_STRICT | - IO_PGTABLE_QUIRK_ARM_TTBR1)) + IO_PGTABLE_QUIRK_ARM_TTBR1 | + IO_PGTABLE_QUIRK_SYS_CACHE)) return NULL; data = arm_lpae_alloc_pgtable(cfg); @@ -773,6 +774,10 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie) tcr->sh = ARM_LPAE_TCR_SH_IS; tcr->irgn = ARM_LPAE_TCR_RGN_WBWA; tcr->orgn = ARM_LPAE_TCR_RGN_WBWA; + } else if (cfg->quirks & IO_PGTABLE_QUIRK_SYS_CACHE) { + tcr->sh = ARM_LPAE_TCR_SH_OS; + tcr->irgn = ARM_LPAE_TCR_RGN_NC; + tcr->orgn = ARM_LPAE_TCR_RGN_WBWA; Given that this only applies in the case where then page-table walker is non-coherent, I think we'd be better off renaming the quirk to something like IO_PGTABLE_QUIRK_ARM_OUTER_WBWA and then rejecting it in the non-coherent case. Do you mean like below? diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index a7a9bc08dcd1..94de1f71db42 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -776,7 +776,10 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie) } else { tcr->sh = ARM_LPAE_TCR_SH_OS; tcr->irgn = ARM_LPAE_TCR_RGN_NC; - tcr->orgn = ARM_LPAE_TCR_RGN_NC; + if (!(cfg->quirks & IO_PGTABLE_QUIRK_ARM_OUTER_WBWA)) + tcr->orgn = ARM_LPAE_TCR_RGN_NC; + else + tcr->orgn = ARM_LPAE_TCR_RGN_WBWA; } tg1 = cfg->quirks & IO_PGTABLE_QUIRK_ARM_TTBR1; Thanks, Sai -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v8 09/26] memory: tegra30: Support interconnect framework
11.11.2020 09:18, Viresh Kumar пишет: > On 11-11-20, 09:14, Dmitry Osipenko wrote: >> 11.11.2020 08:53, Viresh Kumar пишет: +static int tegra_emc_opp_table_init(struct tegra_emc *emc) +{ + struct opp_table *reg_opp_table = NULL, *clk_opp_table, *hw_opp_table; + u32 hw_version = BIT(tegra_sku_info.soc_speedo_id); + const char *rname = "core"; + int err; + + /* + * Legacy device-trees don't have OPP table and EMC driver isn't + * useful in this case. + */ + if (!device_property_present(emc->dev, "operating-points-v2")) { >>> I don't understand why you want to check this ? The below call to >>> dev_pm_opp_of_add_table() will fail anyway and that should be good for >>> you. >>> >> >> The dev_pm_opp_of_add_table() will produce a error message which doesn't >> give a clue about what's wrong, i.e. that device-tree needs to be updated. > > If you think that you need to print something more, then you can do > that in the error message you print when dev_pm_opp_of_add_table() > fails. I would suggest to drop this redundant check here. > Please give the rationale. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v8 13/26] memory: tegra124: Support interconnect framework
Now Internal and External memory controllers are memory interconnection providers. This allows us to use interconnect API for tuning of memory configuration. EMC driver now supports OPPs and DVFS. Tested-by: Nicolas Chauvet Signed-off-by: Dmitry Osipenko --- drivers/memory/tegra/Kconfig| 1 + drivers/memory/tegra/tegra124-emc.c | 338 +++- drivers/memory/tegra/tegra124.c | 82 ++- 3 files changed, 409 insertions(+), 12 deletions(-) diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig index 6265aa39674f..076482e1787b 100644 --- a/drivers/memory/tegra/Kconfig +++ b/drivers/memory/tegra/Kconfig @@ -35,6 +35,7 @@ config TEGRA124_EMC tristate "NVIDIA Tegra124 External Memory Controller driver" default y depends on TEGRA_MC && ARCH_TEGRA_124_SOC + select PM_OPP help This driver is for the External Memory Controller (EMC) found on Tegra124 chips. The EMC controls the external DRAM on the board. diff --git a/drivers/memory/tegra/tegra124-emc.c b/drivers/memory/tegra/tegra124-emc.c index 8fb8c1af25c9..46c546f84baa 100644 --- a/drivers/memory/tegra/tegra124-emc.c +++ b/drivers/memory/tegra/tegra124-emc.c @@ -12,20 +12,26 @@ #include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include #include +#include "mc.h" + #define EMC_FBIO_CFG5 0x104 #defineEMC_FBIO_CFG5_DRAM_TYPE_MASK0x3 #defineEMC_FBIO_CFG5_DRAM_TYPE_SHIFT 0 +#define EMC_FBIO_CFG5_DRAM_WIDTH_X64 BIT(4) #define EMC_INTSTATUS 0x0 #define EMC_INTSTATUS_CLKCHANGE_COMPLETE BIT(4) @@ -461,6 +467,17 @@ struct emc_timing { u32 emc_zcal_interval; }; +enum emc_rate_request_type { + EMC_RATE_DEBUG, + EMC_RATE_ICC, + EMC_RATE_TYPE_MAX, +}; + +struct emc_rate_request { + unsigned long min_rate; + unsigned long max_rate; +}; + struct tegra_emc { struct device *dev; @@ -471,6 +488,7 @@ struct tegra_emc { struct clk *clk; enum emc_dram_type dram_type; + unsigned int dram_bus_width; unsigned int dram_num; struct emc_timing last_timing; @@ -482,6 +500,17 @@ struct tegra_emc { unsigned long min_rate; unsigned long max_rate; } debugfs; + + struct icc_provider provider; + + /* +* There are multiple sources in the EMC driver which could request +* a min/max clock rate, these rates are contained in this array. +*/ + struct emc_rate_request requested_rate[EMC_RATE_TYPE_MAX]; + + /* protect shared rate-change code path */ + struct mutex rate_lock; }; /* Timing change sequence functions */ @@ -870,6 +899,14 @@ static void emc_read_current_timing(struct tegra_emc *emc, static int emc_init(struct tegra_emc *emc) { emc->dram_type = readl(emc->regs + EMC_FBIO_CFG5); + + if (emc->dram_type & EMC_FBIO_CFG5_DRAM_WIDTH_X64) + emc->dram_bus_width = 64; + else + emc->dram_bus_width = 32; + + dev_info(emc->dev, "%ubit DRAM bus\n", emc->dram_bus_width); + emc->dram_type &= EMC_FBIO_CFG5_DRAM_TYPE_MASK; emc->dram_type >>= EMC_FBIO_CFG5_DRAM_TYPE_SHIFT; @@ -1009,6 +1046,83 @@ tegra_emc_find_node_by_ram_code(struct device_node *node, u32 ram_code) return NULL; } +static void tegra_emc_rate_requests_init(struct tegra_emc *emc) +{ + unsigned int i; + + for (i = 0; i < EMC_RATE_TYPE_MAX; i++) { + emc->requested_rate[i].min_rate = 0; + emc->requested_rate[i].max_rate = ULONG_MAX; + } +} + +static int emc_request_rate(struct tegra_emc *emc, + unsigned long new_min_rate, + unsigned long new_max_rate, + enum emc_rate_request_type type) +{ + struct emc_rate_request *req = emc->requested_rate; + unsigned long min_rate = 0, max_rate = ULONG_MAX; + unsigned int i; + int err; + + /* select minimum and maximum rates among the requested rates */ + for (i = 0; i < EMC_RATE_TYPE_MAX; i++, req++) { + if (i == type) { + min_rate = max(new_min_rate, min_rate); + max_rate = min(new_max_rate, max_rate); + } else { + min_rate = max(req->min_rate, min_rate); + max_rate = min(req->max_rate, max_rate); + } + } + + if (min_rate > max_rate) { + dev_err_ratelimited(emc->dev, "%s: type %u: out of range: %lu %lu\n", + __func__, type, min_rate, max_rate); + return -ERANGE; + } + + /* +* EMC rate-changes should go via OPP API because it manages volta
Re: [PATCH v3 00/56] Convert DSI code to use drm_mipi_dsi and drm_panel
> Am 10.11.2020 um 14:49 schrieb H. Nikolaus Schaller : > > Hi Tomi, > >> Am 09.11.2020 um 12:33 schrieb Tomi Valkeinen : >> >> On 09/11/2020 13:09, H. Nikolaus Schaller wrote: >> > I see. > Anyways there is missing some simple thing which makes the driver not > prepared/enabled. > Or is this related to VC? No, that's not related to the VC. >>> >>> Ok, then it is worth searching for that independently. Any idea/hint what >>> could be missing? >> >> Well, if I had to guess, I would go for either 1) some registration or such >> is missing from the >> panel driver, or 2) some config value is invalid, which makes the DRM >> framework or the DSI driver >> fail before calling prepare or enable. > > I did now some tests based on v5.10-rc3 by adding mre and more printk() and > dump_stack(). > And I did blacklist the panel driver so that I could boot and after > modprobing it manually > I could trigger a re-probe by inserting some USB memory stick. > > With this procedure I could trace the problem down to this call sequence: > > dsi_probe() > ... > w677l_probe() >drm_panel_add() -- after this, of_drm_find_panel() is successful > ... > component_add() > try_to_bring_up_master() > master->ops->bind(master->dev) > > This call to bind() does not return and likely the probing thread is then > blocked and > holds some locks which manifests itself in that the system isn't running > stable any > more (e.g. heartbeat LEDs are sometimes stuck although console still works). > > dbg_info() in try_to_bring_up_master() prints: > > [ 102.199362] omapdss_dss 5800.dss: trying to bring up master > > So I am not sure if this is a panel driver issue at all or the DSI patch set > is not > running stable on OMAP5. > > Is a good next step to trace dss_bind() in drivers/gpu/drm/omapdrm//dss/dss.c? There is indeed one kernel worker running at 100% CPU load. top: PID USER PR NIVIRTRESSHR S %CPU %MEM TIME+ COMMAND 3196 root 20 0 0 0 0 R 100.0 0.0 2:58.76 kworker/0:8+events More analysis shows that it hangs in drm_client_modeset_probe() in the loop for (i = 0; i < connector_count; i++) total_modes_count += connectors[i]->funcs->fill_modes(connectors[i], width, height); Most likely not in the loop because that looks sane, but connectors[i]->funcs->fill_modes(). So I have to find out what function connectors[i]->funcs->fill_modes is... BTW: connector_count = 2. BR and thanks, Nikolaus ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v1 07/30] soc/tegra: Add sync state API
11.11.2020 00:22, Dmitry Osipenko пишет: > I added a special spell checking rule for this typo, but it does help > reliably. does *not* ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v8 06/26] memory: tegra30: Add FIFO sizes to memory clients
The latency allowness is calculated based on buffering capabilities of memory clients. Add FIFO sizes to the Tegra30 memory clients. Signed-off-by: Dmitry Osipenko --- drivers/memory/tegra/tegra30.c | 66 ++ 1 file changed, 66 insertions(+) diff --git a/drivers/memory/tegra/tegra30.c b/drivers/memory/tegra/tegra30.c index b1990b4133d8..d0314f29608d 100644 --- a/drivers/memory/tegra/tegra30.c +++ b/drivers/memory/tegra/tegra30.c @@ -42,6 +42,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = { .mask = 0xff, .def = 0x0, }, + .fifo_size = 16 * 2, }, { .id = 0x01, .name = "display0a", @@ -56,6 +57,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = { .mask = 0xff, .def = 0x4e, }, + .fifo_size = 16 * 128, }, { .id = 0x02, .name = "display0ab", @@ -70,6 +72,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = { .mask = 0xff, .def = 0x4e, }, + .fifo_size = 16 * 128, }, { .id = 0x03, .name = "display0b", @@ -84,6 +87,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = { .mask = 0xff, .def = 0x4e, }, + .fifo_size = 16 * 64, }, { .id = 0x04, .name = "display0bb", @@ -98,6 +102,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = { .mask = 0xff, .def = 0x4e, }, + .fifo_size = 16 * 64, }, { .id = 0x05, .name = "display0c", @@ -112,6 +117,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = { .mask = 0xff, .def = 0x4e, }, + .fifo_size = 16 * 128, }, { .id = 0x06, .name = "display0cb", @@ -126,6 +132,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = { .mask = 0xff, .def = 0x4e, }, + .fifo_size = 16 * 128, }, { .id = 0x07, .name = "display1b", @@ -140,6 +147,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = { .mask = 0xff, .def = 0x4e, }, + .fifo_size = 16 * 64, }, { .id = 0x08, .name = "display1bb", @@ -154,6 +162,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = { .mask = 0xff, .def = 0x4e, }, + .fifo_size = 16 * 64, }, { .id = 0x09, .name = "eppup", @@ -168,6 +177,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = { .mask = 0xff, .def = 0x17, }, + .fifo_size = 16 * 8, }, { .id = 0x0a, .name = "g2pr", @@ -182,6 +192,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = { .mask = 0xff, .def = 0x09, }, + .fifo_size = 16 * 64, }, { .id = 0x0b, .name = "g2sr", @@ -196,6 +207,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = { .mask = 0xff, .def = 0x09, }, + .fifo_size = 16 * 64, }, { .id = 0x0c, .name = "mpeunifbr", @@ -210,6 +222,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = { .mask = 0xff, .def = 0x50, }, + .fifo_size = 16 * 8, }, { .id = 0x0d, .name = "viruv", @@ -224,6 +237,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = { .mask = 0xff, .def = 0x2c, }, + .fifo_size = 16 * 8, }, { .id = 0x0e, .name = "afir", @@ -238,6 +252,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = { .mask = 0xff, .def = 0x10, }, + .fifo_size = 16 * 32, }, { .id = 0x0f, .name = "avpcarm7r", @@ -252,6 +267,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = { .mask = 0xff, .def = 0x04, }, + .fif
Re: [PATCH v8 02/26] memory: tegra20-emc: Use dev_pm_opp_set_clkname()
On 11-11-20, 04:14, Dmitry Osipenko wrote: > The dev_pm_opp_get_opp_table() shouldn't be used by drivers, use > dev_pm_opp_set_clkname() instead. > > Suggested-by: Viresh Kumar > Signed-off-by: Dmitry Osipenko > --- > drivers/memory/tegra/tegra20-emc.c | 30 +++--- > 1 file changed, 19 insertions(+), 11 deletions(-) > > diff --git a/drivers/memory/tegra/tegra20-emc.c > b/drivers/memory/tegra/tegra20-emc.c > index 5e10aa97809f..bb3f315c9587 100644 > --- a/drivers/memory/tegra/tegra20-emc.c > +++ b/drivers/memory/tegra/tegra20-emc.c > @@ -902,7 +902,7 @@ static int tegra_emc_interconnect_init(struct tegra_emc > *emc) > > static int tegra_emc_opp_table_init(struct tegra_emc *emc) > { > - struct opp_table *opp_table; > + struct opp_table *reg_opp_table = NULL, *clk_opp_table; > const char *rname = "core"; > int err; > > @@ -917,19 +917,24 @@ static int tegra_emc_opp_table_init(struct tegra_emc > *emc) > } > > /* voltage scaling is optional */ > - if (device_property_present(emc->dev, "core-supply")) > - opp_table = dev_pm_opp_set_regulators(emc->dev, &rname, 1); > - else > - opp_table = dev_pm_opp_get_opp_table(emc->dev); > + if (device_property_present(emc->dev, "core-supply")) { > + reg_opp_table = dev_pm_opp_set_regulators(emc->dev, &rname, 1); > + if (IS_ERR(reg_opp_table)) > + return dev_err_probe(emc->dev, PTR_ERR(reg_opp_table), > + "failed to set OPP regulator\n"); > + } > > - if (IS_ERR(opp_table)) > - return dev_err_probe(emc->dev, PTR_ERR(opp_table), > - "failed to prepare OPP table\n"); > + clk_opp_table = dev_pm_opp_set_clkname(emc->dev, NULL); > + err = PTR_ERR_OR_ZERO(clk_opp_table); Don't check for NULL here. > + if (err) { > + dev_err(emc->dev, "failed to set OPP clk: %d\n", err); > + goto put_reg_table; > + } > > err = dev_pm_opp_of_add_table(emc->dev); > if (err) { > dev_err(emc->dev, "failed to add OPP table: %d\n", err); > - goto put_table; > + goto put_clk_table; > } > > dev_info(emc->dev, "current clock rate %lu MHz\n", > @@ -946,8 +951,11 @@ static int tegra_emc_opp_table_init(struct tegra_emc > *emc) > > remove_table: > dev_pm_opp_of_remove_table(emc->dev); > -put_table: > - dev_pm_opp_put_regulators(opp_table); > +put_clk_table: > + dev_pm_opp_put_clkname(clk_opp_table); > +put_reg_table: > + if (reg_opp_table) This won't be required after my other patchset and yeah it is a classic chicken and egg problem we have here :) Maybe you can fix them separately in 5.11 after everything is applied. > + dev_pm_opp_put_regulators(reg_opp_table); > > return err; > } > -- > 2.29.2 -- viresh ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 00/56] Convert DSI code to use drm_mipi_dsi and drm_panel
Hi Tomi, > Am 09.11.2020 um 12:33 schrieb Tomi Valkeinen : > > On 09/11/2020 13:09, H. Nikolaus Schaller wrote: > I see. Anyways there is missing some simple thing which makes the driver not prepared/enabled. Or is this related to VC? >>> >>> No, that's not related to the VC. >> >> Ok, then it is worth searching for that independently. Any idea/hint what >> could be missing? > > Well, if I had to guess, I would go for either 1) some registration or such > is missing from the > panel driver, or 2) some config value is invalid, which makes the DRM > framework or the DSI driver > fail before calling prepare or enable. I did now some tests based on v5.10-rc3 by adding mre and more printk() and dump_stack(). And I did blacklist the panel driver so that I could boot and after modprobing it manually I could trigger a re-probe by inserting some USB memory stick. With this procedure I could trace the problem down to this call sequence: dsi_probe() ... w677l_probe() drm_panel_add() -- after this, of_drm_find_panel() is successful ... component_add() try_to_bring_up_master() master->ops->bind(master->dev) This call to bind() does not return and likely the probing thread is then blocked and holds some locks which manifests itself in that the system isn't running stable any more (e.g. heartbeat LEDs are sometimes stuck although console still works). dbg_info() in try_to_bring_up_master() prints: [ 102.199362] omapdss_dss 5800.dss: trying to bring up master So I am not sure if this is a panel driver issue at all or the DSI patch set is not running stable on OMAP5. Is a good next step to trace dss_bind() in drivers/gpu/drm/omapdrm//dss/dss.c? BR, Nikolaus ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/ingenic: ipu: Search for scaling coefs up to 102% of?? the screen
Le mar. 10 nov. 2020 à 9:56, Sam Ravnborg a écrit : Hi Paul, On Tue, Nov 10, 2020 at 08:50:22AM +, Paul Cercueil wrote: Hi, Le sam. 7 nov. 2020 à 20:33, Sam Ravnborg a écrit : > Hi Paul. > > On Thu, Nov 05, 2020 at 08:39:05AM +, Paul Cercueil wrote: > > Increase the scaled image's theorical width/height until we find a > > configuration that has valid scaling coefficients, up to 102% of the > > screen's resolution. This makes sure that we can scale from almost > > every resolution possible at the cost of a very small distorsion. > > The CRTC_W / CRTC_H are not modified. > > > > This algorithm was already in place but would not try to go above > > the > > screen's resolution, and as a result would only work if the CRTC_W / > > CRTC_H were smaller than the screen resolution. It will now try > > until it > > reaches 102% of the screen's resolution. > > > > Signed-off-by: Paul Cercueil > > Looks like the patch does what the descriptions says. > So in other words - look OK to me. I am not confident enogh for a r-b > but my code reading is enough to warrant an a-b: > Acked-by: Sam Ravnborg Note that this algorithm exists mostly as a band-aid for a missing functionality: it is not possible for userspace to request the closest mode that would encapsulate the provided one, because the GEM buffer is created beforehand. If there was a way to let the kernel tweak the mode, I could write a better algorithm that would result in a better looking picture. Could you add this nice explanation to the changelog so when we wonder why this was done in some years we can dig up this from git history. Sure! -Paul ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 4/4] drm/omap: hdmi5: fix reference leak in hdmi_runtime_get
pm_runtime_get_sync will increment pm usage counter even it failed. Forgetting to pm_runtime_put_noidle will result in reference leak in hdmi_runtime_get, so we should fix it. Fixes: c44991ce21bef ("drm: omapdrm: hdmi5: Allocate the omap_hdmi data structure dynamically") Signed-off-by: Zhang Qilong --- drivers/gpu/drm/omapdrm/dss/hdmi5.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c index b738d9750686..26ffbd1bd1cc 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c @@ -45,8 +45,10 @@ static int hdmi_runtime_get(struct omap_hdmi *hdmi) r = pm_runtime_get_sync(&hdmi->pdev->dev); WARN_ON(r < 0); - if (r < 0) + if (r < 0) { + pm_runtime_put_noidle(&hdmi->pdev->dev); return r; + } return 0; } -- 2.25.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2] drm: Use state helper instead of CRTC state pointer
On Thu, Nov 05, 2020 at 08:07:57PM +0100, Thomas Zimmermann wrote: > Hi > > Am 05.11.20 um 17:45 schrieb Maxime Ripard: > > Many drivers reference the crtc->pointer in order to get the current CRTC > > state in their atomic_begin or atomic_flush hooks, which would be the new > > CRTC state in the global atomic state since _swap_state happened when those > > hooks are run. > > > > Use the drm_atomic_get_new_crtc_state helper to get that state to make it > > more obvious. > > > > This was made using the coccinelle script below: > > > > @ crtc_atomic_func @ > > identifier helpers; > > identifier func; > > @@ > > > > ( > > static struct drm_crtc_helper_funcs helpers = { > > ..., > > .atomic_begin = func, > > ..., > > }; > > | > > static struct drm_crtc_helper_funcs helpers = { > > ..., > > .atomic_flush = func, > > ..., > > }; > > ) > > > > @@ > > identifier crtc_atomic_func.func; > > identifier crtc, state; > > symbol crtc_state; > > expression e; > > @@ > > > > func(struct drm_crtc *crtc, struct drm_atomic_state *state) { > > ... > > - struct tegra_dc_state *crtc_state = e; > > + struct tegra_dc_state *dc_state = e; > > <+... > > - crtc_state > > + dc_state > > ...+> > > } > > > > @@ > > identifier crtc_atomic_func.func; > > identifier crtc, state; > > symbol crtc_state; > > expression e; > > @@ > > > > func(struct drm_crtc *crtc, struct drm_atomic_state *state) { > > ... > > - struct mtk_crtc_state *crtc_state = e; > > + struct mtk_crtc_state *mtk_crtc_state = e; > > <+... > > - crtc_state > > + mtk_crtc_state > > ...+> > > } > > > > @ replaces_new_state @ > > identifier crtc_atomic_func.func; > > identifier crtc, state, crtc_state; > > @@ > > > > func(struct drm_crtc *crtc, struct drm_atomic_state *state) { > > ... > > - struct drm_crtc_state *crtc_state = crtc->state; > > + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, > > crtc); > > ... > > } > > > > @@ > > identifier crtc_atomic_func.func; > > identifier crtc, state, crtc_state; > > @@ > > > > func(struct drm_crtc *crtc, struct drm_atomic_state *state) { > > struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, > > crtc); > > ... > > - crtc->state > > + crtc_state > > ... > > } > > > > @ adds_new_state @ > > identifier crtc_atomic_func.func; > > identifier crtc, state; > > @@ > > > > func(struct drm_crtc *crtc, struct drm_atomic_state *state) { > > + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, > > crtc); > > ... > > - crtc->state > > + crtc_state > > ... > > } > > > > @ include depends on adds_new_state || replaces_new_state @ > > @@ > > > > #include > > > > @ no_include depends on !include && (adds_new_state || replaces_new_state) @ > > @@ > > > > + #include > > #include > > > > Cc: "James (Qian) Wang" > > Cc: Liviu Dudau > > Cc: Mihail Atanassov > > Cc: Brian Starkey > > Cc: Russell King > > Cc: Paul Cercueil > > Cc: Chun-Kuang Hu > > Cc: Philipp Zabel > > Cc: Sandy Huang > > Cc: "Heiko Stübner" > > Cc: Thierry Reding > > Cc: Gerd Hoffmann > > Reviewed-by: Ville Syrjälä > > Suggested-by: Ville Syrjälä > > Signed-off-by: Maxime Ripard > Acked-by: Thomas Zimmermann Applied, thanks! Maxime signature.asc Description: PGP signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v8 20/26] ARM: tegra: Add interconnect properties to Tegra20 device-tree
Add interconnect properties to the Memory Controller, External Memory Controller and the Display Controller nodes in order to describe hardware interconnection. Signed-off-by: Dmitry Osipenko --- arch/arm/boot/dts/tegra20.dtsi | 26 +- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi index 9347f7789245..2e1304493f7d 100644 --- a/arch/arm/boot/dts/tegra20.dtsi +++ b/arch/arm/boot/dts/tegra20.dtsi @@ -111,6 +111,17 @@ dc@5420 { nvidia,head = <0>; + interconnects = <&mc TEGRA20_MC_DISPLAY0A &emc>, + <&mc TEGRA20_MC_DISPLAY0B &emc>, + <&mc TEGRA20_MC_DISPLAY1B &emc>, + <&mc TEGRA20_MC_DISPLAY0C &emc>, + <&mc TEGRA20_MC_DISPLAYHC &emc>; + interconnect-names = "wina", +"winb", +"winb-vfilter", +"winc", +"cursor"; + rgb { status = "disabled"; }; @@ -128,6 +139,17 @@ dc@5424 { nvidia,head = <1>; + interconnects = <&mc TEGRA20_MC_DISPLAY0AB &emc>, + <&mc TEGRA20_MC_DISPLAY0BB &emc>, + <&mc TEGRA20_MC_DISPLAY1BB &emc>, + <&mc TEGRA20_MC_DISPLAY0CB &emc>, + <&mc TEGRA20_MC_DISPLAYHCB &emc>; + interconnect-names = "wina", +"winb", +"winb-vfilter", +"winc", +"cursor"; + rgb { status = "disabled"; }; @@ -630,15 +652,17 @@ mc: memory-controller@7000f000 { interrupts = ; #reset-cells = <1>; #iommu-cells = <0>; + #interconnect-cells = <1>; }; - memory-controller@7000f400 { + emc: memory-controller@7000f400 { compatible = "nvidia,tegra20-emc"; reg = <0x7000f400 0x400>; interrupts = ; clocks = <&tegra_car TEGRA20_CLK_EMC>; #address-cells = <1>; #size-cells = <0>; + #interconnect-cells = <0>; }; fuse@7000f800 { -- 2.29.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v8 16/26] PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
This patch moves ACTMON driver away from generating OPP table by itself, transitioning it to use the table which comes from device-tree. This change breaks compatibility with older device-trees in order to bring support for the interconnect framework to the driver. This is a mandatory change which needs to be done in order to implement interconnect-based memory DVFS. Users of legacy device-trees will get a message telling that theirs DT needs to be upgraded. Now ACTMON issues memory bandwidth request using dev_pm_opp_set_bw(), instead of driving EMC clock rate directly. Tested-by: Peter Geis Tested-by: Nicolas Chauvet Acked-by: Chanwoo Choi Signed-off-by: Dmitry Osipenko --- drivers/devfreq/tegra30-devfreq.c | 86 --- 1 file changed, 44 insertions(+), 42 deletions(-) diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c index 38cc0d014738..ed6d4469c8c7 100644 --- a/drivers/devfreq/tegra30-devfreq.c +++ b/drivers/devfreq/tegra30-devfreq.c @@ -19,6 +19,8 @@ #include #include +#include + #include "governor.h" #define ACTMON_GLB_STATUS 0x0 @@ -155,6 +157,7 @@ struct tegra_devfreq_device { struct tegra_devfreq { struct devfreq *devfreq; + struct opp_table*opp_table; struct reset_control*reset; struct clk *clock; @@ -612,34 +615,19 @@ static void tegra_actmon_stop(struct tegra_devfreq *tegra) static int tegra_devfreq_target(struct device *dev, unsigned long *freq, u32 flags) { - struct tegra_devfreq *tegra = dev_get_drvdata(dev); - struct devfreq *devfreq = tegra->devfreq; struct dev_pm_opp *opp; - unsigned long rate; - int err; + int ret; opp = devfreq_recommended_opp(dev, freq, flags); if (IS_ERR(opp)) { dev_err(dev, "Failed to find opp for %lu Hz\n", *freq); return PTR_ERR(opp); } - rate = dev_pm_opp_get_freq(opp); - dev_pm_opp_put(opp); - - err = clk_set_min_rate(tegra->emc_clock, rate * KHZ); - if (err) - return err; - - err = clk_set_rate(tegra->emc_clock, 0); - if (err) - goto restore_min_rate; - return 0; - -restore_min_rate: - clk_set_min_rate(tegra->emc_clock, devfreq->previous_freq); + ret = dev_pm_opp_set_bw(dev, opp); + dev_pm_opp_put(opp); - return err; + return ret; } static int tegra_devfreq_get_dev_status(struct device *dev, @@ -655,7 +643,7 @@ static int tegra_devfreq_get_dev_status(struct device *dev, stat->private_data = tegra; /* The below are to be used by the other governors */ - stat->current_frequency = cur_freq; + stat->current_frequency = cur_freq * KHZ; actmon_dev = &tegra->devices[MCALL]; @@ -705,7 +693,12 @@ static int tegra_governor_get_target(struct devfreq *devfreq, target_freq = max(target_freq, dev->target_freq); } - *freq = target_freq; + /* +* tegra-devfreq driver operates with KHz units, while OPP table +* entries use Hz units. Hence we need to convert the units for the +* devfreq core. +*/ + *freq = target_freq * KHZ; return 0; } @@ -774,6 +767,7 @@ static struct devfreq_governor tegra_devfreq_governor = { static int tegra_devfreq_probe(struct platform_device *pdev) { + u32 hw_version = BIT(tegra_sku_info.soc_speedo_id); struct tegra_devfreq_device *dev; struct tegra_devfreq *tegra; struct devfreq *devfreq; @@ -781,6 +775,13 @@ static int tegra_devfreq_probe(struct platform_device *pdev) long rate; int err; + /* legacy device-trees don't have OPP table and must be updated */ + if (!device_property_present(&pdev->dev, "operating-points-v2")) { + dev_err(&pdev->dev, + "OPP table not found, please update your device tree\n"); + return -ENODEV; + } + tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL); if (!tegra) return -ENOMEM; @@ -822,11 +823,25 @@ static int tegra_devfreq_probe(struct platform_device *pdev) return err; } + tegra->opp_table = dev_pm_opp_set_supported_hw(&pdev->dev, + &hw_version, 1); + err = PTR_ERR_OR_ZERO(tegra->opp_table); + if (err) { + dev_err(&pdev->dev, "Failed to set supported HW: %d\n", err); + return err; + } + + err = dev_pm_opp_of_add_table(&pdev->dev); + if (err) { + dev_err(&pdev->dev, "Failed to add OPP table: %d\n", err); + goto put_hw; + } + err = clk_prepare_enable(tegra->clock); if (err) { dev_err(&pdev->dev, "
[PATCH v8 24/26] ARM: tegra: Add DVFS properties to Tegra20 EMC device-tree node
Add EMC OPP DVFS table that will be used for dynamic scaling of memory frequency/voltage. Update board device-trees with optional EMC core supply and remove unsupported OPPs. Signed-off-by: Dmitry Osipenko --- .../boot/dts/tegra20-acer-a500-picasso.dts| 7 ++ arch/arm/boot/dts/tegra20-colibri.dtsi| 4 + arch/arm/boot/dts/tegra20-paz00.dts | 6 ++ .../arm/boot/dts/tegra20-peripherals-opp.dtsi | 92 +++ arch/arm/boot/dts/tegra20.dtsi| 3 + 5 files changed, 112 insertions(+) create mode 100644 arch/arm/boot/dts/tegra20-peripherals-opp.dtsi diff --git a/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts b/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts index a0b829738e8f..b4ed88802387 100644 --- a/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts +++ b/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts @@ -1061,6 +1061,8 @@ map0 { memory-controller@7000f400 { nvidia,use-ram-code; + core-supply = <&vdd_core>; + emc-tables@0 { nvidia,ram-code = <0>; /* elpida-8gb */ @@ -1450,3 +1452,8 @@ emc-table@30 { }; }; }; + +&emc_icc_dvfs_opp_table { + /delete-node/ opp@66600; + /delete-node/ opp@76000; +}; diff --git a/arch/arm/boot/dts/tegra20-colibri.dtsi b/arch/arm/boot/dts/tegra20-colibri.dtsi index 6162d193e12c..585a5b441cf6 100644 --- a/arch/arm/boot/dts/tegra20-colibri.dtsi +++ b/arch/arm/boot/dts/tegra20-colibri.dtsi @@ -742,6 +742,10 @@ sound { }; }; +&emc_icc_dvfs_opp_table { + /delete-node/ opp@76000; +}; + &gpio { lan-reset-n { gpio-hog; diff --git a/arch/arm/boot/dts/tegra20-paz00.dts b/arch/arm/boot/dts/tegra20-paz00.dts index ada2bed8b1b5..52a81d888424 100644 --- a/arch/arm/boot/dts/tegra20-paz00.dts +++ b/arch/arm/boot/dts/tegra20-paz00.dts @@ -314,6 +314,8 @@ nvec@7000c500 { memory-controller@7000f400 { nvidia,use-ram-code; + core-supply = <&core_vdd_reg>; + emc-tables@0 { nvidia,ram-code = <0x0>; #address-cells = <1>; @@ -662,3 +664,7 @@ cpu@1 { }; }; }; + +&emc_icc_dvfs_opp_table { + /delete-node/ opp@76000; +}; diff --git a/arch/arm/boot/dts/tegra20-peripherals-opp.dtsi b/arch/arm/boot/dts/tegra20-peripherals-opp.dtsi new file mode 100644 index ..25b1ba73951e --- /dev/null +++ b/arch/arm/boot/dts/tegra20-peripherals-opp.dtsi @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: GPL-2.0 + +/ { + emc_icc_dvfs_opp_table: emc-dvfs-opp-table { + compatible = "operating-points-v2"; + + opp@3600 { + opp-microvolt = <95 95 130>; + opp-hz = /bits/ 64 <3600>; + }; + + opp@4750 { + opp-microvolt = <95 95 130>; + opp-hz = /bits/ 64 <4750>; + }; + + opp@5000 { + opp-microvolt = <95 95 130>; + opp-hz = /bits/ 64 <5000>; + }; + + opp@5400 { + opp-microvolt = <95 95 130>; + opp-hz = /bits/ 64 <5400>; + }; + + opp@5700 { + opp-microvolt = <95 95 130>; + opp-hz = /bits/ 64 <5700>; + }; + + opp@1 { + opp-microvolt = <100 100 130>; + opp-hz = /bits/ 64 <1>; + }; + + opp@10800 { + opp-microvolt = <100 100 130>; + opp-hz = /bits/ 64 <10800>; + }; + + opp@12000 { + opp-microvolt = <100 100 130>; + opp-hz = /bits/ 64 <12000>; + }; + + opp@15000 { + opp-microvolt = <100 100 130>; + opp-hz = /bits/ 64 <15000>; + }; + + opp@19000 { + opp-microvolt = <100 100 130>; + opp-hz = /bits/ 64 <19000>; + }; + + opp@21600 { + opp-microvolt = <100 100 130>; + opp-hz = /bits/ 64 <21600>; + }; + + opp@3 { + opp-microvolt = <100 100 130>; + opp-hz = /bits/ 64 <3>; + }; + + opp@33300 { + opp-microvolt = <100 100 130>; + opp-hz = /bits/ 64 <33300>; + }; + +
[PATCH v8 22/26] ARM: tegra: Add interconnect properties to Tegra124 device-tree
Add interconnect properties to the Memory Controller, External Memory Controller and the Display Controller nodes in order to describe hardware interconnection. Signed-off-by: Dmitry Osipenko --- arch/arm/boot/dts/tegra124.dtsi | 25 + 1 file changed, 25 insertions(+) diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi index 64f488ba1e72..1801e30b1d3a 100644 --- a/arch/arm/boot/dts/tegra124.dtsi +++ b/arch/arm/boot/dts/tegra124.dtsi @@ -113,6 +113,19 @@ dc@5420 { iommus = <&mc TEGRA_SWGROUP_DC>; nvidia,head = <0>; + + interconnects = <&mc TEGRA124_MC_DISPLAY0A &emc>, + <&mc TEGRA124_MC_DISPLAY0B &emc>, + <&mc TEGRA124_MC_DISPLAY0C &emc>, + <&mc TEGRA124_MC_DISPLAYHC &emc>, + <&mc TEGRA124_MC_DISPLAYD &emc>, + <&mc TEGRA124_MC_DISPLAYT &emc>; + interconnect-names = "wina", +"winb", +"winc", +"cursor", +"wind", +"wint"; }; dc@5424 { @@ -127,6 +140,15 @@ dc@5424 { iommus = <&mc TEGRA_SWGROUP_DCB>; nvidia,head = <1>; + + interconnects = <&mc TEGRA124_MC_DISPLAY0AB &emc>, + <&mc TEGRA124_MC_DISPLAY0BB &emc>, + <&mc TEGRA124_MC_DISPLAY0CB &emc>, + <&mc TEGRA124_MC_DISPLAYHCB &emc>; + interconnect-names = "wina", +"winb", +"winc", +"cursor"; }; hdmi: hdmi@5428 { @@ -628,6 +650,7 @@ mc: memory-controller@70019000 { #iommu-cells = <1>; #reset-cells = <1>; + #interconnect-cells = <1>; }; emc: external-memory-controller@7001b000 { @@ -637,6 +660,8 @@ emc: external-memory-controller@7001b000 { clock-names = "emc"; nvidia,memory-controller = <&mc>; + + #interconnect-cells = <0>; }; sata@7002 { -- 2.29.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v8 15/26] drm/tegra: dc: Extend debug stats with total number of events
It's useful to know the total number of underflow events and currently the debug stats are getting reset each time CRTC is being disabled. Let's account the overall number of events that doesn't get a reset. Tested-by: Peter Geis Tested-by: Nicolas Chauvet Signed-off-by: Dmitry Osipenko --- drivers/gpu/drm/tegra/dc.c | 10 ++ drivers/gpu/drm/tegra/dc.h | 5 + 2 files changed, 15 insertions(+) diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 14168f792977..fd7c8828652d 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -1539,6 +1539,11 @@ static int tegra_dc_show_stats(struct seq_file *s, void *data) seq_printf(s, "underflow: %lu\n", dc->stats.underflow); seq_printf(s, "overflow: %lu\n", dc->stats.overflow); + seq_printf(s, "frames total: %lu\n", dc->stats.frames_total); + seq_printf(s, "vblank total: %lu\n", dc->stats.vblank_total); + seq_printf(s, "underflow total: %lu\n", dc->stats.underflow_total); + seq_printf(s, "overflow total: %lu\n", dc->stats.overflow_total); + return 0; } @@ -2308,6 +2313,7 @@ static irqreturn_t tegra_dc_irq(int irq, void *data) /* dev_dbg(dc->dev, "%s(): frame end\n", __func__); */ + dc->stats.frames_total++; dc->stats.frames++; } @@ -2316,6 +2322,7 @@ static irqreturn_t tegra_dc_irq(int irq, void *data) dev_dbg(dc->dev, "%s(): vertical blank\n", __func__); */ drm_crtc_handle_vblank(&dc->base); + dc->stats.vblank_total++; dc->stats.vblank++; } @@ -2323,6 +2330,7 @@ static irqreturn_t tegra_dc_irq(int irq, void *data) /* dev_dbg(dc->dev, "%s(): underflow\n", __func__); */ + dc->stats.underflow_total++; dc->stats.underflow++; } @@ -2330,11 +2338,13 @@ static irqreturn_t tegra_dc_irq(int irq, void *data) /* dev_dbg(dc->dev, "%s(): overflow\n", __func__); */ + dc->stats.overflow_total++; dc->stats.overflow++; } if (status & HEAD_UF_INT) { dev_dbg_ratelimited(dc->dev, "%s(): head underflow\n", __func__); + dc->stats.underflow_total++; dc->stats.underflow++; } diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h index 0d7bdf66a1ec..ba4ed35139fb 100644 --- a/drivers/gpu/drm/tegra/dc.h +++ b/drivers/gpu/drm/tegra/dc.h @@ -48,6 +48,11 @@ struct tegra_dc_stats { unsigned long vblank; unsigned long underflow; unsigned long overflow; + + unsigned long frames_total; + unsigned long vblank_total; + unsigned long underflow_total; + unsigned long overflow_total; }; struct tegra_windowgroup_soc { -- 2.29.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v8 08/26] memory: tegra30-emc: Continue probing if timings are missing in device-tree
EMC driver will become mandatory after turning it into interconnect provider because interconnect users, like display controller driver, will fail to probe using newer device-trees that have interconnect properties. Thus make EMC driver to probe even if timings are missing in device-tree. Signed-off-by: Dmitry Osipenko --- drivers/memory/tegra/tegra30-emc.c | 29 +++-- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/memory/tegra/tegra30-emc.c b/drivers/memory/tegra/tegra30-emc.c index d0926088360a..3488786da03b 100644 --- a/drivers/memory/tegra/tegra30-emc.c +++ b/drivers/memory/tegra/tegra30-emc.c @@ -988,6 +988,11 @@ static struct device_node *emc_find_node_by_ram_code(struct device *dev) u32 value, ram_code; int err; + if (of_get_child_count(dev->of_node) == 0) { + dev_info(dev, "device-tree doesn't have memory timings\n"); + return NULL; + } + ram_code = tegra_read_ram_code(); for_each_child_of_node(dev->of_node, np) { @@ -1057,6 +1062,9 @@ static long emc_round_rate(unsigned long rate, struct tegra_emc *emc = arg; unsigned int i; + if (!emc->num_timings) + return clk_get_rate(emc->clk); + min_rate = min(min_rate, emc->timings[emc->num_timings - 1].rate); for (i = 0; i < emc->num_timings; i++) { @@ -1262,16 +1270,6 @@ static int tegra_emc_probe(struct platform_device *pdev) struct tegra_emc *emc; int err; - if (of_get_child_count(pdev->dev.of_node) == 0) { - dev_info(&pdev->dev, -"device-tree node doesn't have memory timings\n"); - return -ENODEV; - } - - np = emc_find_node_by_ram_code(&pdev->dev); - if (!np) - return -EINVAL; - emc = devm_kzalloc(&pdev->dev, sizeof(*emc), GFP_KERNEL); if (!emc) { of_node_put(np); @@ -1285,10 +1283,13 @@ static int tegra_emc_probe(struct platform_device *pdev) emc->clk_nb.notifier_call = emc_clk_change_notify; emc->dev = &pdev->dev; - err = emc_load_timings_from_dt(emc, np); - of_node_put(np); - if (err) - return err; + np = emc_find_node_by_ram_code(&pdev->dev); + if (np) { + err = emc_load_timings_from_dt(emc, np); + of_node_put(np); + if (err) + return err; + } emc->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(emc->regs)) -- 2.29.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v8 04/26] memory: tegra20-emc: Add devfreq support
Add devfreq support to the Tegra20 EMC driver. Memory utilization statistics will be periodically polled from the memory controller and appropriate minimum clock rate will be selected by the devfreq governor. Signed-off-by: Dmitry Osipenko --- drivers/memory/tegra/Kconfig | 3 +- drivers/memory/tegra/tegra20-emc.c | 90 ++ 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig index ac3dfe155505..8cc1ec5be443 100644 --- a/drivers/memory/tegra/Kconfig +++ b/drivers/memory/tegra/Kconfig @@ -12,7 +12,8 @@ config TEGRA20_EMC tristate "NVIDIA Tegra20 External Memory Controller driver" default y depends on TEGRA_MC && ARCH_TEGRA_2x_SOC - select PM_OPP + select DEVFREQ_GOV_SIMPLE_ONDEMAND + select PM_DEVFREQ help This driver is for the External Memory Controller (EMC) found on Tegra20 chips. The EMC controls the external DRAM on the board. diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c index d01b556a6d06..b9cd965980e2 100644 --- a/drivers/memory/tegra/tegra20-emc.c +++ b/drivers/memory/tegra/tegra20-emc.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -102,6 +103,10 @@ #define EMC_FBIO_CFG5_DRAM_WIDTH_X16 BIT(4) +#define EMC_PWR_GATHER_CLEAR (1 << 8) +#define EMC_PWR_GATHER_DISABLE (2 << 8) +#define EMC_PWR_GATHER_ENABLE (3 << 8) + static const u16 emc_timing_registers[] = { EMC_RC, EMC_RFC, @@ -157,6 +162,7 @@ struct emc_timing { }; enum emc_rate_request_type { + EMC_RATE_DEVFREQ, EMC_RATE_DEBUG, EMC_RATE_ICC, EMC_RATE_TYPE_MAX, @@ -193,6 +199,8 @@ struct tegra_emc { /* protect shared rate-change code path */ struct mutex rate_lock; + + struct devfreq_simple_ondemand_data ondemand_data; }; static irqreturn_t tegra_emc_isr(int irq, void *data) @@ -1003,6 +1011,87 @@ static int tegra_emc_init_clk(struct tegra_emc *emc) return 0; } +static int tegra_emc_devfreq_target(struct device *dev, unsigned long *freq, + u32 flags) +{ + struct tegra_emc *emc = dev_get_drvdata(dev); + struct dev_pm_opp *opp; + unsigned long rate; + + opp = devfreq_recommended_opp(dev, freq, flags); + if (IS_ERR(opp)) { + dev_err(dev, "failed to find opp for %lu Hz\n", *freq); + return PTR_ERR(opp); + } + + rate = dev_pm_opp_get_freq(opp); + dev_pm_opp_put(opp); + + return emc_set_min_rate(emc, rate, EMC_RATE_DEVFREQ); +} + +static int tegra_emc_devfreq_get_dev_status(struct device *dev, + struct devfreq_dev_status *stat) +{ + struct tegra_emc *emc = dev_get_drvdata(dev); + + /* freeze counters */ + writel_relaxed(EMC_PWR_GATHER_DISABLE, emc->regs + EMC_STAT_CONTROL); + + /* +* busy_time: number of clocks EMC request was accepted +* total_time: number of clocks PWR_GATHER control was set to ENABLE +*/ + stat->busy_time = readl_relaxed(emc->regs + EMC_STAT_PWR_COUNT); + stat->total_time = readl_relaxed(emc->regs + EMC_STAT_PWR_CLOCKS); + stat->current_frequency = clk_get_rate(emc->clk); + + /* clear counters and restart */ + writel_relaxed(EMC_PWR_GATHER_CLEAR, emc->regs + EMC_STAT_CONTROL); + writel_relaxed(EMC_PWR_GATHER_ENABLE, emc->regs + EMC_STAT_CONTROL); + + return 0; +} + +static struct devfreq_dev_profile tegra_emc_devfreq_profile = { + .polling_ms = 30, + .target = tegra_emc_devfreq_target, + .get_dev_status = tegra_emc_devfreq_get_dev_status, +}; + +static int tegra_emc_devfreq_init(struct tegra_emc *emc) +{ + struct devfreq *devfreq; + + /* +* PWR_COUNT is 1/2 of PWR_CLOCKS at max, and thus, the up-threshold +* should be less than 50. Secondly, multiple active memory clients +* may cause over 20% of lost clock cycles due to stalls caused by +* competing memory accesses. This means that threshold should be +* set to a less than 30 in order to have a properly working governor. +*/ + emc->ondemand_data.upthreshold = 20; + + /* +* Reset statistic gathers state, select global bandwidth for the +* statistics collection mode and set clocks counter saturation +* limit to maximum. +*/ + writel_relaxed(0x, emc->regs + EMC_STAT_CONTROL); + writel_relaxed(0x, emc->regs + EMC_STAT_LLMC_CONTROL); + writel_relaxed(0x, emc->regs + EMC_STAT_PWR_CLOCK_LIMIT); + + devfreq = devm_devfreq_add_device(emc->dev, &tegra_emc_devfreq_profile, + DEVFREQ_GOV_SIMPLE_ONDEMAND, +
[PATCH v8 14/26] drm/tegra: dc: Support memory bandwidth management
Display controller (DC) performs isochronous memory transfers, and thus, has a requirement for a minimum memory bandwidth that shall be fulfilled, otherwise framebuffer data can't be fetched fast enough and this results in a DC's data-FIFO underflow that follows by a visual corruption. The Memory Controller drivers provide facility for memory bandwidth management via interconnect API. Let's wire up the interconnect API support to the DC driver in order to fix the distorted display output on T30 Ouya, T124 TK1 and other Tegra devices. Tested-by: Peter Geis Tested-by: Nicolas Chauvet Signed-off-by: Dmitry Osipenko --- drivers/gpu/drm/tegra/Kconfig | 1 + drivers/gpu/drm/tegra/dc.c| 349 ++ drivers/gpu/drm/tegra/dc.h| 14 ++ drivers/gpu/drm/tegra/drm.c | 14 ++ drivers/gpu/drm/tegra/hub.c | 3 + drivers/gpu/drm/tegra/plane.c | 121 drivers/gpu/drm/tegra/plane.h | 15 ++ 7 files changed, 517 insertions(+) diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/drm/tegra/Kconfig index 5043dcaf1cf9..1650a448eabd 100644 --- a/drivers/gpu/drm/tegra/Kconfig +++ b/drivers/gpu/drm/tegra/Kconfig @@ -9,6 +9,7 @@ config DRM_TEGRA select DRM_MIPI_DSI select DRM_PANEL select TEGRA_HOST1X + select INTERCONNECT select IOMMU_IOVA select CEC_CORE if CEC_NOTIFIER help diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 2d86627b0d4e..14168f792977 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -616,6 +617,9 @@ static int tegra_plane_atomic_check(struct drm_plane *plane, struct tegra_dc *dc = to_tegra_dc(state->crtc); int err; + plane_state->peak_memory_bandwidth = 0; + plane_state->avg_memory_bandwidth = 0; + /* no need for further checks if the plane is being disabled */ if (!state->crtc) return 0; @@ -802,6 +806,12 @@ static struct drm_plane *tegra_primary_plane_create(struct drm_device *drm, formats = dc->soc->primary_formats; modifiers = dc->soc->modifiers; + err = tegra_plane_interconnect_init(plane); + if (err) { + kfree(plane); + return ERR_PTR(err); + } + err = drm_universal_plane_init(drm, &plane->base, possible_crtcs, &tegra_plane_funcs, formats, num_formats, modifiers, type, NULL); @@ -833,9 +843,13 @@ static const u32 tegra_cursor_plane_formats[] = { static int tegra_cursor_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) { + struct tegra_plane_state *plane_state = to_tegra_plane_state(state); struct tegra_plane *tegra = to_tegra_plane(plane); int err; + plane_state->peak_memory_bandwidth = 0; + plane_state->avg_memory_bandwidth = 0; + /* no need for further checks if the plane is being disabled */ if (!state->crtc) return 0; @@ -973,6 +987,12 @@ static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm, num_formats = ARRAY_SIZE(tegra_cursor_plane_formats); formats = tegra_cursor_plane_formats; + err = tegra_plane_interconnect_init(plane); + if (err) { + kfree(plane); + return ERR_PTR(err); + } + err = drm_universal_plane_init(drm, &plane->base, possible_crtcs, &tegra_plane_funcs, formats, num_formats, NULL, @@ -1087,6 +1107,12 @@ static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm, num_formats = dc->soc->num_overlay_formats; formats = dc->soc->overlay_formats; + err = tegra_plane_interconnect_init(plane); + if (err) { + kfree(plane); + return ERR_PTR(err); + } + if (!cursor) type = DRM_PLANE_TYPE_OVERLAY; else @@ -1204,6 +1230,7 @@ tegra_crtc_atomic_duplicate_state(struct drm_crtc *crtc) { struct tegra_dc_state *state = to_dc_state(crtc->state); struct tegra_dc_state *copy; + unsigned int i; copy = kmalloc(sizeof(*copy), GFP_KERNEL); if (!copy) @@ -1215,6 +1242,9 @@ tegra_crtc_atomic_duplicate_state(struct drm_crtc *crtc) copy->div = state->div; copy->planes = state->planes; + for (i = 0; i < ARRAY_SIZE(state->plane_peak_bw); i++) + copy->plane_peak_bw[i] = state->plane_peak_bw[i]; + return ©->base; } @@ -1741,6 +1771,106 @@ static int tegra_dc_wait_idle(struct tegra_dc *dc, unsigned long timeout) return -ETIMEDOUT; } +static void +tegra_crtc_update_memory_bandwidth(struct drm_crtc *crtc, + struct
[PATCH v8 07/26] memory: tegra30-emc: Make driver modular
Add modularization support to the Tegra30 EMC driver, which now can be compiled as a loadable kernel module. Signed-off-by: Dmitry Osipenko --- drivers/memory/tegra/Kconfig | 2 +- drivers/memory/tegra/mc.c | 3 +++ drivers/memory/tegra/tegra30-emc.c | 17 - 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig index 8cc1ec5be443..2a4a16bcf91c 100644 --- a/drivers/memory/tegra/Kconfig +++ b/drivers/memory/tegra/Kconfig @@ -21,7 +21,7 @@ config TEGRA20_EMC external memory. config TEGRA30_EMC - bool "NVIDIA Tegra30 External Memory Controller driver" + tristate "NVIDIA Tegra30 External Memory Controller driver" default y depends on TEGRA_MC && ARCH_TEGRA_3x_SOC help diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c index a7e6a8e4c95a..44064de962c2 100644 --- a/drivers/memory/tegra/mc.c +++ b/drivers/memory/tegra/mc.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -346,6 +347,7 @@ int tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate) return 0; } +EXPORT_SYMBOL_GPL(tegra_mc_write_emem_configuration); unsigned int tegra_mc_get_emem_device_count(struct tegra_mc *mc) { @@ -357,6 +359,7 @@ unsigned int tegra_mc_get_emem_device_count(struct tegra_mc *mc) return dram_count; } +EXPORT_SYMBOL_GPL(tegra_mc_get_emem_device_count); static int load_one_timing(struct tegra_mc *mc, struct tegra_mc_timing *timing, diff --git a/drivers/memory/tegra/tegra30-emc.c b/drivers/memory/tegra/tegra30-emc.c index 1be28e28ec34..d0926088360a 100644 --- a/drivers/memory/tegra/tegra30-emc.c +++ b/drivers/memory/tegra/tegra30-emc.c @@ -1330,6 +1330,13 @@ static int tegra_emc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, emc); tegra_emc_debugfs_init(emc); + /* +* Don't allow the kernel module to be unloaded. Unloading adds some +* extra complexity which doesn't really worth the effort in a case of +* this driver. +*/ + try_module_get(THIS_MODULE); + return 0; unset_cb: @@ -1380,6 +1387,7 @@ static const struct of_device_id tegra_emc_of_match[] = { { .compatible = "nvidia,tegra30-emc", }, {}, }; +MODULE_DEVICE_TABLE(of, tegra_emc_of_match); static struct platform_driver tegra_emc_driver = { .probe = tegra_emc_probe, @@ -1390,9 +1398,8 @@ static struct platform_driver tegra_emc_driver = { .suppress_bind_attrs = true, }, }; +module_platform_driver(tegra_emc_driver); -static int __init tegra_emc_init(void) -{ - return platform_driver_register(&tegra_emc_driver); -} -subsys_initcall(tegra_emc_init); +MODULE_AUTHOR("Dmitry Osipenko "); +MODULE_DESCRIPTION("NVIDIA Tegra30 EMC driver"); +MODULE_LICENSE("GPL v2"); -- 2.29.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 00/56] Convert DSI code to use drm_mipi_dsi and drm_panel
> Am 11.11.2020 um 07:40 schrieb Tomi Valkeinen : > > On 10/11/2020 23:04, H. Nikolaus Schaller wrote: >> >>> Am 10.11.2020 um 17:52 schrieb Tomi Valkeinen : >>> >>> On 10/11/2020 18:49, H. Nikolaus Schaller wrote: >>> >>> I guess you have the same issue. It goes to dsi_bridge_mode_valid, then >>> __dsi_calc_config, and stays >>> there finding good clocks. >> > > drm_display_mode.clock is in kHz, but the panel driver writes Hz > (w677l_PIXELCLOCK) to it. Ok, fixing this removes the stuck thread issue. Thanks for pointing this out! > But > there's more after fixing that. The DSI gets configured in bridge's modeset, > which I think is before > w677l_prepare where the panel already sends DSI commands. Also, the dsi > driver fails to lock the > PLL, so possibly the clock calcs are still wrong. What I now get is [ 131.035006] [drm:drm_atomic_helper_wait_for_dependencies [drm_kms_helper]] *ERROR* [CRTC:55:crtc-0] flip_done timed out [ 141.272174] [drm:drm_atomic_helper_wait_for_dependencies [drm_kms_helper]] *ERROR* [CONNECTOR:54:DSI-1] flip_done timed out I think for further experiments we could hack the device tree to compatible = "orisetech,otm8009a"; and configure for panel-orisetech-otm8009a.ko. Since this panel driver is known to work elsewhere we could exclude panel driver issues for the moment. To be safe we can modify otm8009a_dcs_write_buf() to just print what it would be doing. BR, Nikolaus ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v8 02/26] memory: tegra20-emc: Use dev_pm_opp_set_clkname()
On 11-11-20, 11:15, Viresh Kumar wrote: > On 11-11-20, 04:14, Dmitry Osipenko wrote: > > The dev_pm_opp_get_opp_table() shouldn't be used by drivers, use > > dev_pm_opp_set_clkname() instead. > > > > Suggested-by: Viresh Kumar > > Signed-off-by: Dmitry Osipenko > > --- > > drivers/memory/tegra/tegra20-emc.c | 30 +++--- > > 1 file changed, 19 insertions(+), 11 deletions(-) > > > > diff --git a/drivers/memory/tegra/tegra20-emc.c > > b/drivers/memory/tegra/tegra20-emc.c > > index 5e10aa97809f..bb3f315c9587 100644 > > --- a/drivers/memory/tegra/tegra20-emc.c > > +++ b/drivers/memory/tegra/tegra20-emc.c > > @@ -902,7 +902,7 @@ static int tegra_emc_interconnect_init(struct tegra_emc > > *emc) > > > > static int tegra_emc_opp_table_init(struct tegra_emc *emc) > > { > > - struct opp_table *opp_table; > > + struct opp_table *reg_opp_table = NULL, *clk_opp_table; > > const char *rname = "core"; > > int err; > > > > @@ -917,19 +917,24 @@ static int tegra_emc_opp_table_init(struct tegra_emc > > *emc) > > } > > > > /* voltage scaling is optional */ > > - if (device_property_present(emc->dev, "core-supply")) > > - opp_table = dev_pm_opp_set_regulators(emc->dev, &rname, 1); > > - else > > - opp_table = dev_pm_opp_get_opp_table(emc->dev); > > + if (device_property_present(emc->dev, "core-supply")) { > > + reg_opp_table = dev_pm_opp_set_regulators(emc->dev, &rname, 1); > > + if (IS_ERR(reg_opp_table)) > > + return dev_err_probe(emc->dev, PTR_ERR(reg_opp_table), > > +"failed to set OPP regulator\n"); > > + } > > > > - if (IS_ERR(opp_table)) > > - return dev_err_probe(emc->dev, PTR_ERR(opp_table), > > -"failed to prepare OPP table\n"); > > + clk_opp_table = dev_pm_opp_set_clkname(emc->dev, NULL); > > + err = PTR_ERR_OR_ZERO(clk_opp_table); > > Don't check for NULL here. My bad. You aren't checking but just converting to err. Its fine. -- viresh ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm/panel: add missing platform_driver_unregister() on error path
If mipi_dsi_driver_register() failed, platform_driver_unregister() need be called. Fixes: 210fcd9d9cf1 ("drm/panel: Add support for Panasonic VVX10F004B0") Reported-by: Hulk Robot Signed-off-by: Yang Yingliang --- drivers/gpu/drm/panel/panel-simple.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 2be358fb46f7..2966ac13c538 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -4644,8 +4644,10 @@ static int __init panel_simple_init(void) if (IS_ENABLED(CONFIG_DRM_MIPI_DSI)) { err = mipi_dsi_driver_register(&panel_simple_dsi_driver); - if (err < 0) + if (err < 0) { + platform_driver_unregister(&panel_simple_platform_driver); return err; + } } return 0; -- 2.25.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v1 11/30] drm/tegra: dc: Support OPP and SoC core voltage scaling
10.11.2020 23:29, Thierry Reding пишет: >> +/* legacy device-trees don't have OPP table */ >> +if (!device_property_present(dc->dev, "operating-points-v2")) >> +return 0; > "Legacy" is a bit confusing here. For one, no device trees currently > have these tables and secondly, for newer SoCs we may never need them. > I had the same thought and already improved such comments a day ago. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v8 09/26] memory: tegra30: Support interconnect framework
Now Internal and External memory controllers are memory interconnection providers. This allows us to use interconnect API for tuning of memory configuration. EMC driver now supports OPPs and DVFS. MC driver now supports tuning of memory arbitration latency, which needs to be done for ISO memory clients, like a Display client for example. Tested-by: Peter Geis Signed-off-by: Dmitry Osipenko --- drivers/memory/tegra/Kconfig | 1 + drivers/memory/tegra/tegra30-emc.c | 300 - drivers/memory/tegra/tegra30.c | 173 - 3 files changed, 471 insertions(+), 3 deletions(-) diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig index 2a4a16bcf91c..ca7077a06f4c 100644 --- a/drivers/memory/tegra/Kconfig +++ b/drivers/memory/tegra/Kconfig @@ -24,6 +24,7 @@ config TEGRA30_EMC tristate "NVIDIA Tegra30 External Memory Controller driver" default y depends on TEGRA_MC && ARCH_TEGRA_3x_SOC + select PM_OPP help This driver is for the External Memory Controller (EMC) found on Tegra30 chips. The EMC controls the external DRAM on the board. diff --git a/drivers/memory/tegra/tegra30-emc.c b/drivers/memory/tegra/tegra30-emc.c index 3488786da03b..d27df842a667 100644 --- a/drivers/memory/tegra/tegra30-emc.c +++ b/drivers/memory/tegra/tegra30-emc.c @@ -14,16 +14,21 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include +#include +#include #include #include +#include #include #include "mc.h" @@ -323,9 +328,21 @@ struct emc_timing { bool emc_cfg_dyn_self_ref; }; +enum emc_rate_request_type { + EMC_RATE_DEBUG, + EMC_RATE_ICC, + EMC_RATE_TYPE_MAX, +}; + +struct emc_rate_request { + unsigned long min_rate; + unsigned long max_rate; +}; + struct tegra_emc { struct device *dev; struct tegra_mc *mc; + struct icc_provider provider; struct notifier_block clk_nb; struct clk *clk; void __iomem *regs; @@ -352,6 +369,15 @@ struct tegra_emc { unsigned long min_rate; unsigned long max_rate; } debugfs; + + /* +* There are multiple sources in the EMC driver which could request +* a min/max clock rate, these rates are contained in this array. +*/ + struct emc_rate_request requested_rate[EMC_RATE_TYPE_MAX]; + + /* protect shared rate-change code path */ + struct mutex rate_lock; }; static int emc_seq_update_timing(struct tegra_emc *emc) @@ -1094,6 +1120,83 @@ static long emc_round_rate(unsigned long rate, return timing->rate; } +static void tegra_emc_rate_requests_init(struct tegra_emc *emc) +{ + unsigned int i; + + for (i = 0; i < EMC_RATE_TYPE_MAX; i++) { + emc->requested_rate[i].min_rate = 0; + emc->requested_rate[i].max_rate = ULONG_MAX; + } +} + +static int emc_request_rate(struct tegra_emc *emc, + unsigned long new_min_rate, + unsigned long new_max_rate, + enum emc_rate_request_type type) +{ + struct emc_rate_request *req = emc->requested_rate; + unsigned long min_rate = 0, max_rate = ULONG_MAX; + unsigned int i; + int err; + + /* select minimum and maximum rates among the requested rates */ + for (i = 0; i < EMC_RATE_TYPE_MAX; i++, req++) { + if (i == type) { + min_rate = max(new_min_rate, min_rate); + max_rate = min(new_max_rate, max_rate); + } else { + min_rate = max(req->min_rate, min_rate); + max_rate = min(req->max_rate, max_rate); + } + } + + if (min_rate > max_rate) { + dev_err_ratelimited(emc->dev, "%s: type %u: out of range: %lu %lu\n", + __func__, type, min_rate, max_rate); + return -ERANGE; + } + + /* +* EMC rate-changes should go via OPP API because it manages voltage +* changes. +*/ + err = dev_pm_opp_set_rate(emc->dev, min_rate); + if (err) + return err; + + emc->requested_rate[type].min_rate = new_min_rate; + emc->requested_rate[type].max_rate = new_max_rate; + + return 0; +} + +static int emc_set_min_rate(struct tegra_emc *emc, unsigned long rate, + enum emc_rate_request_type type) +{ + struct emc_rate_request *req = &emc->requested_rate[type]; + int ret; + + mutex_lock(&emc->rate_lock); + ret = emc_request_rate(emc, rate, req->max_rate, type); + mutex_unlock(&emc->rate_lock); + + return ret; +} + +static int emc_set_max_rate(struct tegra_emc *emc, unsigned long rate, + enum emc_rate_request_type
Re: [PATCH] drm/ingenic: ipu: Search for scaling coefs up to 102% of the screen
Hi, Le sam. 7 nov. 2020 à 20:33, Sam Ravnborg a écrit : Hi Paul. On Thu, Nov 05, 2020 at 08:39:05AM +, Paul Cercueil wrote: Increase the scaled image's theorical width/height until we find a configuration that has valid scaling coefficients, up to 102% of the screen's resolution. This makes sure that we can scale from almost every resolution possible at the cost of a very small distorsion. The CRTC_W / CRTC_H are not modified. This algorithm was already in place but would not try to go above the screen's resolution, and as a result would only work if the CRTC_W / CRTC_H were smaller than the screen resolution. It will now try until it reaches 102% of the screen's resolution. Signed-off-by: Paul Cercueil Looks like the patch does what the descriptions says. So in other words - look OK to me. I am not confident enogh for a r-b but my code reading is enough to warrant an a-b: Acked-by: Sam Ravnborg Note that this algorithm exists mostly as a band-aid for a missing functionality: it is not possible for userspace to request the closest mode that would encapsulate the provided one, because the GEM buffer is created beforehand. If there was a way to let the kernel tweak the mode, I could write a better algorithm that would result in a better looking picture. Cheers, -Paul ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v8 11/26] memory: tegra124-emc: Make driver modular
Add modularization support to the Tegra124 EMC driver, which now can be compiled as a loadable kernel module. Note that EMC clock must be registered at clk-init time, otherwise PLLM will be disabled as unused clock at boot time if EMC driver is compiled as a module. Hence add a prepare/complete callbacks. similarly to what is done for the Tegra20/30 EMC drivers. Tested-by: Nicolas Chauvet Signed-off-by: Dmitry Osipenko --- drivers/clk/tegra/Makefile | 3 +- drivers/clk/tegra/clk-tegra124-emc.c | 41 drivers/clk/tegra/clk-tegra124.c | 27 -- drivers/clk/tegra/clk.h | 16 +++ drivers/memory/tegra/Kconfig | 2 +- drivers/memory/tegra/tegra124-emc.c | 31 ++--- include/linux/clk/tegra.h| 8 ++ include/soc/tegra/emc.h | 16 --- 8 files changed, 96 insertions(+), 48 deletions(-) delete mode 100644 include/soc/tegra/emc.h diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile index eec2313fd37e..53b76133e905 100644 --- a/drivers/clk/tegra/Makefile +++ b/drivers/clk/tegra/Makefile @@ -22,7 +22,8 @@ obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra20-emc.o obj-$(CONFIG_ARCH_TEGRA_114_SOC) += clk-tegra114.o obj-$(CONFIG_ARCH_TEGRA_124_SOC) += clk-tegra124.o obj-$(CONFIG_TEGRA_CLK_DFLL) += clk-tegra124-dfll-fcpu.o -obj-$(CONFIG_TEGRA124_EMC) += clk-tegra124-emc.o +obj-$(CONFIG_ARCH_TEGRA_124_SOC) += clk-tegra124-emc.o +obj-$(CONFIG_ARCH_TEGRA_132_SOC) += clk-tegra124-emc.o obj-$(CONFIG_ARCH_TEGRA_132_SOC) += clk-tegra124.o obj-y += cvb.o obj-$(CONFIG_ARCH_TEGRA_210_SOC) += clk-tegra210.o diff --git a/drivers/clk/tegra/clk-tegra124-emc.c b/drivers/clk/tegra/clk-tegra124-emc.c index 745f9faa98d8..bdf6f4a51617 100644 --- a/drivers/clk/tegra/clk-tegra124-emc.c +++ b/drivers/clk/tegra/clk-tegra124-emc.c @@ -11,7 +11,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -21,7 +23,6 @@ #include #include -#include #include "clk.h" @@ -80,6 +81,9 @@ struct tegra_clk_emc { int num_timings; struct emc_timing *timings; spinlock_t *lock; + + tegra124_emc_prepare_timing_change_cb *prepare_timing_change; + tegra124_emc_complete_timing_change_cb *complete_timing_change; }; /* Common clock framework callback implementations */ @@ -176,6 +180,9 @@ static struct tegra_emc *emc_ensure_emc_driver(struct tegra_clk_emc *tegra) if (tegra->emc) return tegra->emc; + if (!tegra->prepare_timing_change || !tegra->complete_timing_change) + return NULL; + if (!tegra->emc_node) return NULL; @@ -241,7 +248,7 @@ static int emc_set_timing(struct tegra_clk_emc *tegra, div = timing->parent_rate / (timing->rate / 2) - 2; - err = tegra_emc_prepare_timing_change(emc, timing->rate); + err = tegra->prepare_timing_change(emc, timing->rate); if (err) return err; @@ -259,7 +266,7 @@ static int emc_set_timing(struct tegra_clk_emc *tegra, spin_unlock_irqrestore(tegra->lock, flags); - tegra_emc_complete_timing_change(emc, timing->rate); + tegra->complete_timing_change(emc, timing->rate); clk_hw_reparent(&tegra->hw, __clk_get_hw(timing->parent)); clk_disable_unprepare(tegra->prev_parent); @@ -473,8 +480,8 @@ static const struct clk_ops tegra_clk_emc_ops = { .get_parent = emc_get_parent, }; -struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np, - spinlock_t *lock) +struct clk *tegra124_clk_register_emc(void __iomem *base, struct device_node *np, + spinlock_t *lock) { struct tegra_clk_emc *tegra; struct clk_init_data init; @@ -538,3 +545,27 @@ struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np, return clk; }; + +void tegra124_clk_set_emc_callbacks(tegra124_emc_prepare_timing_change_cb *prep_cb, + tegra124_emc_complete_timing_change_cb *complete_cb) +{ + struct clk *clk = __clk_lookup("emc"); + struct tegra_clk_emc *tegra; + struct clk_hw *hw; + + if (clk) { + hw = __clk_get_hw(clk); + tegra = container_of(hw, struct tegra_clk_emc, hw); + + tegra->prepare_timing_change = prep_cb; + tegra->complete_timing_change = complete_cb; + } +} +EXPORT_SYMBOL_GPL(tegra124_clk_set_emc_callbacks); + +bool tegra124_clk_emc_driver_available(struct clk_hw *hw) +{ + struct tegra_clk_emc *tegra = container_of(hw, struct tegra_clk_emc, hw); + + return tegra->prepare_timing_change && tegra->complete_timing_change; +} diff --git a/drivers/clk/tegra/clk-tegra124.c b
[PATCH v8 01/26] memory: tegra: Correct stub of devm_tegra_memory_controller_get()
Correct typo in a stub of devm_tegra_memory_controller_get() to fix a non-ARM kernel compile-testing. Reported-by: Stephen Rothwell Signed-off-by: Dmitry Osipenko --- include/soc/tegra/mc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/soc/tegra/mc.h b/include/soc/tegra/mc.h index 43876216de34..d731407e23bb 100644 --- a/include/soc/tegra/mc.h +++ b/include/soc/tegra/mc.h @@ -207,7 +207,7 @@ struct tegra_mc *devm_tegra_memory_controller_get(struct device *dev); static inline struct tegra_mc * devm_tegra_memory_controller_get(struct device *dev) { - ERR_PTR(-ENODEV); + return ERR_PTR(-ENODEV); } #endif -- 2.29.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v8 12/26] memory: tegra124-emc: Continue probing if timings are missing in device-tree
EMC driver will become mandatory after turning it into interconnect provider because interconnect users, like display controller driver, will fail to probe using newer device-trees that have interconnect properties. Thus make EMC driver to probe even if timings are missing in device-tree. Signed-off-by: Dmitry Osipenko --- drivers/memory/tegra/tegra124-emc.c | 26 +- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/drivers/memory/tegra/tegra124-emc.c b/drivers/memory/tegra/tegra124-emc.c index edfbf6d6d357..8fb8c1af25c9 100644 --- a/drivers/memory/tegra/tegra124-emc.c +++ b/drivers/memory/tegra/tegra124-emc.c @@ -1201,23 +1201,15 @@ static int tegra_emc_probe(struct platform_device *pdev) ram_code = tegra_read_ram_code(); np = tegra_emc_find_node_by_ram_code(pdev->dev.of_node, ram_code); - if (!np) { - dev_err(&pdev->dev, - "no memory timings for RAM code %u found in DT\n", - ram_code); - return -ENOENT; - } - - err = tegra_emc_load_timings_from_dt(emc, np); - of_node_put(np); - if (err) - return err; - - if (emc->num_timings == 0) { - dev_err(&pdev->dev, - "no memory timings for RAM code %u registered\n", - ram_code); - return -ENOENT; + if (np) { + err = tegra_emc_load_timings_from_dt(emc, np); + of_node_put(np); + if (err) + return err; + } else { + dev_info(&pdev->dev, +"no memory timings for RAM code %u found in DT\n", +ram_code); } err = emc_init(emc); -- 2.29.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v8 00/26] Introduce memory interconnect for NVIDIA Tegra SoCs
This series brings initial support for memory interconnect to Tegra20, Tegra30 and Tegra124 SoCs. For the starter only display controllers and devfreq devices are getting interconnect API support, others could be supported later on. The display controllers have the biggest demand for interconnect API right now because dynamic memory frequency scaling can't be done safely without taking into account bandwidth requirement from the displays. In particular this series fixes distorted display output on T30 Ouya and T124 TK1 devices. Changelog: v8: - Patches that are already applied by Krzysztof Kozlowski not included. - Removed tegra20-devfreq.c from MAINTAINERS, suggested by Chanwoo Choi. - The patch "memory: tegra20-emc: Add devfreq support" now removes PM_OPP for Tegra20 EMC driver from Kconfig, suggested by Chanwoo Choi. - Now using devm_devfreq_add_device() for Tegra20 devfreq, suggested by Chanwoo Choi. - Added acks from Chanwoo Choi. Although, devfreq patches probably should go via devfreq tree in order to avoid conflicts with the other previously-applied patches by Chanwoo. - Dropped superfluous dev_pm_opp_get_opp_table() from patch "devfreq: tegra30: Support interconnect and OPPs from device-tree". - Silenced another minor W=1 compilation warning reported by kernel test robot. - Added couple extra minor clean-up changes, including those that will ease further code changes. Added these new patches: memory: tegra20-emc: Remove IRQ number from error message memory: tegra20-emc: Factor out clk initialization memory: tegra30-emc: Factor out clk initialization Note that some of the new T124 changes are compile-tested only, but I expect that we will re-test them fully soon. - Added patch that fixes compilation of a non-Tegra kernels. memory: tegra: Correct stub of devm_tegra_memory_controller_get() - Replaced dev_pm_opp_get_opp_table() with dev_pm_opp_set_clkname(), as was suggested by Viresh Kumar in other thread. - Added patch that will allow T124 EMC driver to probe even if DT doesn't have memory timings, this was missed by accident previously. memory: tegra124-emc: Continue probing if timings are missing in device-tree Dmitry Osipenko (26): memory: tegra: Correct stub of devm_tegra_memory_controller_get() memory: tegra20-emc: Use dev_pm_opp_set_clkname() memory: tegra20-emc: Factor out clk initialization memory: tegra20-emc: Add devfreq support memory: tegra20-emc: Remove IRQ number from error message memory: tegra30: Add FIFO sizes to memory clients memory: tegra30-emc: Make driver modular memory: tegra30-emc: Continue probing if timings are missing in device-tree memory: tegra30: Support interconnect framework memory: tegra30-emc: Factor out clk initialization memory: tegra124-emc: Make driver modular memory: tegra124-emc: Continue probing if timings are missing in device-tree memory: tegra124: Support interconnect framework drm/tegra: dc: Support memory bandwidth management drm/tegra: dc: Extend debug stats with total number of events PM / devfreq: tegra30: Support interconnect and OPPs from device-tree PM / devfreq: tegra30: Separate configurations per-SoC generation PM / devfreq: tegra20: Deprecate in a favor of emc-stat based driver ARM: tegra: Correct EMC registers size in Tegra20 device-tree ARM: tegra: Add interconnect properties to Tegra20 device-tree ARM: tegra: Add interconnect properties to Tegra30 device-tree ARM: tegra: Add interconnect properties to Tegra124 device-tree ARM: tegra: Add nvidia,memory-controller phandle to Tegra20 EMC device-tree ARM: tegra: Add DVFS properties to Tegra20 EMC device-tree node ARM: tegra: Add DVFS properties to Tegra30 EMC and ACTMON device-tree nodes ARM: tegra: Add DVFS properties to Tegra124 EMC and ACTMON device-tree nodes MAINTAINERS | 1 - arch/arm/boot/dts/tegra124-apalis-emc.dtsi| 8 + .../arm/boot/dts/tegra124-jetson-tk1-emc.dtsi | 8 + arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi | 10 + .../arm/boot/dts/tegra124-nyan-blaze-emc.dtsi | 10 + .../boot/dts/tegra124-peripherals-opp.dtsi| 419 ++ arch/arm/boot/dts/tegra124.dtsi | 31 ++ .../boot/dts/tegra20-acer-a500-picasso.dts| 7 + arch/arm/boot/dts/tegra20-colibri.dtsi| 4 + arch/arm/boot/dts/tegra20-paz00.dts | 6 + .../arm/boot/dts/tegra20-peripherals-opp.dtsi | 92 arch/arm/boot/dts/tegra20.dtsi| 33 +- .../tegra30-asus-nexus7-grouper-common.dtsi | 4 + ...30-asus-nexus7-grouper-memory-timings.dtsi | 12 + .../arm/boot/dts/tegra30-peripherals-opp.dtsi | 383 arch/arm/boot/dts/tegra30.dtsi| 33 +- drivers/clk/tegra/Makefile| 3 +- drivers/clk/tegra/clk-tegra124-emc.c
[PATCH v8 23/26] ARM: tegra: Add nvidia, memory-controller phandle to Tegra20 EMC device-tree
Add nvidia,memory-controller to the Tegra20 External Memory Controller node. This allows to perform a direct lookup of the Memory Controller instead of walking up the whole tree. This puts Tegra20 device-tree on par with Tegra30+. Signed-off-by: Dmitry Osipenko --- arch/arm/boot/dts/tegra20.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi index 2e1304493f7d..8f8ad81916e7 100644 --- a/arch/arm/boot/dts/tegra20.dtsi +++ b/arch/arm/boot/dts/tegra20.dtsi @@ -663,6 +663,8 @@ emc: memory-controller@7000f400 { #address-cells = <1>; #size-cells = <0>; #interconnect-cells = <0>; + + nvidia,memory-controller = <&mc>; }; fuse@7000f800 { -- 2.29.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v8 19/26] ARM: tegra: Correct EMC registers size in Tegra20 device-tree
Fix the size of Tegra20 EMC registers, which should be twice bigger. Acked-by: Krzysztof Kozlowski Signed-off-by: Dmitry Osipenko --- arch/arm/boot/dts/tegra20.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi index 72a4211a618f..9347f7789245 100644 --- a/arch/arm/boot/dts/tegra20.dtsi +++ b/arch/arm/boot/dts/tegra20.dtsi @@ -634,7 +634,7 @@ mc: memory-controller@7000f000 { memory-controller@7000f400 { compatible = "nvidia,tegra20-emc"; - reg = <0x7000f400 0x200>; + reg = <0x7000f400 0x400>; interrupts = ; clocks = <&tegra_car TEGRA20_CLK_EMC>; #address-cells = <1>; -- 2.29.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v1 11/30] drm/tegra: dc: Support OPP and SoC core voltage scaling
10.11.2020 23:29, Thierry Reding пишет: >> + >> +dc->opp_table = dev_pm_opp_get_opp_table(dc->dev); >> +if (IS_ERR(dc->opp_table)) >> +return dev_err_probe(dc->dev, PTR_ERR(dc->opp_table), >> + "failed to prepare OPP table\n"); >> + >> +if (of_machine_is_compatible("nvidia,tegra20")) >> +hw_version = BIT(tegra_sku_info.soc_process_id); >> +else >> +hw_version = BIT(tegra_sku_info.soc_speedo_id); >> + >> +hw_opp_table = dev_pm_opp_set_supported_hw(dc->dev, &hw_version, 1); >> +err = PTR_ERR_OR_ZERO(hw_opp_table); > What's the point of this? A more canonical version would be: > > if (IS_ERR(hw_opp_table)) { > err = PTR_ERR(hw_opp_table); > dev_err(dc->dev, ...); > goto put_table; > } > > That uses the same number of lines but is much easier to read, in my > opinion, because it is the canonical form. > Your variant is much more difficult to read for me :/ I guess the only reason it could be "canonical" is because PTR_ERR_OR_ZERO was added not so long time ago. But don't worry, this code will be moved out in a v2 and it won't use PTR_ERR_OR_ZERO. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 2/4] drm: omapdrm: dss: fix reference leak in dss_runtime_get
pm_runtime_get_sync() will increment pm usage at first and it will resume the device later. If runtime of the device has error or device is in inaccessible state(or other error state), resume operation will fail. If we do not call put operation to decrease the reference, it will result in reference leak in dss_runtime_get. Moreover, this device cannot enter the idle state and always stay busy or other non-idle state later. So we should fix it through adding pm_runtime_put_noidle. Fixes: 7b295257a13d8 ("drm: omapdrm: dss: Pass DSS private structure to runtime PM functions") Signed-off-by: Zhang Qilong --- drivers/gpu/drm/omapdrm/dss/dss.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c index 6ccbc29c4ce4..9571f3db6f71 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.c +++ b/drivers/gpu/drm/omapdrm/dss/dss.c @@ -858,8 +858,12 @@ int dss_runtime_get(struct dss_device *dss) DSSDBG("dss_runtime_get\n"); r = pm_runtime_get_sync(&dss->pdev->dev); - WARN_ON(r < 0); - return r < 0 ? r : 0; + if (WARN_ON(r < 0)) { + pm_runtime_put_noidle(&dss->pdev->dev); + return r; + } + + return 0; } void dss_runtime_put(struct dss_device *dss) -- 2.25.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 00/56] Convert DSI code to use drm_mipi_dsi and drm_panel
> Am 10.11.2020 um 17:52 schrieb Tomi Valkeinen : > > On 10/11/2020 18:49, H. Nikolaus Schaller wrote: > > I guess you have the same issue. It goes to dsi_bridge_mode_valid, then > __dsi_calc_config, and stays > there finding good clocks. Yes, I could trace it down to exactly this point. So the culprit is somehow the panel driver. Because it asks for clocks that the PLL driver does not want to provide... Or is it the victim? Here is what dmesg reports with even more printk(): [ 276.970635] drm_helper_probe_single_connector_modes 12 count=1 [ 277.003509] drm_mode_validate_pipeline 2 ret=0 status=0 [ 277.038678] drm_bridge_chain_mode_valid: func=dsi_bridge_mode_valid+0x0/0xa0 [omapdrm] [ 277.047199] dsi_bridge_mode_valid [ 277.050786] __dsi_calc_config [ 277.057270] dsi_vm_calc [ 277.073251] dss_pll_calc_a clkin=1920 pll_min=1555386656 pll_max=1555410656 func=dsi_vm_calc_pll_cb+0x0/0x48 [omapdrm] [ 277.084975] dss_pll_calc_a pll_hw_max=18 fint_hw_min=15 fint_hw_max=5200 [ 277.093637] dss_pll_calc_a n_start=1 n_inc=1 n_stop=128 pll_max'=1555410656 [ 277.101062] dss_pll_calc_a n=1 clkin=1920 fint=1920 [ 277.107152] dss_pll_calc_a m_start=41 m_inc=1 m_stop=40 Ok, we have to wait quite a while until the for(m;;) loop ends, because m_stop < m_start and m_inc is positive. So something in the formulae in dss_pll_calc_a() does not fit or has unintended rounding effects. Or the values reported by w677l_get_modes() do not fit anything. I think these findings and ideas should help to find a fix. BR and thanks, Nikolaus ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v8 26/26] ARM: tegra: Add DVFS properties to Tegra124 EMC and ACTMON device-tree nodes
Add EMC OPP DVFS/DFS tables and interconnect paths that will be used for dynamic memory bandwidth scaling based on memory utilization statistics. Remove unsupported EMC OPPs from board device-trees. Note that ACTMON watches all memory interconnect paths, but we use a single CPU-READ interconnect path for driving memory bandwidth, for simplicity. Signed-off-by: Dmitry Osipenko --- arch/arm/boot/dts/tegra124-apalis-emc.dtsi| 8 + .../arm/boot/dts/tegra124-jetson-tk1-emc.dtsi | 8 + arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi | 10 + .../arm/boot/dts/tegra124-nyan-blaze-emc.dtsi | 10 + .../boot/dts/tegra124-peripherals-opp.dtsi| 419 ++ arch/arm/boot/dts/tegra124.dtsi | 6 + 6 files changed, 461 insertions(+) create mode 100644 arch/arm/boot/dts/tegra124-peripherals-opp.dtsi diff --git a/arch/arm/boot/dts/tegra124-apalis-emc.dtsi b/arch/arm/boot/dts/tegra124-apalis-emc.dtsi index 32401457ae71..a7ac805eeed5 100644 --- a/arch/arm/boot/dts/tegra124-apalis-emc.dtsi +++ b/arch/arm/boot/dts/tegra124-apalis-emc.dtsi @@ -1465,3 +1465,11 @@ timing-92400 { }; }; }; + +&emc_icc_dvfs_opp_table { + /delete-node/ opp@12,1100; +}; + +&emc_bw_dfs_opp_table { + /delete-node/ opp@12; +}; diff --git a/arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi b/arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi index 861d3f22116b..df4e463afbd1 100644 --- a/arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi +++ b/arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi @@ -2420,3 +2420,11 @@ timing-92400 { }; }; }; + +&emc_icc_dvfs_opp_table { + /delete-node/ opp@12,1100; +}; + +&emc_bw_dfs_opp_table { + /delete-node/ opp@12; +}; diff --git a/arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi b/arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi index c91647d13a50..a0f56cc9da5c 100644 --- a/arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi +++ b/arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi @@ -6649,3 +6649,13 @@ timing-79200 { }; }; }; + +&emc_icc_dvfs_opp_table { + /delete-node/ opp@92400,1100; + /delete-node/ opp@12,1100; +}; + +&emc_bw_dfs_opp_table { + /delete-node/ opp@92400; + /delete-node/ opp@12; +}; diff --git a/arch/arm/boot/dts/tegra124-nyan-blaze-emc.dtsi b/arch/arm/boot/dts/tegra124-nyan-blaze-emc.dtsi index d2beea0bd15f..35c98734d35f 100644 --- a/arch/arm/boot/dts/tegra124-nyan-blaze-emc.dtsi +++ b/arch/arm/boot/dts/tegra124-nyan-blaze-emc.dtsi @@ -2048,3 +2048,13 @@ timing-79200 { }; }; }; + +&emc_icc_dvfs_opp_table { + /delete-node/ opp@92400,1100; + /delete-node/ opp@12,1100; +}; + +&emc_bw_dfs_opp_table { + /delete-node/ opp@92400; + /delete-node/ opp@12; +}; diff --git a/arch/arm/boot/dts/tegra124-peripherals-opp.dtsi b/arch/arm/boot/dts/tegra124-peripherals-opp.dtsi new file mode 100644 index ..49d9420a3289 --- /dev/null +++ b/arch/arm/boot/dts/tegra124-peripherals-opp.dtsi @@ -0,0 +1,419 @@ +// SPDX-License-Identifier: GPL-2.0 + +/ { + emc_icc_dvfs_opp_table: emc-dvfs-opp-table { + compatible = "operating-points-v2"; + + opp@1275,800 { + opp-microvolt = <80 80 115>; + opp-hz = /bits/ 64 <1275>; + opp-supported-hw = <0x0003>; + }; + + opp@1275,950 { + opp-microvolt = <95 95 115>; + opp-hz = /bits/ 64 <1275>; + opp-supported-hw = <0x0008>; + }; + + opp@1275,1050 { + opp-microvolt = <105 105 115>; + opp-hz = /bits/ 64 <1275>; + opp-supported-hw = <0x0010>; + }; + + opp@1275,1110 { + opp-microvolt = <111 111 115>; + opp-hz = /bits/ 64 <1275>; + opp-supported-hw = <0x0004>; + }; + + opp@2040,800 { + opp-microvolt = <80 80 115>; + opp-hz = /bits/ 64 <2040>; + opp-supported-hw = <0x0003>; + }; + + opp@2040,950 { + opp-microvolt = <95 95 115>; + opp-hz = /bits/ 64 <2040>; + opp-supported-hw = <0x0008>; + }; + + opp@2040,1050 { + opp-microvolt = <105 105 115>; + opp-hz = /bits/ 64 <2040>; + opp-supported-hw = <0x0010>; + }; + + opp@2040,1110 { + opp-microvolt = <111 111 115>; +
[PATCH v8 18/26] PM / devfreq: tegra20: Deprecate in a favor of emc-stat based driver
Remove tegra20-devfreq in order to replace it with a EMC_STAT based devfreq driver. Previously we were going to use MC_STAT based tegra20-devfreq driver because EMC_STAT wasn't working properly, but now that problem is resolved. This resolves complications imposed by the removed driver since it was depending on both EMC and MC drivers simultaneously. Acked-by: Chanwoo Choi Signed-off-by: Dmitry Osipenko --- MAINTAINERS | 1 - drivers/devfreq/Kconfig | 10 -- drivers/devfreq/Makefile | 1 - drivers/devfreq/tegra20-devfreq.c | 210 -- 4 files changed, 222 deletions(-) delete mode 100644 drivers/devfreq/tegra20-devfreq.c diff --git a/MAINTAINERS b/MAINTAINERS index 4bbd866dec8e..94d8bebfda60 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11323,7 +11323,6 @@ L: linux...@vger.kernel.org L: linux-te...@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/linux.git S: Maintained -F: drivers/devfreq/tegra20-devfreq.c F: drivers/devfreq/tegra30-devfreq.c MEMORY MANAGEMENT diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig index 0ee36ae2fa79..00704efe6398 100644 --- a/drivers/devfreq/Kconfig +++ b/drivers/devfreq/Kconfig @@ -121,16 +121,6 @@ config ARM_TEGRA_DEVFREQ It reads ACTMON counters of memory controllers and adjusts the operating frequencies and voltages with OPP support. -config ARM_TEGRA20_DEVFREQ - tristate "NVIDIA Tegra20 DEVFREQ Driver" - depends on ARCH_TEGRA_2x_SOC || COMPILE_TEST - depends on COMMON_CLK - select DEVFREQ_GOV_SIMPLE_ONDEMAND - help - This adds the DEVFREQ driver for the Tegra20 family of SoCs. - It reads Memory Controller counters and adjusts the operating - frequencies and voltages with OPP support. - config ARM_RK3399_DMC_DEVFREQ tristate "ARM RK3399 DMC DEVFREQ Driver" depends on (ARCH_ROCKCHIP && HAVE_ARM_SMCCC) || \ diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile index 3ca1ad0ecb97..a16333ea7034 100644 --- a/drivers/devfreq/Makefile +++ b/drivers/devfreq/Makefile @@ -13,7 +13,6 @@ obj-$(CONFIG_ARM_IMX_BUS_DEVFREQ) += imx-bus.o obj-$(CONFIG_ARM_IMX8M_DDRC_DEVFREQ) += imx8m-ddrc.o obj-$(CONFIG_ARM_RK3399_DMC_DEVFREQ) += rk3399_dmc.o obj-$(CONFIG_ARM_TEGRA_DEVFREQ)+= tegra30-devfreq.o -obj-$(CONFIG_ARM_TEGRA20_DEVFREQ) += tegra20-devfreq.o # DEVFREQ Event Drivers obj-$(CONFIG_PM_DEVFREQ_EVENT) += event/ diff --git a/drivers/devfreq/tegra20-devfreq.c b/drivers/devfreq/tegra20-devfreq.c deleted file mode 100644 index fd801534771d.. --- a/drivers/devfreq/tegra20-devfreq.c +++ /dev/null @@ -1,210 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * NVIDIA Tegra20 devfreq driver - * - * Copyright (C) 2019 GRATE-DRIVER project - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "governor.h" - -#define MC_STAT_CONTROL0x90 -#define MC_STAT_EMC_CLOCK_LIMIT0xa0 -#define MC_STAT_EMC_CLOCKS 0xa4 -#define MC_STAT_EMC_CONTROL0xa8 -#define MC_STAT_EMC_COUNT 0xb8 - -#define EMC_GATHER_CLEAR (1 << 8) -#define EMC_GATHER_ENABLE (3 << 8) - -struct tegra_devfreq { - struct devfreq *devfreq; - struct clk *emc_clock; - void __iomem *regs; -}; - -static int tegra_devfreq_target(struct device *dev, unsigned long *freq, - u32 flags) -{ - struct tegra_devfreq *tegra = dev_get_drvdata(dev); - struct devfreq *devfreq = tegra->devfreq; - struct dev_pm_opp *opp; - unsigned long rate; - int err; - - opp = devfreq_recommended_opp(dev, freq, flags); - if (IS_ERR(opp)) - return PTR_ERR(opp); - - rate = dev_pm_opp_get_freq(opp); - dev_pm_opp_put(opp); - - err = clk_set_min_rate(tegra->emc_clock, rate); - if (err) - return err; - - err = clk_set_rate(tegra->emc_clock, 0); - if (err) - goto restore_min_rate; - - return 0; - -restore_min_rate: - clk_set_min_rate(tegra->emc_clock, devfreq->previous_freq); - - return err; -} - -static int tegra_devfreq_get_dev_status(struct device *dev, - struct devfreq_dev_status *stat) -{ - struct tegra_devfreq *tegra = dev_get_drvdata(dev); - - /* -* EMC_COUNT returns number of memory events, that number is lower -* than the number of clocks. Conversion ratio of 1/8 results in a -* bit higher bandwidth than actually needed, it is good enough for -* the time being because drivers don't support requesting minimum -* needed memory bandwidth yet. -* -* TODO: ad
Re: [PATCH v8 02/26] memory: tegra20-emc: Use dev_pm_opp_set_clkname()
11.11.2020 08:45, Viresh Kumar пишет: >> +put_reg_table: >> +if (reg_opp_table) > This won't be required after my other patchset and yeah it is a > classic chicken and egg problem we have here :) > > Maybe you can fix them separately in 5.11 after everything is applied. > I already prepared patch in the "core voltage scaling" series that will remove this code. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v8 25/26] ARM: tegra: Add DVFS properties to Tegra30 EMC and ACTMON device-tree nodes
Add EMC OPP DVFS/DFS tables and interconnect paths that will be used for dynamic memory bandwidth scaling based on memory utilization statistics. Update board device-trees with optional EMC core supply and remove unsupported OPPs. Note that ACTMON watches all memory interconnect paths, but we use a single CPU-READ interconnect path for driving memory bandwidth, for simplicity. Signed-off-by: Dmitry Osipenko --- .../tegra30-asus-nexus7-grouper-common.dtsi | 4 + ...30-asus-nexus7-grouper-memory-timings.dtsi | 12 + .../arm/boot/dts/tegra30-peripherals-opp.dtsi | 383 ++ arch/arm/boot/dts/tegra30.dtsi| 6 + 4 files changed, 405 insertions(+) create mode 100644 arch/arm/boot/dts/tegra30-peripherals-opp.dtsi diff --git a/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-common.dtsi b/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-common.dtsi index 88ca03f57b3b..261e266c61d8 100644 --- a/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-common.dtsi +++ b/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-common.dtsi @@ -956,6 +956,10 @@ pmc@7000e400 { nvidia,sys-clock-req-active-high; }; + memory-controller@7000f400 { + core-supply = <&vdd_core>; + }; + ahub@7008 { i2s@70080400 { status = "okay"; diff --git a/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-memory-timings.dtsi b/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-memory-timings.dtsi index bc0f6f29b956..bcff0997ee51 100644 --- a/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-memory-timings.dtsi +++ b/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-memory-timings.dtsi @@ -1563,3 +1563,15 @@ timing-66700 { }; }; }; + +&emc_icc_dvfs_opp_table { + /delete-node/ opp@75000,1300; + /delete-node/ opp@8,1300; + /delete-node/ opp@9,1350; +}; + +&emc_bw_dfs_opp_table { + /delete-node/ opp@75000; + /delete-node/ opp@8; + /delete-node/ opp@9; +}; diff --git a/arch/arm/boot/dts/tegra30-peripherals-opp.dtsi b/arch/arm/boot/dts/tegra30-peripherals-opp.dtsi new file mode 100644 index ..cbe84d25e726 --- /dev/null +++ b/arch/arm/boot/dts/tegra30-peripherals-opp.dtsi @@ -0,0 +1,383 @@ +// SPDX-License-Identifier: GPL-2.0 + +/ { + emc_icc_dvfs_opp_table: emc-dvfs-opp-table { + compatible = "operating-points-v2"; + + opp@1275,950 { + opp-microvolt = <95 95 135>; + opp-hz = /bits/ 64 <1275>; + opp-supported-hw = <0x0006>; + }; + + opp@1275,1000 { + opp-microvolt = <100 100 135>; + opp-hz = /bits/ 64 <1275>; + opp-supported-hw = <0x0001>; + }; + + opp@1275,1250 { + opp-microvolt = <125 125 135>; + opp-hz = /bits/ 64 <1275>; + opp-supported-hw = <0x0008>; + }; + + opp@2550,950 { + opp-microvolt = <95 95 135>; + opp-hz = /bits/ 64 <2550>; + opp-supported-hw = <0x0006>; + }; + + opp@2550,1000 { + opp-microvolt = <100 100 135>; + opp-hz = /bits/ 64 <2550>; + opp-supported-hw = <0x0001>; + }; + + opp@2550,1250 { + opp-microvolt = <125 125 135>; + opp-hz = /bits/ 64 <2550>; + opp-supported-hw = <0x0008>; + }; + + opp@2700,950 { + opp-microvolt = <95 95 135>; + opp-hz = /bits/ 64 <2700>; + opp-supported-hw = <0x0006>; + }; + + opp@2700,1000 { + opp-microvolt = <100 100 135>; + opp-hz = /bits/ 64 <2700>; + opp-supported-hw = <0x0001>; + }; + + opp@2700,1250 { + opp-microvolt = <125 125 135>; + opp-hz = /bits/ 64 <2700>; + opp-supported-hw = <0x0008>; + }; + + opp@5100,950 { + opp-microvolt = <95 95 135>; + opp-hz = /bits/ 64 <5100>; + opp-supported-hw = <0x0006>; + }; + + opp@5100,1000 { + opp-microvolt = <100 100 135>; + opp-hz = /bits/ 64 <5100>; + opp-supported-hw = <0x0001>; + }; + +
[PATCH 1/4] drm: omapdrm: dsi: fix-reference-leak-in dsi_runtime_get.
pm_runtime_get_sync() will increment pm usage at first and it will resume the device later. If runtime of the device has error or device is in inaccessible state(or other error state), resume operation will fail. If we do not call put operation to decrease the reference, it will result in reference leak in dsi_runtime_get. Moreover, this device cannot enter the idle state and always stay busy or other non-idle state later. So we should fix it through adding pm_runtime_put_noidle. Fixes: 4600ea9c49cc4 ("drm: omapdrm: dsi: Store the struct device pointer in struct dsi_data") Signed-off-by: Zhang Qilong --- drivers/gpu/drm/omapdrm/dss/dsi.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c index eeccf40bae41..f407d9c60ada 100644 --- a/drivers/gpu/drm/omapdrm/dss/dsi.c +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c @@ -1112,8 +1112,12 @@ static int dsi_runtime_get(struct dsi_data *dsi) DSSDBG("dsi_runtime_get\n"); r = pm_runtime_get_sync(dsi->dev); - WARN_ON(r < 0); - return r < 0 ? r : 0; + if (WARN_ON(r < 0)) { + pm_runtime_put_noidle(dsi->dev); + return r; + } + + return 0; } static void dsi_runtime_put(struct dsi_data *dsi) -- 2.25.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v5 2/3] arm64: dts: qcom: sc7180: Add gpu cooling support
On Fri 30 Oct 05:47 CDT 2020, Akhil P Oommen wrote: > Add cooling-cells property and the cooling maps for the gpu tzones > to support GPU cooling. > > Signed-off-by: Akhil P Oommen > Reviewed-by: Matthias Kaehlcke > --- > arch/arm64/boot/dts/qcom/sc7180.dtsi | 30 +++--- > 1 file changed, 23 insertions(+), 7 deletions(-) > > diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi > b/arch/arm64/boot/dts/qcom/sc7180.dtsi > index d46b383..8e2000c 100644 > --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi > +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi > @@ -2,7 +2,7 @@ > /* > * SC7180 SoC device tree source > * > - * Copyright (c) 2019, The Linux Foundation. All rights reserved. > + * Copyright (c) 2019-20, The Linux Foundation. All rights reserved. I took the liberty of spelling out 2020 here, as I applied this patch. Regards, Bjorn > */ > > #include > @@ -1886,6 +1886,8 @@ > operating-points-v2 = <&gpu_opp_table>; > qcom,gmu = <&gmu>; > > + #cooling-cells = <2>; > + > interconnects = <&gem_noc MASTER_GFX3D &mc_virt > SLAVE_EBI1>; > interconnect-names = "gfx-mem"; > > @@ -3825,16 +3827,16 @@ > }; > > gpuss0-thermal { > - polling-delay-passive = <0>; > + polling-delay-passive = <100>; > polling-delay = <0>; > > thermal-sensors = <&tsens0 13>; > > trips { > gpuss0_alert0: trip-point0 { > - temperature = <9>; > + temperature = <95000>; > hysteresis = <2000>; > - type = "hot"; > + type = "passive"; > }; > > gpuss0_crit: gpuss0_crit { > @@ -3843,19 +3845,26 @@ > type = "critical"; > }; > }; > + > + cooling-maps { > + map0 { > + trip = <&gpuss0_alert0>; > + cooling-device = <&gpu THERMAL_NO_LIMIT > THERMAL_NO_LIMIT>; > + }; > + }; > }; > > gpuss1-thermal { > - polling-delay-passive = <0>; > + polling-delay-passive = <100>; > polling-delay = <0>; > > thermal-sensors = <&tsens0 14>; > > trips { > gpuss1_alert0: trip-point0 { > - temperature = <9>; > + temperature = <95000>; > hysteresis = <2000>; > - type = "hot"; > + type = "passive"; > }; > > gpuss1_crit: gpuss1_crit { > @@ -3864,6 +3873,13 @@ > type = "critical"; > }; > }; > + > + cooling-maps { > + map0 { > + trip = <&gpuss1_alert0>; > + cooling-device = <&gpu THERMAL_NO_LIMIT > THERMAL_NO_LIMIT>; > + }; > + }; > }; > > aoss1-thermal { > -- > 2.7.4 > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v8 10/26] memory: tegra30-emc: Factor out clk initialization
Factor out clk initialization and make it resource-managed. This makes easier to follow code and will help to make further changes cleaner. Signed-off-by: Dmitry Osipenko --- drivers/memory/tegra/tegra30-emc.c | 70 -- 1 file changed, 47 insertions(+), 23 deletions(-) diff --git a/drivers/memory/tegra/tegra30-emc.c b/drivers/memory/tegra/tegra30-emc.c index d27df842a667..1df42e212d73 100644 --- a/drivers/memory/tegra/tegra30-emc.c +++ b/drivers/memory/tegra/tegra30-emc.c @@ -1550,6 +1550,49 @@ static int tegra_emc_opp_table_init(struct tegra_emc *emc) return err; } +static void devm_tegra_emc_unset_callback(void *data) +{ + tegra20_clk_set_emc_round_callback(NULL, NULL); +} + +static void devm_tegra_emc_unreg_clk_notifier(void *data) +{ + struct tegra_emc *emc = data; + + clk_notifier_unregister(emc->clk, &emc->clk_nb); +} + +static int tegra_emc_init_clk(struct tegra_emc *emc) +{ + int err; + + tegra20_clk_set_emc_round_callback(emc_round_rate, emc); + + err = devm_add_action_or_reset(emc->dev, devm_tegra_emc_unset_callback, + NULL); + if (err) + return err; + + emc->clk = devm_clk_get(emc->dev, NULL); + if (IS_ERR(emc->clk)) { + dev_err(emc->dev, "failed to get EMC clock: %pe\n", emc->clk); + return PTR_ERR(emc->clk); + } + + err = clk_notifier_register(emc->clk, &emc->clk_nb); + if (err) { + dev_err(emc->dev, "failed to register clk notifier: %d\n", err); + return err; + } + + err = devm_add_action_or_reset(emc->dev, + devm_tegra_emc_unreg_clk_notifier, emc); + if (err) + return err; + + return 0; +} + static int tegra_emc_probe(struct platform_device *pdev) { struct device_node *np; @@ -1599,25 +1642,13 @@ static int tegra_emc_probe(struct platform_device *pdev) return err; } - tegra20_clk_set_emc_round_callback(emc_round_rate, emc); - - emc->clk = devm_clk_get(&pdev->dev, "emc"); - if (IS_ERR(emc->clk)) { - err = PTR_ERR(emc->clk); - dev_err(&pdev->dev, "failed to get emc clock: %d\n", err); - goto unset_cb; - } - - err = clk_notifier_register(emc->clk, &emc->clk_nb); - if (err) { - dev_err(&pdev->dev, "failed to register clk notifier: %d\n", - err); - goto unset_cb; - } + err = tegra_emc_init_clk(emc); + if (err) + return err; err = tegra_emc_opp_table_init(emc); if (err) - goto unreg_notifier; + return err; platform_set_drvdata(pdev, emc); tegra_emc_rate_requests_init(emc); @@ -1632,13 +1663,6 @@ static int tegra_emc_probe(struct platform_device *pdev) try_module_get(THIS_MODULE); return 0; - -unreg_notifier: - clk_notifier_unregister(emc->clk, &emc->clk_nb); -unset_cb: - tegra20_clk_set_emc_round_callback(NULL, NULL); - - return err; } static int tegra_emc_suspend(struct device *dev) -- 2.29.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v8 05/26] memory: tegra20-emc: Remove IRQ number from error message
Remove IRQ number from error message since it doesn't add any useful information, especially because this number is virtual. Signed-off-by: Dmitry Osipenko --- drivers/memory/tegra/tegra20-emc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c index b9cd965980e2..0320d9df4a20 100644 --- a/drivers/memory/tegra/tegra20-emc.c +++ b/drivers/memory/tegra/tegra20-emc.c @@ -1131,7 +1131,7 @@ static int tegra_emc_probe(struct platform_device *pdev) err = devm_request_irq(&pdev->dev, irq, tegra_emc_isr, 0, dev_name(&pdev->dev), emc); if (err) { - dev_err(&pdev->dev, "failed to request IRQ#%u: %d\n", irq, err); + dev_err(&pdev->dev, "failed to request IRQ: %d\n", err); return err; } -- 2.29.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 0/4] drm/omap: fix reference leak in runtime get ops
This series of patches fixed several usage counter leaks refer to pm_runtime_get_sync. Many callers forget to call pm_runtime_put_noidle when pm_runtime_get_sync failed, and we fixed it. Zhang Qilong (4): drm: omapdrm: dsi: fix-reference-leak-in dsi_runtime_get. drm: omapdrm: dss: fix reference leak in dss_runtime_get drm/omap: hdmi4: fix reference leak in hdmi_runtime_get drm/omap: hdmi5: fix reference leak in hdmi_runtime_get drivers/gpu/drm/omapdrm/dss/dsi.c | 8 ++-- drivers/gpu/drm/omapdrm/dss/dss.c | 8 ++-- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 4 +++- drivers/gpu/drm/omapdrm/dss/hdmi5.c | 4 +++- 4 files changed, 18 insertions(+), 6 deletions(-) -- 2.25.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v8 02/26] memory: tegra20-emc: Use dev_pm_opp_set_clkname()
The dev_pm_opp_get_opp_table() shouldn't be used by drivers, use dev_pm_opp_set_clkname() instead. Suggested-by: Viresh Kumar Signed-off-by: Dmitry Osipenko --- drivers/memory/tegra/tegra20-emc.c | 30 +++--- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c index 5e10aa97809f..bb3f315c9587 100644 --- a/drivers/memory/tegra/tegra20-emc.c +++ b/drivers/memory/tegra/tegra20-emc.c @@ -902,7 +902,7 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc) static int tegra_emc_opp_table_init(struct tegra_emc *emc) { - struct opp_table *opp_table; + struct opp_table *reg_opp_table = NULL, *clk_opp_table; const char *rname = "core"; int err; @@ -917,19 +917,24 @@ static int tegra_emc_opp_table_init(struct tegra_emc *emc) } /* voltage scaling is optional */ - if (device_property_present(emc->dev, "core-supply")) - opp_table = dev_pm_opp_set_regulators(emc->dev, &rname, 1); - else - opp_table = dev_pm_opp_get_opp_table(emc->dev); + if (device_property_present(emc->dev, "core-supply")) { + reg_opp_table = dev_pm_opp_set_regulators(emc->dev, &rname, 1); + if (IS_ERR(reg_opp_table)) + return dev_err_probe(emc->dev, PTR_ERR(reg_opp_table), +"failed to set OPP regulator\n"); + } - if (IS_ERR(opp_table)) - return dev_err_probe(emc->dev, PTR_ERR(opp_table), -"failed to prepare OPP table\n"); + clk_opp_table = dev_pm_opp_set_clkname(emc->dev, NULL); + err = PTR_ERR_OR_ZERO(clk_opp_table); + if (err) { + dev_err(emc->dev, "failed to set OPP clk: %d\n", err); + goto put_reg_table; + } err = dev_pm_opp_of_add_table(emc->dev); if (err) { dev_err(emc->dev, "failed to add OPP table: %d\n", err); - goto put_table; + goto put_clk_table; } dev_info(emc->dev, "current clock rate %lu MHz\n", @@ -946,8 +951,11 @@ static int tegra_emc_opp_table_init(struct tegra_emc *emc) remove_table: dev_pm_opp_of_remove_table(emc->dev); -put_table: - dev_pm_opp_put_regulators(opp_table); +put_clk_table: + dev_pm_opp_put_clkname(clk_opp_table); +put_reg_table: + if (reg_opp_table) + dev_pm_opp_put_regulators(reg_opp_table); return err; } -- 2.29.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] dt-bindings: display: panel-simple: Allow optional 'ports' property
On Tue, 2020-11-10 at 06:53 +0100, Sam Ravnborg wrote: > Hi Liu Ying, > On Tue, Nov 10, 2020 at 10:37:27AM +0800, Liu Ying wrote: > > Hi Sam, > > > > On Wed, 2020-11-04 at 11:47 +0100, Sam Ravnborg wrote: > > > Hi Liu Ying > > > > > > On Wed, Nov 04, 2020 at 04:03:37PM +0800, Liu Ying wrote: > > > > Some simple panels have dual LVDS interfaces which receive even > > > > and > > > > odd > > > > pixels respectively, like 'nlt,nl192108ac18-02d' and > > > > 'koe,tx26d202vm0bwa'. > > > > So, let's allow optional 'ports' property so that pixel order > > > > can > > > > be got > > > > via drm_of_lvds_get_dual_link_pixel_order() if it's child > > > > nodes > > > > 'port@0' > > > > and 'port@1' contain 'dual-lvds-even-pixels' and 'dual-lvds- > > > > odd- > > > > pixels' > > > > properties respectively. > > > > > > A panel with dual LVDS interfaces is no longer in the "simple" > > > category. > > > The panel-simple binding shall be limited to the simple pnales > > > only. > > > > > > This is also why we have for example panel-simple-dsi binding. > > > > > > Please consider either a binding dedicated for the dual port > > > displays > > > or > > > > Thanks for your review. > > > > Does a new 'panel-simple-lvds-dual-ports.yaml' binding look ok? > > I assume it would inherit all properties of panel-simple.yaml and > > all > > existing compatibles of LVDS panels with dual ports in > > panel-simple.yaml can be moved to it. > > Yes, that would be fine. If possible we shall have similar panels > described by the same binding. > > Try to send out the binding for review early before starting to move > too > much around - so we can get an early look at it at see if this is > indeed > the right direction to go. Yes. I've sent out one for review: https://lists.freedesktop.org/archives/dri-devel/2020-November/286482.html > > Sam > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Liu Ying ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v1 18/30] pwm: tegra: Support OPP and core voltage scaling
10.11.2020 23:50, Thierry Reding пишет: > On Thu, Nov 05, 2020 at 02:44:15AM +0300, Dmitry Osipenko wrote: > [...] >> +static void tegra_pwm_deinit_opp_table(void *data) >> +{ >> +struct device *dev = data; >> +struct opp_table *opp_table; >> + >> +opp_table = dev_pm_opp_get_opp_table(dev); >> +dev_pm_opp_of_remove_table(dev); >> +dev_pm_opp_put_regulators(opp_table); >> +dev_pm_opp_put_opp_table(opp_table); >> +} >> + >> +static int devm_tegra_pwm_init_opp_table(struct device *dev) >> +{ >> +struct opp_table *opp_table; >> +const char *rname = "core"; >> +int err; >> + >> +/* voltage scaling is optional */ >> +if (device_property_present(dev, "core-supply")) >> +opp_table = dev_pm_opp_set_regulators(dev, &rname, 1); >> +else >> +opp_table = dev_pm_opp_get_opp_table(dev); >> + >> +if (IS_ERR(opp_table)) >> +return dev_err_probe(dev, PTR_ERR(opp_table), >> + "failed to prepare OPP table\n"); >> + >> +/* >> + * OPP table presence is optional and we want the set_rate() of OPP >> + * API to work similarly to clk_set_rate() if table is missing in a >> + * device-tree. The add_table() errors out if OPP is missing in DT. >> + */ >> +if (device_property_present(dev, "operating-points-v2")) { >> +err = dev_pm_opp_of_add_table(dev); >> +if (err) { >> +dev_err(dev, "failed to add OPP table: %d\n", err); >> +goto put_table; >> +} >> +} >> + >> +err = devm_add_action(dev, tegra_pwm_deinit_opp_table, dev); >> +if (err) >> +goto remove_table; >> + >> +return 0; >> + >> +remove_table: >> +dev_pm_opp_of_remove_table(dev); >> +put_table: >> +dev_pm_opp_put_regulators(opp_table); >> + >> +return err; >> +} > > These two functions seem to be heavily boilerplate across all these > drivers. Have you considered splitting these out into separate helpers? The helper is already prepared for v2. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/panel: add missing platform_driver_unregister() on error path
Hi Yang, On Wed, Nov 11, 2020 at 02:44:25PM +0800, Yang Yingliang wrote: > If mipi_dsi_driver_register() failed, platform_driver_unregister() > need be called. > > Fixes: 210fcd9d9cf1 ("drm/panel: Add support for Panasonic VVX10F004B0") > Reported-by: Hulk Robot > Signed-off-by: Yang Yingliang Thanks for the patch but this is already fixed in drm-misx-next. See: commit f2e66f212a9de04afc2caa5ec79057c0ac75c728 drm: panel: simple: add missing platform_driver_unregister() in panel_simple_init Sam ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 01/30] drm/radeon/evergreen: Add comment for 'evergreen_page_flip()'s 'async' param
On Tue, 10 Nov 2020, Alex Deucher wrote: > On Tue, Nov 10, 2020 at 2:31 PM Lee Jones wrote: > > > > Fixes the following W=1 kernel build warning(s): > > > > drivers/gpu/drm/radeon/evergreen.c: In function ‘evergreen_gpu_init’: > > drivers/gpu/drm/radeon/evergreen.c:1419: warning: Function parameter or > > member 'async' not described in 'evergreen_page_flip' > > > > Cc: Alex Deucher > > Cc: "Christian König" > > Cc: David Airlie > > Cc: Daniel Vetter > > Cc: amd-...@lists.freedesktop.org > > Cc: dri-devel@lists.freedesktop.org > > Signed-off-by: Lee Jones > > Applied with minor fixups. Thanks! Superstar! Thanks Alex. Once these are all in -next, I'll rebase and fix the stragglers. -- Lee Jones [李琼斯] Senior Technical Lead - Developer Services Linaro.org │ Open source software for Arm SoCs Follow Linaro: Facebook | Twitter | Blog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 16/17] drm/i915/hdcp: Support for HDCP 2.2 MST shim callbacks
Add support for HDCP 2.2 DP MST shim callback. This adds existing DP HDCP shim callback for Link Authentication and Encryption and HDCP 2.2 stream encryption callback. v2: - Added a WARN_ON() instead of drm_err. [Uma] - Cosmetic changes. [Uma] v3: - 's/port_data/hdcp_port_data' [Ram] - skip redundant link check. [Ram] Cc: Ramalingam C Reviewed-by: Uma Shankar Signed-off-by: Anshuman Gupta --- .../drm/i915/display/intel_display_types.h| 4 + drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 89 +-- 2 files changed, 85 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index d2c744b8b461..83f40896684b 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -374,6 +374,10 @@ struct intel_hdcp_shim { int (*config_stream_type)(struct intel_digital_port *dig_port, bool is_repeater, u8 type); + /* Enable/Disable HDCP 2.2 stream encryption on DP MST Transport Link */ + int (*stream_2_2_encryption)(struct intel_connector *connector, +bool enable); + /* HDCP2.2 Link Integrity Check */ int (*check_2_2_link)(struct intel_digital_port *dig_port, struct intel_connector *connector); diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c index c094839d15d1..9330af6d26a4 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c @@ -698,18 +698,14 @@ intel_dp_mst_hdcp_stream_encryption(struct intel_connector *connector, return 0; } -static -bool intel_dp_mst_hdcp_check_link(struct intel_digital_port *dig_port, - struct intel_connector *connector) +static bool intel_dp_mst_get_qses_status(struct intel_digital_port *dig_port, +struct intel_connector *connector) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); - struct intel_dp *intel_dp = &dig_port->dp; struct drm_dp_query_stream_enc_status_ack_reply reply; + struct intel_dp *intel_dp = &dig_port->dp; int ret; - if (!intel_dp_hdcp_check_link(dig_port, connector)) - return false; - ret = drm_dp_send_query_stream_enc_status(&intel_dp->mst_mgr, connector->port, &reply); if (ret) { @@ -726,6 +722,78 @@ bool intel_dp_mst_hdcp_check_link(struct intel_digital_port *dig_port, return reply.auth_completed && reply.encryption_enabled; } +static +bool intel_dp_mst_hdcp_check_link(struct intel_digital_port *dig_port, + struct intel_connector *connector) +{ + if (!intel_dp_hdcp_check_link(dig_port, connector)) + return false; + + return intel_dp_mst_get_qses_status(dig_port, connector); +} + +static int +intel_dp_mst_hdcp2_stream_encryption(struct intel_connector *connector, +bool enable) +{ + struct intel_digital_port *dig_port = intel_attached_dig_port(connector); + struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_hdcp *hdcp = &connector->hdcp; + struct hdcp_port_data *data = &dig_port->hdcp_port_data; + enum port port = dig_port->base.port; + /* HDCP2.x register uses stream transcoder */ + enum transcoder cpu_transcoder = hdcp->stream_transcoder; + int ret; + + drm_WARN_ON(&i915->drm, enable && + !!(intel_de_read(i915, HDCP2_AUTH_STREAM(i915, cpu_transcoder, port)) + & AUTH_STREAM_TYPE) != data->streams[0].stream_type); + + ret = intel_dp_mst_toggle_hdcp_stream_select(connector, enable); + if (ret) + return ret; + + /* Wait for encryption confirmation */ + if (intel_de_wait_for_register(i915, + HDCP2_STREAM_STATUS(i915, cpu_transcoder, port), + STREAM_ENCRYPTION_STATUS, + enable ? STREAM_ENCRYPTION_STATUS : 0, + HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) { + drm_err(&i915->drm, "Timed out waiting for transcoder: %s stream encryption %s\n", + transcoder_name(cpu_transcoder), enable ? "enabled" : "disabled"); + return -ETIMEDOUT; + } + + return 0; +} + +/* + * DP v2.0 I.3.3 ignore the stream signature L' in QSES reply msg reply. + * I.3.5 MST source device may use a QSES msg to query downstream status + * for a particular stream. + */ +static +int intel_dp_mst_hdcp2_check_link(struct intel_digital_port *dig_port, + struct intel_connector *connect
[PATCH v5 14/17] drm/i915/hdcp: Pass connector to check_2_2_link
This requires for HDCP 2.2 MST check link. As for DP/HDMI shims check_2_2_link retrieves the connector from dig_port, this is not sufficient or DP MST connector, there can be multiple DP MST topology connector associated with same dig_port. Cc: Ramalingam C Reviewed-by: Uma Shankar Signed-off-by: Anshuman Gupta --- drivers/gpu/drm/i915/display/intel_display_types.h | 3 ++- drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 3 ++- drivers/gpu/drm/i915/display/intel_hdcp.c | 2 +- drivers/gpu/drm/i915/display/intel_hdmi.c | 3 ++- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index b93ecf4f21e3..d2c744b8b461 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -375,7 +375,8 @@ struct intel_hdcp_shim { bool is_repeater, u8 type); /* HDCP2.2 Link Integrity Check */ - int (*check_2_2_link)(struct intel_digital_port *dig_port); + int (*check_2_2_link)(struct intel_digital_port *dig_port, + struct intel_connector *connector); }; struct intel_hdcp { diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c index f643d3af59bb..c094839d15d1 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c @@ -585,7 +585,8 @@ int intel_dp_hdcp2_config_stream_type(struct intel_digital_port *dig_port, } static -int intel_dp_hdcp2_check_link(struct intel_digital_port *dig_port) +int intel_dp_hdcp2_check_link(struct intel_digital_port *dig_port, + struct intel_connector *connector) { u8 rx_status; int ret; diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 6a48110c7cd7..0c10afc42f01 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -1942,7 +1942,7 @@ static int intel_hdcp2_check_link(struct intel_connector *connector) goto out; } - ret = hdcp->shim->check_2_2_link(dig_port); + ret = hdcp->shim->check_2_2_link(dig_port, connector); if (ret == HDCP_LINK_PROTECTED) { if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) { intel_hdcp_update_value(connector, diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index 0788de04711b..bd0d91101464 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -1734,7 +1734,8 @@ int intel_hdmi_hdcp2_read_msg(struct intel_digital_port *dig_port, } static -int intel_hdmi_hdcp2_check_link(struct intel_digital_port *dig_port) +int intel_hdmi_hdcp2_check_link(struct intel_digital_port *dig_port, + struct intel_connector *connector) { u8 rx_status[HDCP_2_2_HDMI_RXSTATUS_LEN]; int ret; -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 17/17] drm/i915/hdcp: Enable HDCP 2.2 MST support
Enable HDCP 2.2 over DP MST. Authenticate and enable port encryption only once for an active HDCP 2.2 session, once port is authenticated and encrypted enable encryption for each stream that requires encryption on this port. Similarly disable the stream encryption for each encrypted stream, once all encrypted stream encryption is disabled, disable the port HDCP encryption and deauthenticate the port. v2: - Add connector details in drm_err. [Ram] - 's/port_auth/hdcp_auth_status'. [Ram] - Added a debug print for stream enc. Cc: Ramalingam C Reviewed-by: Uma Shankar Signed-off-by: Anshuman Gupta --- drivers/gpu/drm/i915/display/intel_hdcp.c | 53 ++- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 0c10afc42f01..95f544564fb1 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -1695,6 +1695,36 @@ static int hdcp2_authenticate_sink(struct intel_connector *connector) return ret; } +static int hdcp2_enable_stream_encryption(struct intel_connector *connector) +{ + struct intel_digital_port *dig_port = intel_attached_dig_port(connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_hdcp *hdcp = &connector->hdcp; + enum transcoder cpu_transcoder = hdcp->cpu_transcoder; + enum port port = dig_port->base.port; + int ret = 0; + + if (!(intel_de_read(dev_priv, HDCP2_STATUS(dev_priv, cpu_transcoder, port)) & + LINK_ENCRYPTION_STATUS)) { + drm_err(&dev_priv->drm, "[CONNECTOR:%d:%s] HDCP 2.2 Link is not encrypted\n", + connector->base.base.id, connector->base.name); + return -EPERM; + } + + if (hdcp->shim->stream_2_2_encryption) { + ret = hdcp->shim->stream_2_2_encryption(connector, true); + if (ret) { + drm_err(&dev_priv->drm, "[CONNECTOR:%d:%s] Failed to enable HDCP 2.2 stream enc\n", + connector->base.base.id, connector->base.name); + return ret; + } + drm_dbg_kms(&dev_priv->drm, "HDCP 2.2 transcoder: %s stream encrypted\n", + transcoder_name(hdcp->stream_transcoder)); + } + + return ret; +} + static int hdcp2_enable_encryption(struct intel_connector *connector) { struct intel_digital_port *dig_port = intel_attached_dig_port(connector); @@ -1833,7 +1863,7 @@ static int hdcp2_authenticate_and_encrypt(struct intel_connector *connector) drm_dbg_kms(&i915->drm, "Port deauth failed.\n"); } - if (!ret) { + if (!ret && !dig_port->hdcp_auth_status) { /* * Ensuring the required 200mSec min time interval between * Session Key Exchange and encryption. @@ -1848,6 +1878,8 @@ static int hdcp2_authenticate_and_encrypt(struct intel_connector *connector) } } + ret = hdcp2_enable_stream_encryption(connector); + return ret; } @@ -1893,11 +1925,26 @@ static int _intel_hdcp2_disable(struct intel_connector *connector) struct intel_digital_port *dig_port = intel_attached_dig_port(connector); struct drm_i915_private *i915 = to_i915(connector->base.dev); struct hdcp_port_data *data = &dig_port->hdcp_port_data; + struct intel_hdcp *hdcp = &connector->hdcp; int ret; drm_dbg_kms(&i915->drm, "[%s:%d] HDCP2.2 is being Disabled\n", connector->base.name, connector->base.base.id); + if (hdcp->shim->stream_2_2_encryption) { + ret = hdcp->shim->stream_2_2_encryption(connector, false); + if (ret) { + drm_err(&i915->drm, "[CONNECTOR:%d:%s] Failed to disable HDCP 2.2 stream enc\n", + connector->base.base.id, connector->base.name); + return ret; + } + drm_dbg_kms(&i915->drm, "HDCP 2.2 transcoder: %s stream encryption disabled\n", + transcoder_name(hdcp->stream_transcoder)); + } + + if (dig_port->num_hdcp_streams > 0) + return ret; + ret = hdcp2_disable_encryption(connector); if (hdcp2_deauthenticate_port(connector) < 0) @@ -1921,6 +1968,7 @@ static int intel_hdcp2_check_link(struct intel_connector *connector) int ret = 0; mutex_lock(&hdcp->mutex); + mutex_lock(&dig_port->hdcp_mutex); cpu_transcoder = hdcp->cpu_transcoder; /* hdcp2_check_link is expected only when HDCP2.2 is Enabled */ @@ -1998,6 +2046,7 @@ static int intel_hdcp2_check_link(struct intel_connector *connector) } out: + mutex_unlock(&dig_port->hdcp_mutex); mutex_unlock(&hdc
[PATCH v5 11/17] misc/mei/hdcp: Fix AUTH_STREAM_REQ cmd buffer len
Fix the size of WIRED_REPEATER_AUTH_STREAM_REQ cmd buffer size. It is based upon the actual number of MST streams and size of wired_cmd_repeater_auth_stream_req_in. Excluding the size of hdcp_cmd_header. v2: hdcp_cmd_header size annotation nitpick. [Tomas] Cc: Tomas Winkler Cc: Ramalingam C Acked-by: Tomas Winkler Reviewed-by: Uma Shankar Reviewed-by: Ramalingam C Signed-off-by: Anshuman Gupta --- drivers/misc/mei/hdcp/mei_hdcp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c b/drivers/misc/mei/hdcp/mei_hdcp.c index 9ae9669e46ea..3506a3534294 100644 --- a/drivers/misc/mei/hdcp/mei_hdcp.c +++ b/drivers/misc/mei/hdcp/mei_hdcp.c @@ -569,8 +569,7 @@ static int mei_hdcp_verify_mprime(struct device *dev, verify_mprime_in->header.api_version = HDCP_API_VERSION; verify_mprime_in->header.command_id = WIRED_REPEATER_AUTH_STREAM_REQ; verify_mprime_in->header.status = ME_HDCP_STATUS_SUCCESS; - verify_mprime_in->header.buffer_len = - WIRED_CMD_BUF_LEN_REPEATER_AUTH_STREAM_REQ_MIN_IN; + verify_mprime_in->header.buffer_len = cmd_size - sizeof(verify_mprime_in->header); verify_mprime_in->port.integrated_port_type = data->port_type; verify_mprime_in->port.physical_port = (u8)data->fw_ddi; -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 15/17] drm/i915/hdcp: Add HDCP 2.2 stream register
Add HDCP 2.2 DP MST HDCP2_STREAM_STATUS and HDCP2_AUTH_STREAM register in i915_reg header. Cc: Ramalingam C Reviewed-by: Uma Shankar Reviewed-by: Ramalingam C Signed-off-by: Anshuman Gupta --- drivers/gpu/drm/i915/i915_reg.h | 30 ++ 1 file changed, 30 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 3ae097ed004f..5a2d1ead0f6d 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -9870,6 +9870,7 @@ enum skl_power_gate { _PORTD_HDCP2_BASE, \ _PORTE_HDCP2_BASE, \ _PORTF_HDCP2_BASE) + (x)) + #define PORT_HDCP2_AUTH(port) _PORT_HDCP2_BASE(port, 0x98) #define _TRANSA_HDCP2_AUTH 0x66498 #define _TRANSB_HDCP2_AUTH 0x66598 @@ -9909,6 +9910,35 @@ enum skl_power_gate { TRANS_HDCP2_STATUS(trans) : \ PORT_HDCP2_STATUS(port)) +#define PORT_HDCP2_STREAM_STATUS(port) _PORT_HDCP2_BASE(port, 0xC0) +#define _TRANSA_HDCP2_STREAM_STATUS0x664C0 +#define _TRANSB_HDCP2_STREAM_STATUS0x665C0 +#define TRANS_HDCP2_STREAM_STATUS(trans) _MMIO_TRANS(trans, \ + _TRANSA_HDCP2_STREAM_STATUS, \ + _TRANSB_HDCP2_STREAM_STATUS) +#define STREAM_ENCRYPTION_STATUS BIT(31) +#define STREAM_TYPE_STATUS BIT(30) +#define HDCP2_STREAM_STATUS(dev_priv, trans, port) \ + (INTEL_GEN(dev_priv) >= 12 ? \ +TRANS_HDCP2_STREAM_STATUS(trans) : \ +PORT_HDCP2_STREAM_STATUS(port)) + +#define _PORTA_HDCP2_AUTH_STREAM 0x66F00 +#define _PORTB_HDCP2_AUTH_STREAM 0x66F04 +#define PORT_HDCP2_AUTH_STREAM(port) _MMIO_PORT(port, \ + _PORTA_HDCP2_AUTH_STREAM, \ + _PORTB_HDCP2_AUTH_STREAM) +#define _TRANSA_HDCP2_AUTH_STREAM 0x66F00 +#define _TRANSB_HDCP2_AUTH_STREAM 0x66F04 +#define TRANS_HDCP2_AUTH_STREAM(trans) _MMIO_TRANS(trans, \ + _TRANSA_HDCP2_AUTH_STREAM, \ + _TRANSB_HDCP2_AUTH_STREAM) +#define AUTH_STREAM_TYPE BIT(31) +#define HDCP2_AUTH_STREAM(dev_priv, trans, port) \ + (INTEL_GEN(dev_priv) >= 12 ? \ +TRANS_HDCP2_AUTH_STREAM(trans) : \ +PORT_HDCP2_AUTH_STREAM(port)) + /* Per-pipe DDI Function Control */ #define _TRANS_DDI_FUNC_CTL_A 0x60400 #define _TRANS_DDI_FUNC_CTL_B 0x61400 -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 12/17] drm/hdcp: Max MST content streams
Let's define Maximum MST content streams up to four generically which can be supported by modern display controllers. Cc: Sean Paul Cc: Ramalingam C Acked-by: Maarten Lankhorst Reviewed-by: Uma Shankar Reviewed-by: Ramalingam C Signed-off-by: Anshuman Gupta --- include/drm/drm_hdcp.h | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h index fe58dbb46962..ac22c246542a 100644 --- a/include/drm/drm_hdcp.h +++ b/include/drm/drm_hdcp.h @@ -101,11 +101,11 @@ /* Following Macros take a byte at a time for bit(s) masking */ /* - * TODO: This has to be changed for DP MST, as multiple stream on - * same port is possible. - * For HDCP2.2 on HDMI and DP SST this value is always 1. + * TODO: HDCP_2_2_MAX_CONTENT_STREAMS_CNT is based upon actual + * H/W MST streams capacity. + * This required to be moved out to platform specific header. */ -#define HDCP_2_2_MAX_CONTENT_STREAMS_CNT 1 +#define HDCP_2_2_MAX_CONTENT_STREAMS_CNT 4 #define HDCP_2_2_TXCAP_MASK_LEN2 #define HDCP_2_2_RXCAPS_LEN3 #define HDCP_2_2_RX_REPEATER(x)((x) & BIT(0)) -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 07/17] drm/i915/hdcp: Enable HDCP 1.4 stream encryption
Enable HDCP 1.4 DP MST stream encryption. Enable stream encryption once encryption is enabled on the DP transport driving the link for each stream which has requested encryption. Disable stream encryption for each stream that no longer requires encryption before disabling HDCP encryption on the link. v2: - Added debug print for stream encryption. - Disable the hdcp on port after disabling last stream encryption. v3: - Cosmetic change, removed the value less comment. [Uma] v4: - Split the Gen12 HDCP enablement patch. [Ram] - Add connector details in drm_err. Cc: Ramalingam C Reviewed-by: Uma Shankar Signed-off-by: Anshuman Gupta --- drivers/gpu/drm/i915/display/intel_hdcp.c | 45 --- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 0322a83c151d..e12bd0ac9fb5 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -612,7 +612,12 @@ int intel_hdcp_auth_downstream(struct intel_connector *connector) return ret; } -/* Implements Part 1 of the HDCP authorization procedure */ +/* + * Implements Part 1 of the HDCP authorization procedure. + * Authentication Part 1 steps for Multi-stream DisplayPort. + * Step 1. Auth Part 1 sequence on the driving MST Trasport Link. + * Step 2. Enable encryption for each stream that requires encryption. + */ static int intel_hdcp_auth(struct intel_connector *connector) { struct intel_digital_port *dig_port = intel_attached_dig_port(connector); @@ -766,10 +771,17 @@ static int intel_hdcp_auth(struct intel_connector *connector) return -ETIMEDOUT; } - /* -* XXX: If we have MST-connected devices, we need to enable encryption -* on those as well. -*/ + /* DP MST Auth Part 1 Step 2.a and Step 2.b */ + if (shim->stream_encryption) { + ret = shim->stream_encryption(connector, true); + if (ret) { + drm_err(&dev_priv->drm, "[CONNECTOR:%d:%s] Failed to enable HDCP 1.4 stream enc\n", + connector->base.base.id, connector->base.name); + return ret; + } + drm_dbg_kms(&dev_priv->drm, "HDCP 1.4 transcoder: %s stream encrypted\n", + transcoder_name(hdcp->stream_transcoder)); + } if (repeater_present) return intel_hdcp_auth_downstream(connector); @@ -791,18 +803,23 @@ static int _intel_hdcp_disable(struct intel_connector *connector) drm_dbg_kms(&dev_priv->drm, "[%s:%d] HDCP is being disabled...\n", connector->base.name, connector->base.base.id); + if (hdcp->shim->stream_encryption) { + ret = hdcp->shim->stream_encryption(connector, false); + if (ret) { + drm_err(&dev_priv->drm, "[CONNECTOR:%d:%s] Failed to disable HDCP 1.4 stream enc\n", + connector->base.base.id, connector->base.name); + return ret; + } + drm_dbg_kms(&dev_priv->drm, "HDCP 1.4 transcoder: %s stream encryption disabled\n", + transcoder_name(hdcp->stream_transcoder)); + } + /* -* If there are other connectors on this port using HDCP, don't disable -* it. Instead, toggle the HDCP signalling off on that particular -* connector/pipe and exit. +* If there are other connectors on this port using HDCP, don't disable it. +* Repeat steps 1-2 for each stream that no longer requires encryption. */ - if (dig_port->num_hdcp_streams > 0) { - ret = hdcp->shim->toggle_signalling(dig_port, - cpu_transcoder, false); - if (ret) - DRM_ERROR("Failed to disable HDCP signalling\n"); + if (dig_port->num_hdcp_streams > 0) return ret; - } hdcp->hdcp_encrypted = false; intel_de_write(dev_priv, HDCP_CONF(dev_priv, cpu_transcoder, port), 0); -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 04/17] drm/i915/hdcp: DP MST transcoder for link and stream
Gen12 has H/W delta with respect to HDCP{1.x,2.x} display engine instances lies in Transcoder instead of DDI as in Gen11. This requires hdcp driver to use mst_master_transcoder for link authentication and stream transcoder for stream encryption separately. This will be used for both HDCP 1.4 and HDCP 2.2 over DP MST on Gen12. Cc: Ramalingam C Reviewed-by: Uma Shankar Reviewed-by: Ramalingam C Signed-off-by: Anshuman Gupta --- drivers/gpu/drm/i915/display/intel_ddi.c | 2 +- .../gpu/drm/i915/display/intel_display_types.h| 2 ++ drivers/gpu/drm/i915/display/intel_dp_mst.c | 2 +- drivers/gpu/drm/i915/display/intel_hdcp.c | 15 +++ drivers/gpu/drm/i915/display/intel_hdcp.h | 2 +- 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 19b16517a502..c91962fe09c6 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -4059,7 +4059,7 @@ static void intel_enable_ddi(struct intel_atomic_state *state, if (conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) intel_hdcp_enable(to_intel_connector(conn_state->connector), - crtc_state->cpu_transcoder, + crtc_state, (u8)conn_state->hdcp_content_type); } diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index f6f0626649e0..c47124a679b6 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -432,6 +432,8 @@ struct intel_hdcp { * Hence caching the transcoder here. */ enum transcoder cpu_transcoder; + /* Only used for DP MST stream encryption */ + enum transcoder stream_transcoder; }; struct intel_connector { diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index c8fcec4d0788..16865b200062 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -568,7 +568,7 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state, if (conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) intel_hdcp_enable(to_intel_connector(conn_state->connector), - pipe_config->cpu_transcoder, + pipe_config, (u8)conn_state->hdcp_content_type); } diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index b9d8825e2bb1..fc5de48456ad 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -2095,7 +2095,7 @@ int intel_hdcp_init(struct intel_connector *connector, } int intel_hdcp_enable(struct intel_connector *connector, - enum transcoder cpu_transcoder, u8 content_type) + const struct intel_crtc_state *pipe_config, u8 content_type) { struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); @@ -2111,10 +2111,17 @@ int intel_hdcp_enable(struct intel_connector *connector, drm_WARN_ON(&dev_priv->drm, hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED); hdcp->content_type = content_type; - hdcp->cpu_transcoder = cpu_transcoder; + + if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST)) { + hdcp->cpu_transcoder = pipe_config->mst_master_transcoder; + hdcp->stream_transcoder = pipe_config->cpu_transcoder; + } else { + hdcp->cpu_transcoder = pipe_config->cpu_transcoder; + hdcp->stream_transcoder = INVALID_TRANSCODER; + } if (INTEL_GEN(dev_priv) >= 12) - hdcp->port_data.fw_tc = intel_get_mei_fw_tc(cpu_transcoder); + hdcp->port_data.fw_tc = intel_get_mei_fw_tc(hdcp->cpu_transcoder); /* * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup @@ -2234,7 +2241,7 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state, if (desired_and_not_enabled || content_protection_type_changed) intel_hdcp_enable(connector, - crtc_state->cpu_transcoder, + crtc_state, (u8)conn_state->hdcp_content_type); } diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.h b/drivers/gpu/drm/i915/display/intel_hdcp.h index 1bbf5b67ed0a..bc51c1e9b481 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.h +++ b/drivers/gpu/drm/i915/display/intel_hdcp.h @@ -25,7 +25,7 @@ void intel_hdcp_atomic_c
[PATCH v5 13/17] drm/i915/hdcp: MST streams support in hdcp port_data
Add support for multiple mst stream in hdcp port data which will be used by RepeaterAuthStreamManage msg and HDCP 2.2 security f/w for m' validation. Security f/w doesn't have any provision to mark the stream_type for each stream separately, it just take single input of stream_type while authentiating the port. So driver mark each stream_type with common highest supported content type for all streams in DP MST Topology. Security f/w supports RepeaterAuthStreamManage msg and m' validation only once during port authentication and encryption. v2: - Init the hdcp port data k for HDMI/DP SST stream. v3: - Cosmetic changes. [Uma] v4: - 's/port_auth/hdcp_port_auth'. [Ram] - Commit log improvement. Cc: Ramalingam C Reviewed-by: Uma Shankar Signed-off-by: Anshuman Gupta --- .../drm/i915/display/intel_display_types.h| 4 +- drivers/gpu/drm/i915/display/intel_hdcp.c | 103 +++--- 2 files changed, 92 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 6e597f6aafe8..b93ecf4f21e3 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1445,10 +1445,12 @@ struct intel_digital_port { enum phy_fia tc_phy_fia; u8 tc_phy_fia_idx; - /* protects num_hdcp_streams reference count, port_data */ + /* protects num_hdcp_streams reference count, port_data and port_auth */ struct mutex hdcp_mutex; /* the number of pipes using HDCP signalling out of this port */ unsigned int num_hdcp_streams; + /* port HDCP auth status */ + bool hdcp_auth_status; /* HDCP port data need to pass to security f/w */ struct hdcp_port_data hdcp_port_data; diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 829176df89e7..6a48110c7cd7 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -26,6 +26,64 @@ #define KEY_LOAD_TRIES 5 #define HDCP2_LC_RETRY_CNT 3 +static int intel_conn_to_vcpi(struct intel_connector *connector) +{ + /* For HDMI this is forced to be 0x0. For DP SST also this is 0x0. */ + return connector->port ? connector->port->vcpi.vcpi : 0; +} + +static int +intel_hdcp_required_content_stream(struct intel_digital_port *dig_port) +{ + struct drm_connector_list_iter conn_iter; + struct intel_digital_port *conn_dig_port; + struct intel_connector *connector; + struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct hdcp_port_data *data = &dig_port->hdcp_port_data; + bool enforce_type0 = false; + int k; + + if (dig_port->hdcp_auth_status) + return 0; + + drm_connector_list_iter_begin(&i915->drm, &conn_iter); + for_each_intel_connector_iter(connector, &conn_iter) { + if (!intel_encoder_is_mst(intel_attached_encoder(connector))) + continue; + + conn_dig_port = intel_attached_dig_port(connector); + if (conn_dig_port != dig_port) + continue; + + if (connector->base.status == connector_status_disconnected) + continue; + + if (!enforce_type0 && !intel_hdcp2_capable(connector)) + enforce_type0 = true; + + data->streams[data->k].stream_id = intel_conn_to_vcpi(connector); + data->k++; + + /* if there is only one active stream */ + if (dig_port->dp.active_mst_links <= 1) + break; + } + drm_connector_list_iter_end(&conn_iter); + + if (drm_WARN_ON(&i915->drm, data->k > INTEL_NUM_PIPES(i915) || data->k == 0)) + return -EINVAL; + + /* +* Apply common protection level across all streams in DP MST Topology. +* Use highest supported content type for all streams in DP MST Topology. +*/ + for (k = 0; k < data->k; k++) + data->streams[k].stream_type = + enforce_type0 ? DRM_MODE_HDCP_CONTENT_TYPE0 : DRM_MODE_HDCP_CONTENT_TYPE1; + + return 0; +} + static bool intel_hdcp_is_ksv_valid(u8 *ksv) { @@ -1476,13 +1534,14 @@ static int _hdcp2_propagate_stream_management_info(struct intel_connector *connector) { struct intel_digital_port *dig_port = intel_attached_dig_port(connector); + struct hdcp_port_data *data = &dig_port->hdcp_port_data; struct intel_hdcp *hdcp = &connector->hdcp; union { struct hdcp2_rep_stream_manage stream_manage; struct hdcp2_rep_stream_ready stream_ready; } msgs; const struct intel_hdcp_shim *shim = hdcp->shim; - int ret; + int ret, streams_size_delta, i; if (connector->hdcp.seq_num_m > HDCP_2_2_S
[PATCH v5 00/17] HDCP 2.2 and HDCP 1.4 Gen12 DP MST support
This is v5 version to test with IGT https://patchwork.freedesktop.org/series/82987/ This has addressed the review comments from Ram. It has been also tested manually with above IGT series. [PATCH v5 11/17] misc/mei/hdcp: Fix AUTH_STREAM_REQ cmd buffer len has an Ack from Tomas to merge it via drm-intel. [PATCH v5 12/17] drm/hdcp: Max MST content streams has an Ack from drm-misc maintainer to merge it via drm-intel. Test-with: 20201103082628.9287-2-karthik@intel.com Anshuman Gupta (17): drm/i915/hdcp: Update CP property in update_pipe drm/i915/hdcp: Get conn while content_type changed drm/i915/hotplug: Handle CP_IRQ for DP-MST drm/i915/hdcp: DP MST transcoder for link and stream drm/i915/hdcp: Move HDCP enc status timeout to header drm/i915/hdcp: HDCP stream encryption support drm/i915/hdcp: Enable HDCP 1.4 stream encryption drm/i915/hdcp: Enable Gen12 HDCP 1.4 DP MST support drm/i915/hdcp: Pass dig_port to intel_hdcp_init drm/i915/hdcp: Encapsulate hdcp_port_data to dig_port misc/mei/hdcp: Fix AUTH_STREAM_REQ cmd buffer len drm/hdcp: Max MST content streams drm/i915/hdcp: MST streams support in hdcp port_data drm/i915/hdcp: Pass connector to check_2_2_link drm/i915/hdcp: Add HDCP 2.2 stream register drm/i915/hdcp: Support for HDCP 2.2 MST shim callbacks drm/i915/hdcp: Enable HDCP 2.2 MST support drivers/gpu/drm/i915/display/intel_ddi.c | 14 +- drivers/gpu/drm/i915/display/intel_ddi.h | 6 +- .../drm/i915/display/intel_display_types.h| 20 +- drivers/gpu/drm/i915/display/intel_dp.c | 14 +- drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 182 +-- drivers/gpu/drm/i915/display/intel_dp_mst.c | 12 +- drivers/gpu/drm/i915/display/intel_hdcp.c | 294 ++ drivers/gpu/drm/i915/display/intel_hdcp.h | 8 +- drivers/gpu/drm/i915/display/intel_hdmi.c | 19 +- drivers/gpu/drm/i915/i915_reg.h | 31 ++ drivers/misc/mei/hdcp/mei_hdcp.c | 3 +- include/drm/drm_hdcp.h| 8 +- 12 files changed, 489 insertions(+), 122 deletions(-) -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 05/17] drm/i915/hdcp: Move HDCP enc status timeout to header
DP MST stream encryption status requires time of a link frame in order to change its status, but as there were some HDCP encryption timeout observed earlier, it is safer to use ENCRYPT_STATUS_CHANGE_TIMEOUT_MS timeout for stream status too, it requires to move the macro to a header. It will be used by both HDCP{1.x,2.x} stream status timeout. Related: 'commit 7e90e8d0c0ea ("drm/i915: Increase timeout for Encrypt status change")' Cc: Ramalingam C Reviewed-by: Uma Shankar Reviewed-by: Ramalingam C Signed-off-by: Anshuman Gupta --- drivers/gpu/drm/i915/display/intel_hdcp.c | 9 - drivers/gpu/drm/i915/display/intel_hdcp.h | 2 ++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index fc5de48456ad..0322a83c151d 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -23,7 +23,6 @@ #include "intel_connector.h" #define KEY_LOAD_TRIES 5 -#define ENCRYPT_STATUS_CHANGE_TIMEOUT_MS 50 #define HDCP2_LC_RETRY_CNT 3 static @@ -762,7 +761,7 @@ static int intel_hdcp_auth(struct intel_connector *connector) if (intel_de_wait_for_set(dev_priv, HDCP_STATUS(dev_priv, cpu_transcoder, port), HDCP_STATUS_ENC, - ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) { + HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) { drm_err(&dev_priv->drm, "Timed out waiting for encryption\n"); return -ETIMEDOUT; } @@ -809,7 +808,7 @@ static int _intel_hdcp_disable(struct intel_connector *connector) intel_de_write(dev_priv, HDCP_CONF(dev_priv, cpu_transcoder, port), 0); if (intel_de_wait_for_clear(dev_priv, HDCP_STATUS(dev_priv, cpu_transcoder, port), - ~0, ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) { + ~0, HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) { drm_err(&dev_priv->drm, "Failed to disable HDCP, timeout clearing status\n"); return -ETIMEDOUT; @@ -1641,7 +1640,7 @@ static int hdcp2_enable_encryption(struct intel_connector *connector) HDCP2_STATUS(dev_priv, cpu_transcoder, port), LINK_ENCRYPTION_STATUS, - ENCRYPT_STATUS_CHANGE_TIMEOUT_MS); + HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS); return ret; } @@ -1665,7 +1664,7 @@ static int hdcp2_disable_encryption(struct intel_connector *connector) HDCP2_STATUS(dev_priv, cpu_transcoder, port), LINK_ENCRYPTION_STATUS, - ENCRYPT_STATUS_CHANGE_TIMEOUT_MS); + HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS); if (ret == -ETIMEDOUT) drm_dbg_kms(&dev_priv->drm, "Disable Encryption Timedout"); diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.h b/drivers/gpu/drm/i915/display/intel_hdcp.h index bc51c1e9b481..b912a3a0f5b8 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.h +++ b/drivers/gpu/drm/i915/display/intel_hdcp.h @@ -8,6 +8,8 @@ #include +#define HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS 50 + struct drm_connector; struct drm_connector_state; struct drm_i915_private; -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 09/17] drm/i915/hdcp: Pass dig_port to intel_hdcp_init
Pass dig_port as an argument to intel_hdcp_init() and intel_hdcp2_init(). This will be required for HDCP 2.2 stream encryption. Cc: Ramalingam C Reviewed-by: Uma Shankar Reviewed-by: Ramalingam C Signed-off-by: Anshuman Gupta --- drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 4 ++-- drivers/gpu/drm/i915/display/intel_hdcp.c| 12 +++- drivers/gpu/drm/i915/display/intel_hdcp.h| 4 +++- drivers/gpu/drm/i915/display/intel_hdmi.c| 2 +- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c index c2adac8d7866..f643d3af59bb 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c @@ -755,10 +755,10 @@ int intel_dp_init_hdcp(struct intel_digital_port *dig_port, return 0; if (intel_connector->mst_port) - return intel_hdcp_init(intel_connector, port, + return intel_hdcp_init(intel_connector, dig_port, &intel_dp_mst_hdcp_shim); else if (!intel_dp_is_edp(intel_dp)) - return intel_hdcp_init(intel_connector, port, + return intel_hdcp_init(intel_connector, dig_port, &intel_dp_hdcp_shim); return 0; diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index e12bd0ac9fb5..2d5ee31f671a 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -1984,12 +1984,13 @@ static enum mei_fw_tc intel_get_mei_fw_tc(enum transcoder cpu_transcoder) } static int initialize_hdcp_port_data(struct intel_connector *connector, -enum port port, +struct intel_digital_port *dig_port, const struct intel_hdcp_shim *shim) { struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct intel_hdcp *hdcp = &connector->hdcp; struct hdcp_port_data *data = &hdcp->port_data; + enum port port = dig_port->base.port; if (INTEL_GEN(dev_priv) < 12) data->fw_ddi = intel_get_mei_fw_ddi_index(port); @@ -2062,14 +2063,15 @@ void intel_hdcp_component_init(struct drm_i915_private *dev_priv) } } -static void intel_hdcp2_init(struct intel_connector *connector, enum port port, +static void intel_hdcp2_init(struct intel_connector *connector, +struct intel_digital_port *dig_port, const struct intel_hdcp_shim *shim) { struct drm_i915_private *i915 = to_i915(connector->base.dev); struct intel_hdcp *hdcp = &connector->hdcp; int ret; - ret = initialize_hdcp_port_data(connector, port, shim); + ret = initialize_hdcp_port_data(connector, dig_port, shim); if (ret) { drm_dbg_kms(&i915->drm, "Mei hdcp data init failed\n"); return; @@ -2079,7 +2081,7 @@ static void intel_hdcp2_init(struct intel_connector *connector, enum port port, } int intel_hdcp_init(struct intel_connector *connector, - enum port port, + struct intel_digital_port *dig_port, const struct intel_hdcp_shim *shim) { struct drm_i915_private *dev_priv = to_i915(connector->base.dev); @@ -2090,7 +2092,7 @@ int intel_hdcp_init(struct intel_connector *connector, return -EINVAL; if (is_hdcp2_supported(dev_priv) && !connector->mst_port) - intel_hdcp2_init(connector, port, shim); + intel_hdcp2_init(connector, dig_port, shim); ret = drm_connector_attach_content_protection_property(&connector->base, diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.h b/drivers/gpu/drm/i915/display/intel_hdcp.h index b912a3a0f5b8..8f53b0c7fe5c 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.h +++ b/drivers/gpu/drm/i915/display/intel_hdcp.h @@ -18,13 +18,15 @@ struct intel_connector; struct intel_crtc_state; struct intel_encoder; struct intel_hdcp_shim; +struct intel_digital_port; enum port; enum transcoder; void intel_hdcp_atomic_check(struct drm_connector *connector, struct drm_connector_state *old_state, struct drm_connector_state *new_state); -int intel_hdcp_init(struct intel_connector *connector, enum port port, +int intel_hdcp_init(struct intel_connector *connector, + struct intel_digital_port *dig_port, const struct intel_hdcp_shim *hdcp_shim); int intel_hdcp_enable(struct intel_connector *connector, const struct intel_crtc_state *pipe_config, u8 content_type); diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index f58469226694..0788de04711b 1
[PATCH v5 10/17] drm/i915/hdcp: Encapsulate hdcp_port_data to dig_port
hdcp_port_data is specific to a port on which HDCP encryption is getting enabled, so encapsulate it to intel_digital_port. This will be required to enable HDCP 2.2 stream encryption. v2: - 's/port_data/hdcp_port_data'. [Ram] Cc: Ramalingam C Reviewed-by: Uma Shankar Reviewed-by: Ramalingam C Signed-off-by: Anshuman Gupta --- drivers/gpu/drm/i915/display/intel_ddi.c | 2 + .../drm/i915/display/intel_display_types.h| 5 +- drivers/gpu/drm/i915/display/intel_hdcp.c | 56 +++ 3 files changed, 39 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 37f4a25ffb39..c6a2a2bc716a 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -4746,6 +4746,8 @@ static void intel_ddi_encoder_destroy(struct drm_encoder *encoder) intel_dp_encoder_flush_work(encoder); drm_encoder_cleanup(encoder); + if (dig_port) + kfree(dig_port->hdcp_port_data.streams); kfree(dig_port); } diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 605ec74f8678..6e597f6aafe8 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -402,7 +402,6 @@ struct intel_hdcp { * content can flow only through a link protected by HDCP2.2. */ u8 content_type; - struct hdcp_port_data port_data; bool is_paired; bool is_repeater; @@ -1446,10 +1445,12 @@ struct intel_digital_port { enum phy_fia tc_phy_fia; u8 tc_phy_fia_idx; - /* protects num_hdcp_streams reference count */ + /* protects num_hdcp_streams reference count, port_data */ struct mutex hdcp_mutex; /* the number of pipes using HDCP signalling out of this port */ unsigned int num_hdcp_streams; + /* HDCP port data need to pass to security f/w */ + struct hdcp_port_data hdcp_port_data; void (*write_infoframe)(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 2d5ee31f671a..829176df89e7 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -15,6 +15,7 @@ #include #include +#include "i915_drv.h" #include "i915_reg.h" #include "intel_display_power.h" #include "intel_display_types.h" @@ -1030,7 +1031,8 @@ static int hdcp2_prepare_ake_init(struct intel_connector *connector, struct hdcp2_ake_init *ake_data) { - struct hdcp_port_data *data = &connector->hdcp.port_data; + struct intel_digital_port *dig_port = intel_attached_dig_port(connector); + struct hdcp_port_data *data = &dig_port->hdcp_port_data; struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct i915_hdcp_comp_master *comp; int ret; @@ -1059,7 +1061,8 @@ hdcp2_verify_rx_cert_prepare_km(struct intel_connector *connector, struct hdcp2_ake_no_stored_km *ek_pub_km, size_t *msg_sz) { - struct hdcp_port_data *data = &connector->hdcp.port_data; + struct intel_digital_port *dig_port = intel_attached_dig_port(connector); + struct hdcp_port_data *data = &dig_port->hdcp_port_data; struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct i915_hdcp_comp_master *comp; int ret; @@ -1086,7 +1089,8 @@ hdcp2_verify_rx_cert_prepare_km(struct intel_connector *connector, static int hdcp2_verify_hprime(struct intel_connector *connector, struct hdcp2_ake_send_hprime *rx_hprime) { - struct hdcp_port_data *data = &connector->hdcp.port_data; + struct intel_digital_port *dig_port = intel_attached_dig_port(connector); + struct hdcp_port_data *data = &dig_port->hdcp_port_data; struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct i915_hdcp_comp_master *comp; int ret; @@ -,7 +1115,8 @@ static int hdcp2_store_pairing_info(struct intel_connector *connector, struct hdcp2_ake_send_pairing_info *pairing_info) { - struct hdcp_port_data *data = &connector->hdcp.port_data; + struct intel_digital_port *dig_port = intel_attached_dig_port(connector); + struct hdcp_port_data *data = &dig_port->hdcp_port_data; struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct i915_hdcp_comp_master *comp; int ret; @@ -1137,7 +1142,8 @@ static int hdcp2_prepare_lc_init(struct intel_connector *connector, struct hdcp2_lc_init *lc_init) { - struct hdcp_port_data *data = &connector->hdcp.port_data; +
[PATCH v5 01/17] drm/i915/hdcp: Update CP property in update_pipe
When crtc state need_modeset is true it is not necessary it is going to be a real modeset, it can turns to be a fastset instead of modeset. This turns content protection property to be DESIRED and hdcp update_pipe left with property to be in DESIRED state but actual hdcp->value was ENABLED. This issue is caught with DP MST setup, where we have multiple connector in same DP_MST topology. When disabling HDCP on one of DP MST connector leads to set the crtc state need_modeset to true for all other crtc driving the other DP-MST topology connectors. This turns up other DP MST connectors CP property to be DESIRED despite the actual hdcp->value is ENABLED. Above scenario fails the DP MST HDCP IGT test, disabling HDCP on one MST stream should not cause to disable HDCP on another MST stream on same DP MST topology. v2: Fix WARN_ON(connector->base.registration_state == DRM_CONNECTOR_REGISTERED) v3: Commit log improvement. [Uma] Added a comment before scheduling prop_work. [Uma] Fixes: 33f9a623bfc6 ("drm/i915/hdcp: Update CP as per the kernel internal state") Cc: Ramalingam C Reviewed-by: Uma Shankar Reviewed-by: Ramalingam C Signed-off-by: Anshuman Gupta --- drivers/gpu/drm/i915/display/intel_hdcp.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index b2a4bbcfdcd2..eee8263405b9 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -2221,6 +2221,14 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state, desired_and_not_enabled = hdcp->value != DRM_MODE_CONTENT_PROTECTION_ENABLED; mutex_unlock(&hdcp->mutex); + /* +* If HDCP already ENABLED and CP property is DESIRED, schedule +* prop_work to update correct CP property to user space. +*/ + if (!desired_and_not_enabled && !content_protection_type_changed) { + drm_connector_get(&connector->base); + schedule_work(&hdcp->prop_work); + } } if (desired_and_not_enabled || content_protection_type_changed) -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 06/17] drm/i915/hdcp: HDCP stream encryption support
Both HDCP_{1.x,2.x} requires to select/deselect Multistream HDCP bit in TRANS_DDI_FUNC_CTL in order to enable/disable stream HDCP encryption over DP MST Transport Link. HDCP 1.4 stream encryption requires to validate the stream encryption status in HDCP_STATUS_{TRANSCODER,PORT} register driving that link in order to enable/disable the stream encryption. Both of above requirement are same for all Gen with respect to B.Spec Documentation. v2: Cosmetic changes function name, error msg print and stream typo fixes. [Uma] Cc: Ramalingam C Reviewed-by: Uma Shankar Reviewed-by: Ramalingam C Signed-off-by: Anshuman Gupta --- drivers/gpu/drm/i915/display/intel_ddi.c | 10 +-- drivers/gpu/drm/i915/display/intel_ddi.h | 6 +- .../drm/i915/display/intel_display_types.h| 4 + drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 86 --- drivers/gpu/drm/i915/display/intel_hdmi.c | 14 +-- drivers/gpu/drm/i915/i915_reg.h | 1 + 6 files changed, 95 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index c91962fe09c6..37f4a25ffb39 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -1948,9 +1948,9 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state } } -int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder, -enum transcoder cpu_transcoder, -bool enable) +int intel_ddi_toggle_hdcp_bits(struct intel_encoder *intel_encoder, + enum transcoder cpu_transcoder, + bool enable, u32 hdcp_mask) { struct drm_device *dev = intel_encoder->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); @@ -1965,9 +1965,9 @@ int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder, tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder)); if (enable) - tmp |= TRANS_DDI_HDCP_SIGNALLING; + tmp |= hdcp_mask; else - tmp &= ~TRANS_DDI_HDCP_SIGNALLING; + tmp &= ~hdcp_mask; intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder), tmp); intel_display_power_put(dev_priv, intel_encoder->power_domain, wakeref); return ret; diff --git a/drivers/gpu/drm/i915/display/intel_ddi.h b/drivers/gpu/drm/i915/display/intel_ddi.h index dcc711cfe4fe..a4dd815c 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.h +++ b/drivers/gpu/drm/i915/display/intel_ddi.h @@ -50,9 +50,9 @@ u32 bxt_signal_levels(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state); u32 ddi_signal_levels(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state); -int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder, -enum transcoder cpu_transcoder, -bool enable); +int intel_ddi_toggle_hdcp_bits(struct intel_encoder *intel_encoder, + enum transcoder cpu_transcoder, + bool enable, u32 hdcp_mask); void icl_sanitize_encoder_pll_mapping(struct intel_encoder *encoder); #endif /* __INTEL_DDI_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index c47124a679b6..605ec74f8678 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -339,6 +339,10 @@ struct intel_hdcp_shim { enum transcoder cpu_transcoder, bool enable); + /* Enable/Disable stream encryption on DP MST Transport Link */ + int (*stream_encryption)(struct intel_connector *connector, +bool enable); + /* Ensures the link is still protected */ bool (*check_link)(struct intel_digital_port *dig_port, struct intel_connector *connector); diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c index 03424d20e9f7..c2adac8d7866 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c @@ -16,6 +16,30 @@ #include "intel_dp.h" #include "intel_hdcp.h" +static unsigned int transcoder_to_stream_enc_status(enum transcoder cpu_transcoder) +{ + u32 stream_enc_mask; + + switch (cpu_transcoder) { + case TRANSCODER_A: + stream_enc_mask = HDCP_STATUS_STREAM_A_ENC; + break; + case TRANSCODER_B: + stream_enc_mask = HDCP_STATUS_STREAM_B_ENC; + break; + case TRANSCODER_C: + stream_enc_mask = HDCP_STATUS_STREAM_C_ENC; +
[PATCH v5 08/17] drm/i915/hdcp: Enable Gen12 HDCP 1.4 DP MST support
Enable HDCP 1.4 over DP MST for Gen12. Cc: Ramalingam C Signed-off-by: Anshuman Gupta --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 10 +++--- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 16865b200062..f00e12fc83e8 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -826,13 +826,9 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo intel_attach_force_audio_property(connector); intel_attach_broadcast_rgb_property(connector); - - /* TODO: Figure out how to make HDCP work on GEN12+ */ - if (INTEL_GEN(dev_priv) < 12) { - ret = intel_dp_init_hdcp(dig_port, intel_connector); - if (ret) - DRM_DEBUG_KMS("HDCP init failed, skipping.\n"); - } + ret = intel_dp_init_hdcp(dig_port, intel_connector); + if (ret) + drm_dbg_kms(&dev_priv->drm, "HDCP init failed, skipping.\n"); /* * Reuse the prop from the SST connector because we're -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 03/17] drm/i915/hotplug: Handle CP_IRQ for DP-MST
Handle CP_IRQ in DEVICE_SERVICE_IRQ_VECTOR_ESI0 It requires to call intel_hdcp_handle_cp_irq() in case of CP_IRQ is triggered by a sink in DP-MST topology. Cc: "Ville Syrjälä" Cc: Ramalingam C Reviewed-by: Uma Shankar Reviewed-by: Ramalingam C Signed-off-by: Anshuman Gupta --- drivers/gpu/drm/i915/display/intel_dp.c | 14 +- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index cf09aca7607b..740f30bacfa8 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -5711,6 +5711,17 @@ static void intel_dp_handle_test_request(struct intel_dp *intel_dp) "Could not write test response to sink\n"); } +static void +intel_dp_mst_hpd_irq(struct intel_dp *intel_dp, u8 *esi, bool *handled) +{ + drm_dp_mst_hpd_irq(&intel_dp->mst_mgr, esi, handled); + + if (esi[1] & DP_CP_IRQ) { + intel_hdcp_handle_cp_irq(intel_dp->attached_connector); + *handled = true; + } +} + /** * intel_dp_check_mst_status - service any pending MST interrupts, check link status * @intel_dp: Intel DP struct @@ -5755,7 +5766,8 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp) drm_dbg_kms(&i915->drm, "got esi %3ph\n", esi); - drm_dp_mst_hpd_irq(&intel_dp->mst_mgr, esi, &handled); + intel_dp_mst_hpd_irq(intel_dp, esi, &handled); + if (!handled) break; -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 02/17] drm/i915/hdcp: Get conn while content_type changed
Get DRM connector reference count while scheduling a prop work to avoid any possible destroy of DRM connector when it is in DRM_CONNECTOR_REGISTERED state. Fixes: a6597faa2d59 ("drm/i915: Protect workers against disappearing connectors") Cc: Sean Paul Cc: Ramalingam C Reviewed-by: Uma Shankar Reviewed-by: Ramalingam C Signed-off-by: Anshuman Gupta --- drivers/gpu/drm/i915/display/intel_hdcp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index eee8263405b9..b9d8825e2bb1 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -2210,6 +2210,7 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state, if (content_protection_type_changed) { mutex_lock(&hdcp->mutex); hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED; + drm_connector_get(&connector->base); schedule_work(&hdcp->prop_work); mutex_unlock(&hdcp->mutex); } -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: linux-next: build failure after merge of the drm-misc tree
Hi Michael, On Mon, 2 Nov 2020 05:19:06 -0500 "Michael S. Tsirkin" wrote: > > On Mon, Nov 02, 2020 at 12:43:27PM +1100, Stephen Rothwell wrote: > > > > After merging the drm-misc tree, today's linux-next build (arm > > multi_v7_defconfig) failed like this: > > > > In file included from drivers/gpu/drm/nouveau/nouveau_ttm.c:26: > > include/linux/swiotlb.h: In function 'swiotlb_max_mapping_size': > > include/linux/swiotlb.h:99:9: error: 'SIZE_MAX' undeclared (first use in > > this function) > >99 | return SIZE_MAX; > > | ^~~~ > > include/linux/swiotlb.h:7:1: note: 'SIZE_MAX' is defined in header > > ''; did you forget to '#include '? > > 6 | #include > > +++ |+#include > > 7 | #include > > include/linux/swiotlb.h:99:9: note: each undeclared identifier is reported > > only once for each function it appears in > >99 | return SIZE_MAX; > > | ^~~~ > > > > Caused by commit > > > > abe420bfae52 ("swiotlb: Introduce swiotlb_max_mapping_size()") > > > > but only exposed by commit > > > > 4dbafbd30aef ("drm/nouveu: fix swiotlb include") > > > > I applied the following fix for today: > > > > From: Stephen Rothwell > > Date: Mon, 2 Nov 2020 12:34:57 +1100 > > Subject: [PATCH] swiotlb: using SIZE_MAX needs limits.h included > > > > Fixes: abe420bfae52 ("swiotlb: Introduce swiotlb_max_mapping_size()") > > Signed-off-by: Stephen Rothwell > > Acked-by: Michael S. Tsirkin > > I guess it makes sense to pick this up for this release directly. > I'll merge this unless there are any objections. Christoph is right that the include should not be conditional. But I have not tested that that does not introduce some other problems. -- Cheers, Stephen Rothwell pgpiKloPktYbR.pgp Description: OpenPGP digital signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 00/16] drm/exynos: Convert driver to drm bridge
20. 11. 11. 오후 12:04에 Inki Dae 이(가) 쓴 글: > > > 20. 11. 10. 오후 5:13에 Michael Tretter 이(가) 쓴 글: >> On Mon, 09 Nov 2020 12:15:39 +0900, Inki Dae wrote: >>> 20. 9. 11. 오후 10:53에 Michael Tretter 이(가) 쓴 글: This is v2 of the series to convert the Exynos MIPI DSI driver into a drm bridge and make it usable with other drivers. Although the driver is converted, it still supports the component framework API to stay compliant with the Exynos DRM driver. The Exynos MIPI DSI Phy is also found on the i.MX8M Mini. However, on the i.MX8M Mini, the bridge is driven by an LCDIF display controller instead of the Exynos Decon. The driver for the LCDIF does not use the component framework, but uses drm bridges. I don't have any Exynos SoC to actually test the series. I build a dummy to test the bridge with a component driver, to make sure that at least the initialization is working. Furthermore, tested the driver as a bridge with a few additional unfinished patches on the i.MX8M Mini EVK. However, somebody should verify that the driver is still working on Exynos hardware. I also changed the order of the patches to first make the driver more platform independent (patches 2 to 8), then convert to a drm bridge driver (patches 10 >>> >>> Just a fundamental question, A MIPI-DSI(Display Serial Interface) bus device >>> would be one of an encoder type of devices not bridge such as DSI to LVDS >>> and LVDS to DSI bridge devices, and also image enhancer and image compressor >>> in case of Exynos. >> >> I don't understand, why the MIPI-DSI bus device would be an encoder type and >> DSI to LVDS or MIPI-DSI to HDMI would be bridges. For example, the device >> tree >> documentation for the DSIM states that the DSIM receives RGB video as input >> and produces MIPI-DSI as output. Thus, the DSIM is basically a parallel RGB >> to > > MIPI-DSI receives RGB video as input and encodes it to MIPI packet and then > transfers the packet to MIPI panel. > And finally, MIPI panel decodes the packet and updates it - RGB data - on its > SRAM. > > MIPI-DSI driver programs how the RGB video should be made as MIPI packet. For > more detail, you could refer to MIPI-DSI spec. > This would be why we handle MIPI-DSI driver as an encoder like other ARM SoC > DRM drivers did. > >> MIPI-DSI bridge and the encoder is the LCD controller that encodes the video >> data as parallel RGB. >> >> On the i.MX8MM, the LCDIF is already the encoder. On Exynos, the series >> implements the encoder in the platform glue, but in the end the encoder can >> probably be moved to the DECON. > > As you know, Display controller can transfer RGB video to various devices > such as RGB panel, CPU panel, LVDS panel via LVDS bridge, MIPI panel via > MIPI-DSI bus device, and so on like below, > > Display Controller --> RGB panel or CPU panel. > Display Controller --> LVDS bridge --> LVDS panel. > Display Controller --> MIPI DSI bus device --> MIPI Panel. > ... > > Display controller drivers such as FIMD and DECON series in case of Exynos > don't create an encoder driver-internally instead of it depends on Display > pipeline configuration - what kind of Display panel is used. > In fact, if the Display pipeline uses RGB panel or CPU panel without Display > bus device such as MIPI-DSI, then FIMD and DECON drivers create an encoder > for it internally - just we separated the code to consider other type of > panels. > > On the I.MX8MM, could you share how to handle an encoder if some board has > only MIPI-DSI panel, and in this case, where is an encoder for it created? I > looked into I.MX8MM DRM driver but didn't find MIPI-DSI driver. > Seems that they support only parallel display, HDMI and LVDS panel. One more thing, If I saw correctly, the LVDS driver of IMX DRM - lmx_ldb - creates an encoder internally like MIPI-DSI driver of Exynos DRM did. > > Thanks, > Inki Dae > >> >>> Why do you want to convert such MIPI-DSI driver to bridge type of driver? >>> Seems not sensible. The reason would be just to share MIPI-DSI phy driver >>> for Exynos with i.MX8M Mini? >> >> Yes, the reason is that the driver should be shared between Exynos and >> i.MX8MM. It is the same IP and I don't see a reason why we should introduce >> another driver for the same IP if the driver works for both SoCs. >> >> Michael >> > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 00/16] drm/exynos: Convert driver to drm bridge
20. 11. 10. 오후 5:13에 Michael Tretter 이(가) 쓴 글: > On Mon, 09 Nov 2020 12:15:39 +0900, Inki Dae wrote: >> 20. 9. 11. 오후 10:53에 Michael Tretter 이(가) 쓴 글: >>> This is v2 of the series to convert the Exynos MIPI DSI driver into a drm >>> bridge and make it usable with other drivers. Although the driver is >>> converted, it still supports the component framework API to stay compliant >>> with the Exynos DRM driver. >>> >>> The Exynos MIPI DSI Phy is also found on the i.MX8M Mini. However, on the >>> i.MX8M Mini, the bridge is driven by an LCDIF display controller instead of >>> the Exynos Decon. The driver for the LCDIF does not use the component >>> framework, but uses drm bridges. >>> >>> I don't have any Exynos SoC to actually test the series. I build a dummy to >>> test the bridge with a component driver, to make sure that at least the >>> initialization is working. Furthermore, tested the driver as a bridge with a >>> few additional unfinished patches on the i.MX8M Mini EVK. However, somebody >>> should verify that the driver is still working on Exynos hardware. >>> >>> I also changed the order of the patches to first make the driver more >>> platform >>> independent (patches 2 to 8), then convert to a drm bridge driver (patches >>> 10 >> >> Just a fundamental question, A MIPI-DSI(Display Serial Interface) bus device >> would be one of an encoder type of devices not bridge such as DSI to LVDS >> and LVDS to DSI bridge devices, and also image enhancer and image compressor >> in case of Exynos. > > I don't understand, why the MIPI-DSI bus device would be an encoder type and > DSI to LVDS or MIPI-DSI to HDMI would be bridges. For example, the device tree > documentation for the DSIM states that the DSIM receives RGB video as input > and produces MIPI-DSI as output. Thus, the DSIM is basically a parallel RGB to MIPI-DSI receives RGB video as input and encodes it to MIPI packet and then transfers the packet to MIPI panel. And finally, MIPI panel decodes the packet and updates it - RGB data - on its SRAM. MIPI-DSI driver programs how the RGB video should be made as MIPI packet. For more detail, you could refer to MIPI-DSI spec. This would be why we handle MIPI-DSI driver as an encoder like other ARM SoC DRM drivers did. > MIPI-DSI bridge and the encoder is the LCD controller that encodes the video > data as parallel RGB. > > On the i.MX8MM, the LCDIF is already the encoder. On Exynos, the series > implements the encoder in the platform glue, but in the end the encoder can > probably be moved to the DECON. As you know, Display controller can transfer RGB video to various devices such as RGB panel, CPU panel, LVDS panel via LVDS bridge, MIPI panel via MIPI-DSI bus device, and so on like below, Display Controller --> RGB panel or CPU panel. Display Controller --> LVDS bridge --> LVDS panel. Display Controller --> MIPI DSI bus device --> MIPI Panel. ... Display controller drivers such as FIMD and DECON series in case of Exynos don't create an encoder driver-internally instead of it depends on Display pipeline configuration - what kind of Display panel is used. In fact, if the Display pipeline uses RGB panel or CPU panel without Display bus device such as MIPI-DSI, then FIMD and DECON drivers create an encoder for it internally - just we separated the code to consider other type of panels. On the I.MX8MM, could you share how to handle an encoder if some board has only MIPI-DSI panel, and in this case, where is an encoder for it created? I looked into I.MX8MM DRM driver but didn't find MIPI-DSI driver. Seems that they support only parallel display, HDMI and LVDS panel. Thanks, Inki Dae > >> Why do you want to convert such MIPI-DSI driver to bridge type of driver? >> Seems not sensible. The reason would be just to share MIPI-DSI phy driver >> for Exynos with i.MX8M Mini? > > Yes, the reason is that the driver should be shared between Exynos and > i.MX8MM. It is the same IP and I don't see a reason why we should introduce > another driver for the same IP if the driver works for both SoCs. > > Michael > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/i915/gvt: replace idr_init() by idr_init_base()
On 2020.11.04 17:45:32 +0530, Deepak R Varma wrote: > idr_init() uses base 0 which is an invalid identifier. The new function > idr_init_base allows IDR to set the ID lookup from base 1. This avoids > all lookups that otherwise starts from 0 since 0 is always unused. > > References: commit 6ce711f27500 ("idr: Make 1-based IDRs more efficient") > > Signed-off-by: Deepak R Varma > --- > drivers/gpu/drm/i915/gvt/gvt.c | 2 +- > drivers/gpu/drm/i915/gvt/vgpu.c | 2 +- > 2 files changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c > index c7c561237883..45b492edbb19 100644 > --- a/drivers/gpu/drm/i915/gvt/gvt.c > +++ b/drivers/gpu/drm/i915/gvt/gvt.c > @@ -312,7 +312,7 @@ int intel_gvt_init_device(struct drm_i915_private *i915) > > gvt_dbg_core("init gvt device\n"); > > - idr_init(&gvt->vgpu_idr); > + idr_init_base(&gvt->vgpu_idr, 1); > spin_lock_init(&gvt->scheduler.mmio_context_lock); > mutex_init(&gvt->lock); > mutex_init(&gvt->sched_lock); > diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c > index f6d7e33c7099..1c8e63f84134 100644 > --- a/drivers/gpu/drm/i915/gvt/vgpu.c > +++ b/drivers/gpu/drm/i915/gvt/vgpu.c > @@ -393,7 +393,7 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct > intel_gvt *gvt, > mutex_init(&vgpu->dmabuf_lock); > INIT_LIST_HEAD(&vgpu->dmabuf_obj_list_head); > INIT_RADIX_TREE(&vgpu->page_track_tree, GFP_KERNEL); > - idr_init(&vgpu->object_idr); > + idr_init_base(&vgpu->object_idr, 1); > intel_vgpu_init_cfg_space(vgpu, param->primary); > vgpu->d3_entered = false; > > -- Looks good to me. Thanks! Reviewed-by: Zhenyu Wang -- $gpg --keyserver wwwkeys.pgp.net --recv-keys 4D781827 signature.asc Description: PGP signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v8 04/26] memory: tegra20-emc: Add devfreq support
Hi Dmitry, On 11/11/20 10:14 AM, Dmitry Osipenko wrote: > Add devfreq support to the Tegra20 EMC driver. Memory utilization > statistics will be periodically polled from the memory controller and > appropriate minimum clock rate will be selected by the devfreq governor. > > Signed-off-by: Dmitry Osipenko > --- > drivers/memory/tegra/Kconfig | 3 +- > drivers/memory/tegra/tegra20-emc.c | 90 ++ > 2 files changed, 92 insertions(+), 1 deletion(-) > > diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig > index ac3dfe155505..8cc1ec5be443 100644 > --- a/drivers/memory/tegra/Kconfig > +++ b/drivers/memory/tegra/Kconfig > @@ -12,7 +12,8 @@ config TEGRA20_EMC > tristate "NVIDIA Tegra20 External Memory Controller driver" > default y > depends on TEGRA_MC && ARCH_TEGRA_2x_SOC > - select PM_OPP > + select DEVFREQ_GOV_SIMPLE_ONDEMAND > + select PM_DEVFREQ > help > This driver is for the External Memory Controller (EMC) found on > Tegra20 chips. The EMC controls the external DRAM on the board. > diff --git a/drivers/memory/tegra/tegra20-emc.c > b/drivers/memory/tegra/tegra20-emc.c > index d01b556a6d06..b9cd965980e2 100644 > --- a/drivers/memory/tegra/tegra20-emc.c > +++ b/drivers/memory/tegra/tegra20-emc.c > @@ -8,6 +8,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -102,6 +103,10 @@ > > #define EMC_FBIO_CFG5_DRAM_WIDTH_X16 BIT(4) > > +#define EMC_PWR_GATHER_CLEAR (1 << 8) > +#define EMC_PWR_GATHER_DISABLE (2 << 8) > +#define EMC_PWR_GATHER_ENABLE(3 << 8) > + > static const u16 emc_timing_registers[] = { > EMC_RC, > EMC_RFC, > @@ -157,6 +162,7 @@ struct emc_timing { > }; > > enum emc_rate_request_type { > + EMC_RATE_DEVFREQ, > EMC_RATE_DEBUG, > EMC_RATE_ICC, > EMC_RATE_TYPE_MAX, > @@ -193,6 +199,8 @@ struct tegra_emc { > > /* protect shared rate-change code path */ > struct mutex rate_lock; > + > + struct devfreq_simple_ondemand_data ondemand_data; > }; > > static irqreturn_t tegra_emc_isr(int irq, void *data) > @@ -1003,6 +1011,87 @@ static int tegra_emc_init_clk(struct tegra_emc *emc) > return 0; > } > > +static int tegra_emc_devfreq_target(struct device *dev, unsigned long *freq, > + u32 flags) > +{ > + struct tegra_emc *emc = dev_get_drvdata(dev); > + struct dev_pm_opp *opp; > + unsigned long rate; > + > + opp = devfreq_recommended_opp(dev, freq, flags); > + if (IS_ERR(opp)) { > + dev_err(dev, "failed to find opp for %lu Hz\n", *freq); > + return PTR_ERR(opp); > + } > + > + rate = dev_pm_opp_get_freq(opp); > + dev_pm_opp_put(opp); > + > + return emc_set_min_rate(emc, rate, EMC_RATE_DEVFREQ); > +} > + > +static int tegra_emc_devfreq_get_dev_status(struct device *dev, > + struct devfreq_dev_status *stat) > +{ > + struct tegra_emc *emc = dev_get_drvdata(dev); > + > + /* freeze counters */ > + writel_relaxed(EMC_PWR_GATHER_DISABLE, emc->regs + EMC_STAT_CONTROL); > + > + /* > + * busy_time: number of clocks EMC request was accepted > + * total_time: number of clocks PWR_GATHER control was set to ENABLE > + */ > + stat->busy_time = readl_relaxed(emc->regs + EMC_STAT_PWR_COUNT); > + stat->total_time = readl_relaxed(emc->regs + EMC_STAT_PWR_CLOCKS); > + stat->current_frequency = clk_get_rate(emc->clk); > + > + /* clear counters and restart */ > + writel_relaxed(EMC_PWR_GATHER_CLEAR, emc->regs + EMC_STAT_CONTROL); > + writel_relaxed(EMC_PWR_GATHER_ENABLE, emc->regs + EMC_STAT_CONTROL); > + > + return 0; > +} > + > +static struct devfreq_dev_profile tegra_emc_devfreq_profile = { > + .polling_ms = 30, > + .target = tegra_emc_devfreq_target, > + .get_dev_status = tegra_emc_devfreq_get_dev_status, > +}; > + > +static int tegra_emc_devfreq_init(struct tegra_emc *emc) > +{ > + struct devfreq *devfreq; > + > + /* > + * PWR_COUNT is 1/2 of PWR_CLOCKS at max, and thus, the up-threshold > + * should be less than 50. Secondly, multiple active memory clients > + * may cause over 20% of lost clock cycles due to stalls caused by > + * competing memory accesses. This means that threshold should be > + * set to a less than 30 in order to have a properly working governor. > + */ > + emc->ondemand_data.upthreshold = 20; > + > + /* > + * Reset statistic gathers state, select global bandwidth for the > + * statistics collection mode and set clocks counter saturation > + * limit to maximum. > + */ > + writel_relaxed(0x, emc->regs + EMC_STAT_CONTROL); > + writel_relaxed(0x, emc->regs + EMC_STAT_LLMC_CONTROL); > + writel_relaxed(0x, emc->r
Re: [PATCH 1/2] dt-bindings: drm/bridge: ti-sn65dsi86: Replace #pwm-cells
Hi, On Mon, Nov 2, 2020 at 9:08 AM Bjorn Andersson wrote: > > On Fri 02 Oct 15:42 CDT 2020, Doug Anderson wrote: > > > Hi, > > > > On Wed, Sep 30, 2020 at 3:40 PM Bjorn Andersson > > wrote: > > > > > > While the signal on GPIO4 to drive the backlight controller indeed is > > > pulse width modulated its purpose is specifically to control the > > > brightness of a backlight. > > > > I'm a bit on the fence about this. I guess you're doing this because > > it avoids some -EPROBE_DEFER cycles in Linux? It does seem to have a > > few downsides, though. > > > > No, the reason for exposing a backlight is that while the thing > certainly is a PWM signal, the description of it and the registers > available to control it surely seems "backlight" to me. > > In particular No, the reason for exposing a backlight is that while > while the thing certainly is a PWM signal, the description of it and the > registers available to control it surely seems "backlight" to me. > > > 1. It means a bit of re-inventing the wheel. It's not a very big > > wheel, though, I'll give you. ...but it's still something. > > > > The main problem I saw with exposing this as a PWM was the fact that we > have both period and frequency to control... > > > 2. I'm not sure why you'd want to, but in theory one could use this > > PWM for some other purposes. It really is just a generic PWM. Your > > change prevents that. > > > > ...and in the even that you use it as a "generic" PWM I'd expect that > the specified period is related to the frequency of the signal. But the > period is documented to be related to the number of brightness steps of > the panel. I think the key here is that the "number of brightness steps of the panel" isn't really a thing that's worried about. At least in my experience, you can pretty much just use as many steps as you can represent based on your PWM hardware. If a panel happens to map some of those steps to the same brightness then it wouldn't be the end of the world, but in experience it's not really such a digital thing. If you choose 4096 steps then you likely get 4096 different brightness levels. If you choose 256 steps then you get 256 different brightness levels. Once you have "more than enough" steps then everything's pretty much fine. Looking at one random panel (just to get an idea of numbers), I see that it specifies: * min PWM Freq: 200 Hz * max PWM Freq: 10,000 Hz. ...and refclk is something between 12 MHz and 38.4 MHz, right? The bridge chip datasheet says: PWM_FREQ = REFCLK_FREQ / (PWM_PRE_DIV * BACKLIGHT_SCALE + 1) So let's see what we can do. I'm arguing that we want the client to be able to specify the PWM frequency and duty cycle and we'll do the job of picking the number of steps. We'll try for the most steps we can get (65535). I guess we need to solve for PWM_PRE_DIV : PWM_FREQ * (PWM_PRE_DIV * BACKLIGHT_SCALE + 1) = REFCLK_FREQ PWM_PRE_DIV * BACKLIGHT_SCALE + 1 = REFCLK_FREQ / PWM_FREQ PWM_PRE_DIV * BACKLIGHT_SCALE = REFCLK_FREQ / PWM_FREQ - 1 PWM_PRE_DIV = (REFCLK_FREQ / PWM_FREQ - 1) / BACKLIGHT_SCALE ...and solve for BACKLIGHT_SCALE: BACKLIGHT_SCALE = (REFCLK_FREQ / PWM_FREQ - 1) / PWM_PRE_DIV With 1000 Hz, 12 MHz refclk: PWM_PRE_DIV = DIV_ROUND_UP(1200 / 1000 - 1, 65535) => 1 BACKLIGHT_SCALE = (1200 / 1000 - 1) / 1 => 11999 With 1000 Hz, 38.4 MHz refclk: PWM_PRE_DIV = DIV_ROUND_UP(3840 / 1000 - 1, 65535) => 1 BACKLIGHT_SCALE = (3840 / 1000 - 1) / 1 => 38399 With 200 Hz, 38.4 MHz refclk: PWM_PRE_DIV = DIV_ROUND_UP(3840 / 200 - 1, 65535) => 3 BACKLIGHT_SCALE = (3840 / 200 - 1) / 3 => 63999 Now that you have BACKLIGHT_SCALE specified, then when someone tries to give you a duty cycle you just map it to the closest value you can make. Obviously you won't be able to perfectly make every exact duty cycle / period that a client requests, but that's true of all PWMs out there. The nice thing here is that (assuming my math is right) we should be getting nearly exactly the frequency that the client requested and that (in my mind) is what matters. You also get as many steps as possible which means that (with the PWM backlight API) you'll be able to get as close as possible to whatever a user requests. > > > Drop the #pwm-cells and instead expose a new property to configure the > > > granularity of the backlight PWM signal. > > > > > > Signed-off-by: Bjorn Andersson > > > --- > > > .../devicetree/bindings/display/bridge/ti,sn65dsi86.yaml | 9 ++--- > > > 1 file changed, 6 insertions(+), 3 deletions(-) > > > > > > diff --git > > > a/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml > > > b/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml > > > index f8622bd0f61e..e380218b4646 100644 > > > --- a/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml > > > +++ b/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml > > > @@ -66,9 +66,12 @@ properties: > > >1-based to match the da
Re: [PATCH 25/30] drm/radeon/sumo_dpm: Move 'sumo_get_pi()'s prototype into shared header
On Tue, Nov 10, 2020 at 2:32 PM Lee Jones wrote: > > Fixes the following W=1 kernel build warning(s): > > drivers/gpu/drm/radeon/sumo_dpm.c:81:25: warning: no previous prototype for > ‘sumo_get_pi’ [-Wmissing-prototypes] > 81 | struct sumo_power_info *sumo_get_pi(struct radeon_device *rdev) > | ^~~ > > Cc: Alex Deucher > Cc: "Christian König" > Cc: David Airlie > Cc: Daniel Vetter > Cc: amd-...@lists.freedesktop.org > Cc: dri-devel@lists.freedesktop.org > Signed-off-by: Lee Jones Applied. Thanks! Alex > --- > drivers/gpu/drm/radeon/sumo_dpm.h | 1 + > drivers/gpu/drm/radeon/sumo_smc.c | 2 -- > 2 files changed, 1 insertion(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/radeon/sumo_dpm.h > b/drivers/gpu/drm/radeon/sumo_dpm.h > index f1651135a47ab..db29d37ae2703 100644 > --- a/drivers/gpu/drm/radeon/sumo_dpm.h > +++ b/drivers/gpu/drm/radeon/sumo_dpm.h > @@ -207,6 +207,7 @@ u32 sumo_get_sleep_divider_from_id(u32 id); > u32 sumo_get_sleep_divider_id_from_clock(struct radeon_device *rdev, > u32 sclk, > u32 min_sclk_in_sr); > +struct sumo_power_info *sumo_get_pi(struct radeon_device *rdev); > > /* sumo_smc.c */ > void sumo_initialize_m3_arb(struct radeon_device *rdev); > diff --git a/drivers/gpu/drm/radeon/sumo_smc.c > b/drivers/gpu/drm/radeon/sumo_smc.c > index d781407057366..78d8716067318 100644 > --- a/drivers/gpu/drm/radeon/sumo_smc.c > +++ b/drivers/gpu/drm/radeon/sumo_smc.c > @@ -30,8 +30,6 @@ > #define SUMO_SMU_SERVICE_ROUTINE_ALTVDDNB_NOTIFY 27 > #define SUMO_SMU_SERVICE_ROUTINE_GFX_SRV_ID_20 20 > > -struct sumo_power_info *sumo_get_pi(struct radeon_device *rdev); > - > static void sumo_send_msg_to_smu(struct radeon_device *rdev, u32 id) > { > u32 gfx_int_req; > -- > 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 27/30] drm/radeon/ni: Remove set but unused variable 'mc_shared_chmap'
On Tue, Nov 10, 2020 at 2:32 PM Lee Jones wrote: > > Fixes the following W=1 kernel build warning(s): > > drivers/gpu/drm/radeon/ni.c: In function ‘cayman_gpu_init’: > drivers/gpu/drm/radeon/ni.c:880:6: warning: variable ‘mc_shared_chmap’ set > but not used [-Wunused-but-set-variable] > > Cc: Alex Deucher > Cc: "Christian König" > Cc: David Airlie > Cc: Daniel Vetter > Cc: amd-...@lists.freedesktop.org > Cc: dri-devel@lists.freedesktop.org > Signed-off-by: Lee Jones Applied. Thanks! Alex > --- > drivers/gpu/drm/radeon/ni.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c > index 12dd082069649..1c9030a4631b8 100644 > --- a/drivers/gpu/drm/radeon/ni.c > +++ b/drivers/gpu/drm/radeon/ni.c > @@ -877,7 +877,7 @@ int tn_get_temp(struct radeon_device *rdev) > static void cayman_gpu_init(struct radeon_device *rdev) > { > u32 gb_addr_config = 0; > - u32 mc_shared_chmap, mc_arb_ramcfg; > + u32 mc_arb_ramcfg; > u32 cgts_tcc_disable; > u32 sx_debug_1; > u32 smx_dc_ctl0; > @@ -1002,7 +1002,7 @@ static void cayman_gpu_init(struct radeon_device *rdev) > > evergreen_fix_pci_max_read_req_size(rdev); > > - mc_shared_chmap = RREG32(MC_SHARED_CHMAP); > + RREG32(MC_SHARED_CHMAP); > mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); > > tmp = (mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT; > -- > 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 14/30] drm/radeon/evergreen_dma: Fix doc-rot of function parameter 'resv'
On Tue, Nov 10, 2020 at 2:31 PM Lee Jones wrote: > > Fixes the following W=1 kernel build warning(s): > > drivers/gpu/drm/radeon/evergreen_dma.c:112: warning: Function parameter or > member 'resv' not described in 'evergreen_copy_dma' > drivers/gpu/drm/radeon/evergreen_dma.c:112: warning: Excess function > parameter 'fence' description in 'evergreen_copy_dma' > > Cc: Alex Deucher > Cc: "Christian König" > Cc: David Airlie > Cc: Daniel Vetter > Cc: Sumit Semwal > Cc: amd-...@lists.freedesktop.org > Cc: dri-devel@lists.freedesktop.org > Cc: linux-me...@vger.kernel.org > Cc: linaro-mm-...@lists.linaro.org > Signed-off-by: Lee Jones Applied. Thanks! Alex > --- > drivers/gpu/drm/radeon/evergreen_dma.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/radeon/evergreen_dma.c > b/drivers/gpu/drm/radeon/evergreen_dma.c > index a46ee6c2099dd..767857d4a8c5c 100644 > --- a/drivers/gpu/drm/radeon/evergreen_dma.c > +++ b/drivers/gpu/drm/radeon/evergreen_dma.c > @@ -98,7 +98,7 @@ void evergreen_dma_ring_ib_execute(struct radeon_device > *rdev, > * @src_offset: src GPU address > * @dst_offset: dst GPU address > * @num_gpu_pages: number of GPU pages to xfer > - * @fence: radeon fence object > + * @resv: reservation object with embedded fence > * > * Copy GPU paging using the DMA engine (evergreen-cayman). > * Used by the radeon ttm implementation to move pages if > -- > 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 18/30] drm/radeon/evergreen_cs: Fix misnaming issues surrounding 'p' param
On Tue, Nov 10, 2020 at 2:31 PM Lee Jones wrote: > > Fixes the following W=1 kernel build warning(s): > > drivers/gpu/drm/radeon/evergreen_cs.c:1026: warning: Function parameter or > member 'p' not described in 'evergreen_cs_packet_parse_vline' > drivers/gpu/drm/radeon/evergreen_cs.c:1026: warning: Excess function > parameter 'parser' description in 'evergreen_cs_packet_parse_vline' > drivers/gpu/drm/radeon/evergreen_cs.c:1095: warning: Function parameter or > member 'p' not described in 'evergreen_cs_handle_reg' > drivers/gpu/drm/radeon/evergreen_cs.c:1095: warning: Excess function > parameter 'parser' description in 'evergreen_cs_handle_reg' > drivers/gpu/drm/radeon/evergreen_cs.c:1757: warning: Function parameter or > member 'p' not described in 'evergreen_is_safe_reg' > drivers/gpu/drm/radeon/evergreen_cs.c:1757: warning: Excess function > parameter 'parser' description in 'evergreen_is_safe_reg' > > Cc: Alex Deucher > Cc: "Christian König" > Cc: David Airlie > Cc: Daniel Vetter > Cc: amd-...@lists.freedesktop.org > Cc: dri-devel@lists.freedesktop.org > Signed-off-by: Lee Jones Applied. Thanks! Alex > --- > drivers/gpu/drm/radeon/evergreen_cs.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c > b/drivers/gpu/drm/radeon/evergreen_cs.c > index c410cad28f19f..53b75cf201958 100644 > --- a/drivers/gpu/drm/radeon/evergreen_cs.c > +++ b/drivers/gpu/drm/radeon/evergreen_cs.c > @@ -1015,7 +1015,7 @@ static int evergreen_cs_track_check(struct > radeon_cs_parser *p) > > /** > * evergreen_cs_packet_parse_vline() - parse userspace VLINE packet > - * @parser:parser structure holding parsing context. > + * @p: parser structure holding parsing context. > * > * This is an Evergreen(+)-specific function for parsing VLINE packets. > * Real work is done by r600_cs_common_vline_parse function. > @@ -1087,7 +1087,7 @@ static int evergreen_cs_parse_packet0(struct > radeon_cs_parser *p, > > /** > * evergreen_cs_handle_reg() - process registers that need special handling. > - * @parser: parser structure holding parsing context > + * @p: parser structure holding parsing context > * @reg: register we are testing > * @idx: index into the cs buffer > */ > @@ -1747,7 +1747,7 @@ static int evergreen_cs_handle_reg(struct > radeon_cs_parser *p, u32 reg, u32 idx) > > /** > * evergreen_is_safe_reg() - check if register is authorized or not > - * @parser: parser structure holding parsing context > + * @p: parser structure holding parsing context > * @reg: register we are testing > * > * This function will test against reg_safe_bm and return true > -- > 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 15/30] drm/radeon/cik_sdma: Demote vague attempt at kernel-doc
On Tue, Nov 10, 2020 at 2:31 PM Lee Jones wrote: > > Fixes the following W=1 kernel build warning(s): > > drivers/gpu/drm/radeon/cik_sdma.c:949: warning: Function parameter or member > 'ring' not described in 'cik_dma_vm_flush' > drivers/gpu/drm/radeon/cik_sdma.c:949: warning: Function parameter or member > 'vm_id' not described in 'cik_dma_vm_flush' > drivers/gpu/drm/radeon/cik_sdma.c:949: warning: Function parameter or member > 'pd_addr' not described in 'cik_dma_vm_flush' > > Cc: Alex Deucher > Cc: "Christian König" > Cc: David Airlie > Cc: Daniel Vetter > Cc: Sumit Semwal > Cc: amd-...@lists.freedesktop.org > Cc: dri-devel@lists.freedesktop.org > Cc: linux-me...@vger.kernel.org > Cc: linaro-mm-...@lists.linaro.org > Signed-off-by: Lee Jones Applied. Thanks! Alex > --- > drivers/gpu/drm/radeon/cik_sdma.c | 4 +--- > 1 file changed, 1 insertion(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/radeon/cik_sdma.c > b/drivers/gpu/drm/radeon/cik_sdma.c > index 68403e77756d3..3c709ebe8d1ab 100644 > --- a/drivers/gpu/drm/radeon/cik_sdma.c > +++ b/drivers/gpu/drm/radeon/cik_sdma.c > @@ -936,11 +936,9 @@ void cik_sdma_vm_pad_ib(struct radeon_ib *ib) > ib->ptr[ib->length_dw++] = SDMA_PACKET(SDMA_OPCODE_NOP, 0, 0); > } > > -/** > +/* > * cik_dma_vm_flush - cik vm flush using sDMA > * > - * @rdev: radeon_device pointer > - * > * Update the page table base and flush the VM TLB > * using sDMA (CIK). > */ > -- > 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 17/30] drm/radeon/r600_cs: Fix some doc-rot and supply missing function param docs
On Tue, Nov 10, 2020 at 2:31 PM Lee Jones wrote: > > Fixes the following W=1 kernel build warning(s): > > drivers/gpu/drm/radeon/r600_cs.c:793: warning: Function parameter or member > 'p' not described in 'r600_cs_packet_parse_vline' > drivers/gpu/drm/radeon/r600_cs.c:793: warning: Excess function parameter > 'parser' description in 'r600_cs_packet_parse_vline' > drivers/gpu/drm/radeon/r600_cs.c:826: warning: Function parameter or member > 'p' not described in 'r600_cs_common_vline_parse' > drivers/gpu/drm/radeon/r600_cs.c:826: warning: Excess function parameter > 'parser' description in 'r600_cs_common_vline_parse' > drivers/gpu/drm/radeon/r600_cs.c:968: warning: Function parameter or member > 'p' not described in 'r600_cs_check_reg' > drivers/gpu/drm/radeon/r600_cs.c:968: warning: Excess function parameter > 'parser' description in 'r600_cs_check_reg' > drivers/gpu/drm/radeon/r600_cs.c:1473: warning: Function parameter or member > 'base_offset' not described in 'r600_check_texture_resource' > drivers/gpu/drm/radeon/r600_cs.c:1473: warning: Function parameter or member > 'mip_offset' not described in 'r600_check_texture_resource' > drivers/gpu/drm/radeon/r600_cs.c:1473: warning: Function parameter or member > 'tiling_flags' not described in 'r600_check_texture_resource' > > Cc: Alex Deucher > Cc: "Christian König" > Cc: David Airlie > Cc: Daniel Vetter > Cc: amd-...@lists.freedesktop.org > Cc: dri-devel@lists.freedesktop.org > Signed-off-by: Lee Jones Applied. Thanks! Alex > --- > drivers/gpu/drm/radeon/r600_cs.c | 9 ++--- > 1 file changed, 6 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/radeon/r600_cs.c > b/drivers/gpu/drm/radeon/r600_cs.c > index 390a9621604ae..f20b619466816 100644 > --- a/drivers/gpu/drm/radeon/r600_cs.c > +++ b/drivers/gpu/drm/radeon/r600_cs.c > @@ -782,7 +782,7 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) > > /** > * r600_cs_packet_parse_vline() - parse userspace VLINE packet > - * @parser:parser structure holding parsing context. > + * @p: parser structure holding parsing context. > * > * This is an R600-specific function for parsing VLINE packets. > * Real work is done by r600_cs_common_vline_parse function. > @@ -801,7 +801,7 @@ static int r600_cs_packet_parse_vline(struct > radeon_cs_parser *p) > > /** > * r600_cs_common_vline_parse() - common vline parser > - * @parser:parser structure holding parsing context. > + * @p: parser structure holding parsing context. > * @vline_start_end:table of vline_start_end registers > * @vline_status: table of vline_status registers > * > @@ -956,7 +956,7 @@ static int r600_cs_parse_packet0(struct radeon_cs_parser > *p, > > /** > * r600_cs_check_reg() - check if register is authorized or not > - * @parser: parser structure holding parsing context > + * @p: parser structure holding parsing context > * @reg: register we are testing > * @idx: index into the cs buffer > * > @@ -1460,6 +1460,9 @@ static void r600_texture_size(unsigned nfaces, unsigned > blevel, unsigned llevel, > * @idx: index into the cs buffer > * @texture: texture's bo structure > * @mipmap: mipmap's bo structure > + * @base_offset: base offset (used for error checking) > + * @mip_offset: mip offset (used for error checking) > + * @tiling_flags: tiling flags > * > * This function will check that the resource has valid field and that > * the texture and mipmap bo object are big enough to cover this resource. > -- > 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 16/30] drm/radeon/r100: Fix some kernel-doc formatting, misnaming and missing issues
On Tue, Nov 10, 2020 at 2:31 PM Lee Jones wrote: > > Fixes the following W=1 kernel build warning(s): > > drivers/gpu/drm/radeon/r100.c:163: warning: Function parameter or member > 'async' not described in 'r100_page_flip' > drivers/gpu/drm/radeon/r100.c:848: warning: Function parameter or member > 'rdev' not described in 'r100_ring_hdp_flush' > drivers/gpu/drm/radeon/r100.c:848: warning: Function parameter or member > 'ring' not described in 'r100_ring_hdp_flush' > drivers/gpu/drm/radeon/r100.c:1425: warning: Function parameter or member > 'p' not described in 'r100_cs_packet_parse_vline' > drivers/gpu/drm/radeon/r100.c:1425: warning: Excess function parameter > 'parser' description in 'r100_cs_packet_parse_vline' > > Cc: Alex Deucher > Cc: "Christian König" > Cc: David Airlie > Cc: Daniel Vetter > Cc: Sumit Semwal > Cc: amd-...@lists.freedesktop.org > Cc: dri-devel@lists.freedesktop.org > Cc: linux-me...@vger.kernel.org > Cc: linaro-mm-...@lists.linaro.org > Signed-off-by: Lee Jones Applied with minor fixup. Thanks! Alex > --- > drivers/gpu/drm/radeon/r100.c | 7 --- > 1 file changed, 4 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c > index 24c8db673931a..92075dedf2cb2 100644 > --- a/drivers/gpu/drm/radeon/r100.c > +++ b/drivers/gpu/drm/radeon/r100.c > @@ -153,6 +153,7 @@ void r100_wait_for_vblank(struct radeon_device *rdev, int > crtc) > * @rdev: radeon_device pointer > * @crtc_id: crtc to cleanup pageflip on > * @crtc_base: new address of the crtc (GPU MC address) > + * @async: unused > * > * Does the actual pageflip (r1xx-r4xx). > * During vblank we take the crtc lock and wait for the update_pending > @@ -841,8 +842,8 @@ u32 r100_get_vblank_counter(struct radeon_device *rdev, > int crtc) > > /** > * r100_ring_hdp_flush - flush Host Data Path via the ring buffer > - * rdev: radeon device structure > - * ring: ring buffer struct for emitting packets > + * @rdev: radeon device structure > + * @ring: ring buffer struct for emitting packets > */ > static void r100_ring_hdp_flush(struct radeon_device *rdev, struct > radeon_ring *ring) > { > @@ -1409,7 +1410,7 @@ int r100_cs_parse_packet0(struct radeon_cs_parser *p, > > /** > * r100_cs_packet_next_vline() - parse userspace VLINE packet > - * @parser:parser structure holding parsing context. > + * @p: parser structure holding parsing context. > * > * Userspace sends a special sequence for VLINE waits. > * PACKET0 - VLINE_START_END + value > -- > 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 13/30] drm/radeon/radeon_mn: Supply description for 'cur_seq' even if it is unused
On Tue, Nov 10, 2020 at 2:31 PM Lee Jones wrote: > > Fixes the following W=1 kernel build warning(s): > > drivers/gpu/drm/radeon/radeon_mn.c:51: warning: Function parameter or member > 'cur_seq' not described in 'radeon_mn_invalidate' > > Cc: Alex Deucher > Cc: "Christian König" > Cc: David Airlie > Cc: Daniel Vetter > Cc: amd-...@lists.freedesktop.org > Cc: dri-devel@lists.freedesktop.org > Signed-off-by: Lee Jones Applied with minor fixup. Thanks! Alex > --- > drivers/gpu/drm/radeon/radeon_mn.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/gpu/drm/radeon/radeon_mn.c > b/drivers/gpu/drm/radeon/radeon_mn.c > index 97b9b6dd6dd3b..3c4c4213a7b57 100644 > --- a/drivers/gpu/drm/radeon/radeon_mn.c > +++ b/drivers/gpu/drm/radeon/radeon_mn.c > @@ -41,6 +41,7 @@ > * > * @mn: our notifier > * @range: the VMA under invalidation > + * @cur_seq: unused > * > * We block for all BOs between start and end to be idle and > * unmap them by move them into system domain again. > -- > 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
[PATCH 3/5] drm/panel: s6e63m0: Add some explanations
The SPI DCS code was a bit hard to understand as the device accepts 9-bit transfers packed into 16-bit words with the most significant bit in bit 9 of the 16-bit word. Add some clarifying comments. Cc: Stephan Gerhold Cc: Paweł Chmiel Signed-off-by: Linus Walleij --- drivers/gpu/drm/panel/panel-samsung-s6e63m0-spi.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e63m0-spi.c b/drivers/gpu/drm/panel/panel-samsung-s6e63m0-spi.c index 9e1552a7ccc7..e47647f418ff 100644 --- a/drivers/gpu/drm/panel/panel-samsung-s6e63m0-spi.c +++ b/drivers/gpu/drm/panel/panel-samsung-s6e63m0-spi.c @@ -42,10 +42,17 @@ static int s6e63m0_spi_dcs_write(struct device *dev, const u8 *data, size_t len) int ret = 0; dev_dbg(dev, "SPI writing dcs seq: %*ph\n", (int)len, data); + + /* +* This sends 9 bits with the first bit (bit 8) set to 0 +* This indicates that this is a command. Anything after the +* command is data. +*/ ret = s6e63m0_spi_write_word(dev, *data); while (!ret && --len) { ++data; + /* This sends 9 bits with the first bit (bit 8) set to 1 */ ret = s6e63m0_spi_write_word(dev, *data | DATA_MASK); } -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 4/5] drm/panel: s6e63m0: Support 3WIRE protocol
The panel can be connected using 3WIRE, then it is however necessary that the flag SPI_3WIRE is preserved on the device, as we set this from generic device tree parsing code (or similar). Just |= the SPI mode. Cc: Stephan Gerhold Cc: Paweł Chmiel Signed-off-by: Linus Walleij --- drivers/gpu/drm/panel/panel-samsung-s6e63m0-spi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e63m0-spi.c b/drivers/gpu/drm/panel/panel-samsung-s6e63m0-spi.c index e47647f418ff..b1adf8f89c62 100644 --- a/drivers/gpu/drm/panel/panel-samsung-s6e63m0-spi.c +++ b/drivers/gpu/drm/panel/panel-samsung-s6e63m0-spi.c @@ -72,7 +72,8 @@ static int s6e63m0_spi_probe(struct spi_device *spi) int ret; spi->bits_per_word = 9; - spi->mode = SPI_MODE_3; + /* Preserve e.g. SPI_3WIRE setting */ + spi->mode |= SPI_MODE_3; ret = spi_setup(spi); if (ret < 0) { dev_err(dev, "spi setup failed.\n"); -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 5/5] drm/panel: s6e63m0: Set up some display info
Copy over the width/height in millimeters to the (somewhat redundant) display info, and set up the bus format and bus flags for the display. When used as DPI this display requires DE to be active low and pixel data to be output on the negative edge. It might be that it was previously used with a display controller that either does not support these settings or was hardcoded to use these as default. This information comes from the source code of the Samsung GT-I9070 mobile phone. Cc: Stephan Gerhold Cc: Paweł Chmiel Signed-off-by: Linus Walleij --- drivers/gpu/drm/panel/panel-samsung-s6e63m0.c | 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c b/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c index 3eee67e2d86a..210e70da3a15 100644 --- a/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c +++ b/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c @@ -16,6 +16,7 @@ #include #include #include +#include #include @@ -410,6 +411,7 @@ static int s6e63m0_get_modes(struct drm_panel *panel, struct drm_connector *connector) { struct drm_display_mode *mode; + static const u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24; mode = drm_mode_duplicate(connector->dev, &default_mode); if (!mode) { @@ -419,6 +421,13 @@ static int s6e63m0_get_modes(struct drm_panel *panel, return -ENOMEM; } + connector->display_info.width_mm = mode->width_mm; + connector->display_info.height_mm = mode->height_mm; + drm_display_info_set_bus_formats(&connector->display_info, +&bus_format, 1); + connector->display_info.bus_flags = DRM_BUS_FLAG_DE_LOW | + DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE; + drm_mode_set_name(mode); mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 0/5] Samsung s6e63m0 improvements
These improvements to the Samsung s6e63m0 makes SPI writing and reading to the panel simpler, and add some support required by the Samsung GT-I9070. Tested and working fine on the Samsung GT-I9070 mobile phone with the MCDE display controller in DPI mode. Linus Walleij (5): drm/panel: s6e63m0: Simplify SPI writing drm/panel: s6e63m0: Implement reading from panel drm/panel: s6e63m0: Add some explanations drm/panel: s6e63m0: Support 3WIRE protocol drm/panel: s6e63m0: Set up some display info .../gpu/drm/panel/panel-samsung-s6e63m0-spi.c | 40 +++ drivers/gpu/drm/panel/panel-samsung-s6e63m0.c | 9 + 2 files changed, 33 insertions(+), 16 deletions(-) -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel