Re: [PATCH V6 8/8] drm/mediatek: fix the rate of parent for hdmi phy in MT2701
Hi, Wangyan: On Wed, 2019-03-06 at 18:13 +0800, CK Hu wrote: > Hi, Wangyan: > > On Mon, 2019-02-25 at 10:09 +0800, wangyan wang wrote: > > From: chunhui dai > > > > We should not change the rate of parent for hdmi phy when > > doing round_rate for this clock. The parent clock of hdmi > > phy must be the same as it. We change it when doing set_rate > > only. > > > > Signed-off-by: chunhui dai > > Signed-off-by: wangyan wang > > --- > > drivers/gpu/drm/mediatek/mtk_hdmi_phy.c| 14 -- > > drivers/gpu/drm/mediatek/mtk_hdmi_phy.h| 3 --- > > drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 11 +++ > > drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | 14 ++ > > 4 files changed, 25 insertions(+), 17 deletions(-) > > > > diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c > > b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c > > index 370309d684ec..ca8bc1489f37 100644 > > --- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c > > +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c > > @@ -15,20 +15,6 @@ static const struct phy_ops mtk_hdmi_phy_dev_ops = { > > .owner = THIS_MODULE, > > }; > > > > -long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, > > -unsigned long *parent_rate) > > -{ > > - struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); > > - > > - hdmi_phy->pll_rate = rate; > > - if (rate <= 7425) > > - *parent_rate = rate; > > - else > > - *parent_rate = rate / 2; > > - > > - return rate; > > -} > > - > > u32 mtk_hdmi_phy_read(struct mtk_hdmi_phy *hdmi_phy, u32 offset) > > { > > return readl(hdmi_phy->regs + offset); > > diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h > > b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h > > index 446e2acd1926..c6061ad15ff0 100644 > > --- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h > > +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h > > @@ -50,9 +50,6 @@ void mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy *hdmi_phy, > > u32 offset, > > void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset, > >u32 val, u32 mask); > > struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw); > > -long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, > > -unsigned long *parent_rate); > > - > > extern struct platform_driver mtk_hdmi_phy_driver; > > extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf; > > extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf; > > diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c > > b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c > > index 88dd9e812ca0..33893a180c2e 100644 > > --- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c > > +++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c > > @@ -152,6 +152,17 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, > > unsigned long rate, > > RG_HDMITX_DRV_IBIAS_MASK); > > return 0; > > } > > + > > +static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, > > +unsigned long *parent_rate) > > +{ > > + struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); > > + > > + hdmi_phy->pll_rate = rate; > > I think you don't need to save the rate into pll_rate here, pll_rate > would be set in set_rate() or recalc_rate(). As offline discuss, you mention that this function just need to return current rate. I think you could just remove this line 'hdmi_phy->pll_rate = rate;' and return rate only. You don't need to assign hdmi_phy->pll_rate here because it would be set later in set_rate(). Regards, CK > > Regards, > CK > > > + > > + return rate; > > +} > > + > > static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, > >unsigned long parent_rate) > > { > > diff --git a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c > > b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c > > index 63dde42521b8..3a339f516613 100644 > > --- a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c > > +++ b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c > > @@ -285,6 +285,20 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, > > unsigned long rate, > > return 0; > > } > > > > +static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, > > +unsigned long *parent_rate) > > +{ > > + struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); > > + > > + hdmi_phy->pll_rate = rate; > > + if (rate <= 7425) > > + *parent_rate = rate; > > + else > > + *parent_rate = rate / 2; > > + > > + return rate; > > +} > > + > > static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, > >unsigned long parent_rate) > > { > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: Clang warning in drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
On Wed, Mar 20, 2019 at 4:49 PM Nick Desaulniers wrote: > > On Wed, Mar 20, 2019 at 2:37 AM Koenig, Christian > wrote: > > > > Am 20.03.19 um 05:34 schrieb Nathan Chancellor: > > > On Wed, Mar 20, 2019 at 01:31:27AM +, Pan, Xinhui wrote: > > >> these two enumerated types are same for now. both of them might change > > >> in the future. > > Please consider if the YAGNI principle applies here. > https://martinfowler.com/bliki/Yagni.html > > > >> > > >> I have not used clang, but would .block_id = (int)head->block fix your > > >> warning? If such change is acceptable, I can make one then. > > My preference on solutions, in order: > 1. One enum (this is the simplest most type safe solution). Add > another enum when you actually need it. Otherwise, YAGNI. It make sense to have two enums. One is a firmware interface that is only used by some asics and the other is for the general driver interface (non-asic specific for the ras features. > 2. Safe casting function (like the one Nathan supplied, maybe with > WARN_ONCE rather than WARN). This ensures that at least if the types > diverge you get a runtime warning. A compile-time warning would be > preferred, but I haven't taken the time to think through how that > might be implemented. I'd prefer this one. Alex > 3. Cast to int (this has been used in other places throughout the > kernel, but provides the weakest type safety and doesn't catch future > divergence). > 4. Disabling the warning. (I almost never advocate for this). > > > Another question is if it is such a good idea to just silence the warning? > > For the kernel, it seems that each maintainer can choose what to apply > to their subsystem. I would recommend against disabling additional > warnings that aren't disable kernel-wide for most cases. > -Wenum-conversion has spotted many bugs. While the enums in question > today are not different, they MIGHT eventually diverge and lead to > bugs, like the others we've found and fixed throughout the kernel. So > I would recommend fixing now, and be insulated in the future. > > -- > Thanks, > ~Nick Desaulniers > ___ > amd-gfx mailing list > amd-...@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/amd-gfx ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v6 1/8] drm/mediatek: recalculate hdmi phy clock of MT2701 by querying hardware
Hi, Wangyan: On Wed, 2019-03-06 at 18:07 +0800, CK Hu wrote: > Hi, Wangyan: > > On Mon, 2019-02-25 at 10:09 +0800, wangyan wang wrote: > > From: chunhui dai > > > > Recalculate the rate of this clock, by querying hardware. > > > > Signed-off-by: chunhui dai > > Signed-off-by: wangyan wang > > --- > > drivers/gpu/drm/mediatek/mtk_hdmi_phy.c| 7 ++ > > drivers/gpu/drm/mediatek/mtk_hdmi_phy.h| 3 +-- > > drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 35 > > ++ > > drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | 8 ++ > > 4 files changed, 46 insertions(+), 7 deletions(-) > > > > diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c > > b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c > > index 4ef9c57ffd44..13c5e65b9ead 100644 > > --- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c > > +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c > > @@ -29,12 +29,9 @@ long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned > > long rate, > > return rate; > > } > > > > -unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, > > - unsigned long parent_rate) > > +u32 mtk_hdmi_phy_read(struct mtk_hdmi_phy *hdmi_phy, u32 offset) > > { > > - struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); > > - > > - return hdmi_phy->pll_rate; > > + return readl(hdmi_phy->regs + offset); > > } > > > > void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset, > > diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h > > b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h > > index f39b1fc66612..fdad8b17a915 100644 > > --- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h > > +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h > > @@ -41,6 +41,7 @@ struct mtk_hdmi_phy { > > unsigned int ibias_up; > > }; > > > > +u32 mtk_hdmi_phy_read(struct mtk_hdmi_phy *hdmi_phy, u32 offset); > > void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset, > > u32 bits); > > void mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset, > > @@ -50,8 +51,6 @@ void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 > > offset, > > struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw); > > long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, > > unsigned long *parent_rate); > > -unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, > > - unsigned long parent_rate); > > > > extern struct platform_driver mtk_hdmi_phy_driver; > > extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf; > > diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c > > b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c > > index fcc42dc6ea7f..b25c9dfc432a 100644 > > --- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c > > +++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c > > @@ -153,6 +153,41 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, > > unsigned long rate, > > RG_HDMITX_DRV_IBIAS_MASK); > > return 0; > > } > > +static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, > > + unsigned long parent_rate) > > +{ > > + struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); > > + unsigned long out_rate, val; > > + > > + val = (mtk_hdmi_phy_read(hdmi_phy, HDMI_CON6) > > + & RG_HTPLL_PREDIV_MASK) >> RG_HTPLL_PREDIV; > > + switch (val) { > > + case 0x00: > > + out_rate = parent_rate; > > + break; > > + case 0x01: > > + out_rate = parent_rate / 2; > > + break; > > + default: > > + out_rate = parent_rate / 4; > > + break; > > + } > > + > > + val = (mtk_hdmi_phy_read(hdmi_phy, HDMI_CON6) > > + & RG_HTPLL_FBKDIV_MASK) >> RG_HTPLL_FBKDIV; > > + out_rate *= (val + 1) * 2; > > + val = (mtk_hdmi_phy_read(hdmi_phy, HDMI_CON2) > > + & RG_HDMITX_TX_POSDIV_MASK); > > + > > + out_rate >>= (val >> RG_HDMITX_TX_POSDIV); > > + > > + if (mtk_hdmi_phy_read(hdmi_phy, HDMI_CON2) & RG_HDMITX_EN_TX_POSDIV) > > + out_rate = out_rate / 5; > > + > > All the register you read here is set in mtk_hdmi_pll_set_rate(), so I > think you could determine the out_rate in mtk_hdmi_pll_set_rate(). As offline discuss, you mention that when cat /sys/kernel/debug/ckl/clk_summary, mtk_hdmi_pll_recalc_rate() is called, so read register to get the real clock. The clk_summary call clk_core_get_rate() to get rate, and clk_core_get_rate() would check the flag CLK_GET_RATE_NOCACHE to call __clk_recalc_rates(), but mtk_hdmi_phy does not have this flag, so this function would not be called when clk_summary. So I still think you could determine the out_rate in mtk_hdmi_pll_set_rate(). Regards, CK > > Regards, > CK > > > + hdmi_phy->pll_rate = out_rate; > > + > > + return hdmi_phy->pll_rate; > > +} > > > > static const struct clk_ops mtk_hdmi_phy_pll_ops = { > >
Re: [PATCH libdrm] tests/amdgpu: minor fix for dispatch/draw test
On Tue, Mar 19, 2019 at 10:47 PM Cui, Flora wrote: > > 1. clear cmd buffer > 2. make amdgpu_memcpy_dispatch_test static > 3. tab/space fix > > Change-Id: Idf55f8881f66458b585092eccb55b6042520e4ad > Signed-off-by: Flora Cui Reviewed-by: Alex Deucher and pushed. Thanks! > --- > tests/amdgpu/basic_tests.c | 20 > 1 file changed, 12 insertions(+), 8 deletions(-) > > diff --git a/tests/amdgpu/basic_tests.c b/tests/amdgpu/basic_tests.c > index a364f67..2d47269 100644 > --- a/tests/amdgpu/basic_tests.c > +++ b/tests/amdgpu/basic_tests.c > @@ -2177,6 +2177,7 @@ static void > amdgpu_memset_dispatch_test(amdgpu_device_handle device_handle, > _cmd, (void **)_cmd, > _address_cmd, _cmd); > CU_ASSERT_EQUAL(r, 0); > + memset(ptr_cmd, 0, bo_cmd_size); > > r = amdgpu_bo_alloc_and_map(device_handle, bo_shader_size, 4096, > AMDGPU_GEM_DOMAIN_VRAM, 0, > @@ -2227,7 +2228,7 @@ static void > amdgpu_memset_dispatch_test(amdgpu_device_handle device_handle, > ptr_cmd[i++] = 1; > > while (i & 7) > - ptr_cmd[i++] = 0x1000; /* type3 nop packet */ > + ptr_cmd[i++] = 0x1000; /* type3 nop packet */ > > resources[0] = bo_dst; > resources[1] = bo_shader; > @@ -2283,9 +2284,9 @@ static void > amdgpu_memset_dispatch_test(amdgpu_device_handle device_handle, > CU_ASSERT_EQUAL(r, 0); > } > > -void amdgpu_memcpy_dispatch_test(amdgpu_device_handle device_handle, > -uint32_t ip_type, > -uint32_t ring) > +static void amdgpu_memcpy_dispatch_test(amdgpu_device_handle device_handle, > + uint32_t ip_type, > + uint32_t ring) > { > amdgpu_context_handle context_handle; > amdgpu_bo_handle bo_src, bo_dst, bo_shader, bo_cmd, resources[4]; > @@ -2313,6 +2314,7 @@ void amdgpu_memcpy_dispatch_test(amdgpu_device_handle > device_handle, > _cmd, (void **)_cmd, > _address_cmd, _cmd); > CU_ASSERT_EQUAL(r, 0); > + memset(ptr_cmd, 0, bo_cmd_size); > > r = amdgpu_bo_alloc_and_map(device_handle, bo_shader_size, 4096, > AMDGPU_GEM_DOMAIN_VRAM, 0, > @@ -2371,7 +2373,7 @@ void amdgpu_memcpy_dispatch_test(amdgpu_device_handle > device_handle, > ptr_cmd[i++] = 1; > > while (i & 7) > - ptr_cmd[i++] = 0x1000; /* type3 nop packet */ > + ptr_cmd[i++] = 0x1000; /* type3 nop packet */ > > resources[0] = bo_shader; > resources[1] = bo_src; > @@ -2799,7 +2801,8 @@ void amdgpu_memset_draw(amdgpu_device_handle > device_handle, > AMDGPU_GEM_DOMAIN_GTT, 0, > _cmd, (void **)_cmd, > _address_cmd, _cmd); > -CU_ASSERT_EQUAL(r, 0); > + CU_ASSERT_EQUAL(r, 0); > + memset(ptr_cmd, 0, bo_cmd_size); > > r = amdgpu_bo_alloc_and_map(device_handle, bo_dst_size, 4096, > AMDGPU_GEM_DOMAIN_VRAM, 0, > @@ -2828,7 +2831,7 @@ void amdgpu_memset_draw(amdgpu_device_handle > device_handle, > i += amdgpu_draw_draw(ptr_cmd + i); > > while (i & 7) > - ptr_cmd[i++] = 0x1000; /* type3 nop packet */ > + ptr_cmd[i++] = 0x1000; /* type3 nop packet */ > > resources[0] = bo_dst; > resources[1] = bo_shader_ps; > @@ -2952,6 +2955,7 @@ static void amdgpu_memcpy_draw(amdgpu_device_handle > device_handle, > _cmd, (void **)_cmd, > _address_cmd, _cmd); > CU_ASSERT_EQUAL(r, 0); > + memset(ptr_cmd, 0, bo_cmd_size); > > r = amdgpu_bo_alloc_and_map(device_handle, bo_size, 4096, > AMDGPU_GEM_DOMAIN_VRAM, 0, > @@ -2999,7 +3003,7 @@ static void amdgpu_memcpy_draw(amdgpu_device_handle > device_handle, > i += amdgpu_draw_draw(ptr_cmd + i); > > while (i & 7) > - ptr_cmd[i++] = 0x1000; /* type3 nop packet */ > + ptr_cmd[i++] = 0x1000; /* type3 nop packet */ > > resources[0] = bo_dst; > resources[1] = bo_src; > -- > 2.7.4 > > ___ > 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
[Bug 110213] Used pwm value is lesser than the requested value
https://bugs.freedesktop.org/show_bug.cgi?id=110213 Alex Deucher changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |NOTABUG --- Comment #1 from Alex Deucher --- The hwmon API specifies the range as 0-255, but the hw actually has a different range. The conversion between ranges for read and writes accounts for the difference. See smu7_fan_ctrl_get_fan_speed_percent() and smu7_fan_ctrl_set_fan_speed_percent() smu7_thermal.c and amdgpu_hwmon_get_pwm1() and amdgpu_hwmon_set_pwm1() amdgpu_pm.c. -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[pull] amdgpu drm-fixes-5.1
Hi Dave, Daniel, Fixes for 5.1: - Parially revert a bulk move clean up change to fix a ref count bug - Fix invalid use of change_bit that caused a crash on PPC64 and ARM64 The following changes since commit 9e98c678c2d6ae3a17cb2de55d17f69dddaa231b: Linux 5.1-rc1 (2019-03-17 14:22:26 -0700) are available in the Git repository at: git://people.freedesktop.org/~agd5f/linux drm-fixes-5.1 for you to fetch changes up to 72464382fc2d3673eb51f21a57f2c0a320c1552f: drm/amdgpu: fix invalid use of change_bit (2019-03-19 14:01:42 -0500) Christian König (2): drm/amdgpu: revert "cleanup setting bulk_movable" drm/amdgpu: fix invalid use of change_bit drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 2 ++ drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2] gpu/drm: mediatek: call mtk_dsi_stop() after mtk_drm_crtc_atomic_disable()
Hi, Hsin-yi: On Thu, 2019-03-21 at 09:28 +0800, CK Hu wrote: > Hi, Hsin-yi: > > On Wed, 2019-03-20 at 15:18 +0800, Hsin-Yi Wang wrote: > > mtk_dsi_stop() should be called after mtk_drm_crtc_atomic_disable(), which > > needs > > ovl irq for drm_crtc_wait_one_vblank(), since after mtk_dsi_stop() is > > called, > > ovl irq will be disabled. If drm_crtc_wait_one_vblank() is called after last > > irq, it will timeout with this message: "vblank wait timed out on crtc 0". > > This > > happens sometimes when turning off the screen. > > > > In drm_atomic_helper.c#disable_outputs(), > > the calling sequence when turning off the screen is: > > > > 1. mtk_dsi_encoder_disable() > > --> mtk_output_dsi_disable() > >--> mtk_dsi_stop(); // sometimes make vblank timeout in > > atomic_disable > >--> mtk_dsi_poweroff(); > > 2. mtk_drm_crtc_atomic_disable() > > --> drm_crtc_wait_one_vblank(); > > ... > >--> mtk_dsi_ddp_stop() > > --> mtk_dsi_poweroff(); > > > > mtk_dsi_poweroff() has reference count design, change to make mtk_dsi_stop() > > called in mtk_dsi_poweroff() when refcount is 0. > > > > Fixes: 0707632b5bac ("drm/mediatek: update DSI sub driver flow for sending > > commands to panel") > > Signed-off-by: Hsin-Yi Wang > > --- > > change log: > > v1->v2: > > * update commit message. > > * call mtk_dsi_stop() in mtk_dsi_poweroff() when refcount is 0. > > --- > > drivers/gpu/drm/mediatek/mtk_dsi.c | 5 - > > 1 file changed, 4 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c > > b/drivers/gpu/drm/mediatek/mtk_dsi.c > > index b00eb2d2e086..e152f37af57d 100644 > > --- a/drivers/gpu/drm/mediatek/mtk_dsi.c > > +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c > > @@ -630,6 +630,8 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi) > > if (--dsi->refcount != 0) > > return; > > > > + mtk_dsi_stop(dsi); > > + > > if (!mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500)) { > > if (dsi->panel) { > > if (drm_panel_unprepare(dsi->panel)) { > > I think you just move mtk_dsi_stop() into mtk_dsi_poweroff() would works > fine, but I would rather like calling mtk_dsi_start() and mtk_dsi_stop() > in a symmetric manner. That means you may also move below functions into > mtk_dsi_poweron(): > > mtk_dsi_set_mode(dsi); > mtk_dsi_clk_hs_mode(dsi, 1); > mtk_dsi_start(dsi); > > > > @@ -696,7 +698,6 @@ static void mtk_output_dsi_disable(struct mtk_dsi *dsi) > > } > > } > > > > - mtk_dsi_stop(dsi); > > mtk_dsi_poweroff(dsi); > > > > dsi->enabled = false; > > @@ -1178,6 +1179,8 @@ static int mtk_dsi_remove(struct platform_device > > *pdev) > > struct mtk_dsi *dsi = platform_get_drvdata(pdev); > > > > mtk_output_dsi_disable(dsi); > > + mtk_dsi_stop(dsi); > > + mtk_dsi_poweroff(dsi); > > I think mtk_output_dsi_disable() would call mtk_dsi_poweroff(), and > mtk_dsi_poweroff() would call mtk_dsi_stop(), so these two line are > redundant. And I think you should remove mtk_dsi_stop() in > mtk_output_dsi_disable(), why not in this patch? You've removed mtk_dsi_stop() in mtk_output_dsi_disable(), I just miss it, sorry for this. Regards, CK > > Regards, > CK > > > component_del(>dev, _dsi_component_ops); > > > > return 0; > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: Aw: [PATCH v2] gpu/drm: mediatek: call mtk_dsi_stop() after mtk_drm_crtc_atomic_disable()
Hi, Frank: On Wed, 2019-03-20 at 19:01 +0100, Frank Wunderlich wrote: > Hi, > > i hoped this fixes my warning (maybe have similar cause) on bananapi-r2/mt7623 This patch fix the problem of dsi driver. Your case is hdmi output which does not go through dsi hardware. So your problem is another cause. Regards, CK > > [6.872034] WARNING: CPU: 2 PID: 160 at > drivers/gpu/drm/drm_atomic_helper.c:1 > 430 drm_atomic_helper_wait_for_vblanks.part.1+0x2a4/0x2a8 > [6.872038] [CRTC:36:crtc-0] vblank wait timed out > > ... > > [6.872127] [] (__warn) from [] > (warn_slowpath_fmt+0x58/0 > x74) > [6.872136] r9: r8:0001 r7: r6:0001 r5:c0d7da9c > r4:c > 1008c48 > [6.872145] [] (warn_slowpath_fmt) from [] > (drm_atomic_helper_wait_for_vblanks.part.1+0x2a4/0x2a8) > [6.872150] r3:0024 r2:c0d7da9c > [6.872154] r5: r4:d991f440 > [6.872164] [] (drm_atomic_helper_wait_for_vblanks.part.1) from > [] (drm_atomic_helper_wait_for_vblanks+0x24/0x28) > [6.872172] r10:dae68f28 r9:dae68f38 r8: r7:d9f759c0 r6:d991ec00 > r5:d9f759c0 > [6.872175] r4:0005 > [6.872185] [] (drm_atomic_helper_wait_for_vblanks) from > [] (mtk_atomic_complete+0x98/0xc0) > [6.872194] [] (mtk_atomic_complete) from [] > (mtk_atomic_commit+0xc8/0xcc) > [6.872201] r7:d9f759c0 r6:dae68e40 r5:d991ec00 r4: > [6.872211] [] (mtk_atomic_commit) from [] > (drm_atomic_commit+0x54/0x60) > [6.872219] r10:0002 r9:d9f74eac r8:0001 r7:d98d5700 r6:d991ec00 > r5:d9f759c0 > [6.872223] r4: r3:c060af2c > [6.872234] [] (drm_atomic_commit) from [] > (restore_fbdev_mode_atomic+0x1d4/0x1e4) > [6.872241] r7:d98d5700 r6:0001 r5:d991edb0 r4:d9f759c0 > [6.872251] [] (restore_fbdev_mode_atomic) from [] > (restore_fbdev_mode+0x5c/0x194) > [6.872260] r10: r9:d991ecdc r8:d98d57b4 r7: r6:d98d5700 > r5:d98d5700 > [6.872263] r4: > [6.872274] [] (restore_fbdev_mode) from [] > (drm_fb_helper_restore_fbdev_mode_unlocked+0x64/0xb0) > [6.872282] r10: r9:d991ecdc r8:d98d57b4 r7: r6:c10824c8 > r5:d98d5700 > [6.872285] r4: > [6.872296] [] (drm_fb_helper_restore_fbdev_mode_unlocked) from > [] (drm_fb_helper_set_par+0x40/0x64) > [6.872304] r9:d991ecdc r8:d991ec8c r7:c0d82d88 r6:d98d57b4 r5: > r4: > [6.872315] [] (drm_fb_helper_set_par) from [] > (drm_fb_helper_hotplug_event.part.11+0xb0/0xb8) > [6.872319] r5: r4:d98d5700 > [6.872330] [] (drm_fb_helper_hotplug_event.part.11) from > [] (drm_fbdev_client_hotplug+0x13c/0x1d8) > [6.872337] r7:c0d82d88 r6:d991eca0 r5:d991ec00 r4:d98d5700 > [6.872348] [] (drm_fbdev_client_hotplug) from [] > (drm_client_dev_hotplug+0x84/0xc0) > > this crash also happens without fbdev-patch > > my codebase: https://github.com/frank-w/BPI-R2-4.14/commits/5.1-hdmi > > regards Frank ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 110214] amdgpu: xterm scrollback buffer disappears while paging up/down
https://bugs.freedesktop.org/show_bug.cgi?id=110214 Bug ID: 110214 Summary: amdgpu: xterm scrollback buffer disappears while paging up/down Product: DRI Version: XOrg git Hardware: Other OS: All Status: NEW Severity: normal Priority: medium Component: DRM/AMDgpu Assignee: dri-devel@lists.freedesktop.org Reporter: diego.vi...@gmail.com Whenever I run `dmesg' on a xterm that uses the following options: xterm -fa "DejaVu Sans Mono:style=Book:antialias=true" -fs 9 and I scroll up with the keyboard (shift+page up) parts of the scrollback buffer disappears, making it difficult to read the output. I've tested other terminals (urxvt and alacritty) and I cannot trigger the bug with these terminals, with xterm it happens only with xft and with the options I mentioned above. Steps to reproduce: - run `xterm -fa "DejaVu Sans Mono:style=Book:antialias=true" -fs 9' - run `dmesg', hit enter and page up You should notice parts of the buffer disappearing. I use the modesetting DDX driver, I also tried the xf86-video-amdgpu DDX driver and I can reproduce it with both, however, when setting Option "Accel" "off" in /etc/X11/xorg.conf.d/20-amdgpu.conf I cannot reproduce it anymore. Actual Results: As mentioned, the scrollback buffer disappears when paging up with these xterm options that I mentioned above. Expected Results: xterm works normally with these options, with no scrollback buffer issues. System details: - Arch Linux (x86_64) - linux 5.0.2-arch1-1-ARCH - xorg-server 1.20.4-1 - i3-wm 4.16.1-1 - xterm 344-1 - mesa 19.0.0-1 My machine is a "AMD Ryzen 5 2400G with Radeon Vega Graphics" APU with integrated vega graphics. $ lspci | grep VGA 07:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Raven Ridge [Radeon Vega Series / Radeon Vega Mobile Series] (rev c6) -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2] gpu/drm: mediatek: call mtk_dsi_stop() after mtk_drm_crtc_atomic_disable()
Hi, Hsin-yi: On Wed, 2019-03-20 at 15:18 +0800, Hsin-Yi Wang wrote: > mtk_dsi_stop() should be called after mtk_drm_crtc_atomic_disable(), which > needs > ovl irq for drm_crtc_wait_one_vblank(), since after mtk_dsi_stop() is called, > ovl irq will be disabled. If drm_crtc_wait_one_vblank() is called after last > irq, it will timeout with this message: "vblank wait timed out on crtc 0". > This > happens sometimes when turning off the screen. > > In drm_atomic_helper.c#disable_outputs(), > the calling sequence when turning off the screen is: > > 1. mtk_dsi_encoder_disable() > --> mtk_output_dsi_disable() >--> mtk_dsi_stop(); // sometimes make vblank timeout in atomic_disable >--> mtk_dsi_poweroff(); > 2. mtk_drm_crtc_atomic_disable() > --> drm_crtc_wait_one_vblank(); > ... >--> mtk_dsi_ddp_stop() > --> mtk_dsi_poweroff(); > > mtk_dsi_poweroff() has reference count design, change to make mtk_dsi_stop() > called in mtk_dsi_poweroff() when refcount is 0. > > Fixes: 0707632b5bac ("drm/mediatek: update DSI sub driver flow for sending > commands to panel") > Signed-off-by: Hsin-Yi Wang > --- > change log: > v1->v2: > * update commit message. > * call mtk_dsi_stop() in mtk_dsi_poweroff() when refcount is 0. > --- > drivers/gpu/drm/mediatek/mtk_dsi.c | 5 - > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c > b/drivers/gpu/drm/mediatek/mtk_dsi.c > index b00eb2d2e086..e152f37af57d 100644 > --- a/drivers/gpu/drm/mediatek/mtk_dsi.c > +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c > @@ -630,6 +630,8 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi) > if (--dsi->refcount != 0) > return; > > + mtk_dsi_stop(dsi); > + > if (!mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500)) { > if (dsi->panel) { > if (drm_panel_unprepare(dsi->panel)) { I think you just move mtk_dsi_stop() into mtk_dsi_poweroff() would works fine, but I would rather like calling mtk_dsi_start() and mtk_dsi_stop() in a symmetric manner. That means you may also move below functions into mtk_dsi_poweron(): mtk_dsi_set_mode(dsi); mtk_dsi_clk_hs_mode(dsi, 1); mtk_dsi_start(dsi); > @@ -696,7 +698,6 @@ static void mtk_output_dsi_disable(struct mtk_dsi *dsi) > } > } > > - mtk_dsi_stop(dsi); > mtk_dsi_poweroff(dsi); > > dsi->enabled = false; > @@ -1178,6 +1179,8 @@ static int mtk_dsi_remove(struct platform_device *pdev) > struct mtk_dsi *dsi = platform_get_drvdata(pdev); > > mtk_output_dsi_disable(dsi); > + mtk_dsi_stop(dsi); > + mtk_dsi_poweroff(dsi); I think mtk_output_dsi_disable() would call mtk_dsi_poweroff(), and mtk_dsi_poweroff() would call mtk_dsi_stop(), so these two line are redundant. And I think you should remove mtk_dsi_stop() in mtk_output_dsi_disable(), why not in this patch? Regards, CK > component_del(>dev, _dsi_component_ops); > > return 0; ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 1/9] dma-buf: add new dma_fence_chain container v6
Hi Chunming, I love your patch! Perhaps something to improve: [auto build test WARNING on linus/master] [also build test WARNING on v5.1-rc1 next-20190320] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Chunming-Zhou/dma-buf-add-new-dma_fence_chain-container-v6/20190320-223607 reproduce: # apt-get install sparse make ARCH=x86_64 allmodconfig make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' sparse warnings: (new ones prefixed by >>) >> drivers/dma-buf/dma-fence-chain.c:73:23: sparse: incorrect type in >> initializer (different address spaces) @@expected struct dma_fence >> [noderef] *__old @@got dma_fence [noderef] *__old @@ drivers/dma-buf/dma-fence-chain.c:73:23:expected struct dma_fence [noderef] *__old drivers/dma-buf/dma-fence-chain.c:73:23:got struct dma_fence *[assigned] prev >> drivers/dma-buf/dma-fence-chain.c:73:23: sparse: incorrect type in >> initializer (different address spaces) @@expected struct dma_fence >> [noderef] *__new @@got dma_fence [noderef] *__new @@ drivers/dma-buf/dma-fence-chain.c:73:23:expected struct dma_fence [noderef] *__new drivers/dma-buf/dma-fence-chain.c:73:23:got struct dma_fence *[assigned] replacement >> drivers/dma-buf/dma-fence-chain.c:73:21: sparse: incorrect type in >> assignment (different address spaces) @@expected struct dma_fence *tmp >> @@got struct dma_fence [noderef] *[assigned] __ret >> drivers/dma-buf/dma-fence-chain.c:190:28: sparse: incorrect type in argument >> 1 (different address spaces) @@expected struct dma_fence *fence @@ >> got struct dma_fence struct dma_fence *fence @@ drivers/dma-buf/dma-fence-chain.c:190:28:expected struct dma_fence *fence drivers/dma-buf/dma-fence-chain.c:190:28:got struct dma_fence [noderef] *prev >> drivers/dma-buf/dma-fence-chain.c:222:21: sparse: incorrect type in >> assignment (different address spaces) @@expected struct dma_fence >> [noderef] *prev @@got [noderef] *prev @@ drivers/dma-buf/dma-fence-chain.c:222:21:expected struct dma_fence [noderef] *prev drivers/dma-buf/dma-fence-chain.c:222:21:got struct dma_fence *prev drivers/dma-buf/dma-fence-chain.c:235:33: sparse: expression using sizeof(void) drivers/dma-buf/dma-fence-chain.c:235:33: sparse: expression using sizeof(void) vim +73 drivers/dma-buf/dma-fence-chain.c 38 39 /** 40 * dma_fence_chain_walk - chain walking function 41 * @fence: current chain node 42 * 43 * Walk the chain to the next node. Returns the next fence or NULL if we are at 44 * the end of the chain. Garbage collects chain nodes which are already 45 * signaled. 46 */ 47 struct dma_fence *dma_fence_chain_walk(struct dma_fence *fence) 48 { 49 struct dma_fence_chain *chain, *prev_chain; 50 struct dma_fence *prev, *replacement, *tmp; 51 52 chain = to_dma_fence_chain(fence); 53 if (!chain) { 54 dma_fence_put(fence); 55 return NULL; 56 } 57 58 while ((prev = dma_fence_chain_get_prev(chain))) { 59 60 prev_chain = to_dma_fence_chain(prev); 61 if (prev_chain) { 62 if (!dma_fence_is_signaled(prev_chain->fence)) 63 break; 64 65 replacement = dma_fence_chain_get_prev(prev_chain); 66 } else { 67 if (!dma_fence_is_signaled(prev)) 68 break; 69 70 replacement = NULL; 71 } 72 > 73 tmp = cmpxchg(>prev, prev, replacement); 74 if (tmp == prev) 75 dma_fence_put(tmp); 76 else 77 dma_fence_put(replacement); 78 dma_fence_put(prev); 79 } 80 81 dma_fence_put(fence); 82 return prev; 83 } 84 EXPORT_SYMBOL(dma_fence_chain_walk); 85 86 /** 87 * dma_fence_chain_find_seqno - find fence chain node by seqno 88 * @pfence: pointer to the chain node where to start 89 * @seqno: the sequence number to search for 90 * 91 * Advance the fence pointer to the chain node which will signal this sequence 92 * number. If no sequence number is provided then this is a no-op. 93 * 94 * Returns EINVAL if the fence is not a chain node or the sequence number has 95 * not yet advanced far enough. 96 */ 97 int dma_fence_chain_find_seqno(st
[PULL] drm-intel-fixes
Hi Dave and Daniel, Here goes the first round of fixes for 5.1-rc cycle. I will be out on vacation next week, so next week's pull request might come from Jani. Although things looks calm right now. only 3 patches on top of -rc1: drm-intel-fixes-2019-03-20: A protection on our mmap against attempts to map past the end of the object; plus a fix off-by-one in our hang report and a protection; and a fix for eDP panels on Gen9 platforms on VBT absence. Thanks, Rodrigo. The following changes since commit 9e98c678c2d6ae3a17cb2de55d17f69dddaa231b: Linux 5.1-rc1 (2019-03-17 14:22:26 -0700) are available in the Git repository at: git://anongit.freedesktop.org/drm/drm-intel tags/drm-intel-fixes-2019-03-20 for you to fetch changes up to 000c4f90e3f0194eef218ff2c6a8fd8ca1de4313: drm/i915: Sanity check mmap length against object size (2019-03-18 13:59:42 -0700) A protection on our mmap against attempts to map past the end of the object; plus a fix off-by-one in our hang report and a protection; and a fix for eDP panels on Gen9 platforms on VBT absence. Chris Wilson (2): drm/i915: Fix off-by-one in reporting hanging process drm/i915: Sanity check mmap length against object size Thomas Preston (1): drm/i915/bios: assume eDP is present on port A when there is no VBT drivers/gpu/drm/i915/i915_gem.c | 15 +-- drivers/gpu/drm/i915/i915_gpu_error.c | 2 +- drivers/gpu/drm/i915/intel_bios.c | 1 + 3 files changed, 11 insertions(+), 7 deletions(-) ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] xen, fbfront: mark expected switch fall-through
Hi all, Friendly ping: Who can take this? Thanks -- Gustavo On 2/28/19 5:51 AM, Oleksandr Andrushchenko wrote: > +Xen-devel list > > On 2/27/19 10:53 PM, Gustavo A. R. Silva wrote: >> In preparation to enabling -Wimplicit-fallthrough, mark switch >> cases where we are expecting to fall through. >> >> This patch fixes the following warning: >> >> drivers/video/fbdev/xen-fbfront.c: In function ‘xenfb_backend_changed’: >> drivers/video/fbdev/xen-fbfront.c:678:6: warning: this statement may fall >> through [-Wimplicit-fallthrough=] >> if (dev->state == XenbusStateClosed) >> ^ >> drivers/video/fbdev/xen-fbfront.c:681:2: note: here >> case XenbusStateClosing: >> ^~~~ >> >> Warning level 3 was used: -Wimplicit-fallthrough=3 >> >> Notice that, in this particular case, the code comment is modified >> in accordance with what GCC is expecting to find. >> >> This patch is part of the ongoing efforts to enable >> -Wimplicit-fallthrough. >> >> Signed-off-by: Gustavo A. R. Silva >> --- >> drivers/video/fbdev/xen-fbfront.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/drivers/video/fbdev/xen-fbfront.c >> b/drivers/video/fbdev/xen-fbfront.c >> index 6a4bbc9e1fb0..a3d6b6db221b 100644 >> --- a/drivers/video/fbdev/xen-fbfront.c >> +++ b/drivers/video/fbdev/xen-fbfront.c >> @@ -677,7 +677,7 @@ static void xenfb_backend_changed(struct xenbus_device >> *dev, >> case XenbusStateClosed: >> if (dev->state == XenbusStateClosed) >> break; >> - /* Missed the backend's CLOSING state -- fallthrough */ >> + /* fall through - Missed the backend's CLOSING state. */ >> case XenbusStateClosing: >> xenbus_frontend_closed(dev); >> break; > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Intel-gfx] [PATCH v2 1/2] drm/selftests/mm: Switch to bitmap_zalloc()
Quoting Chris Wilson (2019-03-04 09:43:43) > Quoting Andy Shevchenko (2019-03-04 09:29:07) > > Switch to bitmap_zalloc() to show clearly what we are allocating. > > Besides that it returns pointer of bitmap type instead of opaque void *. > > > > Signed-off-by: Andy Shevchenko > Reviewed-by: Chris Wilson Applied to drm-misc-next. -Chris ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 5/5] media: tvp5150: add support to limit tv norms on connector
Em Wed, 20 Mar 2019 17:36:50 +0100 Marco Felsch escreveu: > Hi Mauro, > > On 19-03-20 11:18, Mauro Carvalho Chehab wrote: > > Em Sat, 2 Feb 2019 13:10:04 +0100 > > Marco Felsch escreveu: > > > > > The tvp5150 accepts NTSC(M,J,4.43), PAL (B,D,G,H,I,M,N) and SECAM video > > > data and is able to auto-detect the input signal. > > > > Hmm... I'm afraid of this change. As far as I remember, I tested some > > weird format variants like V4L2_STD_PAL_60 a long time ago, but there's > > no way to force video to use those. The format selection logic simply > > places the device on auto-detect mode for those weirdos, and that > > works fine at the devices I know. > > Sorry I didn't get this. The format is set to autodetect during probe(). Yes, but apps will change based on G_FMT, TRY_FMT and S_FMT. See, my main concern here is with existing tvp5150 non-platform drivers, as a change there would be a regression. > If there is no format limitation this won't be changed during > media.link_setup(). You're right I forgot to check if the cur_connector > is available during tvp5150_s_std(), in case of pdata related devices. Yeah, that's what I'm talking about. > In such a case we should set supported_norms to V4L2_STD_ALL as it is > done by v4l2_fwnode_parse_connector() if no limitations are given. > > Btw, how does it look with the other patchset? I asked Hans to take a look at the patch series, as he's sub-maintaining the v4l2 stuff. I'm intending to take a deeper look at patch 2/7 v4 from the past series. > > Regards, > Marco > > > > > A change like that may break things. So I would actually have a quirk > > to optionally disable auto-detection on devices that this is not know > > to work. > > > > > The auto-detection > > > does not work if the connector does not receive an input signal and the > > > tvp5150 might not be configured correctly. This misconfiguration leads > > > into wrong decoded video streams if the tvp5150 gets powered on before > > > the video signal is present. > > > > > > Limit the supported tv norms according to the actual selected connector > > > to avoid a misconfiguration. > > > > > > Signed-off-by: Marco Felsch > > > --- > > > drivers/media/i2c/tvp5150.c | 42 - > > > 1 file changed, 41 insertions(+), 1 deletion(-) > > > > > > diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c > > > index f3a2ad00a40d..7619793dee67 100644 > > > --- a/drivers/media/i2c/tvp5150.c > > > +++ b/drivers/media/i2c/tvp5150.c > > > @@ -32,6 +32,13 @@ > > > #define TVP5150_MBUS_FMT MEDIA_BUS_FMT_UYVY8_2X8 > > > #define TVP5150_FIELDV4L2_FIELD_ALTERNATE > > > #define TVP5150_COLORSPACE V4L2_COLORSPACE_SMPTE170M > > > +#define TVP5150_STD_MASK (V4L2_STD_NTSC | \ > > > + V4L2_STD_NTSC_443 | \ > > > + V4L2_STD_PAL | \ > > > + V4L2_STD_PAL_M| \ > > > + V4L2_STD_PAL_N| \ > > > + V4L2_STD_PAL_Nc | \ > > > + V4L2_STD_SECAM) > > > > > > MODULE_DESCRIPTION("Texas Instruments TVP5150A/TVP5150AM1/TVP5151 video > > > decoder driver"); > > > MODULE_AUTHOR("Mauro Carvalho Chehab"); > > > @@ -74,6 +81,7 @@ struct tvp5150 { > > > struct media_pad pads[TVP5150_NUM_PADS]; > > > int pads_state[TVP5150_NUM_PADS]; > > > struct tvp5150_connector *connectors; > > > + struct tvp5150_connector *cur_connector; > > > int connectors_num; > > > bool modify_second_link; > > > #endif > > > @@ -794,17 +802,27 @@ static int tvp5150_g_std(struct v4l2_subdev *sd, > > > v4l2_std_id *std) > > > static int tvp5150_s_std(struct v4l2_subdev *sd, v4l2_std_id std) > > > { > > > struct tvp5150 *decoder = to_tvp5150(sd); > > > + v4l2_std_id supported_norms = > > > + decoder->cur_connector->base.connector.analog.supported_tvnorms; > > > > > > if (decoder->norm == std) > > > return 0; > > > > > > + /* > > > + * check if requested std or group of std's is/are supported by the > > > + * connector > > > + */ > > > + if ((supported_norms & std) == 0) > > > + return -EINVAL; > > > + > > > /* Change cropping height limits */ > > > if (std & V4L2_STD_525_60) > > > decoder->rect.height = TVP5150_V_MAX_525_60; > > > else > > > decoder->rect.height = TVP5150_V_MAX_OTHERS; > > > > > > - decoder->norm = std; > > > + /* set only the specific supported std in case of group of std's */ > > > + decoder->norm = supported_norms & std; > > > > > > return tvp5150_set_std(sd, std); > > > } > > > @@ -1298,6 +1316,7 @@ static int tvp5150_link_setup(struct media_entity > > > *entity, > > > int *pad_state = >pads_state[0]; > > > int i, active_pad, ret = 0; > > > bool is_svideo = false; > > > + bool update_cur_connector = false; > > > > > > /* > > >* The tvp state is determined by the enabled sink pad link. > > >
[PATCH][next] drm/amd/powerplay: fix spelling mistake "unknow" -> "unknown"
From: Colin Ian King There is a spelling mistake in pr_warn message; fix it. Signed-off-by: Colin Ian King --- drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c index 17143888e37e..026bebe6fb45 100644 --- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c @@ -2024,6 +2024,6 @@ void smu_v11_0_set_smu_funcs(struct smu_context *smu) vega20_set_ppt_funcs(smu); break; default: - pr_warn("Unknow asic for smu11\n"); + pr_warn("Unknown asic for smu11\n"); } } -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 102646] Screen flickering under amdgpu-experimental [buggy auto power profile]
https://bugs.freedesktop.org/show_bug.cgi?id=102646 --- Comment #72 from tempel.jul...@gmail.com --- Well, I just accepted to lose 2Hz and use a custom edid with 73Hz instead of 75. -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 102646] Screen flickering under amdgpu-experimental [buggy auto power profile]
https://bugs.freedesktop.org/show_bug.cgi?id=102646 --- Comment #71 from bmil...@gmail.com --- (In reply to George Scorer from comment #70) > Building on julien tempel's workaround, here's a somewhat more complex > script to manage the memory p-state jumps. It switches between low and high > memory p-states very reluctantly, so minimizing instances of flickering. I'm > not a bash expert so please excuse the clumsy coding, but this works for me. > > #!/bin/bash > > # Each memory p-state switch causes a screen flicker. Tweak these variables > to match > # your personal 'flicker aversion' vs efficiency trade-off. > CORE_P_STATE_UP=6# The gpu core p-state at which we should jump up to > memory p-state 2 > CORE_P_STATE_DOWN=1 # The gpu core p-state at which we should drop down to > low memory p-state > UP_DELAY=2 # in seconds. How long to stay in low memory p-state > before checking whether we can jump up to 2. > DOWN_DELAY=10# in seconds. How long to stay in memory p-state 2 > before checking whether we can drop down to low. > SLEEP_INTERVAL=1 # in seconds. How frequently we should poll the core > p-state. > LOW_MEM_STATE=0 # Choose between 0 & 1 > > # Sysfs paths here are hardcoded for one amdgpu card at card0; adjust as > needed. > FILE_PERF_LEVEL=/sys/class/drm/card0/device/power_dpm_force_performance_level > FILE_MEM_P_STATE=/sys/class/drm/card0/device/pp_dpm_mclk > FILE_CORE_P_STATE=/sys/class/drm/card0/device/pp_dpm_sclk > > > # check for root privileges > if [ $UID -ne 0 ] > then > echo "Writing to sysfs requires root privileges; relaunch as root" > exit 1 > fi > > # Set gpu performance level control to manual > # echo "Setting performance level control to manual" > echo "manual" > "$FILE_PERF_LEVEL" > > # Read the current core p-state and set a corresponding initial memory > p-state > > CORE_P_STATE="$(grep -F '*' $FILE_CORE_P_STATE)" > CORE_P_STATE=${CORE_P_STATE:0:1} > > if [ "$CORE_P_STATE" -ge "$CORE_P_STATE_UP" ]; then > MEM_P_STATE=2 > else > MEM_P_STATE=$LOW_MEM_STATE > fi > > echo "$MEM_P_STATE" > "$FILE_MEM_P_STATE" > PROPOSED_MEM_P_STATE=$MEM_P_STATE > > function check_core_p_state { > > CORE_P_STATE="$(grep -F '*' $FILE_CORE_P_STATE)" > CORE_P_STATE=${CORE_P_STATE:0:1} > > # Propose what the corresponding memory p-state should be > OLD_PROPOSED_MEM_P_STATE=$PROPOSED_MEM_P_STATE > PROPOSED_MEM_P_STATE=$MEM_P_STATE > if [ "$CORE_P_STATE" -ge "$CORE_P_STATE_UP" ]; then > PROPOSED_MEM_P_STATE=2 > elif [ "$CORE_P_STATE" -le "$CORE_P_STATE_DOWN" ]; then > PROPOSED_MEM_P_STATE=$LOW_MEM_STATE > fi > > if [ "$PROPOSED_MEM_P_STATE" -ne "$MEM_P_STATE" ]; then > # We want to change so determine where we are in the countdown. > if [ "$PROPOSED_MEM_P_STATE" -ne "$OLD_PROPOSED_MEM_P_STATE" ]; then > if [ "$PROPOSED_MEM_P_STATE" -eq 2 ]; then > CHANGE_COUNTDOWN=$UP_DELAY > else > CHANGE_COUNTDOWN=$DOWN_DELAY > fi > fi > (( CHANGE_COUNTDOWN = $CHANGE_COUNTDOWN - $SLEEP_INTERVAL )) > > if [ $CHANGE_COUNTDOWN -le 0 ]; then > # The countdown has reached 0 so change the memory p-state. > MEM_P_STATE=$PROPOSED_MEM_P_STATE > echo "$MEM_P_STATE" > "$FILE_MEM_P_STATE" > fi > # else > # we don't want to change. > fi > > #echo "Old Prop Mem Core Countdown" > #echo " $OLD_PROPOSED_MEM_P_STATE $PROPOSED_MEM_P_STATE > $MEM_P_STATE $CORE_P_STATE $CHANGE_COUNTDOWN" > #echo "" > } > > function reset_on_fail { > echo "Exiting, setting memory p-state to 2" > echo "manual" > "$FILE_PERF_LEVEL" > echo "2" > "$FILE_MEM_P_STATE" > exit 1 > } > > # always try to fix memory p-state 2 on failure > trap "reset_on_fail" SIGINT SIGTERM > > function run_daemon { > while :; do > sleep $SLEEP_INTERVAL > check_core_p_state > done > } > > # start the loop > > run_daemon Thanks for the script, it doesn't work 100% of the time but the flickers are very rare. Good thing about it is that you still save power when idle since it reclocks back. I'd guess similar logic could be used to fix the driver while still having the feature working, just reclocking less agressively. -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 2/2] drm/vc4: Allocated/liberate the binner BO at firstopen/lastclose
Paul Kocialkowski writes: > The binner BO is a pre-requisite to GPU operations, so we must ensure > that it is always allocated when the GPU is in use. Currently, we are > allocating it at probe time and liberating/allocating it during runtime > pm cycles. > > First, since the binner buffer is only required for GPU rendering, it's > a waste to allocate it when the driver probes since internal users of > the driver (such as fbcon) won't try to use the GPU. > > Move the allocation/liberation to the firstopen/lastclose instead to > only allocate it when userspace has opened the device and adapt the IRQ > handler to return early when no binner BO was allocated yet. > > Second, because the buffer is allocated from the same pool as other GPU > buffers, we might run into a situation where we are out of memory at > runtime resume. This causes the binner BO allocation to fail and results > in all subsequent operations to fail, resulting in a major hang in > userspace. > > As a result, keep the buffer alive during runtime pm. > > Signed-off-by: Paul Kocialkowski > --- > diff --git a/drivers/gpu/drm/vc4/vc4_irq.c b/drivers/gpu/drm/vc4/vc4_irq.c > index 4cd2ccfe15f4..efaba2b02f6c 100644 > --- a/drivers/gpu/drm/vc4/vc4_irq.c > +++ b/drivers/gpu/drm/vc4/vc4_irq.c > @@ -64,6 +64,9 @@ vc4_overflow_mem_work(struct work_struct *work) > struct vc4_exec_info *exec; > unsigned long irqflags; > > + if (!bo) > + return; > + > bin_bo_slot = vc4_v3d_get_bin_slot(vc4); > if (bin_bo_slot < 0) { > DRM_ERROR("Couldn't allocate binner overflow mem\n"); Hmm. We take the OOM IRQ on poweron, have no bin BO since nobody's opened yet, and leave it. Do we ever get the OOM IRQ again after that? Seems like vc4_allocate_bin_bo() might need to kick something so that we can fill an OOM request. signature.asc Description: PGP signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 1/2] drm/file: Rehabilitate the firstopen hook for non-legacy drivers
Paul Kocialkowski writes: > The firstopen DRM driver hook was initially used to perform hardware > initialization, which is now considered legacy. Only a single user of > firstopen remains at this point (savage). > > In some specific cases, non-legacy drivers may also need to implement > these hooks. For instance on VC4, we need to allocate a 16 MiB buffer > for the GPU. Because it's not required for fbcon, it's a waste to > allocate it before userspace starts using the DRM device. > > Using firstopen and lastclose for this allocation seems like the best > fit, so re-habilitate the hook to allow it to be called for non-legacy > drivers. > > Signed-off-by: Paul Kocialkowski > --- > drivers/gpu/drm/drm_file.c | 3 +-- > include/drm/drm_drv.h | 2 +- > 2 files changed, 2 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c > index b1838a41ad43..c011b5cbfb6b 100644 > --- a/drivers/gpu/drm/drm_file.c > +++ b/drivers/gpu/drm/drm_file.c > @@ -266,8 +266,7 @@ static int drm_setup(struct drm_device * dev) > { > int ret; > > - if (dev->driver->firstopen && > - drm_core_check_feature(dev, DRIVER_LEGACY)) { > + if (dev->driver->firstopen) { > ret = dev->driver->firstopen(dev); > if (ret != 0) > return ret; > diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h > index ca46a45a9cce..aa14607e54d4 100644 > --- a/include/drm/drm_drv.h > +++ b/include/drm/drm_drv.h > @@ -236,7 +236,7 @@ struct drm_driver { >* to set/unset the VT into raw mode. >* >* Legacy drivers initialize the hardware in the @firstopen callback, > - * which isn't even called for modern drivers. > + * modern drivers can use it for other purposes only. >*/ > void (*lastclose) (struct drm_device *); Our usage in vc4 is not very different from what we called "hardware initialization" in other devices. I would rather just delete this sentence entirely. The only alternative I can think of to using a firstopen/lastclose-style allocation for this would be to allocate the bin bo on the first (non-dumb?) V3D BO allocation and refcount those to free the binner. signature.asc Description: PGP signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 110213] Used pwm value is lesser than the requested value
https://bugs.freedesktop.org/show_bug.cgi?id=110213 Bug ID: 110213 Summary: Used pwm value is lesser than the requested value Product: DRI Version: unspecified Hardware: x86-64 (AMD64) OS: Linux (All) Status: NEW Severity: normal Priority: medium Component: DRM/AMDgpu Assignee: dri-devel@lists.freedesktop.org Reporter: jpalacios...@gmail.com Created attachment 143743 --> https://bugs.freedesktop.org/attachment.cgi?id=143743=edit dmesg On manual fan control through pwm interface, the used value on pwm1 is lesser that the requested value (except for maximum). For example: echo 1 > /sys/class/drm/card0/device/hwmon/hwmon1/pwm1_enable echo 10 > /sys/class/drm/card0/device/hwmon/hwmon1/pwm1 cat /sys/class/drm/card0/device/hwmon/hwmon1/pwm1 5 echo 100 > /sys/class/drm/card0/device/hwmon/hwmon1/pwm1 cat /sys/class/drm/card0/device/hwmon/hwmon1/pwm1 96 echo 254 > /sys/class/drm/card0/device/hwmon/hwmon1/pwm1 cat /sys/class/drm/card0/device/hwmon/hwmon1/pwm1 249 The maximum value works as expected: echo 255 > /sys/class/drm/card0/device/hwmon/hwmon1/pwm1 cat /sys/class/drm/card0/device/hwmon/hwmon1/pwm1 255 Other info: Hardware: MSI RX480 Gaming (Polaris) Kernel: linux 5.0.2 Please, let me know if more info is needed. Thanks. -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 106571] Stoney [Radeon R5 Graphics] [1002:98E4] hangs on hibernate
https://bugs.freedesktop.org/show_bug.cgi?id=106571 --- Comment #3 from ukbeas...@protonmail.com --- Created attachment 143742 --> https://bugs.freedesktop.org/attachment.cgi?id=143742=edit Hardware list Tested 5.1-rc1, Lenovo laptop will hang after waking from suspend. -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
On Wed, Mar 20, 2019 at 12:30:25PM -0400, Nicolas Dufresne wrote: > Le mercredi 20 mars 2019 à 18:09 +0200, Ville Syrjälä a écrit : > > On Wed, Mar 20, 2019 at 11:51:58AM -0400, Nicolas Dufresne wrote: > > > Le mercredi 20 mars 2019 à 16:27 +0200, Ville Syrjälä a écrit : > > > > On Tue, Mar 19, 2019 at 07:29:18PM -0400, Nicolas Dufresne wrote: > > > > > Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit : > > > > > > V4L2 uses different fourcc's than DRM, and has a different set of > > > > > > formats. > > > > > > For now, let's add the v4l2 fourcc's for the already existing > > > > > > formats. > > > > > > > > > > > > Signed-off-by: Maxime Ripard > > > > > > --- > > > > > > include/linux/image-formats.h | 9 +- > > > > > > lib/image-formats.c | 67 > > > > > > - > > > > > > 2 files changed, 76 insertions(+) > > > > > > > > > > > > diff --git a/include/linux/image-formats.h > > > > > > b/include/linux/image-formats.h > > > > > > index 53fd73a71b3d..fbc3a4501ebd 100644 > > > > > > --- a/include/linux/image-formats.h > > > > > > +++ b/include/linux/image-formats.h > > > > > > @@ -26,6 +26,13 @@ struct image_format_info { > > > > > > }; > > > > > > > > > > > > /** > > > > > > +* @v4l2_fmt: > > > > > > +* > > > > > > +* V4L2 4CC format identifier (V4L2_PIX_FMT_*) > > > > > > +*/ > > > > > > + u32 v4l2_fmt; > > > > > > + > > > > > > + /** > > > > > > * @depth: > > > > > > * > > > > > > * Color depth (number of bits per pixel excluding padding > > > > > > bits), > > > > > > @@ -222,6 +229,8 @@ image_format_info_is_yuv_sampling_444(const > > > > > > struct image_format_info *info) > > > > > > > > > > > > const struct image_format_info *__image_format_drm_lookup(u32 drm); > > > > > > const struct image_format_info *image_format_drm_lookup(u32 drm); > > > > > > +const struct image_format_info *__image_format_v4l2_lookup(u32 > > > > > > v4l2); > > > > > > +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2); > > > > > > unsigned int image_format_plane_cpp(const struct image_format_info > > > > > > *format, > > > > > > int plane); > > > > > > unsigned int image_format_plane_width(int width, > > > > > > diff --git a/lib/image-formats.c b/lib/image-formats.c > > > > > > index 9b9a73220c5d..39f1d38ae861 100644 > > > > > > --- a/lib/image-formats.c > > > > > > +++ b/lib/image-formats.c > > > > > > @@ -8,6 +8,7 @@ > > > > > > static const struct image_format_info formats[] = { > > > > > > { > > > > > > .drm_fmt = DRM_FORMAT_C8, > > > > > > + .v4l2_fmt = V4L2_PIX_FMT_GREY, > > > > > > .depth = 8, > > > > > > .num_planes = 1, > > > > > > .cpp = { 1, 0, 0 }, > > > > > > @@ -15,6 +16,7 @@ static const struct image_format_info formats[] = > > > > > > { > > > > > > .vsub = 1, > > > > > > }, { > > > > > > .drm_fmt = DRM_FORMAT_RGB332, > > > > > > + .v4l2_fmt = V4L2_PIX_FMT_RGB332, > > > > > > .depth = 8, > > > > > > .num_planes = 1, > > > > > > .cpp = { 1, 0, 0 }, > > > > > > @@ -29,6 +31,7 @@ static const struct image_format_info formats[] = > > > > > > { > > > > > > .vsub = 1, > > > > > > }, { > > > > > > .drm_fmt = DRM_FORMAT_XRGB, > > > > > > + .v4l2_fmt = V4L2_PIX_FMT_XRGB444, > > > > > > .depth = 0, > > > > > > .num_planes = 1, > > > > > > .cpp = { 2, 0, 0 }, > > > > > > @@ -57,6 +60,7 @@ static const struct image_format_info formats[] = > > > > > > { > > > > > > .vsub = 1, > > > > > > }, { > > > > > > .drm_fmt = DRM_FORMAT_ARGB, > > > > > > + .v4l2_fmt = V4L2_PIX_FMT_ARGB444, > > > > > > .depth = 0, > > > > > > .num_planes = 1, > > > > > > .cpp = { 2, 0, 0 }, > > > > > > @@ -89,6 +93,7 @@ static const struct image_format_info formats[] = > > > > > > { > > > > > > .has_alpha = true, > > > > > > }, { > > > > > > .drm_fmt = DRM_FORMAT_XRGB1555, > > > > > > + .v4l2_fmt = V4L2_PIX_FMT_XRGB555, > > > > > > .depth = 15, > > > > > > .num_planes = 1, > > > > > > .cpp = { 2, 0, 0 }, > > > > > > @@ -117,6 +122,7 @@ static const struct image_format_info formats[] > > > > > > = { > > > > > > .vsub = 1, > > > > > > }, { > > > > > > .drm_fmt = DRM_FORMAT_ARGB1555, > > > > > > + .v4l2_fmt = V4L2_PIX_FMT_ARGB555, > > > > > > .depth = 15, > > > > > > .num_planes = 1, > > > > > > .cpp = { 2, 0, 0 }, > > > > > > @@ -149,6 +155,7 @@ static const struct image_format_info formats[] > > > > > > = { > > > > > > .has_alpha = true, > > > > > > }, { > > > > > > .drm_fmt = DRM_FORMAT_RGB565, > > > > > > +
[Bug 109526] [CARRIZO] amdgpu fails to resume from S3, atombios stuck executing C554 (len 629, WS 0, PS 0)
https://bugs.freedesktop.org/show_bug.cgi?id=109526 --- Comment #4 from Johannes Hirte --- Anything I can do help debugging this? It's still an issue with 5.1-rc1 and really annoying. -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC][PATCH 0/5 v2] DMA-BUF Heaps (destaging ION)
On Wed, Mar 20, 2019 at 2:16 AM Benjamin Gaignard wrote: > Le mar. 19 mars 2019 à 23:36, John Stultz a écrit : > > On Tue, Mar 19, 2019 at 2:58 PM Rob Clark wrote: > > > For at least some hw the importing driver needs to configure things > > > differently for secure buffers :-/ > > > > Does the import ioctl need/use a flag for that then? Userland already > > has to keep meta-data about dmabufs around. > > To secure a buffer you need to know who is allowed to write/read it and > hardware block involved in the dataflow may need to know that the buffer > is secure to configure themself. > As example for a video decoding you allow hw video decoder to read in > a buffer and display to read it. You can also allow cpu to write on the buffer > to add subtitles. For that we need to be able to mmap/kmap the buffer. > Using a carveout heap for secure buffer mean that you reserved a large > memory region only for this purpose, that isn't possible on embedded device > where we are always limited in memory so we use CMA. > In the past I have used dmabuf's attach function to know who write into > the buffer and then configure who will be able to read it. It was working well > but the issue was how to in generic way this behavior. Given the complexity of the configuration needed when allocating the buffer, instead of trying to make a generic secure buffer allocator, would having per-usege heaps make sense? It just feels there are so many specifics to the secure buffer setup and configuration that maybe there can't be a generic configuration interface. So instead maybe we let the heap implementations provide set usage configs? This doesn't necessarily require that you have separate pools of memory (they can share the same backing store), but by having multiple per-config heap devices, maybe this could avoid trying to fit all the options into one interface? On the import side, I'm not sure how much the importing device needs to know about the specific rules here (out side of "secure buffer" or not), so maybe that's another catch. thanks -john ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
On Wed, Mar 20, 2019 at 11:51:58AM -0400, Nicolas Dufresne wrote: > Le mercredi 20 mars 2019 à 16:27 +0200, Ville Syrjälä a écrit : > > On Tue, Mar 19, 2019 at 07:29:18PM -0400, Nicolas Dufresne wrote: > > > Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit : > > > > V4L2 uses different fourcc's than DRM, and has a different set of > > > > formats. > > > > For now, let's add the v4l2 fourcc's for the already existing formats. > > > > > > > > Signed-off-by: Maxime Ripard > > > > --- > > > > include/linux/image-formats.h | 9 +- > > > > lib/image-formats.c | 67 > > > > - > > > > 2 files changed, 76 insertions(+) > > > > > > > > diff --git a/include/linux/image-formats.h > > > > b/include/linux/image-formats.h > > > > index 53fd73a71b3d..fbc3a4501ebd 100644 > > > > --- a/include/linux/image-formats.h > > > > +++ b/include/linux/image-formats.h > > > > @@ -26,6 +26,13 @@ struct image_format_info { > > > > }; > > > > > > > > /** > > > > +* @v4l2_fmt: > > > > +* > > > > +* V4L2 4CC format identifier (V4L2_PIX_FMT_*) > > > > +*/ > > > > + u32 v4l2_fmt; > > > > + > > > > + /** > > > > * @depth: > > > > * > > > > * Color depth (number of bits per pixel excluding padding > > > > bits), > > > > @@ -222,6 +229,8 @@ image_format_info_is_yuv_sampling_444(const struct > > > > image_format_info *info) > > > > > > > > const struct image_format_info *__image_format_drm_lookup(u32 drm); > > > > const struct image_format_info *image_format_drm_lookup(u32 drm); > > > > +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2); > > > > +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2); > > > > unsigned int image_format_plane_cpp(const struct image_format_info > > > > *format, > > > > int plane); > > > > unsigned int image_format_plane_width(int width, > > > > diff --git a/lib/image-formats.c b/lib/image-formats.c > > > > index 9b9a73220c5d..39f1d38ae861 100644 > > > > --- a/lib/image-formats.c > > > > +++ b/lib/image-formats.c > > > > @@ -8,6 +8,7 @@ > > > > static const struct image_format_info formats[] = { > > > > { > > > > .drm_fmt = DRM_FORMAT_C8, > > > > + .v4l2_fmt = V4L2_PIX_FMT_GREY, > > > > .depth = 8, > > > > .num_planes = 1, > > > > .cpp = { 1, 0, 0 }, > > > > @@ -15,6 +16,7 @@ static const struct image_format_info formats[] = { > > > > .vsub = 1, > > > > }, { > > > > .drm_fmt = DRM_FORMAT_RGB332, > > > > + .v4l2_fmt = V4L2_PIX_FMT_RGB332, > > > > .depth = 8, > > > > .num_planes = 1, > > > > .cpp = { 1, 0, 0 }, > > > > @@ -29,6 +31,7 @@ static const struct image_format_info formats[] = { > > > > .vsub = 1, > > > > }, { > > > > .drm_fmt = DRM_FORMAT_XRGB, > > > > + .v4l2_fmt = V4L2_PIX_FMT_XRGB444, > > > > .depth = 0, > > > > .num_planes = 1, > > > > .cpp = { 2, 0, 0 }, > > > > @@ -57,6 +60,7 @@ static const struct image_format_info formats[] = { > > > > .vsub = 1, > > > > }, { > > > > .drm_fmt = DRM_FORMAT_ARGB, > > > > + .v4l2_fmt = V4L2_PIX_FMT_ARGB444, > > > > .depth = 0, > > > > .num_planes = 1, > > > > .cpp = { 2, 0, 0 }, > > > > @@ -89,6 +93,7 @@ static const struct image_format_info formats[] = { > > > > .has_alpha = true, > > > > }, { > > > > .drm_fmt = DRM_FORMAT_XRGB1555, > > > > + .v4l2_fmt = V4L2_PIX_FMT_XRGB555, > > > > .depth = 15, > > > > .num_planes = 1, > > > > .cpp = { 2, 0, 0 }, > > > > @@ -117,6 +122,7 @@ static const struct image_format_info formats[] = { > > > > .vsub = 1, > > > > }, { > > > > .drm_fmt = DRM_FORMAT_ARGB1555, > > > > + .v4l2_fmt = V4L2_PIX_FMT_ARGB555, > > > > .depth = 15, > > > > .num_planes = 1, > > > > .cpp = { 2, 0, 0 }, > > > > @@ -149,6 +155,7 @@ static const struct image_format_info formats[] = { > > > > .has_alpha = true, > > > > }, { > > > > .drm_fmt = DRM_FORMAT_RGB565, > > > > + .v4l2_fmt = V4L2_PIX_FMT_RGB565, > > > > .depth = 16, > > > > .num_planes = 1, > > > > .cpp = { 2, 0, 0 }, > > > > @@ -163,6 +170,7 @@ static const struct image_format_info formats[] = { > > > > .vsub = 1, > > > > }, { > > > > .drm_fmt = DRM_FORMAT_RGB888, > > > > + .v4l2_fmt = V4L2_PIX_FMT_RGB24, > > > >
Re: [PATCH] drm/fourcc: Fix conflicting Y41x definitions
Op 20-03-2019 om 16:48 schreef Adam Jackson: > On Tue, 2019-03-19 at 13:17 +0100, Maarten Lankhorst wrote: >> There has unfortunately been a conflict with the following 3 commits: >> >> commit e9961ab95af81b8d29054361cd5f0c575102cf87 >> Author: Ayan Kumar Halder >> Date: Fri Nov 9 17:21:12 2018 + >> drm: Added a new format DRM_FORMAT_XVYU2101010 >> >> commit 7ba0fee247ee7a36b3bfbed68f6988d980aa3aa3 >> Author: Brian Starkey >> Date: Fri Oct 5 10:27:00 2018 +0100 >> >> drm/fourcc: Add AFBC yuv fourccs for Mali >> >> and >> >> commit 50bf5d7d595fd0705ef3785f80e679b6da501e5b >> Author: Swati Sharma >> Date: Mon Mar 4 17:26:33 2019 +0530 >> >> drm: Add Y2xx and Y4xx (xx:10/12/16) format definitions and fourcc >> >> Unfortunately gcc didn't warn about the redefinitions, because the >> > ... sentence got cut off here. > > - ajax > ... double defines were the set to same value, and gcc apparently no longer warns about that. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC][PATCH 0/5 v2] DMA-BUF Heaps (destaging ION)
Le mer. 20 mars 2019 à 15:54, Andrew F. Davis a écrit : > > On 3/20/19 4:16 AM, Benjamin Gaignard wrote: > > Le mar. 19 mars 2019 à 23:36, John Stultz a écrit : > >> > >> On Tue, Mar 19, 2019 at 2:58 PM Rob Clark wrote: > >>> > >>> On Tue, Mar 19, 2019 at 1:00 PM Andrew F. Davis wrote: > > On 3/19/19 11:54 AM, Benjamin Gaignard wrote: > > Le mer. 13 mars 2019 à 23:31, John Stultz a > > écrit : > >> > >> On Wed, Mar 13, 2019 at 1:11 PM Liam Mark wrote: > >>> On Tue, 5 Mar 2019, John Stultz wrote: > > Eventual TODOS: > * Reimplement page-pool for system heap (working on this) > * Add stats accounting to system/cma heaps > * Make the kselftest actually useful > * Add other heaps folks see as useful (would love to get > some help from actual carveout/chunk users)! > >>> > >>> We use a modified carveout heap for certain secure use cases. > >> > >> Cool! It would be great to see if you have any concerns about adding > >> such a secure-carveout heap to this framework. I suspect it would be > >> fairly similar to how its integrated into ION, but particularly I'd be > >> interested in issues around the lack of private flags and other > >> allocation arguments like alignment. > >> > >>> Although there would probably be some benefit in discssing how the > >>> dma-buf > >>> heap framework may want to support > >>> secure heaps in the future it is a large topic which I assume you > >>> don't > >>> want to tackle now. > >> > >> So I suspect others (Benjamin?) would have a more informed opinion on > >> the details, but the intent is to allow secure heap implementations. > >> I'm not sure what areas of concern you have for this allocation > >> framework in particular? > > > > yes I would be great to understand how you provide the information to > > tell that a dmabuf > > is secure (or not) since we can't add flag in dmabuf structure itself. > > An option is manage > > the access rights when a device attach itself to the dmabuf but in > > this case you need define > > a list of allowed devices per heap... > > If you have a good solution for secure heaps you are welcome :-) > > > > Do we really need any of that? A secure buffer is secured by the > hardware firewalls that keep out certain IP (including often the > processor running Linux). So the only thing we need to track internally > is that we should not allow mmap/kmap on the buffer. That can be done in > the per-heap layer, everything else stays the same as a standard > carveout heap. > >>> > >>> For at least some hw the importing driver needs to configure things > >>> differently for secure buffers :-/ > >> > >> Does the import ioctl need/use a flag for that then? Userland already > >> has to keep meta-data about dmabufs around. > > > > To secure a buffer you need to know who is allowed to write/read it and > > hardware block involved in the dataflow may need to know that the buffer > > is secure to configure themself. > > As example for a video decoding you allow hw video decoder to read in > > a buffer and display to read it. You can also allow cpu to write on the > > buffer > > to add subtitles. For that we need to be able to mmap/kmap the buffer. > > Using a carveout heap for secure buffer mean that you reserved a large > > memory region only for this purpose, that isn't possible on embedded device > > where we are always limited in memory so we use CMA. > > In the past I have used dmabuf's attach function to know who write into > > the buffer and then configure who will be able to read it. It was working > > well > > but the issue was how to in generic way this behavior. > > > > Okay, I think I see what you are saying now. > > The way we handle secure playback is to firewall everything upfront and > it is up to the application to inform the hardware about what it can and > cannot do to the buffer, or simply not ask anything not allowed (E.g. > writeback the decrypted stream) else it will get a firewall exception. > The buffer itself doesn't have to carry any information. > > It sounds like you want the hardware driver to be able to detect the > use-case based on the buffer itself and configure itself accordingly? Or > the exporter at attach time to check access permissions? Both are needed, the buffer client must know that it is a secure buffer and heap will have to configure the permissions. > > The first would need a change to DMA-BUF framework, maybe an added flag. Sumit will NACK that because dmabuf have to remain neutral and not embedded flags for every possible usage. > The second would just need a heap exporter with the system wide smarts, > but as you say that is not very generic.. yes it is difficult to find a good solution for that. > > Andrew > > >> > >> thanks > >> -john
[PATCH v2 1/2] drm/file: Rehabilitate the firstopen hook for non-legacy drivers
The firstopen DRM driver hook was initially used to perform hardware initialization, which is now considered legacy. Only a single user of firstopen remains at this point (savage). In some specific cases, non-legacy drivers may also need to implement these hooks. For instance on VC4, we need to allocate a 16 MiB buffer for the GPU. Because it's not required for fbcon, it's a waste to allocate it before userspace starts using the DRM device. Using firstopen and lastclose for this allocation seems like the best fit, so re-habilitate the hook to allow it to be called for non-legacy drivers. Signed-off-by: Paul Kocialkowski --- drivers/gpu/drm/drm_file.c | 3 +-- include/drm/drm_drv.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c index b1838a41ad43..c011b5cbfb6b 100644 --- a/drivers/gpu/drm/drm_file.c +++ b/drivers/gpu/drm/drm_file.c @@ -266,8 +266,7 @@ static int drm_setup(struct drm_device * dev) { int ret; - if (dev->driver->firstopen && - drm_core_check_feature(dev, DRIVER_LEGACY)) { + if (dev->driver->firstopen) { ret = dev->driver->firstopen(dev); if (ret != 0) return ret; diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index ca46a45a9cce..aa14607e54d4 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -236,7 +236,7 @@ struct drm_driver { * to set/unset the VT into raw mode. * * Legacy drivers initialize the hardware in the @firstopen callback, -* which isn't even called for modern drivers. +* modern drivers can use it for other purposes only. */ void (*lastclose) (struct drm_device *); -- 2.21.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 0/2] drm/vc4: Binner BO management improvements
Changes since v1: * Squashed the two final patches into one. Paul Kocialkowski (2): drm/file: Rehabilitate the firstopen hook for non-legacy drivers drm/vc4: Allocated/liberate the binner BO at firstopen/lastclose drivers/gpu/drm/drm_file.c| 3 +-- drivers/gpu/drm/vc4/vc4_drv.c | 26 ++ drivers/gpu/drm/vc4/vc4_drv.h | 1 + drivers/gpu/drm/vc4/vc4_irq.c | 3 +++ drivers/gpu/drm/vc4/vc4_v3d.c | 15 +-- include/drm/drm_drv.h | 2 +- 6 files changed, 33 insertions(+), 17 deletions(-) -- 2.21.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/fourcc: Fix conflicting Y41x definitions
On Tue, 2019-03-19 at 13:17 +0100, Maarten Lankhorst wrote: > There has unfortunately been a conflict with the following 3 commits: > > commit e9961ab95af81b8d29054361cd5f0c575102cf87 > Author: Ayan Kumar Halder > Date: Fri Nov 9 17:21:12 2018 + > drm: Added a new format DRM_FORMAT_XVYU2101010 > > commit 7ba0fee247ee7a36b3bfbed68f6988d980aa3aa3 > Author: Brian Starkey > Date: Fri Oct 5 10:27:00 2018 +0100 > > drm/fourcc: Add AFBC yuv fourccs for Mali > > and > > commit 50bf5d7d595fd0705ef3785f80e679b6da501e5b > Author: Swati Sharma > Date: Mon Mar 4 17:26:33 2019 +0530 > > drm: Add Y2xx and Y4xx (xx:10/12/16) format definitions and fourcc > > Unfortunately gcc didn't warn about the redefinitions, because the > ... sentence got cut off here. - ajax ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 2/2] drm/vc4: Allocated/liberate the binner BO at firstopen/lastclose
The binner BO is a pre-requisite to GPU operations, so we must ensure that it is always allocated when the GPU is in use. Currently, we are allocating it at probe time and liberating/allocating it during runtime pm cycles. First, since the binner buffer is only required for GPU rendering, it's a waste to allocate it when the driver probes since internal users of the driver (such as fbcon) won't try to use the GPU. Move the allocation/liberation to the firstopen/lastclose instead to only allocate it when userspace has opened the device and adapt the IRQ handler to return early when no binner BO was allocated yet. Second, because the buffer is allocated from the same pool as other GPU buffers, we might run into a situation where we are out of memory at runtime resume. This causes the binner BO allocation to fail and results in all subsequent operations to fail, resulting in a major hang in userspace. As a result, keep the buffer alive during runtime pm. Signed-off-by: Paul Kocialkowski --- drivers/gpu/drm/vc4/vc4_drv.c | 26 ++ drivers/gpu/drm/vc4/vc4_drv.h | 1 + drivers/gpu/drm/vc4/vc4_irq.c | 3 +++ drivers/gpu/drm/vc4/vc4_v3d.c | 15 +-- 4 files changed, 31 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 3227706700f9..605dc50613e3 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -134,6 +134,30 @@ static void vc4_close(struct drm_device *dev, struct drm_file *file) kfree(vc4file); } +static int vc4_firstopen(struct drm_device *drm) +{ + struct vc4_dev *vc4 = to_vc4_dev(drm); + int ret; + + if (!vc4->bin_bo) { + ret = vc4_allocate_bin_bo(drm); + if (ret) + return ret; + } + + return 0; +} + +static void vc4_lastclose(struct drm_device *drm) +{ + struct vc4_dev *vc4 = to_vc4_dev(drm); + + if (vc4->bin_bo) { + drm_gem_object_put_unlocked(>bin_bo->base.base); + vc4->bin_bo = NULL; + } +} + static const struct vm_operations_struct vc4_vm_ops = { .fault = vc4_fault, .open = drm_gem_vm_open, @@ -180,6 +204,8 @@ static struct drm_driver vc4_drm_driver = { DRIVER_SYNCOBJ), .open = vc4_open, .postclose = vc4_close, + .firstopen = vc4_firstopen, + .lastclose = vc4_lastclose, .irq_handler = vc4_irq, .irq_preinstall = vc4_irq_preinstall, .irq_postinstall = vc4_irq_postinstall, diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 7a3c093e7443..f52bb21e9885 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -808,6 +808,7 @@ extern struct platform_driver vc4_v3d_driver; int vc4_v3d_debugfs_ident(struct seq_file *m, void *unused); int vc4_v3d_debugfs_regs(struct seq_file *m, void *unused); int vc4_v3d_get_bin_slot(struct vc4_dev *vc4); +int vc4_allocate_bin_bo(struct drm_device *drm); /* vc4_validate.c */ int diff --git a/drivers/gpu/drm/vc4/vc4_irq.c b/drivers/gpu/drm/vc4/vc4_irq.c index 4cd2ccfe15f4..efaba2b02f6c 100644 --- a/drivers/gpu/drm/vc4/vc4_irq.c +++ b/drivers/gpu/drm/vc4/vc4_irq.c @@ -64,6 +64,9 @@ vc4_overflow_mem_work(struct work_struct *work) struct vc4_exec_info *exec; unsigned long irqflags; + if (!bo) + return; + bin_bo_slot = vc4_v3d_get_bin_slot(vc4); if (bin_bo_slot < 0) { DRM_ERROR("Couldn't allocate binner overflow mem\n"); diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c index e47e29426078..e04a51a75f01 100644 --- a/drivers/gpu/drm/vc4/vc4_v3d.c +++ b/drivers/gpu/drm/vc4/vc4_v3d.c @@ -218,7 +218,7 @@ int vc4_v3d_get_bin_slot(struct vc4_dev *vc4) * overall CMA pool before they make scenes complicated enough to run * out of bin space. */ -static int vc4_allocate_bin_bo(struct drm_device *drm) +int vc4_allocate_bin_bo(struct drm_device *drm) { struct vc4_dev *vc4 = to_vc4_dev(drm); struct vc4_v3d *v3d = vc4->v3d; @@ -303,9 +303,6 @@ static int vc4_v3d_runtime_suspend(struct device *dev) vc4_irq_uninstall(vc4->dev); - drm_gem_object_put_unlocked(>bin_bo->base.base); - vc4->bin_bo = NULL; - clk_disable_unprepare(v3d->clk); return 0; @@ -317,10 +314,6 @@ static int vc4_v3d_runtime_resume(struct device *dev) struct vc4_dev *vc4 = v3d->vc4; int ret; - ret = vc4_allocate_bin_bo(vc4->dev); - if (ret) - return ret; - ret = clk_prepare_enable(v3d->clk); if (ret != 0) return ret; @@ -384,12 +377,6 @@ static int vc4_v3d_bind(struct device *dev, struct device *master, void *data) if (ret != 0) return ret; - ret = vc4_allocate_bin_bo(drm); - if (ret) { - clk_disable_unprepare(v3d->clk); -
[RFC PATCH 3/3] mm: Add write-protect and clean utilities for address space ranges
Add two utilities to a) write-protect and b) clean all ptes pointing into a range of an address space The utilities are intended to aid in tracking dirty pages (either driver-allocated system memory or pci device memory). The write-protect utility should be used in conjunction with page_mkwrite() and pfn_mkwrite() to trigger write page-faults on page accesses. Typically one would want to use this on sparse accesses into large memory regions. The clean utility should be used to utilize hardware dirtying functionality and avoid the overhead of page-faults, typically on large accesses into small memory regions. Cc: Andrew Morton Cc: Matthew Wilcox Cc: Will Deacon Cc: Peter Zijlstra Cc: Rik van Riel Cc: Minchan Kim Cc: Michal Hocko Cc: Huang Ying Cc: Souptick Joarder Cc: "Jérôme Glisse" Cc: linux...@kvack.org Cc: linux-ker...@vger.kernel.org Signed-off-by: Thomas Hellstrom --- include/linux/mm.h | 9 +- mm/Makefile | 2 +- mm/apply_as_range.c | 257 3 files changed, 266 insertions(+), 2 deletions(-) create mode 100644 mm/apply_as_range.c diff --git a/include/linux/mm.h b/include/linux/mm.h index b7dd4ddd6efb..62f24dd0bfa0 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2642,7 +2642,14 @@ struct pfn_range_apply { }; extern int apply_to_pfn_range(struct pfn_range_apply *closure, unsigned long address, unsigned long size); - +unsigned long apply_as_wrprotect(struct address_space *mapping, +pgoff_t first_index, pgoff_t nr); +unsigned long apply_as_clean(struct address_space *mapping, +pgoff_t first_index, pgoff_t nr, +pgoff_t bitmap_pgoff, +unsigned long *bitmap, +pgoff_t *start, +pgoff_t *end); #ifdef CONFIG_PAGE_POISONING extern bool page_poisoning_enabled(void); extern void kernel_poison_pages(struct page *page, int numpages, int enable); diff --git a/mm/Makefile b/mm/Makefile index d210cc9d6f80..a94b78f12692 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -39,7 +39,7 @@ obj-y := filemap.o mempool.o oom_kill.o fadvise.o \ mm_init.o mmu_context.o percpu.o slab_common.o \ compaction.o vmacache.o \ interval_tree.o list_lru.o workingset.o \ - debug.o $(mmu-y) + debug.o apply_as_range.o $(mmu-y) obj-y += init-mm.o obj-y += memblock.o diff --git a/mm/apply_as_range.c b/mm/apply_as_range.c new file mode 100644 index ..9f03e272ebd0 --- /dev/null +++ b/mm/apply_as_range.c @@ -0,0 +1,257 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include +#include + +/** + * struct apply_as - Closure structure for apply_as_range + * @base: struct pfn_range_apply we derive from + * @start: Address of first modified pte + * @end: Address of last modified pte + 1 + * @total: Total number of modified ptes + * @vma: Pointer to the struct vm_area_struct we're currently operating on + * @flush_cache: Whether to call a cache flush before modifying a pte + * @flush_tlb: Whether to flush the tlb after modifying a pte + */ +struct apply_as { + struct pfn_range_apply base; + unsigned long start, end; + unsigned long total; + const struct vm_area_struct *vma; + u32 flush_cache : 1; + u32 flush_tlb : 1; +}; + +/** + * apply_pt_wrprotect - Leaf pte callback to write-protect a pte + * @pte: Pointer to the pte + * @token: Page table token, see apply_to_pfn_range() + * @addr: The virtual page address + * @closure: Pointer to a struct pfn_range_apply embedded in a + * struct apply_as + * + * The function write-protects a pte and records the range in + * virtual address space of touched ptes for efficient TLB flushes. + * + * Return: Always zero. + */ +static int apply_pt_wrprotect(pte_t *pte, pgtable_t token, + unsigned long addr, + struct pfn_range_apply *closure) +{ + struct apply_as *aas = container_of(closure, typeof(*aas), base); + + if (pte_write(*pte)) { + set_pte_at(closure->mm, addr, pte, pte_wrprotect(*pte)); + aas->total++; + if (addr < aas->start) + aas->start = addr; + if (addr + PAGE_SIZE > aas->end) + aas->end = addr + PAGE_SIZE; + } + + return 0; +} + +/** + * struct apply_as_clean - Closure structure for apply_as_clean + * @base: struct apply_as we derive from + * @bitmap_pgoff: Address_space Page offset of the first bit in @bitmap + * @bitmap: Bitmap with one bit for each page offset in the address_space range + * covered. + * @start: Address_space page offset of first modified pte + * @end: Address_space page offset of last modified
[RFC PATCH 1/3] mm: Allow the [page|pfn]_mkwrite callbacks to drop the mmap_sem
Driver fault callbacks are allowed to drop the mmap_sem when expecting long hardware waits to avoid blocking other mm users. Allow the mkwrite callbacks to do the same by returning early on VM_FAULT_RETRY. In particular we want to be able to drop the mmap_sem when waiting for a reservation object lock on a GPU buffer object. These locks may be held while waiting for the GPU. Cc: Andrew Morton Cc: Matthew Wilcox Cc: Will Deacon Cc: Peter Zijlstra Cc: Rik van Riel Cc: Minchan Kim Cc: Michal Hocko Cc: Huang Ying Cc: Souptick Joarder Cc: "Jérôme Glisse" Cc: linux...@kvack.org Cc: linux-ker...@vger.kernel.org Signed-off-by: Thomas Hellstrom --- mm/memory.c | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mm/memory.c b/mm/memory.c index a52663c0612d..dcd80313cf10 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2144,7 +2144,7 @@ static vm_fault_t do_page_mkwrite(struct vm_fault *vmf) ret = vmf->vma->vm_ops->page_mkwrite(vmf); /* Restore original flags so that caller is not surprised */ vmf->flags = old_flags; - if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE))) + if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_RETRY | VM_FAULT_NOPAGE))) return ret; if (unlikely(!(ret & VM_FAULT_LOCKED))) { lock_page(page); @@ -2419,7 +2419,7 @@ static vm_fault_t wp_pfn_shared(struct vm_fault *vmf) pte_unmap_unlock(vmf->pte, vmf->ptl); vmf->flags |= FAULT_FLAG_MKWRITE; ret = vma->vm_ops->pfn_mkwrite(vmf); - if (ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE)) + if (ret & (VM_FAULT_ERROR | VM_FAULT_RETRY | VM_FAULT_NOPAGE)) return ret; return finish_mkwrite_fault(vmf); } @@ -2440,7 +2440,8 @@ static vm_fault_t wp_page_shared(struct vm_fault *vmf) pte_unmap_unlock(vmf->pte, vmf->ptl); tmp = do_page_mkwrite(vmf); if (unlikely(!tmp || (tmp & - (VM_FAULT_ERROR | VM_FAULT_NOPAGE { + (VM_FAULT_ERROR | VM_FAULT_RETRY | + VM_FAULT_NOPAGE { put_page(vmf->page); return tmp; } @@ -3472,7 +3473,8 @@ static vm_fault_t do_shared_fault(struct vm_fault *vmf) unlock_page(vmf->page); tmp = do_page_mkwrite(vmf); if (unlikely(!tmp || - (tmp & (VM_FAULT_ERROR | VM_FAULT_NOPAGE { + (tmp & (VM_FAULT_ERROR | VM_FAULT_RETRY | + VM_FAULT_NOPAGE { put_page(vmf->page); return tmp; } -- 2.19.0.rc1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH 2/3] mm: Add an apply_to_pfn_range interface
This is basically apply_to_page_range with added functionality: Allocating missing parts of the page table becomes optional, which means that the function can be guaranteed not to error if allocation is disabled. Also passing of the closure struct and callback function becomes different and more in line with how things are done elsewhere. Finally we keep apply_to_page_range as a wrapper around apply_to_pfn_range Cc: Andrew Morton Cc: Matthew Wilcox Cc: Will Deacon Cc: Peter Zijlstra Cc: Rik van Riel Cc: Minchan Kim Cc: Michal Hocko Cc: Huang Ying Cc: Souptick Joarder Cc: "Jérôme Glisse" Cc: linux...@kvack.org Cc: linux-ker...@vger.kernel.org Signed-off-by: Thomas Hellstrom --- include/linux/mm.h | 10 mm/memory.c| 121 + 2 files changed, 99 insertions(+), 32 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index 80bb6408fe73..b7dd4ddd6efb 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2632,6 +2632,16 @@ typedef int (*pte_fn_t)(pte_t *pte, pgtable_t token, unsigned long addr, extern int apply_to_page_range(struct mm_struct *mm, unsigned long address, unsigned long size, pte_fn_t fn, void *data); +struct pfn_range_apply; +typedef int (*pter_fn_t)(pte_t *pte, pgtable_t token, unsigned long addr, +struct pfn_range_apply *closure); +struct pfn_range_apply { + struct mm_struct *mm; + pter_fn_t ptefn; + unsigned int alloc; +}; +extern int apply_to_pfn_range(struct pfn_range_apply *closure, + unsigned long address, unsigned long size); #ifdef CONFIG_PAGE_POISONING extern bool page_poisoning_enabled(void); diff --git a/mm/memory.c b/mm/memory.c index dcd80313cf10..0feb7191c2d2 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1938,18 +1938,17 @@ int vm_iomap_memory(struct vm_area_struct *vma, phys_addr_t start, unsigned long } EXPORT_SYMBOL(vm_iomap_memory); -static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd, -unsigned long addr, unsigned long end, -pte_fn_t fn, void *data) +static int apply_to_pte_range(struct pfn_range_apply *closure, pmd_t *pmd, + unsigned long addr, unsigned long end) { pte_t *pte; int err; pgtable_t token; spinlock_t *uninitialized_var(ptl); - pte = (mm == _mm) ? + pte = (closure->mm == _mm) ? pte_alloc_kernel(pmd, addr) : - pte_alloc_map_lock(mm, pmd, addr, ); + pte_alloc_map_lock(closure->mm, pmd, addr, ); if (!pte) return -ENOMEM; @@ -1960,86 +1959,103 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd, token = pmd_pgtable(*pmd); do { - err = fn(pte++, token, addr, data); + err = closure->ptefn(pte++, token, addr, closure); if (err) break; } while (addr += PAGE_SIZE, addr != end); arch_leave_lazy_mmu_mode(); - if (mm != _mm) + if (closure->mm != _mm) pte_unmap_unlock(pte-1, ptl); return err; } -static int apply_to_pmd_range(struct mm_struct *mm, pud_t *pud, -unsigned long addr, unsigned long end, -pte_fn_t fn, void *data) +static int apply_to_pmd_range(struct pfn_range_apply *closure, pud_t *pud, + unsigned long addr, unsigned long end) { pmd_t *pmd; unsigned long next; - int err; + int err = 0; BUG_ON(pud_huge(*pud)); - pmd = pmd_alloc(mm, pud, addr); + pmd = pmd_alloc(closure->mm, pud, addr); if (!pmd) return -ENOMEM; + do { next = pmd_addr_end(addr, end); - err = apply_to_pte_range(mm, pmd, addr, next, fn, data); + if (!closure->alloc && pmd_none_or_clear_bad(pmd)) + continue; + err = apply_to_pte_range(closure, pmd, addr, next); if (err) break; } while (pmd++, addr = next, addr != end); return err; } -static int apply_to_pud_range(struct mm_struct *mm, p4d_t *p4d, -unsigned long addr, unsigned long end, -pte_fn_t fn, void *data) +static int apply_to_pud_range(struct pfn_range_apply *closure, p4d_t *p4d, + unsigned long addr, unsigned long end) { pud_t *pud; unsigned long next; - int err; + int err = 0; - pud = pud_alloc(mm, p4d, addr); + pud = pud_alloc(closure->mm, p4d, addr); if (!pud) return -ENOMEM; + do { next = pud_addr_end(addr, end); - err = apply_to_pmd_range(mm,
[RFC PATCH 0/3] mm modifications / helpers for emulated GPU coherent memory
Cc: Andrew Morton Cc: Matthew Wilcox Cc: Will Deacon Cc: Peter Zijlstra Cc: Rik van Riel Cc: Minchan Kim Cc: Michal Hocko Cc: Huang Ying Cc: Souptick Joarder Cc: "Jérôme Glisse" Cc: linux...@kvack.org Cc: linux-ker...@vger.kernel.org Hi, This is an early RFC to make sure I don't go too far in the wrong direction. Non-coherent GPUs that can't directly see contents in CPU-visible memory, like VMWare's SVGA device, run into trouble when trying to implement coherent memory requirements of modern graphics APIs. Examples are Vulkan and OpenGL 4.4's ARB_buffer_storage. To remedy, we need to emulate coherent memory. Typically when it's detected that a buffer object is about to be accessed by the GPU, we need to gather the ranges that have been dirtied by the CPU since the last operation, apply an operation to make the content visible to the GPU and clear the the dirty tracking. Depending on the size of the buffer object and the access pattern there are two major possibilities: 1) Use page_mkwrite() and pfn_mkwrite(). (GPU buffer objects are backed either by PCI device memory or by driver-alloced pages). The dirty-tracking needs to be reset by write-protecting the affected ptes and flush tlb. This has a complexity of O(num_dirty_pages), but the write page-fault is of course costly. 2) Use hardware dirty-flags in the ptes. The dirty-tracking needs to be reset by clearing the dirty bits and flush tlb. This has a complexity of O(num_buffer_object_pages) and dirty bits need to be scanned in full before each gpu-access. So in practice the two methods need to be interleaved for best performance. So to facilitate this, I propose two new helpers, apply_as_wrprotect() and apply_as_clean() ("as" stands for address-space) both inspired by unmap_mapping_range(). Users of these helpers are in the making, but needs some cleaning-up. There's also a change to x_mkwrite() to allow dropping the mmap_sem while waiting. Any comments or suggestions appreciated. Thanks, Thomas ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 3/3] drm/vc4: Don't liberate the binner BO at runtime suspend
Hi, Le samedi 16 mars 2019 à 11:58 -0700, Eric Anholt a écrit : > Paul Kocialkowski writes: > > > The binner BO is a pre-requisite to GPU operations, so we must ensure > > that it is always allocated when the GPU is in use. > > > > Because the buffer is allocated from the same pool as other GPU buffers, > > we might run into a situation where we are out of memory at runtime > > resume. This causes the binner BO allocation to fail and results in all > > subsequent operations to fail, resulting in a major hang in userspace. > > > > Now that we allocate the buffer at firstopen and liberate it at > > lastclose, we can just keep it alive during runtime suspend. > > I think this needs to be squashed into the previous patch, as otherwise > coming from suspended, a firstopen -> resume -> render will leak a copy > of the bin BO. Woops, you're definitely right: vc4_allocate_bin_bo won't check whether we already have allocated it or not. I'll send a new version with both patches squashed. Cheers, Paul -- Paul Kocialkowski, Bootlin Embedded Linux and kernel engineering https://bootlin.com ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 102646] Screen flickering under amdgpu-experimental [buggy auto power profile]
https://bugs.freedesktop.org/show_bug.cgi?id=102646 George Scorer changed: What|Removed |Added Priority|low |high Severity|minor |major -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 102646] Screen flickering under amdgpu-experimental [buggy auto power profile]
https://bugs.freedesktop.org/show_bug.cgi?id=102646 George Scorer changed: What|Removed |Added Priority|high|low Severity|major |minor --- Comment #70 from George Scorer --- Building on julien tempel's workaround, here's a somewhat more complex script to manage the memory p-state jumps. It switches between low and high memory p-states very reluctantly, so minimizing instances of flickering. I'm not a bash expert so please excuse the clumsy coding, but this works for me. #!/bin/bash # Each memory p-state switch causes a screen flicker. Tweak these variables to match # your personal 'flicker aversion' vs efficiency trade-off. CORE_P_STATE_UP=6# The gpu core p-state at which we should jump up to memory p-state 2 CORE_P_STATE_DOWN=1 # The gpu core p-state at which we should drop down to low memory p-state UP_DELAY=2 # in seconds. How long to stay in low memory p-state before checking whether we can jump up to 2. DOWN_DELAY=10# in seconds. How long to stay in memory p-state 2 before checking whether we can drop down to low. SLEEP_INTERVAL=1 # in seconds. How frequently we should poll the core p-state. LOW_MEM_STATE=0 # Choose between 0 & 1 # Sysfs paths here are hardcoded for one amdgpu card at card0; adjust as needed. FILE_PERF_LEVEL=/sys/class/drm/card0/device/power_dpm_force_performance_level FILE_MEM_P_STATE=/sys/class/drm/card0/device/pp_dpm_mclk FILE_CORE_P_STATE=/sys/class/drm/card0/device/pp_dpm_sclk # check for root privileges if [ $UID -ne 0 ] then echo "Writing to sysfs requires root privileges; relaunch as root" exit 1 fi # Set gpu performance level control to manual # echo "Setting performance level control to manual" echo "manual" > "$FILE_PERF_LEVEL" # Read the current core p-state and set a corresponding initial memory p-state CORE_P_STATE="$(grep -F '*' $FILE_CORE_P_STATE)" CORE_P_STATE=${CORE_P_STATE:0:1} if [ "$CORE_P_STATE" -ge "$CORE_P_STATE_UP" ]; then MEM_P_STATE=2 else MEM_P_STATE=$LOW_MEM_STATE fi echo "$MEM_P_STATE" > "$FILE_MEM_P_STATE" PROPOSED_MEM_P_STATE=$MEM_P_STATE function check_core_p_state { CORE_P_STATE="$(grep -F '*' $FILE_CORE_P_STATE)" CORE_P_STATE=${CORE_P_STATE:0:1} # Propose what the corresponding memory p-state should be OLD_PROPOSED_MEM_P_STATE=$PROPOSED_MEM_P_STATE PROPOSED_MEM_P_STATE=$MEM_P_STATE if [ "$CORE_P_STATE" -ge "$CORE_P_STATE_UP" ]; then PROPOSED_MEM_P_STATE=2 elif [ "$CORE_P_STATE" -le "$CORE_P_STATE_DOWN" ]; then PROPOSED_MEM_P_STATE=$LOW_MEM_STATE fi if [ "$PROPOSED_MEM_P_STATE" -ne "$MEM_P_STATE" ]; then # We want to change so determine where we are in the countdown. if [ "$PROPOSED_MEM_P_STATE" -ne "$OLD_PROPOSED_MEM_P_STATE" ]; then if [ "$PROPOSED_MEM_P_STATE" -eq 2 ]; then CHANGE_COUNTDOWN=$UP_DELAY else CHANGE_COUNTDOWN=$DOWN_DELAY fi fi (( CHANGE_COUNTDOWN = $CHANGE_COUNTDOWN - $SLEEP_INTERVAL )) if [ $CHANGE_COUNTDOWN -le 0 ]; then # The countdown has reached 0 so change the memory p-state. MEM_P_STATE=$PROPOSED_MEM_P_STATE echo "$MEM_P_STATE" > "$FILE_MEM_P_STATE" fi # else # we don't want to change. fi #echo "Old Prop Mem Core Countdown" #echo " $OLD_PROPOSED_MEM_P_STATE $PROPOSED_MEM_P_STATE $MEM_P_STATE $CORE_P_STATE $CHANGE_COUNTDOWN" #echo "" } function reset_on_fail { echo "Exiting, setting memory p-state to 2" echo "manual" > "$FILE_PERF_LEVEL" echo "2" > "$FILE_MEM_P_STATE" exit 1 } # always try to fix memory p-state 2 on failure trap "reset_on_fail" SIGINT SIGTERM function run_daemon { while :; do sleep $SLEEP_INTERVAL check_core_p_state done } # start the loop run_daemon -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC][PATCH 0/5 v2] DMA-BUF Heaps (destaging ION)
On 3/20/19 4:16 AM, Benjamin Gaignard wrote: > Le mar. 19 mars 2019 à 23:36, John Stultz a écrit : >> >> On Tue, Mar 19, 2019 at 2:58 PM Rob Clark wrote: >>> >>> On Tue, Mar 19, 2019 at 1:00 PM Andrew F. Davis wrote: On 3/19/19 11:54 AM, Benjamin Gaignard wrote: > Le mer. 13 mars 2019 à 23:31, John Stultz a > écrit : >> >> On Wed, Mar 13, 2019 at 1:11 PM Liam Mark wrote: >>> On Tue, 5 Mar 2019, John Stultz wrote: Eventual TODOS: * Reimplement page-pool for system heap (working on this) * Add stats accounting to system/cma heaps * Make the kselftest actually useful * Add other heaps folks see as useful (would love to get some help from actual carveout/chunk users)! >>> >>> We use a modified carveout heap for certain secure use cases. >> >> Cool! It would be great to see if you have any concerns about adding >> such a secure-carveout heap to this framework. I suspect it would be >> fairly similar to how its integrated into ION, but particularly I'd be >> interested in issues around the lack of private flags and other >> allocation arguments like alignment. >> >>> Although there would probably be some benefit in discssing how the >>> dma-buf >>> heap framework may want to support >>> secure heaps in the future it is a large topic which I assume you don't >>> want to tackle now. >> >> So I suspect others (Benjamin?) would have a more informed opinion on >> the details, but the intent is to allow secure heap implementations. >> I'm not sure what areas of concern you have for this allocation >> framework in particular? > > yes I would be great to understand how you provide the information to > tell that a dmabuf > is secure (or not) since we can't add flag in dmabuf structure itself. > An option is manage > the access rights when a device attach itself to the dmabuf but in > this case you need define > a list of allowed devices per heap... > If you have a good solution for secure heaps you are welcome :-) > Do we really need any of that? A secure buffer is secured by the hardware firewalls that keep out certain IP (including often the processor running Linux). So the only thing we need to track internally is that we should not allow mmap/kmap on the buffer. That can be done in the per-heap layer, everything else stays the same as a standard carveout heap. >>> >>> For at least some hw the importing driver needs to configure things >>> differently for secure buffers :-/ >> >> Does the import ioctl need/use a flag for that then? Userland already >> has to keep meta-data about dmabufs around. > > To secure a buffer you need to know who is allowed to write/read it and > hardware block involved in the dataflow may need to know that the buffer > is secure to configure themself. > As example for a video decoding you allow hw video decoder to read in > a buffer and display to read it. You can also allow cpu to write on the buffer > to add subtitles. For that we need to be able to mmap/kmap the buffer. > Using a carveout heap for secure buffer mean that you reserved a large > memory region only for this purpose, that isn't possible on embedded device > where we are always limited in memory so we use CMA. > In the past I have used dmabuf's attach function to know who write into > the buffer and then configure who will be able to read it. It was working well > but the issue was how to in generic way this behavior. > Okay, I think I see what you are saying now. The way we handle secure playback is to firewall everything upfront and it is up to the application to inform the hardware about what it can and cannot do to the buffer, or simply not ask anything not allowed (E.g. writeback the decrypted stream) else it will get a firewall exception. The buffer itself doesn't have to carry any information. It sounds like you want the hardware driver to be able to detect the use-case based on the buffer itself and configure itself accordingly? Or the exporter at attach time to check access permissions? The first would need a change to DMA-BUF framework, maybe an added flag. The second would just need a heap exporter with the system wide smarts, but as you say that is not very generic.. Andrew >> >> thanks >> -john ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] driver : staging : ion: optimization for decreasing memory fragmentaion
On 3/20/19 7:23 AM, Vlastimil Babka wrote: You should have CC'd the ION maintainers/lists per ./scripts/get_maintainer.pl - CCing now. On 3/14/19 12:06 PM, Zhaoyang Huang wrote: From: Zhaoyang Huang Two action for this patch: 1. set a batch size for system heap's shrinker, which can have it buffer reasonable page blocks in pool for future allocation. 2. reverse the order sequence when free page blocks, the purpose is also to have system heap keep as more big blocks as it can. By testing on an android system with 2G RAM, the changes with setting batch = 48MB can help reduce the fragmentation obviously and improve big block allocation speed for 15%. Signed-off-by: Zhaoyang Huang --- drivers/staging/android/ion/ion_heap.c| 12 +++- drivers/staging/android/ion/ion_system_heap.c | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c index 31db510..9e9caf2 100644 --- a/drivers/staging/android/ion/ion_heap.c +++ b/drivers/staging/android/ion/ion_heap.c @@ -16,6 +16,8 @@ #include #include "ion.h" +unsigned long ion_heap_batch = 0; + void *ion_heap_map_kernel(struct ion_heap *heap, struct ion_buffer *buffer) { @@ -303,7 +305,15 @@ int ion_heap_init_shrinker(struct ion_heap *heap) heap->shrinker.count_objects = ion_heap_shrink_count; heap->shrinker.scan_objects = ion_heap_shrink_scan; heap->shrinker.seeks = DEFAULT_SEEKS; - heap->shrinker.batch = 0; + heap->shrinker.batch = ion_heap_batch; return register_shrinker(>shrinker); } + +static int __init ion_system_heap_batch_init(char *arg) +{ +ion_heap_batch = memparse(arg, NULL); + + return 0; +} +early_param("ion_batch", ion_system_heap_batch_init); diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index 701eb9f..d249f8d 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -182,7 +182,7 @@ static int ion_system_heap_shrink(struct ion_heap *heap, gfp_t gfp_mask, if (!nr_to_scan) only_scan = 1; - for (i = 0; i < NUM_ORDERS; i++) { + for (i = NUM_ORDERS - 1; i >= 0; i--) { pool = sys_heap->pools[i]; if (only_scan) { We're in the process of significantly reworking Ion so I don't think it makes sense to take these as we work to get things out of staging. You can resubmit this later, but when you do please split this into two separate patches since it's actually two independent changes. Thanks, Laura ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC PATCH 05/20] drm: Replace instances of drm_format_info by drm_get_format_info
Hi, Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit : > drm_get_format_info directly calls into drm_format_info, but takes directly > a struct drm_mode_fb_cmd2 pointer, instead of the fourcc directly. It's > shorter to not dereference it, and we can customise the behaviour at the > driver level if we want to, so let's switch to it where it makes sense. > > Signed-off-by: Maxime Ripard Makes good sense to me! Reviewed-by: Paul Kocialkowski Cheers, Paul > --- > drivers/gpu/drm/gma500/framebuffer.c | 2 +- > drivers/gpu/drm/omapdrm/omap_fb.c| 2 +- > 2 files changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/gma500/framebuffer.c > b/drivers/gpu/drm/gma500/framebuffer.c > index c934b3df1f81..46f0078f7a91 100644 > --- a/drivers/gpu/drm/gma500/framebuffer.c > +++ b/drivers/gpu/drm/gma500/framebuffer.c > @@ -232,7 +232,7 @@ static int psb_framebuffer_init(struct drm_device *dev, >* Reject unknown formats, YUV formats, and formats with more than >* 4 bytes per pixel. >*/ > - info = drm_format_info(mode_cmd->pixel_format); > + info = drm_get_format_info(dev, mode_cmd); > if (!info || !info->depth || info->cpp[0] > 4) > return -EINVAL; > > diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c > b/drivers/gpu/drm/omapdrm/omap_fb.c > index cfb641363a32..6557b2d6e16e 100644 > --- a/drivers/gpu/drm/omapdrm/omap_fb.c > +++ b/drivers/gpu/drm/omapdrm/omap_fb.c > @@ -339,7 +339,7 @@ struct drm_framebuffer *omap_framebuffer_init(struct > drm_device *dev, > dev, mode_cmd, mode_cmd->width, mode_cmd->height, > (char *)_cmd->pixel_format); > > - format = drm_format_info(mode_cmd->pixel_format); > + format = drm_get_format_info(dev, mode_cmd); > > for (i = 0; i < ARRAY_SIZE(formats); i++) { > if (formats[i] == mode_cmd->pixel_format) -- Paul Kocialkowski, Bootlin Embedded Linux and kernel engineering https://bootlin.com ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
On Tue, Mar 19, 2019 at 07:29:18PM -0400, Nicolas Dufresne wrote: > Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit : > > V4L2 uses different fourcc's than DRM, and has a different set of formats. > > For now, let's add the v4l2 fourcc's for the already existing formats. > > > > Signed-off-by: Maxime Ripard > > --- > > include/linux/image-formats.h | 9 +- > > lib/image-formats.c | 67 - > > 2 files changed, 76 insertions(+) > > > > diff --git a/include/linux/image-formats.h b/include/linux/image-formats.h > > index 53fd73a71b3d..fbc3a4501ebd 100644 > > --- a/include/linux/image-formats.h > > +++ b/include/linux/image-formats.h > > @@ -26,6 +26,13 @@ struct image_format_info { > > }; > > > > /** > > +* @v4l2_fmt: > > +* > > +* V4L2 4CC format identifier (V4L2_PIX_FMT_*) > > +*/ > > + u32 v4l2_fmt; > > + > > + /** > > * @depth: > > * > > * Color depth (number of bits per pixel excluding padding bits), > > @@ -222,6 +229,8 @@ image_format_info_is_yuv_sampling_444(const struct > > image_format_info *info) > > > > const struct image_format_info *__image_format_drm_lookup(u32 drm); > > const struct image_format_info *image_format_drm_lookup(u32 drm); > > +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2); > > +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2); > > unsigned int image_format_plane_cpp(const struct image_format_info *format, > > int plane); > > unsigned int image_format_plane_width(int width, > > diff --git a/lib/image-formats.c b/lib/image-formats.c > > index 9b9a73220c5d..39f1d38ae861 100644 > > --- a/lib/image-formats.c > > +++ b/lib/image-formats.c > > @@ -8,6 +8,7 @@ > > static const struct image_format_info formats[] = { > > { > > .drm_fmt = DRM_FORMAT_C8, > > + .v4l2_fmt = V4L2_PIX_FMT_GREY, > > .depth = 8, > > .num_planes = 1, > > .cpp = { 1, 0, 0 }, > > @@ -15,6 +16,7 @@ static const struct image_format_info formats[] = { > > .vsub = 1, > > }, { > > .drm_fmt = DRM_FORMAT_RGB332, > > + .v4l2_fmt = V4L2_PIX_FMT_RGB332, > > .depth = 8, > > .num_planes = 1, > > .cpp = { 1, 0, 0 }, > > @@ -29,6 +31,7 @@ static const struct image_format_info formats[] = { > > .vsub = 1, > > }, { > > .drm_fmt = DRM_FORMAT_XRGB, > > + .v4l2_fmt = V4L2_PIX_FMT_XRGB444, > > .depth = 0, > > .num_planes = 1, > > .cpp = { 2, 0, 0 }, > > @@ -57,6 +60,7 @@ static const struct image_format_info formats[] = { > > .vsub = 1, > > }, { > > .drm_fmt = DRM_FORMAT_ARGB, > > + .v4l2_fmt = V4L2_PIX_FMT_ARGB444, > > .depth = 0, > > .num_planes = 1, > > .cpp = { 2, 0, 0 }, > > @@ -89,6 +93,7 @@ static const struct image_format_info formats[] = { > > .has_alpha = true, > > }, { > > .drm_fmt = DRM_FORMAT_XRGB1555, > > + .v4l2_fmt = V4L2_PIX_FMT_XRGB555, > > .depth = 15, > > .num_planes = 1, > > .cpp = { 2, 0, 0 }, > > @@ -117,6 +122,7 @@ static const struct image_format_info formats[] = { > > .vsub = 1, > > }, { > > .drm_fmt = DRM_FORMAT_ARGB1555, > > + .v4l2_fmt = V4L2_PIX_FMT_ARGB555, > > .depth = 15, > > .num_planes = 1, > > .cpp = { 2, 0, 0 }, > > @@ -149,6 +155,7 @@ static const struct image_format_info formats[] = { > > .has_alpha = true, > > }, { > > .drm_fmt = DRM_FORMAT_RGB565, > > + .v4l2_fmt = V4L2_PIX_FMT_RGB565, > > .depth = 16, > > .num_planes = 1, > > .cpp = { 2, 0, 0 }, > > @@ -163,6 +170,7 @@ static const struct image_format_info formats[] = { > > .vsub = 1, > > }, { > > .drm_fmt = DRM_FORMAT_RGB888, > > + .v4l2_fmt = V4L2_PIX_FMT_RGB24, > > .depth = 24, > > .num_planes = 1, > > .cpp = { 3, 0, 0 }, > > @@ -170,6 +178,7 @@ static const struct image_format_info formats[] = { > > .vsub = 1, > > }, { > > .drm_fmt = DRM_FORMAT_BGR888, > > + .v4l2_fmt = V4L2_PIX_FMT_BGR24, > > .depth = 24, > > .num_planes = 1, > > .cpp = { 3, 0, 0 }, > > @@ -177,6 +186,7 @@ static const struct image_format_info formats[] = { > > .vsub = 1, > > }, { > > .drm_fmt = DRM_FORMAT_XRGB, > > + .v4l2_fmt = V4L2_PIX_FMT_XRGB32, > > > All RGB mapping should be surrounded by ifdef, because many (not all) > DRM formats represent the order of component when placed in a CPU > register, unlike V4L2 which uses memory order. I've pick this one DRM formats are explicitly defined
Re: [RFC PATCH 04/20] drm/fourcc: Pass the format_info pointer to drm_format_plane_width/height
Hi, Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit : > So far, the drm_format_plane_height/width functions were operating on the > format's fourcc and was doing a lookup to retrieve the drm_format_info > structure and return the cpp. > > However, this is inefficient since in most cases, we will have the > drm_format_info pointer already available so we shouldn't have to perform a > new lookup. Some drm_fourcc functions also already operate on the > drm_format_info pointer for that reason, so the API is quite inconsistent > there. Same comment as for the previous patch, I think having a drm_format_info prefix and switching to an inline helper would make good sense. Cheers, Paul > Let's follow the latter pattern and remove the extra lookup while being a > bit more consistent. > > Signed-off-by: Maxime Ripard > --- > drivers/gpu/drm/drm_fourcc.c | 16 ++-- > drivers/gpu/drm/meson/meson_overlay.c | 6 +++--- > include/drm/drm_fourcc.h | 6 -- > 3 files changed, 13 insertions(+), 15 deletions(-) > > diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c > index d8ada4cb689e..57389b9753b2 100644 > --- a/drivers/gpu/drm/drm_fourcc.c > +++ b/drivers/gpu/drm/drm_fourcc.c > @@ -325,17 +325,15 @@ EXPORT_SYMBOL(drm_format_plane_cpp); > /** > * drm_format_plane_width - width of the plane given the first plane > * @width: width of the first plane > - * @format: pixel format > + * @format: pixel format info > * @plane: plane index > * > * Returns: > * The width of @plane, given that the width of the first plane is @width. > */ > -int drm_format_plane_width(int width, uint32_t format, int plane) > +int drm_format_plane_width(int width, const struct drm_format_info *info, > +int plane) > { > - const struct drm_format_info *info; > - > - info = drm_format_info(format); > if (!info || plane >= info->num_planes) > return 0; > > @@ -349,17 +347,15 @@ EXPORT_SYMBOL(drm_format_plane_width); > /** > * drm_format_plane_height - height of the plane given the first plane > * @height: height of the first plane > - * @format: pixel format > + * @format: pixel format info > * @plane: plane index > * > * Returns: > * The height of @plane, given that the height of the first plane is @height. > */ > -int drm_format_plane_height(int height, uint32_t format, int plane) > +int drm_format_plane_height(int height, const struct drm_format_info *info, > + int plane) > { > - const struct drm_format_info *info; > - > - info = drm_format_info(format); > if (!info || plane >= info->num_planes) > return 0; > > diff --git a/drivers/gpu/drm/meson/meson_overlay.c > b/drivers/gpu/drm/meson/meson_overlay.c > index 8ff15d01a8f9..6987c15b6ab9 100644 > --- a/drivers/gpu/drm/meson/meson_overlay.c > +++ b/drivers/gpu/drm/meson/meson_overlay.c > @@ -475,7 +475,7 @@ static void meson_overlay_atomic_update(struct drm_plane > *plane, > priv->viu.vd1_stride2 = fb->pitches[2]; > priv->viu.vd1_height2 = > drm_format_plane_height(fb->height, > - fb->format->format, 2); > + fb->format, 2); > DRM_DEBUG("plane 2 addr 0x%x stride %d height %d\n", >priv->viu.vd1_addr2, >priv->viu.vd1_stride2, > @@ -487,7 +487,7 @@ static void meson_overlay_atomic_update(struct drm_plane > *plane, > priv->viu.vd1_stride1 = fb->pitches[1]; > priv->viu.vd1_height1 = > drm_format_plane_height(fb->height, > - fb->format->format, 1); > + fb->format, 1); > DRM_DEBUG("plane 1 addr 0x%x stride %d height %d\n", >priv->viu.vd1_addr1, >priv->viu.vd1_stride1, > @@ -499,7 +499,7 @@ static void meson_overlay_atomic_update(struct drm_plane > *plane, > priv->viu.vd1_stride0 = fb->pitches[0]; > priv->viu.vd1_height0 = > drm_format_plane_height(fb->height, > - fb->format->format, 0); > + fb->format, 0); > DRM_DEBUG("plane 0 addr 0x%x stride %d height %d\n", >priv->viu.vd1_addr0, >priv->viu.vd1_stride0, > diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h > index 97a58f3e7462..2291f2618211 100644 > --- a/include/drm/drm_fourcc.h > +++ b/include/drm/drm_fourcc.h > @@ -269,8 +269,10 @@ uint32_t drm_mode_legacy_fb_format(uint32_t bpp, > uint32_t depth); > uint32_t drm_driver_legacy_fb_format(struct drm_device *dev, >uint32_t bpp, uint32_t depth); >
Re: [RFC PATCH 03/20] drm/fourcc: Pass the format_info pointer to drm_format_plane_cpp
Hi, Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit : > So far, the drm_format_plane_cpp function was operating on the format's > fourcc and was doing a lookup to retrieve the drm_format_info structure and > return the cpp. > > However, this is inefficient since in most cases, we will have the > drm_format_info pointer already available so we shouldn't have to perform a > new lookup. Some drm_fourcc functions also already operate on the > drm_format_info pointer for that reason, so the API is quite inconsistent > there. Well, it seems that drm_fourcc functions that take a drm_format_info have a drm_format_info prefix, so having this would be more consistent. And given what the helper does, I think it would make good sense to switch it over to an inline drm_format_info_plane_cpp helper. What do you think? Cheers, Paul > Let's follow the latter pattern and remove the extra lookup while being a > bit more consistent. > > Signed-off-by: Maxime Ripard > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 4 +++- > drivers/gpu/drm/arm/malidp_hw.c| 4 +++- > drivers/gpu/drm/cirrus/cirrus_fbdev.c | 4 +++- > drivers/gpu/drm/cirrus/cirrus_main.c | 4 +++- > drivers/gpu/drm/drm_client.c | 3 ++- > drivers/gpu/drm/drm_fb_helper.c| 2 +- > drivers/gpu/drm/drm_fourcc.c | 7 ++- > drivers/gpu/drm/i915/intel_sprite.c| 3 ++- > drivers/gpu/drm/mediatek/mtk_drm_fb.c | 2 +- > drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 3 ++- > drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c | 2 +- > drivers/gpu/drm/msm/msm_fb.c | 2 +- > drivers/gpu/drm/radeon/radeon_fb.c | 4 +++- > drivers/gpu/drm/rockchip/rockchip_drm_fb.c | 2 +- > drivers/gpu/drm/stm/ltdc.c | 2 +- > drivers/gpu/drm/tegra/fb.c | 2 +- > drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c | 2 +- > drivers/gpu/drm/zte/zx_plane.c | 2 +- > include/drm/drm_fourcc.h | 2 +- > 19 files changed, 33 insertions(+), 23 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c > index 5cbde74b97dd..48170a843b48 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c > @@ -123,6 +123,8 @@ static int amdgpufb_create_pinned_object(struct > amdgpu_fbdev *rfbdev, >struct drm_mode_fb_cmd2 *mode_cmd, >struct drm_gem_object **gobj_p) > { > + const struct drm_format_info *info = drm_get_format_info(dev, > + mode_cmd); > struct amdgpu_device *adev = rfbdev->adev; > struct drm_gem_object *gobj = NULL; > struct amdgpu_bo *abo = NULL; > @@ -133,7 +135,7 @@ static int amdgpufb_create_pinned_object(struct > amdgpu_fbdev *rfbdev, > int height = mode_cmd->height; > u32 cpp; > > - cpp = drm_format_plane_cpp(mode_cmd->pixel_format, 0); > + cpp = drm_format_plane_cpp(info, 0); > > /* need to align pitch with crtc limits */ > mode_cmd->pitches[0] = amdgpu_align_pitch(adev, mode_cmd->width, cpp, > diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c > index b9bed1138fa3..07971ad53b29 100644 > --- a/drivers/gpu/drm/arm/malidp_hw.c > +++ b/drivers/gpu/drm/arm/malidp_hw.c > @@ -326,12 +326,14 @@ static void malidp500_modeset(struct malidp_hw_device > *hwdev, struct videomode * > > static int malidp500_rotmem_required(struct malidp_hw_device *hwdev, u16 w, > u16 h, u32 fmt) > { > + const struct drm_format_info *info = drm_format_info(fmt); > + > /* >* Each layer needs enough rotation memory to fit 8 lines >* worth of pixel data. Required size is then: >*size = rotated_width * (bpp / 8) * 8; >*/ > - return w * drm_format_plane_cpp(fmt, 0) * 8; > + return w * drm_format_plane_cpp(info, 0) * 8; > } > > static void malidp500_se_write_pp_coefftab(struct malidp_hw_device *hwdev, > diff --git a/drivers/gpu/drm/cirrus/cirrus_fbdev.c > b/drivers/gpu/drm/cirrus/cirrus_fbdev.c > index 39df62acac69..759847bafda8 100644 > --- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c > +++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c > @@ -137,6 +137,8 @@ static int cirrusfb_create_object(struct cirrus_fbdev > *afbdev, > const struct drm_mode_fb_cmd2 *mode_cmd, > struct drm_gem_object **gobj_p) > { > + const struct drm_format_info *info = drm_get_format_info(dev, > + mode_cmd); > struct drm_device *dev = afbdev->helper.dev; > struct cirrus_device *cdev = dev->dev_private; > u32 bpp; > @@ -144,7 +146,7 @@ static int cirrusfb_create_object(struct cirrus_fbdev >
Re: [PATCH] driver : staging : ion: optimization for decreasing memory fragmentaion
You should have CC'd the ION maintainers/lists per ./scripts/get_maintainer.pl - CCing now. On 3/14/19 12:06 PM, Zhaoyang Huang wrote: > From: Zhaoyang Huang > > Two action for this patch: > 1. set a batch size for system heap's shrinker, which can have it buffer > reasonable page blocks in pool for future allocation. > 2. reverse the order sequence when free page blocks, the purpose is also > to have system heap keep as more big blocks as it can. > > By testing on an android system with 2G RAM, the changes with setting > batch = 48MB can help reduce the fragmentation obviously and improve > big block allocation speed for 15%. > > Signed-off-by: Zhaoyang Huang > --- > drivers/staging/android/ion/ion_heap.c| 12 +++- > drivers/staging/android/ion/ion_system_heap.c | 2 +- > 2 files changed, 12 insertions(+), 2 deletions(-) > > diff --git a/drivers/staging/android/ion/ion_heap.c > b/drivers/staging/android/ion/ion_heap.c > index 31db510..9e9caf2 100644 > --- a/drivers/staging/android/ion/ion_heap.c > +++ b/drivers/staging/android/ion/ion_heap.c > @@ -16,6 +16,8 @@ > #include > #include "ion.h" > > +unsigned long ion_heap_batch = 0; > + > void *ion_heap_map_kernel(struct ion_heap *heap, > struct ion_buffer *buffer) > { > @@ -303,7 +305,15 @@ int ion_heap_init_shrinker(struct ion_heap *heap) > heap->shrinker.count_objects = ion_heap_shrink_count; > heap->shrinker.scan_objects = ion_heap_shrink_scan; > heap->shrinker.seeks = DEFAULT_SEEKS; > - heap->shrinker.batch = 0; > + heap->shrinker.batch = ion_heap_batch; > > return register_shrinker(>shrinker); > } > + > +static int __init ion_system_heap_batch_init(char *arg) > +{ > + ion_heap_batch = memparse(arg, NULL); > + > + return 0; > +} > +early_param("ion_batch", ion_system_heap_batch_init); > diff --git a/drivers/staging/android/ion/ion_system_heap.c > b/drivers/staging/android/ion/ion_system_heap.c > index 701eb9f..d249f8d 100644 > --- a/drivers/staging/android/ion/ion_system_heap.c > +++ b/drivers/staging/android/ion/ion_system_heap.c > @@ -182,7 +182,7 @@ static int ion_system_heap_shrink(struct ion_heap *heap, > gfp_t gfp_mask, > if (!nr_to_scan) > only_scan = 1; > > - for (i = 0; i < NUM_ORDERS; i++) { > + for (i = NUM_ORDERS - 1; i >= 0; i--) { > pool = sys_heap->pools[i]; > > if (only_scan) { > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 5/5] media: tvp5150: add support to limit tv norms on connector
Em Sat, 2 Feb 2019 13:10:04 +0100 Marco Felsch escreveu: > The tvp5150 accepts NTSC(M,J,4.43), PAL (B,D,G,H,I,M,N) and SECAM video > data and is able to auto-detect the input signal. Hmm... I'm afraid of this change. As far as I remember, I tested some weird format variants like V4L2_STD_PAL_60 a long time ago, but there's no way to force video to use those. The format selection logic simply places the device on auto-detect mode for those weirdos, and that works fine at the devices I know. A change like that may break things. So I would actually have a quirk to optionally disable auto-detection on devices that this is not know to work. > The auto-detection > does not work if the connector does not receive an input signal and the > tvp5150 might not be configured correctly. This misconfiguration leads > into wrong decoded video streams if the tvp5150 gets powered on before > the video signal is present. > > Limit the supported tv norms according to the actual selected connector > to avoid a misconfiguration. > > Signed-off-by: Marco Felsch > --- > drivers/media/i2c/tvp5150.c | 42 - > 1 file changed, 41 insertions(+), 1 deletion(-) > > diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c > index f3a2ad00a40d..7619793dee67 100644 > --- a/drivers/media/i2c/tvp5150.c > +++ b/drivers/media/i2c/tvp5150.c > @@ -32,6 +32,13 @@ > #define TVP5150_MBUS_FMT MEDIA_BUS_FMT_UYVY8_2X8 > #define TVP5150_FIELDV4L2_FIELD_ALTERNATE > #define TVP5150_COLORSPACE V4L2_COLORSPACE_SMPTE170M > +#define TVP5150_STD_MASK (V4L2_STD_NTSC | \ > + V4L2_STD_NTSC_443 | \ > + V4L2_STD_PAL | \ > + V4L2_STD_PAL_M| \ > + V4L2_STD_PAL_N| \ > + V4L2_STD_PAL_Nc | \ > + V4L2_STD_SECAM) > > MODULE_DESCRIPTION("Texas Instruments TVP5150A/TVP5150AM1/TVP5151 video > decoder driver"); > MODULE_AUTHOR("Mauro Carvalho Chehab"); > @@ -74,6 +81,7 @@ struct tvp5150 { > struct media_pad pads[TVP5150_NUM_PADS]; > int pads_state[TVP5150_NUM_PADS]; > struct tvp5150_connector *connectors; > + struct tvp5150_connector *cur_connector; > int connectors_num; > bool modify_second_link; > #endif > @@ -794,17 +802,27 @@ static int tvp5150_g_std(struct v4l2_subdev *sd, > v4l2_std_id *std) > static int tvp5150_s_std(struct v4l2_subdev *sd, v4l2_std_id std) > { > struct tvp5150 *decoder = to_tvp5150(sd); > + v4l2_std_id supported_norms = > + decoder->cur_connector->base.connector.analog.supported_tvnorms; > > if (decoder->norm == std) > return 0; > > + /* > + * check if requested std or group of std's is/are supported by the > + * connector > + */ > + if ((supported_norms & std) == 0) > + return -EINVAL; > + > /* Change cropping height limits */ > if (std & V4L2_STD_525_60) > decoder->rect.height = TVP5150_V_MAX_525_60; > else > decoder->rect.height = TVP5150_V_MAX_OTHERS; > > - decoder->norm = std; > + /* set only the specific supported std in case of group of std's */ > + decoder->norm = supported_norms & std; > > return tvp5150_set_std(sd, std); > } > @@ -1298,6 +1316,7 @@ static int tvp5150_link_setup(struct media_entity > *entity, > int *pad_state = >pads_state[0]; > int i, active_pad, ret = 0; > bool is_svideo = false; > + bool update_cur_connector = false; > > /* >* The tvp state is determined by the enabled sink pad link. > @@ -1344,10 +1363,12 @@ static int tvp5150_link_setup(struct media_entity > *entity, > decoder->modify_second_link = false; > tvp5150_s_routing(sd, TVP5150_SVIDEO, > TVP5150_NORMAL, 0); > + update_cur_connector = true; > } > } else { > tvp5150_s_routing(sd, tvp5150_pad->index, > TVP5150_NORMAL, 0); > + update_cur_connector = true; > } > } else { > /* > @@ -1376,6 +1397,14 @@ static int tvp5150_link_setup(struct media_entity > *entity, > active_pad, TVP5150_BLACK_SCREEN, 0); > decoder->modify_second_link = false; > } > + > + if (update_cur_connector) { > + /* Update tvnorm according to connector */ > + decoder->cur_connector = > + container_of(remote, struct tvp5150_connector, pad); > + tvp5150_s_std(sd, > + > decoder->cur_connector->base.connector.analog.supported_tvnorms); > + } > out: > return ret;
Re: [RFC PATCH 02/20] drm: Remove users of drm_format_(horz|vert)_chroma_subsampling
Hi, Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit : > drm_format_horz_chroma_subsampling and drm_format_vert_chroma_subsampling > are basically a lookup in the drm_format_info table plus an access to the > hsub and vsub fields of the appropriate entry. > > Most drivers are using this function while having access to the entry > already, which means that we will perform an unnecessary lookup. Removing > the call to these functions is therefore more efficient. > > Some drivers will not have access to that entry in the function, but in > this case the overhead is minimal (we just have to call drm_format_info() > to perform the lookup) and we can even avoid multiple, inefficient lookups > in some places that need multiple fields from the drm_format_info > structure. > > This is amplified by the fact that most of the time the callers will have > to retrieve both the vsub and hsub fields, meaning that they would perform > twice the lookup. Cheers for nuking these two as well! Reviewed-by: Paul Kocialkowski Cheers, Paul > Signed-off-by: Maxime Ripard > --- > drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 9 + > drivers/gpu/drm/drm_fourcc.c| 34 +-- > drivers/gpu/drm/imx/ipuv3-plane.c | 15 +++- > drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 9 + > drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 24 + > drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c| 2 +- > drivers/gpu/drm/msm/msm_fb.c| 8 +--- > drivers/gpu/drm/rockchip/rockchip_drm_fb.c | 9 + > drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 13 ++- > drivers/gpu/drm/tegra/fb.c | 9 + > drivers/gpu/drm/vc4/vc4_plane.c | 13 ++- > include/drm/drm_fourcc.h| 2 +- > 12 files changed, 37 insertions(+), 110 deletions(-) > > diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c > b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c > index e836e2de35ce..fdd607ad27fe 100644 > --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c > +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c > @@ -603,8 +603,6 @@ static int atmel_hlcdc_plane_atomic_check(struct > drm_plane *p, > const struct drm_display_mode *mode; > struct drm_crtc_state *crtc_state; > unsigned int tmp; > - int hsub = 1; > - int vsub = 1; > int ret; > int i; > > @@ -642,13 +640,10 @@ static int atmel_hlcdc_plane_atomic_check(struct > drm_plane *p, > if (state->nplanes > ATMEL_HLCDC_LAYER_MAX_PLANES) > return -EINVAL; > > - hsub = drm_format_horz_chroma_subsampling(fb->format->format); > - vsub = drm_format_vert_chroma_subsampling(fb->format->format); > - > for (i = 0; i < state->nplanes; i++) { > unsigned int offset = 0; > - int xdiv = i ? hsub : 1; > - int ydiv = i ? vsub : 1; > + int xdiv = i ? fb->format->hsub : 1; > + int ydiv = i ? fb->format->vsub : 1; > > state->bpp[i] = fb->format->cpp[i]; > if (!state->bpp[i]) > diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c > index 22c7fa459f65..04be330b7cae 100644 > --- a/drivers/gpu/drm/drm_fourcc.c > +++ b/drivers/gpu/drm/drm_fourcc.c > @@ -326,40 +326,6 @@ int drm_format_plane_cpp(uint32_t format, int plane) > EXPORT_SYMBOL(drm_format_plane_cpp); > > /** > - * drm_format_horz_chroma_subsampling - get the horizontal chroma > subsampling factor > - * @format: pixel format (DRM_FORMAT_*) > - * > - * Returns: > - * The horizontal chroma subsampling factor for the > - * specified pixel format. > - */ > -int drm_format_horz_chroma_subsampling(uint32_t format) > -{ > - const struct drm_format_info *info; > - > - info = drm_format_info(format); > - return info ? info->hsub : 1; > -} > -EXPORT_SYMBOL(drm_format_horz_chroma_subsampling); > - > -/** > - * drm_format_vert_chroma_subsampling - get the vertical chroma subsampling > factor > - * @format: pixel format (DRM_FORMAT_*) > - * > - * Returns: > - * The vertical chroma subsampling factor for the > - * specified pixel format. > - */ > -int drm_format_vert_chroma_subsampling(uint32_t format) > -{ > - const struct drm_format_info *info; > - > - info = drm_format_info(format); > - return info ? info->vsub : 1; > -} > -EXPORT_SYMBOL(drm_format_vert_chroma_subsampling); > - > -/** > * drm_format_plane_width - width of the plane given the first plane > * @width: width of the first plane > * @format: pixel format > diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c > b/drivers/gpu/drm/imx/ipuv3-plane.c > index 21e964f6ab5c..2530143281b2 100644 > --- a/drivers/gpu/drm/imx/ipuv3-plane.c > +++ b/drivers/gpu/drm/imx/ipuv3-plane.c > @@ -115,8 +115,8 @@ drm_plane_state_to_ubo(struct drm_plane_state *state) > cma_obj = drm_fb_cma_get_gem_obj(fb, 1); > BUG_ON(!cma_obj); >
Re: [RFC PATCH 01/20] drm: Remove users of drm_format_num_planes
Hi, On Tue, 2019-03-19 at 22:57 +0100, Maxime Ripard wrote: > drm_format_num_planes() is basically a lookup in the drm_format_info table > plus an access to the num_planes field of the appropriate entry. > > Most drivers are using this function while having access to the entry > already, which means that we will perform an unnecessary lookup. Removing > the call to drm_format_num_planes is therefore more efficient. > > Some drivers will not have access to that entry in the function, but in > this case the overhead is minimal (we just have to call drm_format_info() > to perform the lookup) and we can even avoid multiple, inefficient lookups > in some places that need multiple fields from the drm_format_info > structure. Great, happy to see drm_format_num_planes getting nuked! Reviewed-by: Paul Kocialkowski Cheers, Paul > Signed-off-by: Maxime Ripard > --- > drivers/gpu/drm/arm/malidp_mw.c | 2 +- > drivers/gpu/drm/armada/armada_fb.c | 3 ++- > drivers/gpu/drm/drm_fourcc.c| 16 > drivers/gpu/drm/mediatek/mtk_drm_fb.c | 6 -- > drivers/gpu/drm/meson/meson_overlay.c | 2 +- > drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c | 9 ++--- > drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c| 3 ++- > drivers/gpu/drm/msm/msm_fb.c| 8 ++-- > drivers/gpu/drm/omapdrm/omap_fb.c | 4 +++- > drivers/gpu/drm/rockchip/rockchip_drm_fb.c | 6 +++--- > drivers/gpu/drm/tegra/fb.c | 3 ++- > drivers/gpu/drm/vc4/vc4_plane.c | 2 +- > drivers/gpu/drm/zte/zx_plane.c | 4 +--- > include/drm/drm_fourcc.h| 1 - > 14 files changed, 32 insertions(+), 37 deletions(-) > > diff --git a/drivers/gpu/drm/arm/malidp_mw.c b/drivers/gpu/drm/arm/malidp_mw.c > index 041a64dc7167..91580b7a3781 100644 > --- a/drivers/gpu/drm/arm/malidp_mw.c > +++ b/drivers/gpu/drm/arm/malidp_mw.c > @@ -153,7 +153,7 @@ malidp_mw_encoder_atomic_check(struct drm_encoder > *encoder, > return -EINVAL; > } > > - n_planes = drm_format_num_planes(fb->format->format); > + n_planes = fb->format->num_planes; > for (i = 0; i < n_planes; i++) { > struct drm_gem_cma_object *obj = drm_fb_cma_get_gem_obj(fb, i); > /* memory write buffers are never rotated */ > diff --git a/drivers/gpu/drm/armada/armada_fb.c > b/drivers/gpu/drm/armada/armada_fb.c > index 058ac7d9920f..a2f6472eb482 100644 > --- a/drivers/gpu/drm/armada/armada_fb.c > +++ b/drivers/gpu/drm/armada/armada_fb.c > @@ -87,6 +87,7 @@ struct armada_framebuffer *armada_framebuffer_create(struct > drm_device *dev, > struct drm_framebuffer *armada_fb_create(struct drm_device *dev, > struct drm_file *dfile, const struct drm_mode_fb_cmd2 *mode) > { > + const struct drm_format_info *info = drm_get_format_info(dev, mode); > struct armada_gem_object *obj; > struct armada_framebuffer *dfb; > int ret; > @@ -97,7 +98,7 @@ struct drm_framebuffer *armada_fb_create(struct drm_device > *dev, > mode->pitches[2]); > > /* We can only handle a single plane at the moment */ > - if (drm_format_num_planes(mode->pixel_format) > 1 && > + if (info->num_planes > 1 && > (mode->handles[0] != mode->handles[1] || >mode->handles[0] != mode->handles[2])) { > ret = -EINVAL; > diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c > index ba7e19d4336c..22c7fa459f65 100644 > --- a/drivers/gpu/drm/drm_fourcc.c > +++ b/drivers/gpu/drm/drm_fourcc.c > @@ -306,22 +306,6 @@ drm_get_format_info(struct drm_device *dev, > EXPORT_SYMBOL(drm_get_format_info); > > /** > - * drm_format_num_planes - get the number of planes for format > - * @format: pixel format (DRM_FORMAT_*) > - * > - * Returns: > - * The number of planes used by the specified pixel format. > - */ > -int drm_format_num_planes(uint32_t format) > -{ > - const struct drm_format_info *info; > - > - info = drm_format_info(format); > - return info ? info->num_planes : 1; > -} > -EXPORT_SYMBOL(drm_format_num_planes); > - > -/** > * drm_format_plane_cpp - determine the bytes per pixel value > * @format: pixel format (DRM_FORMAT_*) > * @plane: plane index > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_fb.c > b/drivers/gpu/drm/mediatek/mtk_drm_fb.c > index e20fcaef2851..68fdef8b12bd 100644 > --- a/drivers/gpu/drm/mediatek/mtk_drm_fb.c > +++ b/drivers/gpu/drm/mediatek/mtk_drm_fb.c > @@ -32,10 +32,11 @@ static struct drm_framebuffer > *mtk_drm_framebuffer_init(struct drm_device *dev, > const struct drm_mode_fb_cmd2 *mode, > struct drm_gem_object *obj) > { > + const struct drm_format_info *info = drm_get_format_info(dev, mode); > struct drm_framebuffer *fb; > int ret; > > - if (drm_format_num_planes(mode->pixel_format) != 1) > + if
[PATCH] ARM: dts: exynos: Increase minimal value of the Exynos4 mem buses to 160MHz
On Exynos 4, the 'DMC' and 'leftbus' buses feed the internal buses of the TV display subsystem and the Exynos Mixer hardware modules. When those buses are set below 160MHz, Exynos Mixer is not able to properly handle two XRGB display planes at FullHD-60MHz. DMA underrun happens, which in turn might result in reading data out of the configured buffer, what causes IOMMU page fault and kernel panic. This change fixes the following IOMMU fault, observed, when 2 Mixer planes were enabled: exynos-sysmmu 12e2.sysmmu: 12c1.mixer: PAGE FAULT occurred at 0x20fe9000 [ cut here ] kernel BUG at drivers/iommu/exynos-iommu.c:450! Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM Modules linked in: CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.1.0-rc1-next-20190320-dirty #5628 Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) PC is at exynos_sysmmu_irq+0x1c8/0x244 LR is at lock_is_held_type+0x80/0x100 ... Process swapper/0 (pid: 0, stack limit = 0xf4b67ceb) Stack: (0xc1001e18 to 0xc1002000) ... [] (exynos_sysmmu_irq) from [] (__handle_irq_event_percpu+0x98/0x470) [] (__handle_irq_event_percpu) from [] (handle_irq_event_percpu+0x1c/0x58) [] (handle_irq_event_percpu) from [] (handle_irq_event+0x38/0x5c) [] (handle_irq_event) from [] (handle_level_irq+0xc0/0x134) [] (handle_level_irq) from [] (generic_handle_irq+0x18/0x28) [] (generic_handle_irq) from [] (combiner_handle_cascade_irq+0x84/0xd4) [] (combiner_handle_cascade_irq) from [] (generic_handle_irq+0x18/0x28) [] (generic_handle_irq) from [] (__handle_domain_irq+0x6c/0xe4) [] (__handle_domain_irq) from [] (gic_handle_irq+0x54/0xa0) [] (gic_handle_irq) from [] (__irq_svc+0x70/0xb0) Exception stack(0xc1001f28 to 0xc1001f70) ... [] (__irq_svc) from [] (arch_cpu_idle+0x20/0x44) [] (arch_cpu_idle) from [] (do_idle+0x154/0x284) [] (do_idle) from [] (cpu_startup_entry+0x18/0x1c) [] (cpu_startup_entry) from [] (start_kernel+0x408/0x490) Code: e7923103 e59f206c ebfdaa09 ead8 (e7f001f2) ---[ end trace f8c3df0ee70697ef ]--- Kernel panic - not syncing: Fatal exception in interrupt Signed-off-by: Marek Szyprowski --- arch/arm/boot/dts/exynos4412.dtsi | 16 1 file changed, 16 deletions(-) diff --git a/arch/arm/boot/dts/exynos4412.dtsi b/arch/arm/boot/dts/exynos4412.dtsi index e5c041ec0756..f01c57cc895e 100644 --- a/arch/arm/boot/dts/exynos4412.dtsi +++ b/arch/arm/boot/dts/exynos4412.dtsi @@ -413,14 +413,6 @@ compatible = "operating-points-v2"; opp-shared; - opp-1 { - opp-hz = /bits/ 64 <1>; - opp-microvolt = <90>; - }; - opp-13400 { - opp-hz = /bits/ 64 <13400>; - opp-microvolt = <90>; - }; opp-16000 { opp-hz = /bits/ 64 <16000>; opp-microvolt = <90>; @@ -506,14 +498,6 @@ compatible = "operating-points-v2"; opp-shared; - opp-1 { - opp-hz = /bits/ 64 <1>; - opp-microvolt = <90>; - }; - opp-13400 { - opp-hz = /bits/ 64 <13400>; - opp-microvolt = <925000>; - }; opp-16000 { opp-hz = /bits/ 64 <16000>; opp-microvolt = <95>; -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC PATCH 06/20] lib: Add video format information library
On Tue, 19 Mar 2019 22:57:11 +0100 Maxime Ripard wrote: > Move the DRM formats API to turn this into a more generic image formats API > to be able to leverage it into some other places of the kernel, such as > v4l2 drivers. > > Signed-off-by: Maxime Ripard > --- > include/linux/image-formats.h | 240 +++- > lib/Kconfig | 7 +- > lib/Makefile | 3 +- > lib/image-formats-selftests.c | 326 +++- > lib/image-formats.c | 760 +++- > 5 files changed, 1336 insertions(+) > create mode 100644 include/linux/image-formats.h > create mode 100644 lib/image-formats-selftests.c > create mode 100644 lib/image-formats.c > [...] > --- /dev/null > +++ b/lib/image-formats.c > @@ -0,0 +1,760 @@ > +#include > +#include > +#include > +#include > + > +#include > + > +static const struct image_format_info formats[] = { > + { ... > + }, > +}; > + > +#define __image_format_lookup(_field, _fmt) \ > + ({ \ > + const struct image_format_info *format = NULL; \ > + unsigned i; \ > + \ > + for (i = 0; i < ARRAY_SIZE(formats); i++) \ > + if (formats[i]._field == _fmt) \ > + format = [i]; \ > + \ > + format; \ > + }) > + > +/** > + * __image_format_drm_lookup - query information for a given format > + * @drm: DRM fourcc pixel format (DRM_FORMAT_*) > + * > + * The caller should only pass a supported pixel format to this function. > + * > + * Returns: > + * The instance of struct image_format_info that describes the pixel format, > or > + * NULL if the format is unsupported. > + */ > +const struct image_format_info *__image_format_drm_lookup(u32 drm) > +{ > + return __image_format_lookup(drm_fmt, drm); > +} > +EXPORT_SYMBOL(__image_format_drm_lookup); > + > +/** > + * image_format_drm_lookup - query information for a given format > + * @drm: DRM fourcc pixel format (DRM_FORMAT_*) > + * > + * The caller should only pass a supported pixel format to this function. > + * Unsupported pixel formats will generate a warning in the kernel log. > + * > + * Returns: > + * The instance of struct image_format_info that describes the pixel format, > or > + * NULL if the format is unsupported. > + */ > +const struct image_format_info *image_format_drm_lookup(u32 drm) > +{ > + const struct image_format_info *format; > + > + format = __image_format_drm_lookup(drm); > + > + WARN_ON(!format); > + return format; > +} > +EXPORT_SYMBOL(image_format_drm_lookup); I think this function and the DRM formats table should be moved in drivers/gpu/drm/drm_image_format.c since they are DRM specific. The remaining functions can IMHO be placed in include/linux/image-formats.h as static inline funcs. This way you can get rid of lib/image-formats.c and the associated Kconfig entry. > + > +/** > + * image_format_plane_cpp - determine the bytes per pixel value > + * @format: pointer to the image_format > + * @plane: plane index > + * > + * Returns: > + * The bytes per pixel value for the specified plane. > + */ > +unsigned int image_format_plane_cpp(const struct image_format_info *format, > + int plane) > +{ > + if (!format || plane >= format->num_planes) > + return 0; > + > + return format->cpp[plane]; > +} > +EXPORT_SYMBOL(image_format_plane_cpp); > + > +/** > + * image_format_plane_width - width of the plane given the first plane > + * @format: pointer to the image_format > + * @width: width of the first plane > + * @plane: plane index > + * > + * Returns: > + * The width of @plane, given that the width of the first plane is @width. > + */ > +unsigned int image_format_plane_width(int width, > + const struct image_format_info *format, > + int plane) > +{ > + if (!format || plane >= format->num_planes) > + return 0; > + > + if (plane == 0) > + return width; > + > + return width / format->hsub; > +} > +EXPORT_SYMBOL(image_format_plane_width); > + > +/** > + * image_format_plane_height - height of the plane given the first plane > + * @format: pointer to the image_format > + * @height: height of the first plane > + * @plane: plane index > + * > + * Returns: > + * The height of @plane, given that the height of the first plane is @height. > + */ > +unsigned int image_format_plane_height(int height, > +const struct image_format_info *format, > +int plane) > +{ > + if (!format || plane >= format->num_planes) > +
Re: [PATCH 8/9] drm/syncobj: add timeline signal ioctl for syncobj v3
On 20/03/2019 03:53, zhoucm1 wrote: On 2019年03月19日 19:54, Lionel Landwerlin wrote: On 15/03/2019 12:09, Chunming Zhou wrote: v2: individually allocate chain array, since chain node is free independently. v3: all existing points must be already signaled before cpu perform signal operation, so add check condition for that. Signed-off-by: Chunming Zhou --- drivers/gpu/drm/drm_internal.h | 2 + drivers/gpu/drm/drm_ioctl.c | 2 + drivers/gpu/drm/drm_syncobj.c | 103 + include/uapi/drm/drm.h | 1 + 4 files changed, 108 insertions(+) diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index dd11ae5f1eef..d9a483a5fce0 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -190,6 +190,8 @@ int drm_syncobj_reset_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private); int drm_syncobj_signal_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private); +int drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_private); int drm_syncobj_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private); diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 92b3b7b2fd81..d337f161909c 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -696,6 +696,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = { DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_SIGNAL, drm_syncobj_signal_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, drm_syncobj_timeline_signal_ioctl, + DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_QUERY, drm_syncobj_query_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, drm_crtc_get_sequence_ioctl, DRM_UNLOCKED), diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 306c7b7e2770..eaeb038f97d7 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -1183,6 +1183,109 @@ drm_syncobj_signal_ioctl(struct drm_device *dev, void *data, return ret; } +int +drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_private) +{ + struct drm_syncobj_timeline_array *args = data; + struct drm_syncobj **syncobjs; + struct dma_fence_chain **chains; + uint64_t *points; + uint32_t i, j, timeline_count = 0; + int ret; + + if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) + return -EOPNOTSUPP; + + if (args->pad != 0) + return -EINVAL; + + if (args->count_handles == 0) + return -EINVAL; + + ret = drm_syncobj_array_find(file_private, + u64_to_user_ptr(args->handles), + args->count_handles, + ); + if (ret < 0) + return ret; + + for (i = 0; i < args->count_handles; i++) { + struct dma_fence_chain *chain; + struct dma_fence *fence; + + fence = drm_syncobj_fence_get(syncobjs[i]); + chain = to_dma_fence_chain(fence); + if (chain) { + struct dma_fence *iter; + + dma_fence_chain_for_each(iter, fence) { + if (!iter) + break; + if (!dma_fence_is_signaled(iter)) { + dma_fence_put(iter); + DRM_ERROR("Client must guarantee all existing timeline points signaled before performing host signal operation!"); + ret = -EPERM; + goto out; Sorry if I'm failing to remember whether we discussed this before. Signaling a point from the host should be fine even if the previous points in the timeline are not signaled. ok, will remove that checking. After all this can happen on the device side as well (out of order signaling). I thought the thing we didn't want is out of order submission. Just checking the last chain node seqno against the host signal point should be enough. What about simply returning -EPERM, we can warn the application from userspace? OK, will add that. Sorry for coming back to this again, but we probably ought to drop this check completely. This is allowed on the device signaling side, so I'm not quite sure what that protects us from. Also we do the check at this point in the signal_timeline_ioctl() function but there is nothing that says that when we later call the add_point() function this condition still holds. -Lionel ___ dri-devel mailing list dri-devel@lists.freedesktop.org
Re: [PATCH 1/4] drm/amd/display: Prevent vblank irq disable while VRR is active. (v2)
On 3/20/19 4:12 AM, Mario Kleiner wrote: > During VRR mode we can not allow vblank irq dis-/enable > transitions, as an enable after a disable can happen at > an arbitrary time during the video refresh cycle, e.g., > with a high likelyhood inside vblank front-porch. An > enable during front-porch would cause vblank timestamp > updates/calculations which are completely bogus, given > the code can't know when the vblank will end as long > as we are in front-porch with no page flip completed. > > Hold a permanent vblank reference on the crtc while > in active VRR mode to prevent a vblank disable, and > drop the reference again when switching back to fixed > refresh rate non-VRR mode. > > v2: Make sure transition is also handled if vrr is > disabled and stream gets disabled in the same > atomic commit. Suggested by Nicholas. > > Signed-off-by: Mario Kleiner > --- > drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 36 > +++ > 1 file changed, 36 insertions(+) > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > index a718ac2..1c83e80 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > @@ -251,6 +251,12 @@ get_crtc_by_otg_inst(struct amdgpu_device *adev, > return NULL; > } > > +static inline bool amdgpu_dm_vrr_active(struct dm_crtc_state *dm_state) > +{ > + return dm_state->freesync_config.state == VRR_STATE_ACTIVE_VARIABLE || > +dm_state->freesync_config.state == VRR_STATE_ACTIVE_FIXED; > +} > + > static void dm_pflip_high_irq(void *interrupt_params) > { > struct amdgpu_crtc *amdgpu_crtc; > @@ -4716,6 +4722,31 @@ static void update_freesync_state_on_stream( > (int)vrr_params.state); > } > > +static void amdgpu_dm_handle_vrr_transition(struct dm_crtc_state *old_state, > + struct dm_crtc_state *new_state) > +{ > + bool old_vrr_active = amdgpu_dm_vrr_active(old_state); > + bool new_vrr_active = amdgpu_dm_vrr_active(new_state); > + > + if (!old_vrr_active && new_vrr_active) { > + /* Transition VRR inactive -> active: > + * While VRR is active, we must not disable vblank irq, as a > + * reenable after disable would compute bogus vblank/pflip > + * timestamps if it likely happened inside display front-porch. > + */ > + drm_crtc_vblank_get(new_state->base.crtc); > + DRM_DEBUG_DRIVER("%s: crtc=%u VRR off->on: Get vblank ref\n", > + __func__, new_state->base.crtc->base.id); > + } else if (old_vrr_active && !new_vrr_active) { > + /* Transition VRR active -> inactive: > + * Allow vblank irq disable again for fixed refresh rate. > + */ > + drm_crtc_vblank_put(new_state->base.crtc); > + DRM_DEBUG_DRIVER("%s: crtc=%u VRR on->off: Drop vblank ref\n", > + __func__, new_state->base.crtc->base.id); > + } > +} > + > static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, > struct dc_state *dc_state, > struct drm_device *dev, > @@ -5250,6 +5281,11 @@ static void amdgpu_dm_atomic_commit_tail(struct > drm_atomic_state *state) > > dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); > dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); > + > + /* Handle vrr on->off / off->on transitions */ > + amdgpu_dm_handle_vrr_transition(dm_old_crtc_state, > + dm_new_crtc_state); > + I guess there's actually another problem with this here - we won't have the actual dm_state->freesync_config.state until the commit following this one since it gets calculated below this transition handler. We need this handler to trigger before the new framebuffer address is written but after these parameters are calculated. So this needs a v3 or another patch in the series that shifts the calculation of config.state before this. While it's probably sufficient to just reuse the block: if (new_crtc_state->vrr_supported && config.min_refresh_in_uhz && config.max_refresh_in_uhz) { config.state = new_crtc_state->base.vrr_enabled ? VRR_STATE_ACTIVE_VARIABLE : VRR_STATE_INACTIVE; } else { config.state = VRR_STATE_UNSUPPORTED; } the problem is config.state could still technically be modified within mod_freesync_build_vrr_params I think. So it's probably best to shift everything up to and including mod_freesync_build_vrr_params(...) from within update_freesync_state_on_stream(...) earlier, either in atomic check or in commit tail in
[PATCH v2 RESEND 18/24] arm64: dts: exynos: configure GSCALER related clocks
GSCALER should be feed with clock at certain rates. Signed-off-by: Andrzej Hajda --- arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi | 6 ++ arch/arm64/boot/dts/exynos/exynos5433-tm2.dts | 6 -- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi index d88e2f0e179a..d2de16645e10 100644 --- a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi @@ -289,6 +289,12 @@ assigned-clock-parents = <_top CLK_ACLK_MFC_400>; }; +_mif { + assigned-clocks = <_mif CLK_MOUT_SCLK_DSD_A>, <_mif CLK_DIV_SCLK_DSD>; + assigned-clock-parents = <_mif CLK_MOUT_MFC_PLL_DIV2>; + assigned-clock-rates = <0>, <33300>; +}; + _mscl { assigned-clocks = <_mscl CLK_MOUT_ACLK_MSCL_400_USER>, <_mscl CLK_MOUT_SCLK_JPEG_USER>, diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts index 3d7e0a782243..dda5d2746a74 100644 --- a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts +++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts @@ -33,7 +33,8 @@ <_disp CLK_MOUT_DISP_PLL>, <_mif CLK_MOUT_SCLK_DECON_TV_ECLK_A>, <_disp CLK_MOUT_SCLK_DECON_TV_ECLK_USER>, - <_disp CLK_MOUT_SCLK_DECON_TV_ECLK>; + <_disp CLK_MOUT_SCLK_DECON_TV_ECLK>, + <_disp CLK_MOUT_SCLK_DSD_USER>; assigned-clock-parents = <0>, <0>, <_mif CLK_ACLK_DISP_333>, <_mif CLK_SCLK_DSIM0_DISP>, @@ -45,7 +46,8 @@ <_disp CLK_FOUT_DISP_PLL>, <_mif CLK_MOUT_BUS_PLL_DIV2>, <_mif CLK_SCLK_DECON_TV_ECLK_DISP>, -<_disp CLK_MOUT_SCLK_DECON_TV_ECLK_USER>; +<_disp CLK_MOUT_SCLK_DECON_TV_ECLK_USER>, +<_mif CLK_SCLK_DSD_DISP>; assigned-clock-rates = <25000>, <4>; }; -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 RESEND 24/24] drm/exynos/gscaler: fix handling YVU420 pixel format
YVU420 requires swapping addresses of U and V planes. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos_drm_gsc.c | 52 ++--- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c index c7a97d053ab1..f75739e8bc55 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c @@ -535,10 +535,8 @@ static void gsc_src_set_fmt(struct gsc_context *ctx, u32 fmt, bool tiled) cfg |= GSC_IN_YUV422_3P; break; case DRM_FORMAT_YUV420: - cfg |= (GSC_IN_CHROMA_ORDER_CBCR | GSC_IN_YUV420_3P); - break; case DRM_FORMAT_YVU420: - cfg |= (GSC_IN_CHROMA_ORDER_CRCB | GSC_IN_YUV420_3P); + cfg |= (GSC_IN_CHROMA_ORDER_CBCR | GSC_IN_YUV420_3P); break; case DRM_FORMAT_NV12: cfg |= (GSC_IN_CHROMA_ORDER_CBCR | GSC_IN_YUV420_2P); @@ -658,13 +656,32 @@ static void gsc_src_set_buf_seq(struct gsc_context *ctx, u32 buf_id, gsc_write(cfg, GSC_IN_BASE_ADDR_CR_MASK); } +/* returns HW plane index based on pixel format */ +static int gsc_hw_plane_index(int index, u32 format) +{ + switch (format) { + case DRM_FORMAT_YVU420: + switch (index) { + case 0: return 0; + case 1: return 2; + case 2: return 1; + } + default: + return index; + } +} + static void gsc_src_set_addr(struct gsc_context *ctx, u32 buf_id, struct exynos_drm_ipp_buffer *buf) { + int idx; + /* address register set */ gsc_write(buf->dma_addr[0], GSC_IN_BASE_ADDR_Y(buf_id)); - gsc_write(buf->dma_addr[1], GSC_IN_BASE_ADDR_CB(buf_id)); - gsc_write(buf->dma_addr[2], GSC_IN_BASE_ADDR_CR(buf_id)); + idx = gsc_hw_plane_index(1, buf->format->format); + gsc_write(buf->dma_addr[idx], GSC_IN_BASE_ADDR_CB(buf_id)); + idx = gsc_hw_plane_index(2, buf->format->format); + gsc_write(buf->dma_addr[idx], GSC_IN_BASE_ADDR_CR(buf_id)); gsc_src_set_buf_seq(ctx, buf_id, true); } @@ -722,10 +739,8 @@ static void gsc_dst_set_fmt(struct gsc_context *ctx, u32 fmt, bool tiled) cfg |= GSC_OUT_YUV422_3P; break; case DRM_FORMAT_YUV420: - cfg |= (GSC_OUT_CHROMA_ORDER_CBCR | GSC_OUT_YUV420_3P); - break; case DRM_FORMAT_YVU420: - cfg |= (GSC_OUT_CHROMA_ORDER_CRCB | GSC_OUT_YUV420_3P); + cfg |= (GSC_OUT_CHROMA_ORDER_CBCR | GSC_OUT_YUV420_3P); break; case DRM_FORMAT_NV12: cfg |= (GSC_OUT_CHROMA_ORDER_CBCR | GSC_OUT_YUV420_2P); @@ -985,10 +1000,13 @@ static void gsc_dst_set_buf_seq(struct gsc_context *ctx, u32 buf_id, static void gsc_dst_set_addr(struct gsc_context *ctx, u32 buf_id, struct exynos_drm_ipp_buffer *buf) { - /* address register set */ + int i; + gsc_write(buf->dma_addr[0], GSC_OUT_BASE_ADDR_Y(buf_id)); - gsc_write(buf->dma_addr[1], GSC_OUT_BASE_ADDR_CB(buf_id)); - gsc_write(buf->dma_addr[2], GSC_OUT_BASE_ADDR_CR(buf_id)); + i = gsc_hw_plane_index(1, buf->format->format); + gsc_write(buf->dma_addr[i], GSC_OUT_BASE_ADDR_CB(buf_id)); + i = gsc_hw_plane_index(2, buf->format->format); + gsc_write(buf->dma_addr[i], GSC_OUT_BASE_ADDR_CR(buf_id)); gsc_dst_set_buf_seq(ctx, buf_id, true); } @@ -1238,10 +1256,14 @@ static void gsc_update_plane(struct exynos_drm_plane *plane) gsc_write(BIT(16) * cropped_w / scaled_w, GSC_MAIN_H_RATIO); gsc_write(BIT(16) * cropped_h / scaled_h, GSC_MAIN_V_RATIO); gsc_write(exynos_drm_fb_dma_addr(fb, 0), GSC_IN_BASE_ADDR_Y(0)); - if (fb->format->num_planes > 1) - gsc_write(exynos_drm_fb_dma_addr(fb, 1), GSC_IN_BASE_ADDR_CB(0)); - if (fb->format->num_planes > 2) - gsc_write(exynos_drm_fb_dma_addr(fb, 2), GSC_IN_BASE_ADDR_CR(0)); + if (fb->format->num_planes > 1) { + i = gsc_hw_plane_index(1, fb->format->format); + gsc_write(exynos_drm_fb_dma_addr(fb, i), GSC_IN_BASE_ADDR_CB(0)); + } + if (fb->format->num_planes > 2) { + i = gsc_hw_plane_index(2, fb->format->format); + gsc_write(exynos_drm_fb_dma_addr(fb, i), GSC_IN_BASE_ADDR_CR(0)); + } gsc_src_set_fmt(ctx, fb->format->format, fb->modifier); gsc_write(scaled_w * scaled_h, GSC_SMART_IF_PIXEL_NUM); gsc_write(GSC_ENABLE_SFR_UPDATE | GSC_ENABLE_ON, GSC_ENABLE); -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 RESEND 21/24] drm/exynos/decon5433: add local path support
GSCALERs in Exynos5433 have local path to DECON and DECON_TV. They can be used as extra planes with support for non-RGB formats and scaling. To enable it on DECON update_plane and disable_plane callback should be modified. Moreover DSD mux should be set accordingly, and finally atomic_check callback should be used to limit the number of active planes. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 80 +++ drivers/gpu/drm/exynos/regs-decon5433.h | 6 ++ 2 files changed, 72 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index 958972e3ee1e..b0332763594e 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -26,6 +26,10 @@ #include "exynos_drm_fb.h" #include "regs-decon5433.h" +#define DSD_CFG 0x1000 +#define DSD_CFG_GSCL_MODE(gsc, decon, wb) (((wb) << 1) | decon) << (3 + ((gsc) << 1)) +#define DSD_CFG_GSCL_MODE_MASK(gsc) DSD_CFG_GSCL_MODE(gsc, 1, 1) + #define DSD_CFG_MUX 0x1004 #define DSD_CFG_MUX_TE_UNMASK_GLOBAL BIT(13) @@ -47,6 +51,7 @@ static const char * const decon_clks_name[] = { "pclk_smmu_decon1x", "sclk_decon_vclk", "sclk_decon_eclk", + "dsd" }; struct decon_context { @@ -370,11 +375,40 @@ static void decon_shadow_protect(struct decon_context *ctx, bool protect) protect ? ~0 : 0); } +static int decon_atomic_check(struct exynos_drm_crtc *crtc, + struct drm_crtc_state *state) +{ + struct decon_context *ctx = to_decon(crtc); + + if (hweight32(state->plane_mask) > WINDOWS_NR - ctx->first_win) + return -EINVAL; + return 0; +} + +static void decon_set_gscl_mode(struct decon_context *ctx) +{ + u32 plane_mask = ctx->crtc.base.state->plane_mask; + struct drm_plane *bplane; + u32 mask = 0, val = 0; + bool decon_id = ctx->out_type & IFTYPE_HDMI; + + drm_for_each_plane_mask(bplane, ctx->drm_dev, plane_mask) { + struct exynos_drm_plane *plane = to_exynos_plane(bplane); + + if (!(plane->capabilities & EXYNOS_DRM_PLANE_CAP_GSCALER)) + continue; + mask |= DSD_CFG_GSCL_MODE_MASK(plane->index); + val |= DSD_CFG_GSCL_MODE(plane->index, decon_id, 0); + } + regmap_update_bits(ctx->sysreg, DSD_CFG, mask, val); +} + static void decon_atomic_begin(struct exynos_drm_crtc *crtc) { struct decon_context *ctx = to_decon(crtc); decon_shadow_protect(ctx, true); + decon_set_gscl_mode(ctx); } #define BIT_VAL(x, e, s) (((x) & ((1 << ((e) - (s) + 1)) - 1)) << (s)) @@ -394,6 +428,9 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, dma_addr_t dma_addr = exynos_drm_fb_dma_addr(fb, 0); u32 val; + if (plane->ops && plane->ops->update_plane) + plane->ops->update_plane(plane); + if (crtc->base.mode.flags & DRM_MODE_FLAG_INTERLACE) { val = COORDINATE_X(state->crtc.x) | COORDINATE_Y(state->crtc.y / 2); @@ -419,25 +456,38 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, VIDOSD_Wx_ALPHA_B_F(0x0); writel(val, ctx->addr + DECON_VIDOSDxD(win)); - writel(dma_addr, ctx->addr + DECON_VIDW0xADD0B0(win)); - - val = dma_addr + pitch * state->src.h; - writel(val, ctx->addr + DECON_VIDW0xADD1B0(win)); - - if (!(ctx->out_type & IFTYPE_HDMI)) - val = BIT_VAL(pitch - state->crtc.w * cpp, 27, 14) - | BIT_VAL(state->crtc.w * cpp, 13, 0); - else - val = BIT_VAL(pitch - state->crtc.w * cpp, 29, 15) - | BIT_VAL(state->crtc.w * cpp, 14, 0); - writel(val, ctx->addr + DECON_VIDW0xADD2(win)); - decon_win_set_pixfmt(ctx, plane); + if (plane->capabilities & EXYNOS_DRM_PLANE_CAP_GSCALER) { + writel(UPDATE_SCHEME_OTF_PER_FRAME, + ctx->addr + DECON_UPDATE_SCHEME); + decon_set_bits(ctx, DECON_WINCONx(win), + WINCONx_ENLOCAL_F | WINCONx_LOCALSEL_MASK, + WINCONx_ENLOCAL_F | WINCONx_LOCALSEL_F(plane->index)); + } else { + writel(dma_addr, ctx->addr + DECON_VIDW0xADD0B0(win)); + val = dma_addr + pitch * state->src.h; + writel(val, ctx->addr + DECON_VIDW0xADD1B0(win)); + if (!(ctx->out_type & IFTYPE_HDMI)) + val = BIT_VAL(pitch - state->crtc.w * cpp, 27, 14) + | BIT_VAL(state->crtc.w * cpp, 13, 0); + else + val = BIT_VAL(pitch - state->crtc.w * cpp, 29, 15) + | BIT_VAL(state->crtc.w * cpp, 14, 0); + writel(val, ctx->addr + DECON_VIDW0xADD2(win)); +
[PATCH v2 RESEND 15/24] drm/exynos: add plane update/disable callbacks for planes
Display controllers in Exynos beside native planes/windows can use external planes provided by other IPs - GSCALER, FIMD, VPP. To add support to them we will need plane specific callbacks. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos_drm_drv.h | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 6643db865500..5d06e796dc80 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -76,6 +76,12 @@ to_exynos_plane_state(struct drm_plane_state *state) #define EXYNOS_DRM_PLANE_CAP_PIX_BLEND (1 << 4) #define EXYNOS_DRM_PLANE_CAP_WIN_BLEND (1 << 5) +struct exynos_drm_plane; +struct exynos_drm_plane_ops { + void (*update_plane)(struct exynos_drm_plane *plane); + void (*disable_plane)(struct exynos_drm_plane *plane); +}; + /* * Exynos drm common overlay structure. * @@ -89,6 +95,7 @@ to_exynos_plane_state(struct drm_plane_state *state) struct exynos_drm_plane { struct drm_plane base; + const struct exynos_drm_plane_ops *ops; unsigned int index; unsigned int capabilities; }; -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 RESEND 13/24] drm/exynos: set primary plane in exynos_drm_crtc_init
exynos_drm_crtc_init has all information necessary to discover primary plane. Let's move logic for setting primary plane into this function. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 3 --- drivers/gpu/drm/exynos/exynos7_drm_decon.c| 1 - drivers/gpu/drm/exynos/exynos_drm_crtc.c | 10 +- drivers/gpu/drm/exynos/exynos_drm_drv.h | 2 -- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 1 - drivers/gpu/drm/exynos/exynos_drm_vidi.c | 1 - drivers/gpu/drm/exynos/exynos_mixer.c | 1 - 7 files changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index 663446ca2d09..958972e3ee1e 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -30,8 +30,6 @@ #define DSD_CFG_MUX_TE_UNMASK_GLOBAL BIT(13) #define WINDOWS_NR 5 -#define PRIMARY_WIN2 -#define CURSON_WIN 4 #define MIN_FB_WIDTH_FOR_16WORD_BURST 128 @@ -625,7 +623,6 @@ static int decon_bind(struct device *dev, struct device *master, void *data) ret = exynos_drm_crtc_init(>crtc, drm_dev); if (ret) return ret; - ctx->crtc.base.primary = >planes[PRIMARY_WIN].base; decon_clear_channels(>crtc); diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c index b6ad2faed159..3d8c96f0b02a 100644 --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c @@ -635,7 +635,6 @@ static int decon_bind(struct device *dev, struct device *master, void *data) decon_ctx_remove(ctx); return ret; } - ctx->crtc.base.primary = >planes[DEFAULT_WIN].base; if (ctx->encoder) exynos_dpi_bind(drm_dev, ctx->encoder); diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 72e224e80565..ec1319781b8b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -176,9 +176,17 @@ int exynos_drm_crtc_init(struct exynos_drm_crtc *exynos_crtc, struct drm_device *drm_dev) { struct drm_crtc *crtc = _crtc->base; + struct drm_plane *primary = NULL, *plane; + + drm_for_each_plane(plane, drm_dev) { + if (plane->possible_crtcs != BIT(drm_dev->mode_config.num_crtc)) + continue; + if (!primary && plane->type == DRM_PLANE_TYPE_PRIMARY) + primary = plane; + } drm_crtc_helper_add(crtc, _crtc_helper_funcs); - return drm_crtc_init_with_planes(drm_dev, crtc, NULL, NULL, + return drm_crtc_init_with_planes(drm_dev, crtc, primary, NULL, _crtc_funcs, NULL); } diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 23b27b82de6e..6643db865500 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -21,8 +21,6 @@ #define MAX_PLANE 5 #define MAX_FB_BUFFER 4 -#define DEFAULT_WIN0 - #define to_exynos_crtc(x) container_of(x, struct exynos_drm_crtc, base) #define to_exynos_plane(x) container_of(x, struct exynos_drm_plane, base) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index b3c11bca5aed..14e70971547a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -1051,7 +1051,6 @@ static int fimd_bind(struct device *dev, struct device *master, void *data) ret = exynos_drm_crtc_init(>crtc, drm_dev); if (ret) return ret; - ctx->crtc.base.primary = >planes[DEFAULT_WIN].base; if (ctx->driver_data->has_dp_clk) { ctx->dp_clk.enable = fimd_dp_clock_enable; diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index eb1fd3a2cdf3..19cd7275b20f 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -387,7 +387,6 @@ static int vidi_bind(struct device *dev, struct device *master, void *data) DRM_ERROR("failed to create crtc.\n"); return ret; } - ctx->crtc.base.primary = >planes[DEFAULT_WIN].base; drm_encoder_init(drm_dev, encoder, _vidi_encoder_funcs, DRM_MODE_ENCODER_TMDS, NULL); diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index d0dcbbfc67e5..8bb31a0e572e 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -1157,7 +1157,6 @@ static int mixer_bind(struct device *dev, struct device *manager, void *data) mixer_ctx_remove(ctx); goto
[PATCH v2 RESEND 22/24] drm/exynos/decon5433: wait for finish previous update
DECON should wait for previous update before starting new one. Otherwise internal registers can be updated in non-atomic, error prone way. This patch fixes occasional occurrences of vblank timeouts on tm2 platform: [ 3167.968742] [CRTC:55:crtc-0] vblank wait timed out [ 3167.987440] WARNING: CPU: 1 PID: 194 at ../drivers/gpu/drm/drm_atomic_helper.c:1423 drm_atomic_helper_wait_for_vblanks.part.9+0x2c0/0x2c8 [ 3168.029990] Modules linked in: [ 3168.047240] CPU: 1 PID: 194 Comm: modetest Tainted: GW 5.0.0-rc1+ #694 [ 3168.069539] Hardware name: Samsung TM2 board (DT) ... [ 3168.453566] Call trace: [ 3168.469705] drm_atomic_helper_wait_for_vblanks.part.9+0x2c0/0x2c8 [ 3168.489983] drm_atomic_helper_commit_tail_rpm+0x60/0x78 [ 3168.509463] commit_tail+0x44/0x78 [ 3168.527053] drm_atomic_helper_commit+0xe8/0x160 [ 3168.546010] drm_atomic_commit+0x48/0x58 [ 3168.564304] drm_atomic_helper_update_plane+0x11c/0x140 [ 3168.584080] __setplane_atomic+0x130/0x150 [ 3168.602799] setplane_internal+0xb0/0x1a8 [ 3168.621493] drm_mode_setplane+0xc4/0x1b8 [ 3168.640219] drm_ioctl_kernel+0x94/0x110 [ 3168.658920] drm_ioctl+0x1c8/0x428 ... Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index b0332763594e..09f035f52444 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -406,6 +406,11 @@ static void decon_set_gscl_mode(struct decon_context *ctx) static void decon_atomic_begin(struct exynos_drm_crtc *crtc) { struct decon_context *ctx = to_decon(crtc); + u32 val; + + /* wait for finish previous updates */ + if (readl_poll_timeout(ctx->addr + DECON_UPDATE, val, !val, 1000, 2) < 0) + dev_err(ctx->dev, "DECON_UPDATE timeout\n"); decon_shadow_protect(ctx, true); decon_set_gscl_mode(ctx); -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 RESEND 19/24] arm64: dts: exynos: add DSD/GSD clocks to DECONs and GSCALERs
To support local paths both DECON and GSCALER should enable respective Smart Deck clocks DSD and GSD. Signed-off-by: Andrzej Hajda --- arch/arm64/boot/dts/exynos/exynos5433.dtsi | 25 +- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi index e7cd3b67d818..e6d32b2fb3c0 100644 --- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi @@ -848,12 +848,13 @@ <_disp CLK_ACLK_XIU_DECON1X>, <_disp CLK_PCLK_SMMU_DECON1X>, <_disp CLK_SCLK_DECON_VCLK>, - <_disp CLK_SCLK_DECON_ECLK>; + <_disp CLK_SCLK_DECON_ECLK>, + <_disp CLK_SCLK_DSD>; clock-names = "pclk", "aclk_decon", "aclk_smmu_decon0x", "aclk_xiu_decon0x", "pclk_smmu_decon0x", "aclk_smmu_decon1x", "aclk_xiu_decon1x", "pclk_smmu_decon1x", "sclk_decon_vclk", - "sclk_decon_eclk"; + "sclk_decon_eclk", "dsd"; power-domains = <_disp>; interrupt-names = "fifo", "vsync", "lcd_sys"; interrupts = , @@ -890,12 +891,13 @@ <_disp CLK_ACLK_XIU_TV1X>, <_disp CLK_PCLK_SMMU_TV1X>, <_disp CLK_SCLK_DECON_TV_VCLK>, -<_disp CLK_SCLK_DECON_TV_ECLK>; +<_disp CLK_SCLK_DECON_TV_ECLK>, +<_disp CLK_SCLK_DSD>; clock-names = "pclk", "aclk_decon", "aclk_smmu_decon0x", "aclk_xiu_decon0x", "pclk_smmu_decon0x", "aclk_smmu_decon1x", "aclk_xiu_decon1x", "pclk_smmu_decon1x", "sclk_decon_vclk", - "sclk_decon_eclk"; + "sclk_decon_eclk", "dsd"; samsung,disp-sysreg = <_disp>; power-domains = <_disp>; interrupt-names = "fifo", "vsync", "lcd_sys"; @@ -1022,11 +1024,12 @@ reg = <0x13c0 0x1000>; interrupts = ; clock-names = "pclk", "aclk", "aclk_xiu", - "aclk_gsclbend"; + "aclk_gsclbend", "gsd"; clocks = <_gscl CLK_PCLK_GSCL0>, <_gscl CLK_ACLK_GSCL0>, <_gscl CLK_ACLK_XIU_GSCLX>, -<_gscl CLK_ACLK_GSCLBEND_333>; +<_gscl CLK_ACLK_GSCLBEND_333>, +<_gscl CLK_ACLK_GSD>; iommus = <_gscl0>; power-domains = <_gscl>; }; @@ -1036,11 +1039,12 @@ reg = <0x13c1 0x1000>; interrupts = ; clock-names = "pclk", "aclk", "aclk_xiu", - "aclk_gsclbend"; + "aclk_gsclbend", "gsd"; clocks = <_gscl CLK_PCLK_GSCL1>, <_gscl CLK_ACLK_GSCL1>, <_gscl CLK_ACLK_XIU_GSCLX>, -<_gscl CLK_ACLK_GSCLBEND_333>; +<_gscl CLK_ACLK_GSCLBEND_333>, +<_gscl CLK_ACLK_GSD>; iommus = <_gscl1>; power-domains = <_gscl>; }; @@ -1050,11 +1054,12 @@ reg = <0x13c2 0x1000>; interrupts = ; clock-names = "pclk", "aclk", "aclk_xiu", - "aclk_gsclbend"; + "aclk_gsclbend", "gsd"; clocks = <_gscl CLK_PCLK_GSCL2>, <_gscl CLK_ACLK_GSCL2>, <_gscl CLK_ACLK_XIU_GSCLX>, -<_gscl CLK_ACLK_GSCLBEND_333>; +<_gscl CLK_ACLK_GSCLBEND_333>, +<_gscl CLK_ACLK_GSD>; iommus = <_gscl2>; power-domains = <_gscl>; }; -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 RESEND 12/24] drm/exynos: unify plane type assignment
Since all Exynos CRTCs uses the first plane as primary plane and the last one as cursor plane we can drop custom assignments per CRTC and replace it with common code. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 7 +-- drivers/gpu/drm/exynos/exynos7_drm_decon.c| 7 +-- drivers/gpu/drm/exynos/exynos_drm_drv.h | 2 +- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 10 +- drivers/gpu/drm/exynos/exynos_drm_plane.c | 19 +-- drivers/gpu/drm/exynos/exynos_drm_vidi.c | 8 +--- drivers/gpu/drm/exynos/exynos_mixer.c | 6 ++ 7 files changed, 20 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index 0d409f453923..663446ca2d09 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -78,11 +78,6 @@ static const uint32_t decon_formats[] = { DRM_FORMAT_ARGB, }; -static const enum drm_plane_type decon_win_types[WINDOWS_NR] = { - [PRIMARY_WIN] = DRM_PLANE_TYPE_PRIMARY, - [CURSON_WIN] = DRM_PLANE_TYPE_CURSOR, -}; - static inline void decon_set_bits(struct decon_context *ctx, u32 reg, u32 mask, u32 val) { @@ -619,7 +614,7 @@ static int decon_bind(struct device *dev, struct device *master, void *data) | EXYNOS_DRM_PLANE_CAP_PIX_BLEND; ret = exynos_plane_init(drm_dev, >planes[i], decon_formats, ARRAY_SIZE(decon_formats), - decon_win_types[i]); + WINDOWS_NR - ctx->first_win); if (ret) return ret; } diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c index 22659f2da755..b6ad2faed159 100644 --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c @@ -78,11 +78,6 @@ static const uint32_t decon_formats[] = { DRM_FORMAT_BGRA, }; -static const enum drm_plane_type decon_win_types[WINDOWS_NR] = { - DRM_PLANE_TYPE_PRIMARY, - DRM_PLANE_TYPE_CURSOR, -}; - static void decon_wait_for_vblank(struct exynos_drm_crtc *crtc) { struct decon_context *ctx = to_decon(crtc); @@ -628,7 +623,7 @@ static int decon_bind(struct device *dev, struct device *master, void *data) for (i = 0; i < WINDOWS_NR; i++) { ctx->planes[i].index = i; ret = exynos_plane_init(drm_dev, >planes[i], decon_formats, - ARRAY_SIZE(decon_formats), decon_win_types[i]); + ARRAY_SIZE(decon_formats), WINDOWS_NR); if (ret) return ret; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 82af112be03d..23b27b82de6e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -97,7 +97,7 @@ struct exynos_drm_plane { int exynos_plane_init(struct drm_device *dev, struct exynos_drm_plane *plane, const uint32_t *pixel_formats, int num_pixel_formats, - enum drm_plane_type type); + int win_count); /* * Exynos drm crtc ops diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 8ea1cfd51736..b3c11bca5aed 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -212,14 +212,6 @@ static const struct of_device_id fimd_driver_dt_match[] = { }; MODULE_DEVICE_TABLE(of, fimd_driver_dt_match); -static const enum drm_plane_type fimd_win_types[WINDOWS_NR] = { - DRM_PLANE_TYPE_PRIMARY, - DRM_PLANE_TYPE_OVERLAY, - DRM_PLANE_TYPE_OVERLAY, - DRM_PLANE_TYPE_OVERLAY, - DRM_PLANE_TYPE_CURSOR, -}; - static const uint32_t fimd_formats[] = { DRM_FORMAT_C8, DRM_FORMAT_XRGB1555, @@ -1049,7 +1041,7 @@ static int fimd_bind(struct device *dev, struct device *master, void *data) | EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND; ret = exynos_plane_init(drm_dev, >planes[i], fimd_formats, - ARRAY_SIZE(fimd_formats), fimd_win_types[i]); + ARRAY_SIZE(fimd_formats), WINDOWS_NR); if (ret) return ret; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index e1aa504539fa..5f8f56b69369 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -291,9 +291,18 @@ static void exynos_plane_attach_zpos_property(struct drm_plane *plane,
[PATCH v2 RESEND 11/24] drm/exynos/vidi: remove encoder_to_vidi helper
It can be replaced by recently introduced to_vidi helper. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos_drm_vidi.c | 7 +-- 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index 377aae5f7631..2579462aec70 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -52,11 +52,6 @@ struct vidi_context { struct mutexlock; }; -static inline struct vidi_context *encoder_to_vidi(struct drm_encoder *e) -{ - return container_of(e, struct vidi_context, encoder); -} - #define to_vidi(ptr) container_of(ptr, struct vidi_context, ptr) static const char fake_edid_info[] = { @@ -331,7 +326,7 @@ static const struct drm_connector_helper_funcs vidi_connector_helper_funcs = { static int vidi_create_connector(struct drm_encoder *encoder) { - struct vidi_context *ctx = encoder_to_vidi(encoder); + struct vidi_context *ctx = to_vidi(encoder); struct drm_connector *connector = >connector; int ret; -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 RESEND 14/24] drm/exynos: set cursor plane in exynos_drm_crtc_init
The patch configures cursor plane in exynos_drm_crtc_init. Since Exynos DRM does not support fast/async path for cursor update, it must be disabled. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos_drm_crtc.c | 6 -- drivers/gpu/drm/exynos/exynos_drm_fb.c | 10 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index ec1319781b8b..303df018f0a1 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -176,17 +176,19 @@ int exynos_drm_crtc_init(struct exynos_drm_crtc *exynos_crtc, struct drm_device *drm_dev) { struct drm_crtc *crtc = _crtc->base; - struct drm_plane *primary = NULL, *plane; + struct drm_plane *primary = NULL, *cursor = NULL, *plane; drm_for_each_plane(plane, drm_dev) { if (plane->possible_crtcs != BIT(drm_dev->mode_config.num_crtc)) continue; if (!primary && plane->type == DRM_PLANE_TYPE_PRIMARY) primary = plane; + if (!cursor && plane->type == DRM_PLANE_TYPE_CURSOR) + cursor = plane; } drm_crtc_helper_add(crtc, _crtc_helper_funcs); - return drm_crtc_init_with_planes(drm_dev, crtc, primary, NULL, + return drm_crtc_init_with_planes(drm_dev, crtc, primary, cursor, _crtc_funcs, NULL); } diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c index 1f11ab0f8e9d..d705e363f703 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c @@ -155,11 +155,19 @@ static struct drm_mode_config_helper_funcs exynos_drm_mode_config_helpers = { .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm, }; +int exynos_drm_atomic_helper_commit(struct drm_device *dev, + struct drm_atomic_state *state, + bool nonblock) +{ + state->legacy_cursor_update = false; + return drm_atomic_helper_commit(dev, state, nonblock); +} + static const struct drm_mode_config_funcs exynos_drm_mode_config_funcs = { .fb_create = exynos_user_fb_create, .output_poll_changed = drm_fb_helper_output_poll_changed, .atomic_check = drm_atomic_helper_check, - .atomic_commit = drm_atomic_helper_commit, + .atomic_commit = exynos_drm_atomic_helper_commit, }; void exynos_drm_mode_config_init(struct drm_device *dev) -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 RESEND 05/24] drm/exynos/decon5433: embed exynos_drm_crtc directly into context
Since crtc maps 1:1 to the device there is no point in allocating it separately, another benefit is possibility of direct initialisation of its fields which is more readable and allows further expansion. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 52 +-- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index ae0f475eb633..0d409f453923 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -54,7 +54,7 @@ static const char * const decon_clks_name[] = { struct decon_context { struct device *dev; struct drm_device *drm_dev; - struct exynos_drm_crtc *crtc; + struct exynos_drm_crtc crtc; struct exynos_drm_plane planes[WINDOWS_NR]; void __iomem*addr; struct regmap *sysreg; @@ -69,6 +69,8 @@ struct decon_context { u32 frame_id; }; +#define to_decon(ptr) container_of(ptr, struct decon_context, ptr) + static const uint32_t decon_formats[] = { DRM_FORMAT_XRGB1555, DRM_FORMAT_RGB565, @@ -90,7 +92,7 @@ static inline void decon_set_bits(struct decon_context *ctx, u32 reg, u32 mask, static int decon_enable_vblank(struct exynos_drm_crtc *crtc) { - struct decon_context *ctx = crtc->ctx; + struct decon_context *ctx = to_decon(crtc); u32 val; val = VIDINTCON0_INTEN; @@ -110,7 +112,7 @@ static int decon_enable_vblank(struct exynos_drm_crtc *crtc) static void decon_disable_vblank(struct exynos_drm_crtc *crtc) { - struct decon_context *ctx = crtc->ctx; + struct decon_context *ctx = to_decon(crtc); if (!(ctx->out_type & I80_HW_TRG)) disable_irq_nosync(ctx->te_irq); @@ -143,7 +145,7 @@ static u32 decon_get_frame_count(struct decon_context *ctx, bool end) switch (status & (VIDCON1_VSTATUS_MASK | VIDCON1_I80_ACTIVE)) { case VIDCON1_VSTATUS_VS: - if (!(ctx->crtc->i80_mode)) + if (!(ctx->crtc.i80_mode)) --frm; break; case VIDCON1_VSTATUS_BP: @@ -163,7 +165,7 @@ static u32 decon_get_frame_count(struct decon_context *ctx, bool end) static void decon_setup_trigger(struct decon_context *ctx) { - if (!ctx->crtc->i80_mode && !(ctx->out_type & I80_HW_TRG)) + if (!ctx->crtc.i80_mode && !(ctx->out_type & I80_HW_TRG)) return; if (!(ctx->out_type & I80_HW_TRG)) { @@ -183,7 +185,7 @@ static void decon_setup_trigger(struct decon_context *ctx) static void decon_commit(struct exynos_drm_crtc *crtc) { - struct decon_context *ctx = crtc->ctx; + struct decon_context *ctx = to_decon(crtc); struct drm_display_mode *m = >base.mode; bool interlaced = false; u32 val; @@ -377,7 +379,7 @@ static void decon_shadow_protect(struct decon_context *ctx, bool protect) static void decon_atomic_begin(struct exynos_drm_crtc *crtc) { - struct decon_context *ctx = crtc->ctx; + struct decon_context *ctx = to_decon(crtc); decon_shadow_protect(ctx, true); } @@ -391,7 +393,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, { struct exynos_drm_plane_state *state = to_exynos_plane_state(plane->base.state); - struct decon_context *ctx = crtc->ctx; + struct decon_context *ctx = to_decon(crtc); struct drm_framebuffer *fb = state->base.fb; unsigned int win = state->base.normalized_zpos + ctx->first_win; unsigned int cpp = fb->format->cpp[0]; @@ -445,7 +447,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, static void decon_atomic_flush(struct exynos_drm_crtc *crtc) { - struct decon_context *ctx = crtc->ctx; + struct decon_context *ctx = to_decon(crtc); unsigned long flags; int win = hweight32(crtc->base.state->plane_mask) + ctx->first_win; @@ -502,7 +504,7 @@ static void decon_swreset(struct decon_context *ctx) static void decon_enable(struct exynos_drm_crtc *crtc) { - struct decon_context *ctx = crtc->ctx; + struct decon_context *ctx = to_decon(crtc); pm_runtime_get_sync(ctx->dev); @@ -510,12 +512,12 @@ static void decon_enable(struct exynos_drm_crtc *crtc) decon_swreset(ctx); - decon_commit(ctx->crtc); + decon_commit(>crtc); } static void decon_disable(struct exynos_drm_crtc *crtc) { - struct decon_context *ctx = crtc->ctx; + struct decon_context *ctx = to_decon(crtc); int i; if (!(ctx->out_type & I80_HW_TRG)) @@ -548,7 +550,7 @@ static irqreturn_t decon_te_irq_handler(int irq, void *dev_id) static void decon_clear_channels(struct exynos_drm_crtc
[PATCH v2 RESEND 03/24] drm/exynos: drop exynos_drm_plane_config structure
exynos_drm_plane_config must be present for every plane, and most fields are redundant with exynos_drm_plane: - pixel_formats, num_pixel_formats are stored in plane.base.format_*, - type is stored in plane.base.type, - zpos is always equal to plane.index. The only non-redundant field capabilities can be moved to exynos_drm_plane. As consequence of removing the structure some code should be refactored. The patch should not have functional changes. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 18 +++--- drivers/gpu/drm/exynos/exynos7_drm_decon.c| 11 +--- drivers/gpu/drm/exynos/exynos_drm_drv.h | 39 - drivers/gpu/drm/exynos/exynos_drm_fimd.c | 17 ++ drivers/gpu/drm/exynos/exynos_drm_plane.c | 56 +- drivers/gpu/drm/exynos/exynos_drm_vidi.c | 11 +--- drivers/gpu/drm/exynos/exynos_mixer.c | 58 +++ 7 files changed, 76 insertions(+), 134 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index 24df0b307b2f..ae0f475eb633 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -56,7 +56,6 @@ struct decon_context { struct drm_device *drm_dev; struct exynos_drm_crtc *crtc; struct exynos_drm_plane planes[WINDOWS_NR]; - struct exynos_drm_plane_config configs[WINDOWS_NR]; void __iomem*addr; struct regmap *sysreg; struct clk *clks[ARRAY_SIZE(decon_clks_name)]; @@ -608,22 +607,19 @@ static int decon_bind(struct device *dev, struct device *master, void *data) struct drm_device *drm_dev = data; struct exynos_drm_plane *exynos_plane; enum exynos_drm_output_type out_type; - unsigned int win; + unsigned int i; int ret; ctx->drm_dev = drm_dev; - for (win = ctx->first_win; win < WINDOWS_NR; win++) { - ctx->configs[win].pixel_formats = decon_formats; - ctx->configs[win].num_pixel_formats = ARRAY_SIZE(decon_formats); - ctx->configs[win].zpos = win - ctx->first_win; - ctx->configs[win].type = decon_win_types[win]; - ctx->configs[win].capabilities = EXYNOS_DRM_PLANE_CAP_ZPOS + for (i = ctx->first_win; i < WINDOWS_NR; i++) { + ctx->planes[i].index = i - ctx->first_win; + ctx->planes[i].capabilities = EXYNOS_DRM_PLANE_CAP_ZPOS | EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND; - - ret = exynos_plane_init(drm_dev, >planes[win], win, - >configs[win]); + ret = exynos_plane_init(drm_dev, >planes[i], + decon_formats, ARRAY_SIZE(decon_formats), + decon_win_types[i]); if (ret) return ret; } diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c index 812941b84287..6d462f057531 100644 --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c @@ -44,7 +44,6 @@ struct decon_context { struct drm_device *drm_dev; struct exynos_drm_crtc *crtc; struct exynos_drm_plane planes[WINDOWS_NR]; - struct exynos_drm_plane_config configs[WINDOWS_NR]; struct clk *pclk; struct clk *aclk; struct clk *eclk; @@ -626,13 +625,9 @@ static int decon_bind(struct device *dev, struct device *master, void *data) } for (i = 0; i < WINDOWS_NR; i++) { - ctx->configs[i].pixel_formats = decon_formats; - ctx->configs[i].num_pixel_formats = ARRAY_SIZE(decon_formats); - ctx->configs[i].zpos = i; - ctx->configs[i].type = decon_win_types[i]; - - ret = exynos_plane_init(drm_dev, >planes[i], i, - >configs[i]); + ctx->planes[i].index = i; + ret = exynos_plane_init(drm_dev, >planes[i], decon_formats, + ARRAY_SIZE(decon_formats), decon_win_types[i]); if (ret) return ret; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 1f6bb5516170..1d4ef0245958 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -71,11 +71,19 @@ to_exynos_plane_state(struct drm_plane_state *state) return container_of(state, struct exynos_drm_plane_state, base); } +#define EXYNOS_DRM_PLANE_CAP_DOUBLE(1 << 0) +#define EXYNOS_DRM_PLANE_CAP_SCALE
[PATCH v2 RESEND 04/24] drm/exynos: add exynos_drm_crtc_init function
Since exynos_drm_crtc is a struct which maps 1:1 to underlying device it is better to put it directly into device's context instead of allocating it separately. Another benefit is possibility of initialisation of its fields directly, without expanding exynos_drm_crtc_create which is already overloaded with number of arguments. As a first step of the transition initialisation function should be created. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos_drm_crtc.c | 10 ++ drivers/gpu/drm/exynos/exynos_drm_crtc.h | 2 ++ 2 files changed, 12 insertions(+) diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 1eebfa3fa8da..4ff1e0ff2255 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -172,6 +172,16 @@ static const struct drm_crtc_funcs exynos_crtc_funcs = { .disable_vblank = exynos_drm_crtc_disable_vblank, }; +int exynos_drm_crtc_init(struct exynos_drm_crtc *exynos_crtc, +struct drm_device *drm_dev) +{ + struct drm_crtc *crtc = _crtc->base; + + drm_crtc_helper_add(crtc, _crtc_helper_funcs); + return drm_crtc_init_with_planes(drm_dev, crtc, NULL, NULL, +_crtc_funcs, NULL); +} + struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev, struct drm_plane *plane, enum exynos_drm_output_type type, diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.h b/drivers/gpu/drm/exynos/exynos_drm_crtc.h index dec446109e6c..9e35a9e02332 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.h +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.h @@ -18,6 +18,8 @@ #include "exynos_drm_drv.h" +int exynos_drm_crtc_init(struct exynos_drm_crtc *exynos_crtc, +struct drm_device *drm_dev); struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev, struct drm_plane *plane, enum exynos_drm_output_type out_type, -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 RESEND 17/24] drm/exynos/gscaler: fix id assignement
Id should be assigned based on OF alias. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos_drm_gsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c index f048d97fe9e2..8d5aa70c8ab8 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c @@ -1287,7 +1287,7 @@ static int gsc_probe(struct platform_device *pdev) } /* context initailization */ - ctx->id = pdev->id; + ctx->id = of_alias_get_id(dev->of_node, "gsc"); platform_set_drvdata(pdev, ctx); -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 RESEND 10/24] drm/exynos: remove standalone exynos_drm_crtc leftovers
Since exynos_drm_crtc is always embedded exynos_drm_crtc_create helper and ctx field can be removed. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos_drm_crtc.c | 35 drivers/gpu/drm/exynos/exynos_drm_crtc.h | 5 drivers/gpu/drm/exynos/exynos_drm_drv.h | 2 -- 3 files changed, 42 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 4ff1e0ff2255..72e224e80565 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -182,41 +182,6 @@ int exynos_drm_crtc_init(struct exynos_drm_crtc *exynos_crtc, _crtc_funcs, NULL); } -struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev, - struct drm_plane *plane, - enum exynos_drm_output_type type, - const struct exynos_drm_crtc_ops *ops, - void *ctx) -{ - struct exynos_drm_crtc *exynos_crtc; - struct drm_crtc *crtc; - int ret; - - exynos_crtc = kzalloc(sizeof(*exynos_crtc), GFP_KERNEL); - if (!exynos_crtc) - return ERR_PTR(-ENOMEM); - - exynos_crtc->type = type; - exynos_crtc->ops = ops; - exynos_crtc->ctx = ctx; - - crtc = _crtc->base; - - ret = drm_crtc_init_with_planes(drm_dev, crtc, plane, NULL, - _crtc_funcs, NULL); - if (ret < 0) - goto err_crtc; - - drm_crtc_helper_add(crtc, _crtc_helper_funcs); - - return exynos_crtc; - -err_crtc: - plane->funcs->destroy(plane); - kfree(exynos_crtc); - return ERR_PTR(ret); -} - struct exynos_drm_crtc *exynos_drm_crtc_get_by_type(struct drm_device *drm_dev, enum exynos_drm_output_type out_type) { diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.h b/drivers/gpu/drm/exynos/exynos_drm_crtc.h index 9e35a9e02332..7b0c964521fa 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.h +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.h @@ -20,11 +20,6 @@ int exynos_drm_crtc_init(struct exynos_drm_crtc *exynos_crtc, struct drm_device *drm_dev); -struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev, - struct drm_plane *plane, - enum exynos_drm_output_type out_type, - const struct exynos_drm_crtc_ops *ops, - void *context); void exynos_drm_crtc_wait_pending_update(struct exynos_drm_crtc *exynos_crtc); void exynos_drm_crtc_finish_update(struct exynos_drm_crtc *exynos_crtc, struct exynos_drm_plane *exynos_plane); diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 1d4ef0245958..82af112be03d 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -147,14 +147,12 @@ struct exynos_drm_clk { * @base: crtc object. * @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI. * @ops: pointer to callbacks for exynos drm specific functionality - * @ctx: A pointer to the crtc's implementation specific context * @pipe_clk: A pointer to the crtc's pipeline clock. */ struct exynos_drm_crtc { struct drm_crtc base; enum exynos_drm_output_type type; const struct exynos_drm_crtc_ops*ops; - void*ctx; struct exynos_drm_clk *pipe_clk; booli80_mode : 1; }; -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 RESEND 20/24] drm/exynos/gscaler: add local path support
GSCALERs in Exynos5433 have local path to DECON and DECON_TV. They can be used as extra planes with support for non-RGB formats and scaling. To enable it GSCALER must expose exynos_plane with associated plane callbacks and bind it to DECONs CRTCs. Moreover device locking should be added to prevent simultanous device usage by IPP and DRM. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos_drm_gsc.c | 179 drivers/gpu/drm/exynos/regs-gsc.h | 6 + 2 files changed, 156 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c index 8d5aa70c8ab8..28a738a68a82 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c @@ -16,14 +16,16 @@ #include #include #include -#include #include #include +#include #include #include #include "regs-gsc.h" +#include "exynos_drm_crtc.h" #include "exynos_drm_drv.h" +#include "exynos_drm_fb.h" #include "exynos_drm_ipp.h" /* @@ -98,11 +100,13 @@ struct gsc_scaler { */ struct gsc_context { struct exynos_drm_ipp ipp; + struct exynos_drm_plane plane; struct drm_device *drm_dev; struct device *dev; struct exynos_drm_ipp_task *task; struct exynos_drm_ipp_formats *formats; unsigned intnum_formats; + struct spinlock lock; struct resource *regs_res; void __iomem*regs; @@ -113,8 +117,12 @@ struct gsc_context { int id; int irq; boolrotation; + boolenabled; + booluse_local_path; }; +#define to_gsc(ptr) container_of(ptr, struct gsc_context, ptr) + /** * struct gsc_driverdata - per device type driver data for init time. * @@ -127,6 +135,7 @@ struct gsc_driverdata { int num_limits; const char *clk_names[GSC_MAX_CLOCKS]; int num_clocks; + booluse_local_path; }; /* 8-tap Filter Coefficient */ @@ -377,6 +386,32 @@ static const int v_coef_4t[GSC_COEF_RATIO][GSC_COEF_ATTR][GSC_COEF_V_4T] = { } }; +static int gsc_dev_lock(struct gsc_context *ctx, void *task) +{ + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(>lock, flags); + if (ctx->task) + ret = -EBUSY; + else + ctx->task = task; + spin_unlock_irqrestore(>lock, flags); + return ret; +} + +static void *gsc_dev_unlock(struct gsc_context *ctx) +{ + unsigned long flags; + void *task; + + spin_lock_irqsave(>lock, flags); + task = ctx->task; + ctx->task = NULL; + spin_unlock_irqrestore(>lock, flags); + return task; +} + static int gsc_sw_reset(struct gsc_context *ctx) { u32 cfg; @@ -1021,6 +1056,7 @@ static int gsc_get_dst_buf_index(struct gsc_context *ctx) static irqreturn_t gsc_irq_handler(int irq, void *dev_id) { struct gsc_context *ctx = dev_id; + struct exynos_drm_ipp_task *task; u32 status; int err = 0; @@ -1049,10 +1085,8 @@ static irqreturn_t gsc_irq_handler(int irq, void *dev_id) err = -EINVAL; } - if (ctx->task) { - struct exynos_drm_ipp_task *task = ctx->task; - - ctx->task = NULL; + task = gsc_dev_unlock(ctx); + if (!IS_ERR_OR_NULL(task)) { pm_runtime_mark_last_busy(ctx->dev); pm_runtime_put_autosuspend(ctx->dev); exynos_drm_ipp_task_done(task, err); @@ -1117,13 +1151,15 @@ static int gsc_commit(struct exynos_drm_ipp *ipp, struct gsc_context *ctx = container_of(ipp, struct gsc_context, ipp); int ret; - pm_runtime_get_sync(ctx->dev); - ctx->task = task; + ret = gsc_dev_lock(ctx, task); + if (ret) + return ret; + pm_runtime_get_sync(ctx->dev); ret = gsc_reset(ctx); if (ret) { pm_runtime_put_autosuspend(ctx->dev); - ctx->task = NULL; + gsc_dev_unlock(ctx); return ret; } @@ -1147,10 +1183,8 @@ static void gsc_abort(struct exynos_drm_ipp *ipp, container_of(ipp, struct gsc_context, ipp); gsc_reset(ctx); - if (ctx->task) { - struct exynos_drm_ipp_task *task = ctx->task; - - ctx->task = NULL; + task = gsc_dev_unlock(ctx); + if (!IS_ERR_OR_NULL(task)) { pm_runtime_mark_last_busy(ctx->dev); pm_runtime_put_autosuspend(ctx->dev); exynos_drm_ipp_task_done(task, -EIO); @@ -1162,11 +1196,97 @@ static struct exynos_drm_ipp_funcs ipp_funcs = { .abort = gsc_abort, }; +static const unsigned int gsc_formats[] = { + DRM_FORMAT_ARGB, DRM_FORMAT_XRGB, DRM_FORMAT_BGRX, + DRM_FORMAT_RGB565, + DRM_FORMAT_NV12, DRM_FORMAT_NV16,
[PATCH v2 RESEND 23/24] drm/exynos/gscaler: change supported color format BGRX8888 to XBGR8888
GSCALER does not support BGRX, instead it supports XBGR. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos_drm_gsc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c index 28a738a68a82..c7a97d053ab1 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c @@ -502,7 +502,7 @@ static void gsc_src_set_fmt(struct gsc_context *ctx, u32 fmt, bool tiled) case DRM_FORMAT_ARGB: cfg |= GSC_IN_XRGB; break; - case DRM_FORMAT_BGRX: + case DRM_FORMAT_XBGR: cfg |= (GSC_IN_XRGB | GSC_IN_RB_SWAP); break; case DRM_FORMAT_YUYV: @@ -689,7 +689,7 @@ static void gsc_dst_set_fmt(struct gsc_context *ctx, u32 fmt, bool tiled) case DRM_FORMAT_XRGB: cfg |= (GSC_OUT_XRGB | GSC_OUT_GLOBAL_ALPHA(0xff)); break; - case DRM_FORMAT_BGRX: + case DRM_FORMAT_XBGR: cfg |= (GSC_OUT_XRGB | GSC_OUT_RB_SWAP); break; case DRM_FORMAT_YUYV: @@ -1197,7 +1197,7 @@ static struct exynos_drm_ipp_funcs ipp_funcs = { }; static const unsigned int gsc_formats[] = { - DRM_FORMAT_ARGB, DRM_FORMAT_XRGB, DRM_FORMAT_BGRX, + DRM_FORMAT_ARGB, DRM_FORMAT_XRGB, DRM_FORMAT_XBGR, DRM_FORMAT_RGB565, DRM_FORMAT_NV12, DRM_FORMAT_NV16, DRM_FORMAT_NV21, DRM_FORMAT_NV61, DRM_FORMAT_UYVY, DRM_FORMAT_VYUY, DRM_FORMAT_YUYV, DRM_FORMAT_YVYU, -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 RESEND 16/24] drm/exynos: add GSCALER plane capability
This bit will indicate the plane is provided by GSCALER. Tests shows that GSCALER does not like to convert from/to too small buffers. Since exact constraints are not provided by documentation rough estimate of 64 pixel has been applied. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos_drm_drv.h | 1 + drivers/gpu/drm/exynos/exynos_drm_plane.c | 14 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 5d06e796dc80..7bdbac639b2b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -75,6 +75,7 @@ to_exynos_plane_state(struct drm_plane_state *state) #define EXYNOS_DRM_PLANE_CAP_TILE (1 << 3) #define EXYNOS_DRM_PLANE_CAP_PIX_BLEND (1 << 4) #define EXYNOS_DRM_PLANE_CAP_WIN_BLEND (1 << 5) +#define EXYNOS_DRM_PLANE_CAP_GSCALER (1 << 6) struct exynos_drm_plane; struct exynos_drm_plane_ops { diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index 5f8f56b69369..89168157e1e2 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -198,6 +198,11 @@ exynos_drm_plane_check_format(struct exynos_drm_plane_state *state) return 0; } +static bool is_in_range(int val, int min, int max) +{ + return (val >= min) && (val < max); +} + static int exynos_drm_plane_check_size(struct exynos_drm_plane_state *state) { @@ -205,7 +210,7 @@ exynos_drm_plane_check_size(struct exynos_drm_plane_state *state) bool width_ok = false, height_ok = false; if (plane->capabilities & EXYNOS_DRM_PLANE_CAP_SCALE) - return 0; + width_ok = height_ok = true; if (state->src.w == state->crtc.w) width_ok = true; @@ -221,6 +226,13 @@ exynos_drm_plane_check_size(struct exynos_drm_plane_state *state) state->v_ratio == (1 << 15)) height_ok = true; + if (plane->capabilities & EXYNOS_DRM_PLANE_CAP_GSCALER) { + width_ok = is_in_range(state->src.w, 64, 4800) && + is_in_range(state->crtc.w, 64, 4800); + height_ok = is_in_range(state->src.h, 64, 3344) && + is_in_range(state->crtc.h, 64, 3344); + } + if (width_ok && height_ok) return 0; -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 RESEND 09/24] drm/exynos/vidi: embed exynos_drm_crtc directly into context
Since crtc maps 1:1 to the device there is no point in allocating it separately, another benefit is possibility of direct initialisation of its fields which is more readable and allows further expansion. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos_drm_vidi.c | 26 +--- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index b61ae3415b8c..377aae5f7631 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -41,7 +41,7 @@ struct vidi_context { struct drm_encoder encoder; struct platform_device *pdev; struct drm_device *drm_dev; - struct exynos_drm_crtc *crtc; + struct exynos_drm_crtc crtc; struct drm_connectorconnector; struct exynos_drm_plane planes[WINDOWS_NR]; struct edid *raw_edid; @@ -57,6 +57,8 @@ static inline struct vidi_context *encoder_to_vidi(struct drm_encoder *e) return container_of(e, struct vidi_context, encoder); } +#define to_vidi(ptr) container_of(ptr, struct vidi_context, ptr) + static const char fake_edid_info[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x4c, 0x2d, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x30, 0x12, 0x01, 0x03, 0x80, 0x10, 0x09, 0x78, @@ -96,7 +98,7 @@ static const enum drm_plane_type vidi_win_types[WINDOWS_NR] = { static int vidi_enable_vblank(struct exynos_drm_crtc *crtc) { - struct vidi_context *ctx = crtc->ctx; + struct vidi_context *ctx = to_vidi(crtc); if (ctx->suspended) return -EPERM; @@ -115,7 +117,7 @@ static void vidi_update_plane(struct exynos_drm_crtc *crtc, struct exynos_drm_plane *plane) { struct drm_plane_state *state = plane->base.state; - struct vidi_context *ctx = crtc->ctx; + struct vidi_context *ctx = to_vidi(crtc); dma_addr_t addr; if (ctx->suspended) @@ -127,7 +129,7 @@ static void vidi_update_plane(struct exynos_drm_crtc *crtc, static void vidi_enable(struct exynos_drm_crtc *crtc) { - struct vidi_context *ctx = crtc->ctx; + struct vidi_context *ctx = to_vidi(crtc); mutex_lock(>lock); @@ -140,7 +142,7 @@ static void vidi_enable(struct exynos_drm_crtc *crtc) static void vidi_disable(struct exynos_drm_crtc *crtc) { - struct vidi_context *ctx = crtc->ctx; + struct vidi_context *ctx = to_vidi(crtc); drm_crtc_vblank_off(>base); @@ -164,7 +166,7 @@ static void vidi_fake_vblank_timer(struct timer_list *t) { struct vidi_context *ctx = from_timer(ctx, t, timer); - if (drm_crtc_handle_vblank(>crtc->base)) + if (drm_crtc_handle_vblank(>crtc.base)) mod_timer(>timer, jiffies + msecs_to_jiffies(VIDI_REFRESH_TIME) - 1); } @@ -377,7 +379,6 @@ static int vidi_bind(struct device *dev, struct device *master, void *data) struct vidi_context *ctx = dev_get_drvdata(dev); struct drm_device *drm_dev = data; struct drm_encoder *encoder = >encoder; - struct exynos_drm_plane *exynos_plane; unsigned int i; int ret; @@ -390,13 +391,14 @@ static int vidi_bind(struct device *dev, struct device *master, void *data) return ret; } - exynos_plane = >planes[DEFAULT_WIN]; - ctx->crtc = exynos_drm_crtc_create(drm_dev, _plane->base, - EXYNOS_DISPLAY_TYPE_VIDI, _crtc_ops, ctx); - if (IS_ERR(ctx->crtc)) { + ctx->crtc.type = EXYNOS_DISPLAY_TYPE_VIDI; + ctx->crtc.ops = _crtc_ops; + ret = exynos_drm_crtc_init(>crtc, drm_dev); + if (ret) { DRM_ERROR("failed to create crtc.\n"); - return PTR_ERR(ctx->crtc); + return ret; } + ctx->crtc.base.primary = >planes[DEFAULT_WIN].base; drm_encoder_init(drm_dev, encoder, _vidi_encoder_funcs, DRM_MODE_ENCODER_TMDS, NULL); -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 RESEND 08/24] drm/exynos/mixer: embed exynos_drm_crtc directly into context
Since crtc maps 1:1 to the device there is no point in allocating it separately, another benefit is possibility of direct initialisation of its fields which is more readable and allows further expansion. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos_mixer.c | 39 ++- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 750f682e9c31..946d62ae83e3 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -98,7 +98,7 @@ struct mixer_context { struct platform_device *pdev; struct device *dev; struct drm_device *drm_dev; - struct exynos_drm_crtc *crtc; + struct exynos_drm_crtc crtc; struct exynos_drm_plane planes[MIXER_WIN_NR]; unsigned long flags; @@ -116,6 +116,8 @@ struct mixer_context { int scan_value; }; +#define to_mixer(ptr) container_of(ptr, struct mixer_context, ptr) + struct mixer_drv_data { enum mixer_version_id version; boolis_vp_enabled; @@ -426,7 +428,7 @@ static void mixer_stop(struct mixer_context *ctx) static void mixer_commit(struct mixer_context *ctx) { - struct drm_display_mode *mode = >crtc->base.state->adjusted_mode; + struct drm_display_mode *mode = >crtc.base.state->adjusted_mode; mixer_cfg_scan(ctx, mode->hdisplay, mode->vdisplay); mixer_cfg_rgb_fmt(ctx, mode); @@ -712,7 +714,7 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg) goto out; } - drm_crtc_handle_vblank(>crtc->base); + drm_crtc_handle_vblank(>crtc.base); } out: @@ -856,7 +858,7 @@ static void mixer_ctx_remove(struct mixer_context *mixer_ctx) static int mixer_enable_vblank(struct exynos_drm_crtc *crtc) { - struct mixer_context *mixer_ctx = crtc->ctx; + struct mixer_context *mixer_ctx = to_mixer(crtc); __set_bit(MXR_BIT_VSYNC, _ctx->flags); if (!test_bit(MXR_BIT_POWERED, _ctx->flags)) @@ -871,7 +873,7 @@ static int mixer_enable_vblank(struct exynos_drm_crtc *crtc) static void mixer_disable_vblank(struct exynos_drm_crtc *crtc) { - struct mixer_context *mixer_ctx = crtc->ctx; + struct mixer_context *mixer_ctx = to_mixer(crtc); __clear_bit(MXR_BIT_VSYNC, _ctx->flags); @@ -885,7 +887,7 @@ static void mixer_disable_vblank(struct exynos_drm_crtc *crtc) static void mixer_atomic_begin(struct exynos_drm_crtc *crtc) { - struct mixer_context *mixer_ctx = crtc->ctx; + struct mixer_context *mixer_ctx = to_mixer(crtc); if (!test_bit(MXR_BIT_POWERED, _ctx->flags)) return; @@ -896,7 +898,7 @@ static void mixer_atomic_begin(struct exynos_drm_crtc *crtc) static void mixer_update_plane(struct exynos_drm_crtc *crtc, struct exynos_drm_plane *plane) { - struct mixer_context *mixer_ctx = crtc->ctx; + struct mixer_context *mixer_ctx = to_mixer(crtc); DRM_DEBUG_KMS("win: %d\n", plane->index); @@ -912,7 +914,7 @@ static void mixer_update_plane(struct exynos_drm_crtc *crtc, static void mixer_disable_plane(struct exynos_drm_crtc *crtc, struct exynos_drm_plane *plane) { - struct mixer_context *mixer_ctx = crtc->ctx; + struct mixer_context *mixer_ctx = to_mixer(crtc); unsigned long flags; DRM_DEBUG_KMS("win: %d\n", plane->index); @@ -927,7 +929,7 @@ static void mixer_disable_plane(struct exynos_drm_crtc *crtc, static void mixer_atomic_flush(struct exynos_drm_crtc *crtc) { - struct mixer_context *mixer_ctx = crtc->ctx; + struct mixer_context *mixer_ctx = to_mixer(crtc); if (!test_bit(MXR_BIT_POWERED, _ctx->flags)) return; @@ -938,7 +940,7 @@ static void mixer_atomic_flush(struct exynos_drm_crtc *crtc) static void mixer_enable(struct exynos_drm_crtc *crtc) { - struct mixer_context *ctx = crtc->ctx; + struct mixer_context *ctx = to_mixer(crtc); if (test_bit(MXR_BIT_POWERED, >flags)) return; @@ -967,7 +969,7 @@ static void mixer_enable(struct exynos_drm_crtc *crtc) static void mixer_disable(struct exynos_drm_crtc *crtc) { - struct mixer_context *ctx = crtc->ctx; + struct mixer_context *ctx = to_mixer(crtc); int i; if (!test_bit(MXR_BIT_POWERED, >flags)) @@ -989,7 +991,7 @@ static void mixer_disable(struct exynos_drm_crtc *crtc) static int mixer_mode_valid(struct exynos_drm_crtc *crtc, const struct drm_display_mode *mode) { - struct mixer_context *ctx = crtc->ctx; + struct mixer_context *ctx = to_mixer(crtc); u32 w = mode->hdisplay, h = mode->vdisplay; DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d,
[PATCH v2 RESEND 01/24] drm/exynos: remove exynos_drm_plane.h header
The header contains only declaration of one function, the rest of exynos plane declaration is in exynos_drm_drv.h. Let's merge it together. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 1 - drivers/gpu/drm/exynos/exynos7_drm_decon.c| 1 - drivers/gpu/drm/exynos/exynos_drm_crtc.c | 1 - drivers/gpu/drm/exynos/exynos_drm_drv.c | 1 - drivers/gpu/drm/exynos/exynos_drm_drv.h | 4 drivers/gpu/drm/exynos/exynos_drm_fimd.c | 1 - drivers/gpu/drm/exynos/exynos_drm_plane.c | 1 - drivers/gpu/drm/exynos/exynos_drm_plane.h | 14 -- drivers/gpu/drm/exynos/exynos_drm_vidi.c | 1 - drivers/gpu/drm/exynos/exynos_mixer.c | 1 - 10 files changed, 4 insertions(+), 22 deletions(-) delete mode 100644 drivers/gpu/drm/exynos/exynos_drm_plane.h diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index bdfec5f977e9..24df0b307b2f 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -24,7 +24,6 @@ #include "exynos_drm_drv.h" #include "exynos_drm_crtc.h" #include "exynos_drm_fb.h" -#include "exynos_drm_plane.h" #include "regs-decon5433.h" #define DSD_CFG_MUX 0x1004 diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c index 381aa3d60e37..812941b84287 100644 --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c @@ -27,7 +27,6 @@ #include #include "exynos_drm_crtc.h" -#include "exynos_drm_plane.h" #include "exynos_drm_drv.h" #include "exynos_drm_fb.h" #include "regs-decon7.h" diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 96ee83a798c4..1eebfa3fa8da 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -20,7 +20,6 @@ #include "exynos_drm_crtc.h" #include "exynos_drm_drv.h" -#include "exynos_drm_plane.h" static void exynos_drm_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index e1ef9dc9ebf3..2155586646dc 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -26,7 +26,6 @@ #include "exynos_drm_fbdev.h" #include "exynos_drm_fb.h" #include "exynos_drm_gem.h" -#include "exynos_drm_plane.h" #include "exynos_drm_ipp.h" #include "exynos_drm_vidi.h" #include "exynos_drm_g2d.h" diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 71eb240bc1f4..6e38d0dc4457 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -113,6 +113,10 @@ struct exynos_drm_plane_config { unsigned int capabilities; }; +int exynos_plane_init(struct drm_device *dev, + struct exynos_drm_plane *exynos_plane, unsigned int index, + const struct exynos_drm_plane_config *config); + /* * Exynos drm crtc ops * diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 46588a14f0c3..b1a9502a4140 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -31,7 +31,6 @@ #include "exynos_drm_drv.h" #include "exynos_drm_fb.h" #include "exynos_drm_crtc.h" -#include "exynos_drm_plane.h" /* * FIMD stands for Fully Interactive Mobile Display and diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index df0508e0e49e..8af0eba3f362 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -19,7 +19,6 @@ #include "exynos_drm_crtc.h" #include "exynos_drm_fb.h" #include "exynos_drm_gem.h" -#include "exynos_drm_plane.h" /* * This function is to get X or Y size shown via screen. This needs length and diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.h b/drivers/gpu/drm/exynos/exynos_drm_plane.h deleted file mode 100644 index 497047b19614.. --- a/drivers/gpu/drm/exynos/exynos_drm_plane.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (C) 2011 Samsung Electronics Co.Ltd - * Authors: Joonyoung Shim - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -int exynos_plane_init(struct drm_device *dev, - struct exynos_drm_plane *exynos_plane, unsigned int index, - const struct exynos_drm_plane_config *config); diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index
[PATCH v2 RESEND 02/24] drm/exynos: remove spare macro
MAX_CRTC macro is not used at all. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos_drm_drv.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 6e38d0dc4457..1f6bb5516170 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -18,7 +18,6 @@ #include #include -#define MAX_CRTC 3 #define MAX_PLANE 5 #define MAX_FB_BUFFER 4 -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 RESEND 07/24] drm/exynos/fimd: embed exynos_drm_crtc directly into context
Since crtc maps 1:1 to the device there is no point in allocating it separately, another benefit is possibility of direct initialisation of its fields which is more readable and allows further expansion. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 60 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 2d34ca375ee1..8ea1cfd51736 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -169,7 +169,7 @@ static struct fimd_driver_data exynos5420_fimd_driver_data = { struct fimd_context { struct device *dev; struct drm_device *drm_dev; - struct exynos_drm_crtc *crtc; + struct exynos_drm_crtc crtc; struct exynos_drm_plane planes[WINDOWS_NR]; struct clk *bus_clk; struct clk *lcd_clk; @@ -193,6 +193,8 @@ struct fimd_context { struct exynos_drm_clk dp_clk; }; +#define to_fimd(ptr) container_of(ptr, struct fimd_context, ptr) + static const struct of_device_id fimd_driver_dt_match[] = { { .compatible = "samsung,s3c6400-fimd", .data = _fimd_driver_data }, @@ -235,7 +237,7 @@ static inline void fimd_set_bits(struct fimd_context *ctx, u32 reg, u32 mask, static int fimd_enable_vblank(struct exynos_drm_crtc *crtc) { - struct fimd_context *ctx = crtc->ctx; + struct fimd_context *ctx = to_fimd(crtc); u32 val; if (ctx->suspended) @@ -267,7 +269,7 @@ static int fimd_enable_vblank(struct exynos_drm_crtc *crtc) static void fimd_disable_vblank(struct exynos_drm_crtc *crtc) { - struct fimd_context *ctx = crtc->ctx; + struct fimd_context *ctx = to_fimd(crtc); u32 val; if (ctx->suspended) @@ -291,7 +293,7 @@ static void fimd_disable_vblank(struct exynos_drm_crtc *crtc) static void fimd_wait_for_vblank(struct exynos_drm_crtc *crtc) { - struct fimd_context *ctx = crtc->ctx; + struct fimd_context *ctx = to_fimd(crtc); if (ctx->suspended) return; @@ -345,7 +347,7 @@ static void fimd_disable_win(struct fimd_context *ctx, int win) static void fimd_clear_channels(struct exynos_drm_crtc *crtc) { - struct fimd_context *ctx = crtc->ctx; + struct fimd_context *ctx = to_fimd(crtc); unsigned int win, ch_enabled = 0; DRM_DEBUG_KMS("%s\n", __FILE__); @@ -370,9 +372,9 @@ static void fimd_clear_channels(struct exynos_drm_crtc *crtc) if (ch_enabled) { ctx->suspended = false; - fimd_enable_vblank(ctx->crtc); - fimd_wait_for_vblank(ctx->crtc); - fimd_disable_vblank(ctx->crtc); + fimd_enable_vblank(>crtc); + fimd_wait_for_vblank(>crtc); + fimd_disable_vblank(>crtc); ctx->suspended = true; } @@ -388,7 +390,7 @@ static int fimd_atomic_check(struct exynos_drm_crtc *crtc, struct drm_crtc_state *state) { struct drm_display_mode *mode = >adjusted_mode; - struct fimd_context *ctx = crtc->ctx; + struct fimd_context *ctx = to_fimd(crtc); unsigned long ideal_clk, lcd_rate; u32 clkdiv; @@ -448,7 +450,7 @@ static void fimd_setup_trigger(struct fimd_context *ctx) static void fimd_commit(struct exynos_drm_crtc *crtc) { - struct fimd_context *ctx = crtc->ctx; + struct fimd_context *ctx = to_fimd(crtc); struct drm_display_mode *mode = >base.state->adjusted_mode; const struct fimd_driver_data *driver_data = ctx->driver_data; void *timing_base = ctx->regs + driver_data->timing_base; @@ -754,7 +756,7 @@ static void fimd_shadow_protect_win(struct fimd_context *ctx, static void fimd_atomic_begin(struct exynos_drm_crtc *crtc) { - struct fimd_context *ctx = crtc->ctx; + struct fimd_context *ctx = to_fimd(crtc); int i; if (ctx->suspended) @@ -766,7 +768,7 @@ static void fimd_atomic_begin(struct exynos_drm_crtc *crtc) static void fimd_atomic_flush(struct exynos_drm_crtc *crtc) { - struct fimd_context *ctx = crtc->ctx; + struct fimd_context *ctx = to_fimd(crtc); int i; if (ctx->suspended) @@ -789,7 +791,7 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc, { struct exynos_drm_plane_state *state = to_exynos_plane_state(plane->base.state); - struct fimd_context *ctx = crtc->ctx; + struct fimd_context *ctx = to_fimd(crtc); struct drm_framebuffer *fb = state->base.fb; dma_addr_t dma_addr; unsigned long val, size, offset; @@ -878,7 +880,7 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc, static void fimd_enable(struct exynos_drm_crtc *crtc) {
[PATCH v2 RESEND 00/24] drm/exynos: add support for GSCALER planes on Exynos5433
Hi Inki, GSCALERs in Exynos SoCs support conversion between wide range of image formats, plus scaling and rotation. Driver already supports mem2mem mode - via ExynosDRM IPP framework. This patchset adds support for mem to display mode - framebuffers can be converted, scaled and send directly to Display Controller. From DRM framework's point of view every GSCALER exposes drm_plane which can be connected to display controller (display panel or TV). The feature is not well documented so the development was quite difficult - a process of trial and error, vendor code analysis, guessing from datasheets. Hopefully most of the issues were solved. I have developed and tested it on TM2 device with panel and TV paths. The patchset contains three parts: 1. Preparatory patches - mostly cleanup and refactoring of drm_crtc and drm_plane related structures, to allow usage of planes which are not physically bound to crtcs (01-13). 2. Adding local path support to GSCALER and DECON (14-20). 3. Few fixes of bugs existing already in the code but discovered due to added local path support (21-23). The patchset is based on exynos_drm_next plus my patchset adding zpos to DECON and FIMD - 'drm/exynos: add support for dynamic zpos in DECON and FIMD' - it is required to allow set z-pos position of GSCALER planes. To simplify tests I have also created branch containing all required patches: Repo: https://git.tizen.org/cgit/platform/kernel/linux-exynos Branch: sandbox/ahajda/dev/exynos-drm-local-path This is v2 version of the patchset. In this version I have moved code setting cursor plane in crtc to separate patch together with code disabling fast cursor updates - hardware does not support it. To keep bisectability DTS patches should be applied before subsequent ones. Regards Andrzej Andrzej Hajda (24): drm/exynos: remove exynos_drm_plane.h header drm/exynos: remove spare macro drm/exynos: drop exynos_drm_plane_config structure drm/exynos: add exynos_drm_crtc_init function drm/exynos/decon5433: embed exynos_drm_crtc directly into context drm/exynos/decon7: embed exynos_drm_crtc directly into context drm/exynos/fimd: embed exynos_drm_crtc directly into context drm/exynos/mixer: embed exynos_drm_crtc directly into context drm/exynos/vidi: embed exynos_drm_crtc directly into context drm/exynos: remove standalone exynos_drm_crtc leftovers drm/exynos/vidi: remove encoder_to_vidi helper drm/exynos: unify plane type assignment drm/exynos: set primary plane in exynos_drm_crtc_init drm/exynos: set cursor plane in exynos_drm_crtc_init drm/exynos: add plane update/disable callbacks for planes drm/exynos: add GSCALER plane capability drm/exynos/gscaler: fix id assignement arm64: dts: exynos: configure GSCALER related clocks arm64: dts: exynos: add DSD/GSD clocks to DECONs and GSCALERs drm/exynos/gscaler: add local path support drm/exynos/decon5433: add local path support drm/exynos/decon5433: wait for finish previous update drm/exynos/gscaler: change supported color format BGRX to XBGR drm/exynos/gscaler: fix handling YVU420 pixel format .../dts/exynos/exynos5433-tm2-common.dtsi | 6 + arch/arm64/boot/dts/exynos/exynos5433-tm2.dts | 6 +- arch/arm64/boot/dts/exynos/exynos5433.dtsi| 25 +- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 162 - drivers/gpu/drm/exynos/exynos7_drm_decon.c| 66 +++-- drivers/gpu/drm/exynos/exynos_drm_crtc.c | 46 ++-- drivers/gpu/drm/exynos/exynos_drm_crtc.h | 7 +- drivers/gpu/drm/exynos/exynos_drm_drv.c | 1 - drivers/gpu/drm/exynos/exynos_drm_drv.h | 50 ++-- drivers/gpu/drm/exynos/exynos_drm_fb.c| 10 +- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 85 +++ drivers/gpu/drm/exynos/exynos_drm_gsc.c | 229 ++ drivers/gpu/drm/exynos/exynos_drm_plane.c | 84 --- drivers/gpu/drm/exynos/exynos_drm_plane.h | 14 -- drivers/gpu/drm/exynos/exynos_drm_vidi.c | 48 ++-- drivers/gpu/drm/exynos/exynos_mixer.c | 95 +++- drivers/gpu/drm/exynos/regs-decon5433.h | 6 + drivers/gpu/drm/exynos/regs-gsc.h | 6 + 18 files changed, 538 insertions(+), 408 deletions(-) delete mode 100644 drivers/gpu/drm/exynos/exynos_drm_plane.h -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 RESEND 06/24] drm/exynos/decon7: embed exynos_drm_crtc directly into context
Since crtc maps 1:1 to the device there is no point in allocating it separately, another benefit is possibility of direct initialisation of its fields which is more readable and allows further expansion. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos7_drm_decon.c | 50 +++--- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c index 6d462f057531..22659f2da755 100644 --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c @@ -42,7 +42,7 @@ struct decon_context { struct device *dev; struct drm_device *drm_dev; - struct exynos_drm_crtc *crtc; + struct exynos_drm_crtc crtc; struct exynos_drm_plane planes[WINDOWS_NR]; struct clk *pclk; struct clk *aclk; @@ -58,6 +58,8 @@ struct decon_context { struct drm_encoder *encoder; }; +#define to_decon(ptr) container_of(ptr, struct decon_context, ptr) + static const struct of_device_id decon_driver_dt_match[] = { {.compatible = "samsung,exynos7-decon"}, {}, @@ -83,7 +85,7 @@ static const enum drm_plane_type decon_win_types[WINDOWS_NR] = { static void decon_wait_for_vblank(struct exynos_drm_crtc *crtc) { - struct decon_context *ctx = crtc->ctx; + struct decon_context *ctx = to_decon(crtc); if (ctx->suspended) return; @@ -102,7 +104,7 @@ static void decon_wait_for_vblank(struct exynos_drm_crtc *crtc) static void decon_clear_channels(struct exynos_drm_crtc *crtc) { - struct decon_context *ctx = crtc->ctx; + struct decon_context *ctx = to_decon(crtc); unsigned int win, ch_enabled = 0; DRM_DEBUG_KMS("%s\n", __FILE__); @@ -120,7 +122,7 @@ static void decon_clear_channels(struct exynos_drm_crtc *crtc) /* Wait for vsync, as disable channel takes effect at next vsync */ if (ch_enabled) - decon_wait_for_vblank(ctx->crtc); + decon_wait_for_vblank(>crtc); } static int decon_ctx_initialize(struct decon_context *ctx, @@ -128,7 +130,7 @@ static int decon_ctx_initialize(struct decon_context *ctx, { ctx->drm_dev = drm_dev; - decon_clear_channels(ctx->crtc); + decon_clear_channels(>crtc); return exynos_drm_register_dma(drm_dev, ctx->dev); } @@ -153,7 +155,7 @@ static u32 decon_calc_clkdiv(struct decon_context *ctx, static void decon_commit(struct exynos_drm_crtc *crtc) { - struct decon_context *ctx = crtc->ctx; + struct decon_context *ctx = to_decon(crtc); struct drm_display_mode *mode = >base.state->adjusted_mode; u32 val, clkdiv; @@ -218,7 +220,7 @@ static void decon_commit(struct exynos_drm_crtc *crtc) static int decon_enable_vblank(struct exynos_drm_crtc *crtc) { - struct decon_context *ctx = crtc->ctx; + struct decon_context *ctx = to_decon(crtc); u32 val; if (ctx->suspended) @@ -243,7 +245,7 @@ static int decon_enable_vblank(struct exynos_drm_crtc *crtc) static void decon_disable_vblank(struct exynos_drm_crtc *crtc) { - struct decon_context *ctx = crtc->ctx; + struct decon_context *ctx = to_decon(crtc); u32 val; if (ctx->suspended) @@ -368,7 +370,7 @@ static void decon_shadow_protect_win(struct decon_context *ctx, static void decon_atomic_begin(struct exynos_drm_crtc *crtc) { - struct decon_context *ctx = crtc->ctx; + struct decon_context *ctx = to_decon(crtc); int i; if (ctx->suspended) @@ -383,7 +385,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, { struct exynos_drm_plane_state *state = to_exynos_plane_state(plane->base.state); - struct decon_context *ctx = crtc->ctx; + struct decon_context *ctx = to_decon(crtc); struct drm_framebuffer *fb = state->base.fb; int padding; unsigned long val, alpha; @@ -479,7 +481,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, static void decon_disable_plane(struct exynos_drm_crtc *crtc, struct exynos_drm_plane *plane) { - struct decon_context *ctx = crtc->ctx; + struct decon_context *ctx = to_decon(crtc); unsigned int win = plane->index; u32 val; @@ -501,7 +503,7 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc, static void decon_atomic_flush(struct exynos_drm_crtc *crtc) { - struct decon_context *ctx = crtc->ctx; + struct decon_context *ctx = to_decon(crtc); int i; if (ctx->suspended) @@ -531,7 +533,7 @@ static void decon_init(struct decon_context *ctx) static void decon_enable(struct exynos_drm_crtc *crtc) { - struct decon_context *ctx = crtc->ctx; + struct
Re: [21/21] drm/bridge: tc358767: implement naive HPD handling
On 20/03/2019 08:57, Tomi Valkeinen wrote: > On 19/03/2019 20:18, Andrey Smirnov wrote: > >> TC358767 has two GPIO pins that can be used for HPD signal. I think >> instead of hardcoding GPIO0 here it would be more flexible to expose >> boths gpios as a gpiochip and use gpiolib API to query the value of >> HPD as well as use "hpd-gpios" binidng in DT to select which input to >> use. >> >> Another argument in favour of this solution is that Toshiba's FAEs (at >> least some) recommend thier customers to connect HPD signal to SoC's >> GPIOs and bypass TC358767 entirely. Their reasoning being that >> TC358767 implements a generic GPIO contoller and there's no advantage >> in going through TC358767 if you could use your "normal" GPIOs. >> >> Using gpiolib API would allow us to handle both usecase with the same >> code. >> >> Lastly, by treating "hpd-gpios" as an optional property, we can >> preserve old driver behaviour regardless if it is connected to DP or >> eDP panel. Not saying that this is really worth doing, just pointing >> out that this option would be on the table as well. > > I think that's a good point. > > There's one thing that TC358767 offers, which may not be available on > most generic GPIO controllers, though: it can detect short (programmable > length) pulses, thus it's possible to easily implement the DisplayPort > IRQ mechanism. I'm not sure if it's possible to implement reliable DP > IRQ detection without HW support. > > Still, I think using standard gpios makes sense. After implementing the gpiochip (it works), I started to wonder... If TC358767 is used as a gpio expander, for whatever purpose, outside the TC358767 driver, then obviously we need the gpiochip driver. But I don't think anyone needs that. Then we have two cases 1) HPD connected to TC358767, 2) HPD goes directly to the SoC, or worded differently, HPD is handled by something else than TC358767. 1) was implemented in this current patch, and there's no real benefit with the gpiochip. It's somewhat confusing that the driver provides a gpiochip which the same driver then uses, for its internal functionality. 2) should actually not involve TC358767 driver at all as it's totally outside TC358767. If the HPD goes from the DP connector to the SoC, we should have the DP connector driver handle it. Currently that connector is in the TC358767 driver, but it should really be separated. So... Obviously what's missing from the current patch is that we need to be able to say which of the two GPIOs are used for the HPD (if any). But I'm debating with myself whether gpiochip here is a sane choice or not. 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
Re: [PATCH 3/4] drm/amd/display: In VRR mode, do DRM core vblank handling at end of vblank.
On 3/20/19 3:51 AM, Mario Kleiner wrote: > Ok, fixed all the style issues and ran checkpatch over the patches. Thanks. > > On Tue, Mar 19, 2019 at 2:32 PM Kazlauskas, Nicholas > wrote: >> >> On 3/19/19 9:23 AM, Kazlauskas, Nicholas wrote: >>> On 3/18/19 1:19 PM, Mario Kleiner wrote: In VRR mode, proper vblank/pageflip timestamps can only be computed after the display scanout position has left front-porch. Therefore delay calls to drm_crtc_handle_vblank(), and thereby calls to drm_update_vblank_count() and pageflip event delivery, to after the end of front-porch when in VRR mode. We add a new vupdate irq, which triggers at the end of the vupdate interval, ie. at the end of vblank, and calls the core vblank handler function. The new irq handler is not executed in standard non-VRR mode, so vblank handling for fixed refresh rate mode is identical to the past implementation. Signed-off-by: Mario Kleiner >> >> Looks I lost some of my comments I wanted to send in my last email. Just >> a few nitpicks (including some things Paul mentioned). >> >> Also meant to CC Harry on this as well. >> --- drivers/gpu/drm/amd/amdgpu/amdgpu.h| 1 + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 129 - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 9 ++ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c | 22 .../amd/display/dc/irq/dce110/irq_service_dce110.c | 7 +- .../amd/display/dc/irq/dce120/irq_service_dce120.c | 7 +- .../amd/display/dc/irq/dce80/irq_service_dce80.c | 6 +- .../amd/display/dc/irq/dcn10/irq_service_dcn10.c | 40 +-- 8 files changed, 205 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index f88761a..64167dd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -827,6 +827,7 @@ struct amdgpu_device { /* For pre-DCE11. DCE11 and later are in "struct amdgpu_device->dm" */ struct work_struct hotplug_work; struct amdgpu_irq_src crtc_irq; +struct amdgpu_irq_src vupdate_irq; struct amdgpu_irq_src pageflip_irq; struct amdgpu_irq_src hpd_irq; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 85e4f87..555d9e9f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -315,6 +315,32 @@ static void dm_pflip_high_irq(void *interrupt_params) drm_crtc_vblank_put(_crtc->base); } +static void dm_vupdate_high_irq(void *interrupt_params) +{ +struct common_irq_params *irq_params = interrupt_params; +struct amdgpu_device *adev = irq_params->adev; +struct amdgpu_crtc *acrtc; +struct dm_crtc_state *acrtc_state; + +acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_VUPDATE); + +if (acrtc) { +acrtc_state = to_dm_crtc_state(acrtc->base.state); + +DRM_DEBUG_DRIVER("crtc:%d, vupdate-vrr:%d\n", acrtc->crtc_id, + amdgpu_dm_vrr_active(acrtc_state)); + +/* Core vblank handling is done here after end of front-porch in + * vrr mode, as vblank timestamping will give valid results + * while now done after front-porch. This will also deliver + * page-flip completion events that have been queued to us + * if a pageflip happened inside front-porch. + */ +if (amdgpu_dm_vrr_active(acrtc_state)) +drm_crtc_handle_vblank(>base) >>> I was thinking that 3 and 4 might have to be merged, but VRR pflip >>> timestamping seems to be the same as it was before (off by a line or >>> two) since it's not handled here yet. This seems to fix vblank events >>> and timestamping at least. >>> +} +} + static void dm_crtc_high_irq(void *interrupt_params) { struct common_irq_params *irq_params = interrupt_params; @@ -325,11 +351,24 @@ static void dm_crtc_high_irq(void *interrupt_params) acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_VBLANK); if (acrtc) { -drm_crtc_handle_vblank(>base); -amdgpu_dm_crtc_handle_crc_irq(>base); - acrtc_state = to_dm_crtc_state(acrtc->base.state); +DRM_DEBUG_DRIVER("crtc:%d, vupdate-vrr:%d\n", acrtc->crtc_id, +
Re: [RFC] drm/i915: adding state checker for gamma lut values
On Wed, 20 Mar 2019, "Sharma, Swati2" wrote: > On 15-Mar-19 3:17 PM, Nikula, Jani wrote: >> On Fri, 15 Mar 2019, swati2.sha...@intel.com wrote: >>> From: Swati Sharma >>> >>> Added state checker to validate gamma_lut values. This >>> reads hardware state, and compares the originally requested >>> state to the state read from hardware. >>> >>> This implementation can be used for Gen9+ platforms, >>> I haven't implemented it for legacy platforms. Just want to get >>> feedback if this is the right approach to follow. >>> >>> Also, inverse function of drm_color_lut_extract is missing >>> to convert hardware read values back to user values. >>> Thinking for that. I have added all "TODOs" and "Placeholders". >>> >>> Another approach: >>> Storing "word" to be written into hardware in dev_priv and >>> instead of comparing blob, comparing "word"? In dev_priv, >>> only pointer will be there (something like *gamma_word). >> You can't store it in dev_priv because it's crtc state specific >> data. Even if stored in crtc state, the approach doesn't help the >> initial hw state readout and takeover. >> >> Please use intel-gfx mailing list for i915 patches. >> >>> For this too, I will send a patch to make it more clear. >>> >>> Signed-off-by: Swati Sharma >>> --- >>> drivers/gpu/drm/i915/i915_drv.h | 1 + >>> drivers/gpu/drm/i915/intel_color.c | 127 >>> +-- >>> drivers/gpu/drm/i915/intel_display.c | 50 ++ >>> drivers/gpu/drm/i915/intel_drv.h | 1 + >>> 4 files changed, 173 insertions(+), 6 deletions(-) >>> >>> diff --git a/drivers/gpu/drm/i915/i915_drv.h >>> b/drivers/gpu/drm/i915/i915_drv.h >>> index c4ffe19..b41bfaa 100644 >>> --- a/drivers/gpu/drm/i915/i915_drv.h >>> +++ b/drivers/gpu/drm/i915/i915_drv.h >>> @@ -334,6 +334,7 @@ struct drm_i915_display_funcs { >>> * involved with the same commit. >>> */ >>> void (*load_luts)(const struct intel_crtc_state *crtc_state); >>> + void (*get_config)(struct intel_crtc_state *crtc_state); >> The name is too generic. >> >>> }; >>> >>> #define CSR_VERSION(major, minor) ((major) << 16 | (minor)) >>> diff --git a/drivers/gpu/drm/i915/intel_color.c >>> b/drivers/gpu/drm/i915/intel_color.c >>> index da7a07d..a515e9f 100644 >>> --- a/drivers/gpu/drm/i915/intel_color.c >>> +++ b/drivers/gpu/drm/i915/intel_color.c >>> @@ -74,6 +74,11 @@ >>> #define ILK_CSC_COEFF_1_0 \ >>> ((7 << 12) | ILK_CSC_COEFF_FP(CTM_COEFF_1_0, 8)) >>> >>> +/* Mask to extract RGB values from registers */ >>> +#define COLOR_BLUE_MASK 0x03FF /* 9:0 */ >>> +#define COLOR_GREEN_MASK0x000FFC00 /* 19:10 */ >>> +#define COLOR_RED_MASK 0x3FF0 /* 29:20 */ >> These belong in i915_reg.h, and you need platform specific shifts and >> masks. The code that writes the registers seems to use magic numbers... >> >>> + >>> static bool lut_is_legacy(const struct drm_property_blob *lut) >>> { >>> return drm_color_lut_size(lut) == LEGACY_LUT_LENGTH; >>> @@ -672,6 +677,97 @@ static void cherryview_load_luts(const struct >>> intel_crtc_state *crtc_state) >>> i9xx_load_luts_internal(crtc_state, NULL); >>> } >>> >>> +static void bdw_get_gamma_config(struct intel_crtc_state *crtc_state, u32 >>> offset) >>> +{ >>> + struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); >>> + struct drm_device *dev = crtc->base.dev; >>> + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); >>> + u32 i, tmp, lut_size = INTEL_INFO(dev_priv)->color.gamma_lut_size; >>> + enum pipe pipe = crtc->pipe; >>> + struct drm_property_blob *blob = NULL; >>> + struct drm_color_lut *blob_data; >>> + >>> + WARN_ON(offset & ~PAL_PREC_INDEX_VALUE_MASK); >>> + >>> + I915_WRITE(PREC_PAL_INDEX(pipe), >>> + (offset ? PAL_PREC_SPLIT_MODE : 0) | >>> + PAL_PREC_AUTO_INCREMENT | >>> + offset); >>> + >>> + blob = drm_property_create_blob(dev, >>> + sizeof(struct drm_color_lut) * lut_size, >>> + NULL); >>> + if (IS_ERR(blob)) >>> + return; >>> + >>> + blob_data = blob->data; >>> + >>> + for (i = 0; i < lut_size; i++) { >>> + tmp = I915_READ(PREC_PAL_DATA(pipe)); >>> + /* >>> +* TODO: convert RGB value read from register into >>> corresponding user value using >>> +* some wrapper like drm_color_lut_put() (or) >>> intel_color_lut_put() so that it >>> +* can be compared later. >>> +*/ >> Yeah, you'll need this. > Can you please help in this? Something like this: /* convert hw value with given bit_precision to lut property val */ u32 drm_color_lut_pack(u32 val, u32 bit_precision) { u32 max = 0x >> (16 - bit_precision); val = clamp_val(val, 0, max); if (bit_precision < 16) val <<= 16 - bit_precision; return val; } /* compare
Re: [PATCH 8/9] drm/syncobj: add timeline signal ioctl for syncobj v3
On 20/03/2019 03:53, zhoucm1 wrote: On 2019年03月19日 19:54, Lionel Landwerlin wrote: On 15/03/2019 12:09, Chunming Zhou wrote: v2: individually allocate chain array, since chain node is free independently. v3: all existing points must be already signaled before cpu perform signal operation, so add check condition for that. Signed-off-by: Chunming Zhou --- drivers/gpu/drm/drm_internal.h | 2 + drivers/gpu/drm/drm_ioctl.c | 2 + drivers/gpu/drm/drm_syncobj.c | 103 + include/uapi/drm/drm.h | 1 + 4 files changed, 108 insertions(+) diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index dd11ae5f1eef..d9a483a5fce0 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -190,6 +190,8 @@ int drm_syncobj_reset_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private); int drm_syncobj_signal_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private); +int drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_private); int drm_syncobj_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private); diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 92b3b7b2fd81..d337f161909c 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -696,6 +696,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = { DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_SIGNAL, drm_syncobj_signal_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, drm_syncobj_timeline_signal_ioctl, + DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_QUERY, drm_syncobj_query_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, drm_crtc_get_sequence_ioctl, DRM_UNLOCKED), diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 306c7b7e2770..eaeb038f97d7 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -1183,6 +1183,109 @@ drm_syncobj_signal_ioctl(struct drm_device *dev, void *data, return ret; } +int +drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_private) +{ + struct drm_syncobj_timeline_array *args = data; + struct drm_syncobj **syncobjs; + struct dma_fence_chain **chains; + uint64_t *points; + uint32_t i, j, timeline_count = 0; + int ret; + + if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) + return -EOPNOTSUPP; + + if (args->pad != 0) + return -EINVAL; + + if (args->count_handles == 0) + return -EINVAL; + + ret = drm_syncobj_array_find(file_private, + u64_to_user_ptr(args->handles), + args->count_handles, + ); + if (ret < 0) + return ret; + + for (i = 0; i < args->count_handles; i++) { + struct dma_fence_chain *chain; + struct dma_fence *fence; + + fence = drm_syncobj_fence_get(syncobjs[i]); + chain = to_dma_fence_chain(fence); + if (chain) { + struct dma_fence *iter; + + dma_fence_chain_for_each(iter, fence) { + if (!iter) + break; + if (!dma_fence_is_signaled(iter)) { + dma_fence_put(iter); + DRM_ERROR("Client must guarantee all existing timeline points signaled before performing host signal operation!"); + ret = -EPERM; + goto out; Sorry if I'm failing to remember whether we discussed this before. Signaling a point from the host should be fine even if the previous points in the timeline are not signaled. ok, will remove that checking. After all this can happen on the device side as well (out of order signaling). I thought the thing we didn't want is out of order submission. Just checking the last chain node seqno against the host signal point should be enough. What about simply returning -EPERM, we can warn the application from userspace? OK, will add that. + } + } + } + } + + points = kmalloc_array(args->count_handles, sizeof(*points), + GFP_KERNEL); + if (!points) { + ret = -ENOMEM; + goto out; + } + if (!u64_to_user_ptr(args->points)) { + memset(points, 0, args->count_handles * sizeof(uint64_t)); + } else if (copy_from_user(points, u64_to_user_ptr(args->points), + sizeof(uint64_t) * args->count_handles)) { + ret = -EFAULT; + goto
[Bug 110208] New GPU sysfs Power State Interface for custom pp_od_clk_voltage
https://bugs.freedesktop.org/show_bug.cgi?id=110208 --- Comment #1 from famo --- Link to documentation: https://dri.freedesktop.org/docs/drm/gpu/amdgpu.html#power-dpm-force-performance-level Quote: pp_od_clk_voltage The amdgpu driver provides a sysfs API for adjusting the clocks and voltages in each power level within a power state. The pp_od_clk_voltage is used for this. < For Vega10 and previous ASICs > Reading the file will display: a list of engine clock levels and voltages labeled OD_SCLK a list of memory clock levels and voltages labeled OD_MCLK a list of valid ranges for sclk, mclk, and voltage labeled OD_RANGE To manually adjust these settings, first select manual using power_dpm_force_performance_level. ... -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 110208] New GPU sysfs Power State Interface for custom pp_od_clk_voltage
https://bugs.freedesktop.org/show_bug.cgi?id=110208 Bug ID: 110208 Summary: New GPU sysfs Power State Interface for custom pp_od_clk_voltage Product: DRI Version: unspecified Hardware: Other OS: All Status: NEW Severity: normal Priority: medium Component: DRM/AMDgpu Assignee: dri-devel@lists.freedesktop.org Reporter: richard.l...@gmail.com In order to use a custom pp_od_clk_voltage one has to set power_dpm_force_performance_level to manual. However this way it is not possible to use custom pp_od_clk_voltage and force - for instance - high or peak performance levels. The forcing of different performance levels doesn't (and shouldn't) relate to custom clocks/voltages. Putting this setting in the same interface is a poor choice and (unnecessarily) restricts the possibilities. Please add a new sysfs interface for *solely* choosing between default and custom pp_od_clk_voltage. -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 101473] (SI) latest stable & cant boot
https://bugs.freedesktop.org/show_bug.cgi?id=101473 famo changed: What|Removed |Added Resolution|--- |FIXED Status|NEW |RESOLVED -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v1 4/6] reset: hi6220: Add support for AO reset controller
Hi Peter, On Mon, 2019-03-18 at 19:38 +, Peter Griffin wrote: > This is required to bring Mali450 gpu out of reset. > > Signed-off-by: Peter Griffin > --- > drivers/reset/hisilicon/hi6220_reset.c | 51 > +- > 1 file changed, 50 insertions(+), 1 deletion(-) > > diff --git a/drivers/reset/hisilicon/hi6220_reset.c > b/drivers/reset/hisilicon/hi6220_reset.c > index d5e5229..0cd5f92 100644 > --- a/drivers/reset/hisilicon/hi6220_reset.c > +++ b/drivers/reset/hisilicon/hi6220_reset.c > @@ -36,6 +36,7 @@ > enum hi6220_reset_ctrl_type { > PERIPHERAL, > MEDIA, > + AO, > }; > > struct hi6220_reset_data { > @@ -95,6 +96,47 @@ static const struct reset_control_ops > hi6220_media_reset_ops = { > .deassert = hi6220_media_deassert, > }; > > +#define AO_SCTRL_SC_PW_CLKEN0 0x800 > +#define AO_SCTRL_SC_PW_CLKDIS00x804 > + > +#define AO_SCTRL_SC_PW_RSTEN0 0x810 > +#define AO_SCTRL_SC_PW_RSTDIS00x814 > + > +#define AO_SCTRL_SC_PW_ISOEN0 0x820 > +#define AO_SCTRL_SC_PW_ISODIS00x824 > +#define AO_MAX_INDEX 12 > + > +static int hi6220_ao_assert(struct reset_controller_dev *rc_dev, > +unsigned long idx) > +{ > + struct hi6220_reset_data *data = to_reset_data(rc_dev); > + struct regmap *regmap = data->regmap; > + int ret; > + > + ret = regmap_write(regmap, AO_SCTRL_SC_PW_RSTEN0, BIT(idx)); > + ret |= regmap_write(regmap, AO_SCTRL_SC_PW_ISOEN0, BIT(idx)); > + ret |= regmap_write(regmap, AO_SCTRL_SC_PW_CLKDIS0, BIT(idx)); What if two regmap_writes return a different error code? Better check for ret and return individually. Also, no need to issue two more writes if the first one failed. > + return ret; > +} > + > +static int hi6220_ao_deassert(struct reset_controller_dev *rc_dev, > + unsigned long idx) > +{ > + struct hi6220_reset_data *data = to_reset_data(rc_dev); > + struct regmap *regmap = data->regmap; > + int ret; > + > + ret = regmap_write(regmap, AO_SCTRL_SC_PW_RSTDIS0, BIT(idx)); > + ret |= regmap_write(regmap, AO_SCTRL_SC_PW_ISODIS0, BIT(idx)); > + ret |= regmap_write(regmap, AO_SCTRL_SC_PW_CLKEN0, BIT(idx)); Same as above. Otherwise this looks fine. With this fixed, I could pick up patches 2, 4, and 5. regards Philipp ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC] drm/i915: adding state checker for gamma lut values
On 15-Mar-19 3:17 PM, Nikula, Jani wrote: On Fri, 15 Mar 2019, swati2.sha...@intel.com wrote: From: Swati Sharma Added state checker to validate gamma_lut values. This reads hardware state, and compares the originally requested state to the state read from hardware. This implementation can be used for Gen9+ platforms, I haven't implemented it for legacy platforms. Just want to get feedback if this is the right approach to follow. Also, inverse function of drm_color_lut_extract is missing to convert hardware read values back to user values. Thinking for that. I have added all "TODOs" and "Placeholders". Another approach: Storing "word" to be written into hardware in dev_priv and instead of comparing blob, comparing "word"? In dev_priv, only pointer will be there (something like *gamma_word). You can't store it in dev_priv because it's crtc state specific data. Even if stored in crtc state, the approach doesn't help the initial hw state readout and takeover. Please use intel-gfx mailing list for i915 patches. For this too, I will send a patch to make it more clear. Signed-off-by: Swati Sharma --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_color.c | 127 +-- drivers/gpu/drm/i915/intel_display.c | 50 ++ drivers/gpu/drm/i915/intel_drv.h | 1 + 4 files changed, 173 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index c4ffe19..b41bfaa 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -334,6 +334,7 @@ struct drm_i915_display_funcs { * involved with the same commit. */ void (*load_luts)(const struct intel_crtc_state *crtc_state); + void (*get_config)(struct intel_crtc_state *crtc_state); The name is too generic. }; #define CSR_VERSION(major, minor) ((major) << 16 | (minor)) diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index da7a07d..a515e9f 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -74,6 +74,11 @@ #define ILK_CSC_COEFF_1_0 \ ((7 << 12) | ILK_CSC_COEFF_FP(CTM_COEFF_1_0, 8)) +/* Mask to extract RGB values from registers */ +#define COLOR_BLUE_MASK 0x03FF /* 9:0 */ +#define COLOR_GREEN_MASK0x000FFC00 /* 19:10 */ +#define COLOR_RED_MASK 0x3FF0 /* 29:20 */ These belong in i915_reg.h, and you need platform specific shifts and masks. The code that writes the registers seems to use magic numbers... + static bool lut_is_legacy(const struct drm_property_blob *lut) { return drm_color_lut_size(lut) == LEGACY_LUT_LENGTH; @@ -672,6 +677,97 @@ static void cherryview_load_luts(const struct intel_crtc_state *crtc_state) i9xx_load_luts_internal(crtc_state, NULL); } +static void bdw_get_gamma_config(struct intel_crtc_state *crtc_state, u32 offset) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + u32 i, tmp, lut_size = INTEL_INFO(dev_priv)->color.gamma_lut_size; + enum pipe pipe = crtc->pipe; + struct drm_property_blob *blob = NULL; + struct drm_color_lut *blob_data; + + WARN_ON(offset & ~PAL_PREC_INDEX_VALUE_MASK); + + I915_WRITE(PREC_PAL_INDEX(pipe), + (offset ? PAL_PREC_SPLIT_MODE : 0) | + PAL_PREC_AUTO_INCREMENT | + offset); + + blob = drm_property_create_blob(dev, + sizeof(struct drm_color_lut) * lut_size, + NULL); + if (IS_ERR(blob)) + return; + + blob_data = blob->data; + + for (i = 0; i < lut_size; i++) { + tmp = I915_READ(PREC_PAL_DATA(pipe)); + /* +* TODO: convert RGB value read from register into corresponding user value using +* some wrapper like drm_color_lut_put() (or) intel_color_lut_put() so that it +* can be compared later. +*/ Yeah, you'll need this. Can you please help in this? + blob_data[i].red = (tmp & COLOR_RED_MASK) >> 20; + blob_data[i].green = (tmp & COLOR_GREEN_MASK) >> 10; + blob_data[i].blue = tmp & COLOR_BLUE_MASK; + } + + I915_WRITE(PREC_PAL_INDEX(pipe), 0); + + crtc_state->base.gamma_lut = blob; +} + +static void i9xx_get_config(struct intel_crtc_state *crtc_state) Please include (de)gamma or color in the function names. +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + u32 i, tmp; + enum pipe pipe =
Re: [PATCH] drm/fourcc: Fix conflicting Y41x definitions
Op 19-03-2019 om 17:18 schreef Ville Syrjälä: > On Tue, Mar 19, 2019 at 05:06:36PM +0100, Maarten Lankhorst wrote: >> Op 19-03-2019 om 14:02 schreef Ville Syrjälä: >>> On Tue, Mar 19, 2019 at 01:17:02PM +0100, Maarten Lankhorst wrote: There has unfortunately been a conflict with the following 3 commits: commit e9961ab95af81b8d29054361cd5f0c575102cf87 Author: Ayan Kumar Halder Date: Fri Nov 9 17:21:12 2018 + drm: Added a new format DRM_FORMAT_XVYU2101010 commit 7ba0fee247ee7a36b3bfbed68f6988d980aa3aa3 Author: Brian Starkey Date: Fri Oct 5 10:27:00 2018 +0100 drm/fourcc: Add AFBC yuv fourccs for Mali and commit 50bf5d7d595fd0705ef3785f80e679b6da501e5b Author: Swati Sharma Date: Mon Mar 4 17:26:33 2019 +0530 drm: Add Y2xx and Y4xx (xx:10/12/16) format definitions and fourcc Unfortunately gcc didn't warn about the redefinitions, because the Fix this by using new XYVU for i915, without alpha, and making the Y41x definitions match msdn, with alpha. >>> The naming of all these is rather unfortunate because now the alpha vs. >>> non-alpha formats have totally different looking names :( Fourccs are >>> stupid! >>> Fortunately we caught it early, and the conflict hasn't even landed in drm-next yet. Signed-off-by: Maarten Lankhorst Cc: Brian Starkey Cc: Swati Sharma Cc: Ayan Kumar Halder Cc: mal...@foss.arm.com Cc: Daniel Vetter Cc: Maxime Ripard Cc: Sean Paul Cc: Dave Airlie Cc: Liviu Dudau --- drivers/gpu/drm/drm_fourcc.c | 12 +-- drivers/gpu/drm/i915/intel_display.c | 18 - drivers/gpu/drm/i915/intel_sprite.c | 30 ++-- include/uapi/drm/drm_fourcc.h| 21 +-- 4 files changed, 41 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c index b914b16db9b2..6ea55fb4526d 100644 --- a/drivers/gpu/drm/drm_fourcc.c +++ b/drivers/gpu/drm/drm_fourcc.c @@ -229,17 +229,17 @@ const struct drm_format_info *__drm_format_info(u32 format) { .format = DRM_FORMAT_UYVY,.depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, { .format = DRM_FORMAT_VYUY,.depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, { .format = DRM_FORMAT_XYUV,.depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, - { .format = DRM_FORMAT_Y210,.depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, { .format = DRM_FORMAT_VUY888, .depth = 0, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, - { .format = DRM_FORMAT_Y410,.depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, .is_yuv = true }, { .format = DRM_FORMAT_AYUV,.depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, .is_yuv = true }, - { .format = DRM_FORMAT_XVYU2101010, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, { .format = DRM_FORMAT_Y210,.depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, { .format = DRM_FORMAT_Y212,.depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, { .format = DRM_FORMAT_Y216,.depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, - { .format = DRM_FORMAT_Y410,.depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, - { .format = DRM_FORMAT_Y412,.depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, - { .format = DRM_FORMAT_Y416,.depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, + { .format = DRM_FORMAT_Y410,.depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, .is_yuv = true }, + { .format = DRM_FORMAT_Y412,.depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, .is_yuv = true }, + { .format = DRM_FORMAT_Y416,.depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub
[v6 12/13] drm/i915: Set Infoframe for non modeset case for HDR
HDR metadata requires a infoframe to be set. Due to fastset, full modeset is not performed hence adding it to update_pipe to handle that. Signed-off-by: Uma Shankar --- drivers/gpu/drm/i915/intel_ddi.c | 13 + 1 file changed, 13 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 69aa0d1..a27aab9 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -3566,6 +3566,10 @@ static void intel_ddi_update_pipe(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_digital_port *intel_dig_port = + enc_to_dig_port(>base); + if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) intel_ddi_update_pipe_dp(encoder, crtc_state, conn_state); @@ -3575,6 +3579,15 @@ static void intel_ddi_update_pipe(struct intel_encoder *encoder, else if (conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED) intel_hdcp_disable(to_intel_connector(conn_state->connector)); + + /* Set the infoframe for NON modeset cases as well */ + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { + if ((INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) && + conn_state->hdr_metadata_changed) + intel_dig_port->set_infoframes(encoder, + crtc_state->has_infoframe, + crtc_state, conn_state); + } } static void intel_ddi_set_fia_lane_count(struct intel_encoder *encoder, -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[v6 10/13] drm/i915: Enable infoframes on GLK+ for HDR
From: Ville Syrjälä This patch enables infoframes on GLK+ to be used to send HDR metadata to HDMI sink. v2: Addressed Shashank's review comment. Signed-off-by: Ville Syrjälä Signed-off-by: Uma Shankar --- drivers/gpu/drm/i915/i915_reg.h | 4 drivers/gpu/drm/i915/intel_hdmi.c | 18 +- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 31a3020..fe931e7 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4718,6 +4718,7 @@ enum { #define VIDEO_DIP_FREQ_MASK (3 << 16) /* HSW and later: */ #define DRM_DIP_ENABLE (1 << 28) +#define VIDEO_DIP_ENABLE_DRM_GLK (1 << 28) #define PSR_VSC_BIT_7_SET(1 << 27) #define VSC_SELECT_MASK (0x3 << 25) #define VSC_SELECT_SHIFT 25 @@ -8156,6 +8157,7 @@ enum { #define _HSW_VIDEO_DIP_SPD_DATA_A 0x602A0 #define _HSW_VIDEO_DIP_GMP_DATA_A 0x602E0 #define _HSW_VIDEO_DIP_VSC_DATA_A 0x60320 +#define _GLK_VIDEO_DIP_DRM_DATA_A 0x60440 #define _HSW_VIDEO_DIP_AVI_ECC_A 0x60240 #define _HSW_VIDEO_DIP_VS_ECC_A0x60280 #define _HSW_VIDEO_DIP_SPD_ECC_A 0x602C0 @@ -8169,6 +8171,7 @@ enum { #define _HSW_VIDEO_DIP_SPD_DATA_B 0x612A0 #define _HSW_VIDEO_DIP_GMP_DATA_B 0x612E0 #define _HSW_VIDEO_DIP_VSC_DATA_B 0x61320 +#define _GLK_VIDEO_DIP_DRM_DATA_B 0x61440 #define _HSW_VIDEO_DIP_BVI_ECC_B 0x61240 #define _HSW_VIDEO_DIP_VS_ECC_B0x61280 #define _HSW_VIDEO_DIP_SPD_ECC_B 0x612C0 @@ -8194,6 +8197,7 @@ enum { #define HSW_TVIDEO_DIP_SPD_DATA(trans, i) _MMIO_TRANS2(trans, _HSW_VIDEO_DIP_SPD_DATA_A + (i) * 4) #define HSW_TVIDEO_DIP_GMP_DATA(trans, i) _MMIO_TRANS2(trans, _HSW_VIDEO_DIP_GMP_DATA_A + (i) * 4) #define HSW_TVIDEO_DIP_VSC_DATA(trans, i) _MMIO_TRANS2(trans, _HSW_VIDEO_DIP_VSC_DATA_A + (i) * 4) +#define GLK_TVIDEO_DIP_DRM_DATA(trans, i) _MMIO_TRANS2(trans, _GLK_VIDEO_DIP_DRM_DATA_A + (i) * 4) #define ICL_VIDEO_DIP_PPS_DATA(trans, i) _MMIO_TRANS2(trans, _ICL_VIDEO_DIP_PPS_DATA_A + (i) * 4) #define ICL_VIDEO_DIP_PPS_ECC(trans, i)_MMIO_TRANS2(trans, _ICL_VIDEO_DIP_PPS_ECC_A + (i) * 4) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index e4bc7fc..8decafd 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -134,6 +134,8 @@ static u32 hsw_infoframe_enable(unsigned int type) return VIDEO_DIP_ENABLE_SPD_HSW; case HDMI_INFOFRAME_TYPE_VENDOR: return VIDEO_DIP_ENABLE_VS_HSW; + case HDMI_INFOFRAME_TYPE_DRM: + return VIDEO_DIP_ENABLE_DRM_GLK; default: MISSING_CASE(type); return 0; @@ -159,6 +161,8 @@ static u32 hsw_infoframe_enable(unsigned int type) return HSW_TVIDEO_DIP_SPD_DATA(cpu_transcoder, i); case HDMI_INFOFRAME_TYPE_VENDOR: return HSW_TVIDEO_DIP_VS_DATA(cpu_transcoder, i); + case HDMI_INFOFRAME_TYPE_DRM: + return GLK_TVIDEO_DIP_DRM_DATA(cpu_transcoder, i); default: MISSING_CASE(type); return INVALID_MMIO_REG; @@ -545,7 +549,8 @@ static u32 hsw_infoframes_enabled(struct intel_encoder *encoder, return val & (VIDEO_DIP_ENABLE_VSC_HSW | VIDEO_DIP_ENABLE_AVI_HSW | VIDEO_DIP_ENABLE_GCP_HSW | VIDEO_DIP_ENABLE_VS_HSW | - VIDEO_DIP_ENABLE_GMP_HSW | VIDEO_DIP_ENABLE_SPD_HSW); + VIDEO_DIP_ENABLE_GMP_HSW | VIDEO_DIP_ENABLE_SPD_HSW | + VIDEO_DIP_ENABLE_DRM_GLK); } static const u8 infoframe_type_to_idx[] = { @@ -1177,7 +1182,8 @@ static void hsw_set_infoframes(struct intel_encoder *encoder, val &= ~(VIDEO_DIP_ENABLE_VSC_HSW | VIDEO_DIP_ENABLE_AVI_HSW | VIDEO_DIP_ENABLE_GCP_HSW | VIDEO_DIP_ENABLE_VS_HSW | -VIDEO_DIP_ENABLE_GMP_HSW | VIDEO_DIP_ENABLE_SPD_HSW); +VIDEO_DIP_ENABLE_GMP_HSW | VIDEO_DIP_ENABLE_SPD_HSW | +VIDEO_DIP_ENABLE_DRM_GLK); if (!enable) { I915_WRITE(reg, val); @@ -1200,9 +1206,11 @@ static void hsw_set_infoframes(struct intel_encoder *encoder, intel_write_infoframe(encoder, crtc_state, HDMI_INFOFRAME_TYPE_VENDOR, _state->infoframes.hdmi); - intel_write_infoframe(encoder, crtc_state, - HDMI_INFOFRAME_TYPE_DRM, - _state->infoframes.drm); + if ((INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) && + conn_state->hdr_metadata_changed) + intel_write_infoframe(encoder, crtc_state, + HDMI_INFOFRAME_TYPE_DRM, +
[v6 04/13] drm/i915: Attach HDR metadata property to connector
Attach HDR metadata property to connector object. v2: Rebase v3: Updated the property name as per updated name while creating hdr metadata property Signed-off-by: Uma Shankar Reviewed-by: Shashank Sharma --- drivers/gpu/drm/i915/intel_hdmi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 5ccb305..5f06237 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -2719,6 +2719,8 @@ static void intel_hdmi_destroy(struct drm_connector *connector) drm_connector_attach_content_type_property(connector); connector->state->picture_aspect_ratio = HDMI_PICTURE_ASPECT_NONE; + drm_object_attach_property(>base, + connector->dev->mode_config.hdr_output_metadata_property, 0); if (!HAS_GMCH(dev_priv)) drm_connector_attach_max_bpc_property(connector, 8, 12); -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[v6 06/13] drm: Enable HDR infoframe support
Enable Dynamic Range and Mastering Infoframe for HDR content, which is defined in CEA 861.3 spec. The metadata will be computed based on blending policy in userspace compositors and passed as a connector property blob to driver. The same will be sent as infoframe to panel which support HDR. v2: Rebase and added Ville's POC changes. v3: No Change v4: Addressed Shashank's review comments and merged the patch making drm infoframe function arguments as constant. v5: Rebase v6: Fixed checkpatch warnings with --strict option. Addressed Shashank's review comments and added his RB. Signed-off-by: Uma Shankar Signed-off-by: Ville Syrjälä Reviewed-by: Shashank Sharma --- drivers/gpu/drm/drm_edid.c | 56 drivers/video/hdmi.c | 129 + include/drm/drm_edid.h | 4 ++ include/linux/hdmi.h | 22 4 files changed, 211 insertions(+) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 676569b..78c0b97 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -4916,6 +4916,62 @@ static bool is_hdmi2_sink(struct drm_connector *connector) } /** + * drm_hdmi_infoframe_set_hdr_metadata() - fill an HDMI AVI infoframe with + * HDR metadata from userspace + * @frame: HDMI AVI infoframe + * @hdr_source_metadata: hdr_source_metadata info from userspace + * + * Return: 0 on success or a negative error code on failure. + */ +int +drm_hdmi_infoframe_set_hdr_metadata(struct hdmi_drm_infoframe *frame, + void *hdr_metadata) +{ + struct hdr_static_metadata *hdr_source_metadata; + int err, i; + + if (!frame || !hdr_metadata) + return true; + + err = hdmi_drm_infoframe_init(frame); + if (err < 0) + return err; + + DRM_DEBUG_KMS("type = %x\n", frame->type); + + hdr_source_metadata = (struct hdr_static_metadata *)hdr_metadata; + + frame->length = sizeof(struct hdr_static_metadata); + + frame->eotf = hdr_source_metadata->eotf; + frame->metadata_type = hdr_source_metadata->metadata_type; + + for (i = 0; i < 3; i++) { + frame->display_primaries[i].x = + hdr_source_metadata->display_primaries[i].x; + frame->display_primaries[i].y = + hdr_source_metadata->display_primaries[i].y; + } + + frame->white_point.x = hdr_source_metadata->white_point.x; + frame->white_point.y = hdr_source_metadata->white_point.y; + + frame->max_mastering_display_luminance = + hdr_source_metadata->max_mastering_display_luminance; + frame->min_mastering_display_luminance = + hdr_source_metadata->min_mastering_display_luminance; + + frame->max_cll = hdr_source_metadata->max_cll; + frame->max_fall = hdr_source_metadata->max_fall; + + hdmi_infoframe_log(KERN_CRIT, NULL, + (union hdmi_infoframe *)frame); + + return 0; +} +EXPORT_SYMBOL(drm_hdmi_infoframe_set_hdr_metadata); + +/** * drm_hdmi_avi_infoframe_from_display_mode() - fill an HDMI AVI infoframe with * data from a DRM display mode * @frame: HDMI AVI infoframe diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c index 799ae49..80bb0ee 100644 --- a/drivers/video/hdmi.c +++ b/drivers/video/hdmi.c @@ -650,6 +650,93 @@ ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame, return 0; } +/** + * hdmi_drm_infoframe_init() - initialize an HDMI Dynaminc Range and + * mastering infoframe + * @frame: HDMI DRM infoframe + * + * Returns 0 on success or a negative error code on failure. + */ +int hdmi_drm_infoframe_init(struct hdmi_drm_infoframe *frame) +{ + memset(frame, 0, sizeof(*frame)); + + frame->type = HDMI_INFOFRAME_TYPE_DRM; + frame->version = 1; + + return 0; +} +EXPORT_SYMBOL(hdmi_drm_infoframe_init); + +/** + * hdmi_drm_infoframe_pack() - write HDMI DRM infoframe to binary buffer + * @frame: HDMI DRM infoframe + * @buffer: destination buffer + * @size: size of buffer + * + * Packs the information contained in the @frame structure into a binary + * representation that can be written into the corresponding controller + * registers. Also computes the checksum as required by section 5.3.5 of + * the HDMI 1.4 specification. + * + * Returns the number of bytes packed into the binary buffer or a negative + * error code on failure. + */ +ssize_t hdmi_drm_infoframe_pack(struct hdmi_drm_infoframe *frame, void *buffer, + size_t size) +{ + u8 *ptr = buffer; + size_t length; + int i; + + length = HDMI_INFOFRAME_HEADER_SIZE + frame->length; + + if (size < length) + return -ENOSPC; + + memset(buffer, 0, size); + + ptr[0] = frame->type; + ptr[1] =
[v6 08/13] drm/i915: [DO NOT MERGE] hack for glk board outputs
From: Ville Syrjälä This is to limit PORT C on GLK to drive only HDMI. Not sure if this is mandatory, this is just to test HDR on GLK HDMI. Signed-off-by: Ville Syrjälä Signed-off-by: Uma Shankar --- drivers/gpu/drm/i915/intel_bios.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 64f2017..4934b5f 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -1405,6 +1405,13 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, is_hdmi = false; } + if (IS_GEMINILAKE(dev_priv) && port == PORT_C) { + is_hdmi = true; + is_dvi = true; + is_dp = false; + is_edp = false; + } + info->supports_dvi = is_dvi; info->supports_hdmi = is_hdmi; info->supports_dp = is_dp; -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[v6 05/13] drm: Implement HDR output metadata set and get property handling
This patch implements get() and set() functions for HDR output metadata property.The blob data is received from userspace and saved in connector state, the same is returned as blob in get property call to userspace. v2: Rebase and added Ville's POC changes v3: No Change v4: Addressed Shashank's review comments Signed-off-by: Uma Shankar --- drivers/gpu/drm/drm_atomic.c | 2 ++ drivers/gpu/drm/drm_atomic_uapi.c | 13 + 2 files changed, 15 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 5eb4013..8b9c126 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -881,6 +881,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p, drm_printf(p, "connector[%u]: %s\n", connector->base.id, connector->name); drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)"); + drm_printf(p, "\thdr_metadata_changed=%d\n", + state->hdr_metadata_changed); if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK) if (state->writeback_job && state->writeback_job->fb) diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index 4eb81f1..18c8b81f 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -686,6 +686,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector, { struct drm_device *dev = connector->dev; struct drm_mode_config *config = >mode_config; + bool replaced = false; + int ret; if (property == config->prop_crtc_id) { struct drm_crtc *crtc = drm_crtc_find(dev, NULL, val); @@ -734,6 +736,14 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector, */ if (state->link_status != DRM_LINK_STATUS_GOOD) state->link_status = val; + } else if (property == config->hdr_output_metadata_property) { + ret = drm_atomic_replace_property_blob_from_id(dev, + >hdr_output_metadata_blob_ptr, + val, + -1, sizeof(struct hdr_static_metadata), + ); + state->hdr_metadata_changed |= replaced; + return ret; } else if (property == config->aspect_ratio_property) { state->picture_aspect_ratio = val; } else if (property == config->content_type_property) { @@ -820,6 +830,9 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector, *val = state->colorspace; } else if (property == connector->scaling_mode_property) { *val = state->scaling_mode; + } else if (property == config->hdr_output_metadata_property) { + *val = (state->hdr_output_metadata_blob_ptr) ? + state->hdr_output_metadata_blob_ptr->base.id : 0; } else if (property == connector->content_protection_property) { *val = state->content_protection; } else if (property == config->writeback_fb_id_property) { -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[v6 09/13] drm/i915: Add HLG EOTF
From: Ville Syrjälä ADD HLG EOTF to the list of EOTF transfer functions supported. Hybrid Log-Gamma (HLG) is a high dynamic range (HDR) standard. HLG defines a nonlinear transfer function in which the lower half of the signal values use a gamma curve and the upper half of the signal values use a logarithmic curve. v2: Rebase v3: Fixed a warning message v4: Addressed Shashank's review comments Signed-off-by: Ville Syrjälä Signed-off-by: Uma Shankar Reviewed-by: Shashank Sharma --- drivers/gpu/drm/drm_edid.c | 3 ++- include/linux/hdmi.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 78c0b97..4784447 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -3868,7 +3868,8 @@ static uint8_t eotf_supported(const u8 *edid_ext) return edid_ext[2] & (BIT(HDMI_EOTF_TRADITIONAL_GAMMA_SDR) | BIT(HDMI_EOTF_TRADITIONAL_GAMMA_HDR) | -BIT(HDMI_EOTF_SMPTE_ST2084)); +BIT(HDMI_EOTF_SMPTE_ST2084) | +BIT(HDMI_EOTF_BT_2100_HLG)); } static uint8_t hdr_metadata_type(const u8 *edid_ext) diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h index b925b24..202ed4a 100644 --- a/include/linux/hdmi.h +++ b/include/linux/hdmi.h @@ -161,6 +161,7 @@ enum hdmi_eotf { HDMI_EOTF_TRADITIONAL_GAMMA_SDR, HDMI_EOTF_TRADITIONAL_GAMMA_HDR, HDMI_EOTF_SMPTE_ST2084, + HDMI_EOTF_BT_2100_HLG, }; struct hdmi_avi_infoframe { -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[v6 07/13] drm/i915: Write HDR infoframe and send to panel
Enable writing of HDR metadata infoframe to panel. The data will be provid by usersapace compositors, based on blending policies and passsed to driver through a blob property. v2: Rebase v3: Fixed a warning message v4: Addressed Shashank's review comments v5: Rebase. Added infoframe calculation in compute config. v6: Addressed Shashank's review comment. Added HDR metadata support from GEN10 onwards as per Shashank's recommendation. Signed-off-by: Uma Shankar --- drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_hdmi.c | 41 +++ 2 files changed, 42 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index d9f188e..c6c3cc7 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1043,6 +1043,7 @@ struct intel_crtc_state { union hdmi_infoframe avi; union hdmi_infoframe spd; union hdmi_infoframe hdmi; + union hdmi_infoframe drm; } infoframes; /* HDMI scrambling status */ diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 5f06237..e4bc7fc 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -555,6 +555,7 @@ static u32 hsw_infoframes_enabled(struct intel_encoder *encoder, HDMI_INFOFRAME_TYPE_AVI, HDMI_INFOFRAME_TYPE_SPD, HDMI_INFOFRAME_TYPE_VENDOR, + HDMI_INFOFRAME_TYPE_DRM, }; u32 intel_hdmi_infoframe_enable(unsigned int type) @@ -777,6 +778,30 @@ void intel_read_infoframe(struct intel_encoder *encoder, return true; } +static bool +intel_hdmi_compute_drm_infoframe(struct intel_encoder *encoder, +struct intel_crtc_state *crtc_state, +struct drm_connector_state *conn_state) +{ + struct hdmi_drm_infoframe *frame = _state->infoframes.drm.drm; + struct hdr_static_metadata *hdr_metadata; + int ret; + + hdr_metadata = (struct hdr_static_metadata *) + conn_state->hdr_output_metadata_blob_ptr->data; + + ret = drm_hdmi_infoframe_set_hdr_metadata(frame, hdr_metadata); + if (ret < 0) { + DRM_ERROR("couldn't set HDR metadata in infoframe\n"); + return false; + } + + crtc_state->infoframes.enable |= + intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_DRM); + + return true; +} + static void g4x_set_infoframes(struct intel_encoder *encoder, bool enable, const struct intel_crtc_state *crtc_state, @@ -1175,6 +1200,9 @@ static void hsw_set_infoframes(struct intel_encoder *encoder, intel_write_infoframe(encoder, crtc_state, HDMI_INFOFRAME_TYPE_VENDOR, _state->infoframes.hdmi); + intel_write_infoframe(encoder, crtc_state, + HDMI_INFOFRAME_TYPE_DRM, + _state->infoframes.drm); } void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable) @@ -2381,6 +2409,19 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder, return -EINVAL; } + /* +* Support HDR Metadata from Gen10 onwards +* ToDo: Gen9 also can support HDR with LSPCON. +* Support for the same to be enabled later. +*/ + if (INTEL_GEN(dev_priv) >= 10) { + if (!intel_hdmi_compute_drm_infoframe(encoder, pipe_config, + conn_state)) { + DRM_DEBUG_KMS("bad DRM infoframe\n"); + return -EINVAL; + } + } + return 0; } -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[v6 13/13] video/hdmi: Add const variants for drm infoframe
Added the const version of infoframe for DRM metadata for HDR. Signed-off-by: Uma Shankar --- drivers/video/hdmi.c | 63 ++-- include/linux/hdmi.h | 5 + 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c index 80bb0ee..f9ca555 100644 --- a/drivers/video/hdmi.c +++ b/drivers/video/hdmi.c @@ -668,6 +668,30 @@ int hdmi_drm_infoframe_init(struct hdmi_drm_infoframe *frame) } EXPORT_SYMBOL(hdmi_drm_infoframe_init); +static int hdmi_drm_infoframe_check_only(const struct hdmi_drm_infoframe *frame) +{ + if (frame->type != HDMI_INFOFRAME_TYPE_DRM || + frame->version != 1) + return -EINVAL; + + return 0; +} + +/** + * hdmi_drm_infoframe_check() - check a HDMI DRM infoframe + * @frame: HDMI DRM infoframe + * + * Validates that the infoframe is consistent and updates derived fields + * (eg. length) based on other fields. + * + * Returns 0 on success or a negative error code on failure. + */ +int hdmi_drm_infoframe_check(struct hdmi_drm_infoframe *frame) +{ + return hdmi_drm_infoframe_check_only(frame); +} +EXPORT_SYMBOL(hdmi_drm_infoframe_check); + /** * hdmi_drm_infoframe_pack() - write HDMI DRM infoframe to binary buffer * @frame: HDMI DRM infoframe @@ -682,8 +706,8 @@ int hdmi_drm_infoframe_init(struct hdmi_drm_infoframe *frame) * Returns the number of bytes packed into the binary buffer or a negative * error code on failure. */ -ssize_t hdmi_drm_infoframe_pack(struct hdmi_drm_infoframe *frame, void *buffer, - size_t size) +ssize_t hdmi_drm_infoframe_pack_only(const struct hdmi_drm_infoframe *frame, +void *buffer, size_t size) { u8 *ptr = buffer; size_t length; @@ -736,6 +760,37 @@ ssize_t hdmi_drm_infoframe_pack(struct hdmi_drm_infoframe *frame, void *buffer, return length; } +EXPORT_SYMBOL(hdmi_drm_infoframe_pack_only); + +/** + * hdmi_drm_infoframe_pack() - check a HDMI DRM infoframe, + * and write it to binary buffer + * @frame: HDMI DRM infoframe + * @buffer: destination buffer + * @size: size of buffer + * + * Validates that the infoframe is consistent and updates derived fields + * (eg. length) based on other fields, after which it packs the information + * contained in the @frame structure into a binary representation that + * can be written into the corresponding controller registers. This function + * also computes the checksum as required by section 5.3.5 of the HDMI 1.4 + * specification. + * + * Returns the number of bytes packed into the binary buffer or a negative + * error code on failure. + */ +ssize_t hdmi_drm_infoframe_pack(struct hdmi_drm_infoframe *frame, + void *buffer, size_t size) +{ + int ret; + + ret = hdmi_drm_infoframe_check(frame); + if (ret) + return ret; + + return hdmi_drm_infoframe_pack_only(frame, buffer, size); +} +EXPORT_SYMBOL(hdmi_drm_infoframe_pack); /* * hdmi_vendor_any_infoframe_check() - check a vendor infoframe @@ -845,6 +900,10 @@ ssize_t hdmi_drm_infoframe_pack(struct hdmi_drm_infoframe *frame, void *buffer, length = hdmi_avi_infoframe_pack_only(>avi, buffer, size); break; + case HDMI_INFOFRAME_TYPE_DRM: + length = hdmi_drm_infoframe_pack_only(>drm, + buffer, size); + break; case HDMI_INFOFRAME_TYPE_SPD: length = hdmi_spd_infoframe_pack_only(>spd, buffer, size); diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h index 202ed4a..fd8e534 100644 --- a/include/linux/hdmi.h +++ b/include/linux/hdmi.h @@ -213,6 +213,11 @@ ssize_t hdmi_avi_infoframe_pack_only(const struct hdmi_avi_infoframe *frame, void *buffer, size_t size); int hdmi_avi_infoframe_check(struct hdmi_avi_infoframe *frame); int hdmi_drm_infoframe_init(struct hdmi_drm_infoframe *frame); +ssize_t hdmi_drm_infoframe_pack(struct hdmi_drm_infoframe *frame, void *buffer, + size_t size); +ssize_t hdmi_drm_infoframe_pack_only(const struct hdmi_drm_infoframe *frame, +void *buffer, size_t size); +int hdmi_drm_infoframe_check(struct hdmi_drm_infoframe *frame); enum hdmi_spd_sdi { HDMI_SPD_SDI_UNKNOWN, -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[v6 11/13] drm/i915:Enabled Modeset when HDR Infoframe changes
This patch enables modeset whenever HDR metadata needs to be updated to sink. Signed-off-by: Ville Syrjälä Signed-off-by: Uma Shankar --- drivers/gpu/drm/i915/intel_atomic.c | 15 ++- drivers/gpu/drm/i915/intel_hdmi.c | 4 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c index b844e88..4ff6042 100644 --- a/drivers/gpu/drm/i915/intel_atomic.c +++ b/drivers/gpu/drm/i915/intel_atomic.c @@ -102,6 +102,16 @@ int intel_digital_connector_atomic_set_property(struct drm_connector *connector, return -EINVAL; } +static bool blob_equal(const struct drm_property_blob *a, + const struct drm_property_blob *b) +{ + if (a && b) + return a->length == b->length && + !memcmp(a->data, b->data, a->length); + + return !a == !b; +} + int intel_digital_connector_atomic_check(struct drm_connector *conn, struct drm_connector_state *new_state) { @@ -129,7 +139,10 @@ int intel_digital_connector_atomic_check(struct drm_connector *conn, new_conn_state->base.colorspace != old_conn_state->base.colorspace || new_conn_state->base.picture_aspect_ratio != old_conn_state->base.picture_aspect_ratio || new_conn_state->base.content_type != old_conn_state->base.content_type || - new_conn_state->base.scaling_mode != old_conn_state->base.scaling_mode) + new_conn_state->base.scaling_mode != + old_conn_state->base.scaling_mode || + !blob_equal(new_conn_state->base.hdr_output_metadata_blob_ptr, + old_conn_state->base.hdr_output_metadata_blob_ptr)) crtc_state->mode_changed = true; return 0; diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 8decafd..4d06734 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -792,6 +792,10 @@ void intel_read_infoframe(struct intel_encoder *encoder, struct hdr_static_metadata *hdr_metadata; int ret; + if (!conn_state->hdr_output_metadata_blob_ptr || + conn_state->hdr_output_metadata_blob_ptr->length == 0) + return true; + hdr_metadata = (struct hdr_static_metadata *) conn_state->hdr_output_metadata_blob_ptr->data; -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[v6 02/13] drm: Parse HDR metadata info from EDID
HDR metadata block is introduced in CEA-861.3 spec. Parsing the same to get the panel's HDR metadata. v2: Rebase and added Ville's POC changes to the patch. v3: No Change v4: Addressed Shashank's review comments Signed-off-by: Uma Shankar --- drivers/gpu/drm/drm_edid.c | 49 ++ 1 file changed, 49 insertions(+) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index fa39592..fd8a621a 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -2840,6 +2840,7 @@ static int drm_cvt_modes(struct drm_connector *connector, #define VIDEO_BLOCK 0x02 #define VENDOR_BLOCK0x03 #define SPEAKER_BLOCK 0x04 +#define HDR_STATIC_METADATA_BLOCK 0x6 #define USE_EXTENDED_TAG 0x07 #define EXT_VIDEO_CAPABILITY_BLOCK 0x00 #define EXT_VIDEO_DATA_BLOCK_420 0x0E @@ -3587,6 +3588,12 @@ static int add_3d_struct_modes(struct drm_connector *connector, u16 structure, } static int +cea_db_payload_len_ext(const u8 *db) +{ + return (db[0] & 0x1f) - 1; +} + +static int cea_db_extended_tag(const u8 *db) { return db[1]; @@ -3822,6 +3829,46 @@ static void fixup_detailed_cea_mode_clock(struct drm_display_mode *mode) mode->clock = clock; } +static bool cea_db_is_hdmi_hdr_metadata_block(const u8 *db) +{ + if (cea_db_tag(db) != USE_EXTENDED_TAG) + return false; + + if (db[1] != HDR_STATIC_METADATA_BLOCK) + return false; + + return true; +} + +static uint8_t eotf_supported(const u8 *edid_ext) +{ + return edid_ext[2] & + (BIT(HDMI_EOTF_TRADITIONAL_GAMMA_SDR) | +BIT(HDMI_EOTF_TRADITIONAL_GAMMA_HDR) | +BIT(HDMI_EOTF_SMPTE_ST2084)); +} + +static uint8_t hdr_metadata_type(const u8 *edid_ext) +{ + return edid_ext[3] & + BIT(HDMI_STATIC_METADATA_TYPE1); +} + +static void +drm_parse_hdr_metadata_block(struct drm_connector *connector, const u8 *db) +{ + u16 len; + + len = cea_db_payload_len_ext(db); + connector->hdr_metadata.eotf = eotf_supported(db); + connector->hdr_metadata.metadata_type = hdr_metadata_type(db); + + if (len >= 5) + connector->hdr_metadata.max_fall = db[5]; + if (len >= 4) + connector->hdr_metadata.max_cll = db[4]; +} + static void drm_parse_hdmi_vsdb_audio(struct drm_connector *connector, const u8 *db) { @@ -4449,6 +4496,8 @@ static void drm_parse_cea_ext(struct drm_connector *connector, drm_parse_y420cmdb_bitmap(connector, db); if (cea_db_is_vcdb(db)) drm_parse_vcdb(connector, db); + if (cea_db_is_hdmi_hdr_metadata_block(db)) + drm_parse_hdr_metadata_block(connector, db); } } -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[v6 01/13] drm: Add HDR source metadata property
This patch adds a blob property to get HDR metadata information from userspace. This will be send as part of AVI Infoframe to panel. v2: Rebase and modified the metadata structure elements as per Ville's POC changes. v3: No Change v4: Addressed Shashank's review comments v5: Rebase. Signed-off-by: Uma Shankar --- drivers/gpu/drm/drm_connector.c | 6 ++ include/drm/drm_connector.h | 10 ++ include/drm/drm_mode_config.h | 6 ++ include/linux/hdmi.h| 10 ++ include/uapi/drm/drm_mode.h | 16 5 files changed, 48 insertions(+) diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 2355124..0bdae90 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -1058,6 +1058,12 @@ int drm_connector_create_standard_properties(struct drm_device *dev) return -ENOMEM; dev->mode_config.non_desktop_property = prop; + prop = drm_property_create(dev, DRM_MODE_PROP_BLOB, + "HDR_OUTPUT_METADATA", 0); + if (!prop) + return -ENOMEM; + dev->mode_config.hdr_output_metadata_property = prop; + return 0; } diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index c806199..29388bd 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -561,6 +561,13 @@ struct drm_connector_state { * and the connector bpc limitations obtained from edid. */ u8 max_bpc; + + /** +* @metadata_blob_ptr: +* DRM blob property for HDR output metadata +*/ + struct drm_property_blob *hdr_output_metadata_blob_ptr; + u8 hdr_metadata_changed : 1; }; /** @@ -1201,6 +1208,9 @@ struct drm_connector { * _mode_config.connector_free_work. */ struct llist_node free_node; + + /* HDR metdata */ + struct hdr_static_metadata hdr_metadata; }; #define obj_to_connector(x) container_of(x, struct drm_connector, base) diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h index 7f60e8e..ef2656b 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h @@ -836,6 +836,12 @@ struct drm_mode_config { */ struct drm_property *writeback_out_fence_ptr_property; + /* +* hdr_metadata_property: Connector property containing hdr metatda +* This will be provided by userspace compositors based on HDR content +*/ + struct drm_property *hdr_output_metadata_property; + /* dumb ioctl parameters */ uint32_t preferred_depth, prefer_shadow; diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h index 927ad64..a065194 100644 --- a/include/linux/hdmi.h +++ b/include/linux/hdmi.h @@ -152,6 +152,16 @@ enum hdmi_content_type { HDMI_CONTENT_TYPE_GAME, }; +enum hdmi_metadata_type { + HDMI_STATIC_METADATA_TYPE1 = 1, +}; + +enum hdmi_eotf { + HDMI_EOTF_TRADITIONAL_GAMMA_SDR, + HDMI_EOTF_TRADITIONAL_GAMMA_HDR, + HDMI_EOTF_SMPTE_ST2084, +}; + struct hdmi_avi_infoframe { enum hdmi_infoframe_type type; unsigned char version; diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index a439c2e..5012af2 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -630,6 +630,22 @@ struct drm_color_lut { __u16 reserved; }; +/* HDR Metadata */ +struct hdr_static_metadata { + uint8_t eotf; + uint8_t metadata_type; + struct { + uint16_t x, y; + } display_primaries[3]; + struct { + uint16_t x, y; + } white_point; + uint16_t max_mastering_display_luminance; + uint16_t min_mastering_display_luminance; + uint16_t max_fall; + uint16_t max_cll; +}; + #define DRM_MODE_PAGE_FLIP_EVENT 0x01 #define DRM_MODE_PAGE_FLIP_ASYNC 0x02 #define DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE 0x4 -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel