Re: [PATCH v7 1/6] drm: move the buddy allocator from i915 into common drm
Am 09.01.22 um 15:19 schrieb Arunpravin: +// SPDX-License-Identifier: MIT +MODULE_DESCRIPTION("DRM Buddy Allocator"); +MODULE_LICENSE("GPL"); I'm not an expert on this, but maybe we should use "Dual MIT/GPL" here? The code is certainly MIT licensed. Regards, Christian.
[PATCH] drm/self_refresh: Don't trigger the entry timer for self refresh work if CRTC state is inactive
If the CRTC state is already inactive, it doesn't make sense to trigger the entry timer for self refresh work to make the display enter self refresh mode, because the disabled CRTC hints that either the entire display pipeline is disabled or the previous atomic commit is triggered by the self refresh work(the CRTC is disabled, while the relevant encoder and bridges could be disabled or not depending on the drivers). Cc: Rob Clark Cc: Sean Paul Cc: Zain Wang Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Thomas Zimmermann Cc: David Airlie Cc: Daniel Vetter Signed-off-by: Liu Ying --- drivers/gpu/drm/drm_self_refresh_helper.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_self_refresh_helper.c b/drivers/gpu/drm/drm_self_refresh_helper.c index dd33fec5aabd..e76eb3cd22c7 100644 --- a/drivers/gpu/drm/drm_self_refresh_helper.c +++ b/drivers/gpu/drm/drm_self_refresh_helper.c @@ -204,8 +204,12 @@ void drm_self_refresh_helper_alter_state(struct drm_atomic_state *state) struct drm_self_refresh_data *sr_data; unsigned int delay; - /* Don't trigger the entry timer when we're already in SR */ - if (crtc_state->self_refresh_active) + /* +* Don't trigger the entry timer when we're already inactive. +* Note that the inactive state hints that either we're already +* in SR or the entire display pipeline is already disabled. +*/ + if (!crtc_state->active) continue; sr_data = crtc->self_refresh_data; -- 2.25.1
Re: [PATCH 1/2] video: vga16fb: Fix logic that checks for the display standard
Hello Geert and Kara, On 1/9/22 21:20, Kris Karas (Bug reporting) wrote: > Groetje, Geert, > > Geert Uytterhoeven wrote: >> >>> - par->isVGA = screen_info.orig_video_isVGA; >>> + par->isVGA = screen_info.orig_video_isVGA == VIDEO_TYPE_VGAC; >> All non-x86 architectures (except for 2 MIPS platforms) treat >> orig_video_isVGA as a boolean flag, and just assign 1 to it. >> Hence this change would break them. > > I see a bit of a conflict with using orig_video_isVGA as a boolean. All > the modern architecture-agnostic driver code, such as sysfb, > sysfb_simplefb, and efifb, all use and expect orig_video_isVGA to be an > integer. On the other hand, the VGA driver for XEN first sets > orig_video_isVGA = 1 (boolean), and then VIDEO_TYPE_VLFB or > VIDEO_TYPE_EFI (integer). Overloading the definition for > orig_video_isVGA to be both boolean and integer - within the same file - > seems like a recipe for bugs to me. > Agreed with Kara on this. I believe the non-x86 arches should be fixed to set it to the correct value. > That said, I think that wrapping the par->isVGA code, above, within a > check for CONFIG_X86 seems safe and expedient. But I would be much > happier if the non-x86 architectures would set it to a proper integer > value (even if fake) that coincidentally satisfies boolean "true", say > VIDEO_TYPE_VGAC; that way, there would be no confusion as to data type > in all the more recent architecture-agnostic framebuffer code. > Yes, I'll post a v2 to do that but hopefully the CONFIG_X86 guard could be dropped in the future once all the architectures are fixed. > Kris > Best regards, -- Javier Martinez Canillas Linux Engineering Red Hat
[PATCH] i915: make array flex_regs static const
Don't populate the read-only array flex_regs on the stack but instead it static const. Also makes the object code a little smaller. Signed-off-by: Colin Ian King --- drivers/gpu/drm/i915/i915_perf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c index e27f3b7cf094..df698960fdc0 100644 --- a/drivers/gpu/drm/i915/i915_perf.c +++ b/drivers/gpu/drm/i915/i915_perf.c @@ -2114,7 +2114,7 @@ gen8_update_reg_state_unlocked(const struct intel_context *ce, u32 ctx_oactxctrl = stream->perf->ctx_oactxctrl_offset; u32 ctx_flexeu0 = stream->perf->ctx_flexeu0_offset; /* The MMIO offsets for Flex EU registers aren't contiguous */ - i915_reg_t flex_regs[] = { + static const i915_reg_t flex_regs[] = { EU_PERF_CNTL0, EU_PERF_CNTL1, EU_PERF_CNTL2, -- 2.32.0
Re: [PATCH 1/2] drm/i2c/tda998x: Switch to atomic operations
On Mon, Jan 03, 2022 at 09:35:14AM -0300, Fabio Estevam wrote: > Hi Laurent, > > On Mon, Jan 3, 2022 at 8:48 AM Laurent Pinchart > wrote: > > > With the comment from 2/2 taken into account, > > > > Reviewed-by: Laurent Pinchart > > Thanks for the review. I addressed your feedback and sent v2. > > I noticed a problem when removing/inserting the HDMI cable. > > If I boot the board with the HDMI cable connected, then after > removal/insertion of the HDMI cable, the following > kernel warning is observed: > > # [ 23.201080] [ cut here ] > [ 23.207275] WARNING: CPU: 0 PID: 56 at > drivers/gpu/drm/drm_atomic_helper.c:1514 > drm_atomic_helper_wait_for_vblanks.part.0+0x27c/0x294 > [ 23.221469] [CRTC:35:crtc-0] vblank wait timed out > [ 23.226448] Modules linked in: > [ 23.230255] CPU: 0 PID: 56 Comm: kworker/0:3 Not tainted > 5.15.12-3-g27f29fb60028 #94 > [ 23.238508] Hardware name: Freescale i.MX6 SoloX (Device Tree) > [ 23.244457] Workqueue: events output_poll_execute > [ 23.249377] [] (unwind_backtrace) from [] > (show_stack+0x10/0x14) > [ 23.257316] [] (show_stack) from [] > (dump_stack_lvl+0x58/0x70) > [ 23.265059] [] (dump_stack_lvl) from [] > (__warn+0xd8/0x114) > [ 23.272533] [] (__warn) from [] > (warn_slowpath_fmt+0x90/0xc4) > [ 23.280166] [] (warn_slowpath_fmt) from [] > (drm_atomic_helper_wait_for_vblanks.part.0+0x27c/0x294) > [ 23.291054] [] > (drm_atomic_helper_wait_for_vblanks.part.0) from [] > (drm_atomic_helper_commit_tail_rpm+0x5c/0x6c) > [ 23.303150] [] (drm_atomic_helper_commit_tail_rpm) from > [] (commit_tail+0x9c/0x190) > [ 23.312717] [] (commit_tail) from [] > (drm_atomic_helper_commit+0x158/0x18c) > [ 23.321588] [] (drm_atomic_helper_commit) from > [] (drm_client_modeset_commit_atomic+0x238/0x284) > [ 23.332314] [] (drm_client_modeset_commit_atomic) from > [] (drm_client_modeset_commit_locked+0x60/0x1cc) > [ 23.343615] [] (drm_client_modeset_commit_locked) from > [] (drm_client_modeset_commit+0x24/0x40) > [ 23.354218] [] (drm_client_modeset_commit) from > [] (__drm_fb_helper_restore_fbdev_mode_unlocked+0x9c/0xc8) > [ 23.365803] [] > (__drm_fb_helper_restore_fbdev_mode_unlocked) from [] > (drm_fb_helper_set_par+0x38/0x68) > [ 23.377015] [] (drm_fb_helper_set_par) from [] > (drm_fb_helper_hotplug_event.part.0+0xa4/0xc0) > [ 23.387443] [] (drm_fb_helper_hotplug_event.part.0) from > [] (drm_client_dev_hotplug+0x6c/0xb4) > [ 23.397959] [] (drm_client_dev_hotplug) from [] > (output_poll_execute+0x200/0x21c) > [ 23.407346] [] (output_poll_execute) from [] > (process_one_work+0x298/0x7cc) > [ 23.416224] [] (process_one_work) from [] > (worker_thread+0x30/0x50c) > [ 23.424479] [] (worker_thread) from [] > (kthread+0x154/0x17c) > [ 23.432039] [] (kthread) from [] > (ret_from_fork+0x14/0x38) > [ 23.439413] Exception stack(0xc42a1fb0 to 0xc42a1ff8) > [ 23.444588] 1fa0: > > [ 23.452888] 1fc0: > > [ 23.461182] 1fe0: 0013 > [ 23.468734] irq event stamp: 43775 > [ 23.472305] hardirqs last enabled at (43783): [] > __up_console_sem+0x50/0x60 > [ 23.480785] hardirqs last disabled at (43792): [] > __up_console_sem+0x3c/0x60 > [ 23.489224] softirqs last enabled at (43774): [] > __do_softirq+0x2ec/0x5a4 > [ 23.497163] softirqs last disabled at (43747): [] > irq_exit+0x18c/0x210 > [ 23.505106] ---[ end trace 86572327287ca501 ]--- > > I haven't managed to fix this yet, but if you have any suggestions, > please let me know. > > Thanks, > > Fabio Estevam Hi Fabio, If you need some test let me know. Whitch filesystem are you using? In the next days I will investigate on this issue. Let me know. Thanks, Tommaso
[PATCH] drm/bridge: adv7533: make array clock_div_by_lanes static const
Don't populate the read-only array clock_div_by_lanes on the stack but instead it static const. Also makes the object code a little smaller. Signed-off-by: Colin Ian King --- drivers/gpu/drm/bridge/adv7511/adv7533.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7533.c b/drivers/gpu/drm/bridge/adv7511/adv7533.c index eb7579dec40a..ef6270806d1d 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7533.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c @@ -29,7 +29,7 @@ static void adv7511_dsi_config_timing_gen(struct adv7511 *adv) struct mipi_dsi_device *dsi = adv->dsi; struct drm_display_mode *mode = &adv->curr_mode; unsigned int hsw, hfp, hbp, vsw, vfp, vbp; - u8 clock_div_by_lanes[] = { 6, 4, 3 }; /* 2, 3, 4 lanes */ + static const u8 clock_div_by_lanes[] = { 6, 4, 3 }; /* 2, 3, 4 lanes */ hsw = mode->hsync_end - mode->hsync_start; hfp = mode->hsync_start - mode->hdisplay; -- 2.32.0
Re: [PATCH v2] hv: account for packet descriptor in maximum packet size
(Extending Cc: list,) On Sun, Jan 09, 2022 at 05:55:16PM +0800, Yanming Liu wrote: > Commit adae1e931acd ("Drivers: hv: vmbus: Copy packets sent by Hyper-V > out of the ring buffer") introduced a notion of maximum packet size in > vmbus channel and used that size to initialize a buffer holding all > incoming packet along with their vmbus packet header. Currently, some > vmbus drivers set max_pkt_size to the size of their receive buffer > passed to vmbus_recvpacket, however vmbus_open expects this size to also > include vmbus packet header. This leads to corruption of the ring buffer > state when receiving a maximum sized packet. > > Specifically, in hv_balloon I have observed of a dm_unballoon_request > message of 4096 bytes being truncated to 4080 bytes. When the driver > tries to read next packet it starts from a wrong read_index, receives > garbage and prints a lot of "Unhandled message: type: " in > dmesg. > > The same mismatch also happens in hv_fcopy, hv_kvp, hv_snapshot, > hv_util, hyperv_drm and hyperv_fb, though bad cases are not observed > yet. > > Allocate the buffer with HV_HYP_PAGE_SIZE more bytes to make room for > the descriptor, assuming the vmbus packet header will never be larger > than HV_HYP_PAGE_SIZE. This is essentially free compared to just adding > 'sizeof(struct vmpacket_descriptor)' because these buffers are all more > than HV_HYP_PAGE_SIZE bytes so kmalloc rounds them up anyway. > > Fixes: adae1e931acd ("Drivers: hv: vmbus: Copy packets sent by Hyper-V out of > the ring buffer") > Suggested-by: Andrea Parri (Microsoft) > Signed-off-by: Yanming Liu Thanks for sorting this out; the patch looks good to me: Reviewed-by: Andrea Parri (Microsoft) In future submissions (if any), please include LKML as well as subsystem lists&maintainers; scripts/get_maintainer.pl can be useful to this end. Andrea > --- > v2: Changed to modify max_pkt_size in individual drivers instead of in > vmbus code as suggested by Andrea Parri. > > drivers/gpu/drm/hyperv/hyperv_drm_proto.c | 2 ++ > drivers/hv/hv_balloon.c | 7 +++ > drivers/hv/hv_fcopy.c | 2 +- > drivers/hv/hv_kvp.c | 2 +- > drivers/hv/hv_snapshot.c | 2 +- > drivers/hv/hv_util.c | 17 + > drivers/video/fbdev/hyperv_fb.c | 2 ++ > 7 files changed, 31 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_proto.c > b/drivers/gpu/drm/hyperv/hyperv_drm_proto.c > index c0155c6271bf..bf1548054276 100644 > --- a/drivers/gpu/drm/hyperv/hyperv_drm_proto.c > +++ b/drivers/gpu/drm/hyperv/hyperv_drm_proto.c > @@ -478,6 +478,8 @@ int hyperv_connect_vsp(struct hv_device *hdev) > struct drm_device *dev = &hv->dev; > int ret; > > + hdev->channel->max_pkt_size = HV_HYP_PAGE_SIZE + VMBUS_MAX_PACKET_SIZE; > + > ret = vmbus_open(hdev->channel, VMBUS_RING_BUFSIZE, VMBUS_RING_BUFSIZE, >NULL, 0, hyperv_receive, hdev); > if (ret) { > diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c > index ca873a3b98db..ee2527c3d3b8 100644 > --- a/drivers/hv/hv_balloon.c > +++ b/drivers/hv/hv_balloon.c > @@ -1660,6 +1660,13 @@ static int balloon_connect_vsp(struct hv_device *dev) > unsigned long t; > int ret; > > + /* > + * max_pkt_size should be large enough for one vmbus packet header plus > + * our receive buffer size. We assume vmbus packet header is smaller > + * than HV_HYP_PAGE_SIZE. > + */ > + dev->channel->max_pkt_size = HV_HYP_PAGE_SIZE * 2; > + > ret = vmbus_open(dev->channel, dm_ring_size, dm_ring_size, NULL, 0, >balloon_onchannelcallback, dev); > if (ret) > diff --git a/drivers/hv/hv_fcopy.c b/drivers/hv/hv_fcopy.c > index 660036da7449..07a508ce65db 100644 > --- a/drivers/hv/hv_fcopy.c > +++ b/drivers/hv/hv_fcopy.c > @@ -349,7 +349,7 @@ int hv_fcopy_init(struct hv_util_service *srv) > { > recv_buffer = srv->recv_buffer; > fcopy_transaction.recv_channel = srv->channel; > - fcopy_transaction.recv_channel->max_pkt_size = HV_HYP_PAGE_SIZE * 2; > + fcopy_transaction.recv_channel->max_pkt_size = HV_HYP_PAGE_SIZE * 3; > > /* >* When this driver loads, the user level daemon that > diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c > index c698592b83e4..b85d725ae5b1 100644 > --- a/drivers/hv/hv_kvp.c > +++ b/drivers/hv/hv_kvp.c > @@ -757,7 +757,7 @@ hv_kvp_init(struct hv_util_service *srv) > { > recv_buffer = srv->recv_buffer; > kvp_transaction.recv_channel = srv->channel; > - kvp_transaction.recv_channel->max_pkt_size = HV_HYP_PAGE_SIZE * 4; > + kvp_transaction.recv_channel->max_pkt_size = HV_HYP_PAGE_SIZE * 5; > > /* >* When this driver loads, the user level daemon that > diff --git a/drivers/hv/hv_snapshot.c b/drivers/hv/hv_snapshot.c > index 6018b9d1b1fb..dba6baacbf17 100644 > --
Re: [PATCH 1/2] video: vga16fb: Fix logic that checks for the display standard
Groetje, Geert, Geert Uytterhoeven wrote: - par->isVGA = screen_info.orig_video_isVGA; + par->isVGA = screen_info.orig_video_isVGA == VIDEO_TYPE_VGAC; All non-x86 architectures (except for 2 MIPS platforms) treat orig_video_isVGA as a boolean flag, and just assign 1 to it. Hence this change would break them. I see a bit of a conflict with using orig_video_isVGA as a boolean. All the modern architecture-agnostic driver code, such as sysfb, sysfb_simplefb, and efifb, all use and expect orig_video_isVGA to be an integer. On the other hand, the VGA driver for XEN first sets orig_video_isVGA = 1 (boolean), and then VIDEO_TYPE_VLFB or VIDEO_TYPE_EFI (integer). Overloading the definition for orig_video_isVGA to be both boolean and integer - within the same file - seems like a recipe for bugs to me. That said, I think that wrapping the par->isVGA code, above, within a check for CONFIG_X86 seems safe and expedient. But I would be much happier if the non-x86 architectures would set it to a proper integer value (even if fake) that coincidentally satisfies boolean "true", say VIDEO_TYPE_VGAC; that way, there would be no confusion as to data type in all the more recent architecture-agnostic framebuffer code. Kris
[PATCH] fbdev: aty128fb: make some arrays static const
Don't populate some read-only arrays on the stack but instead make them static const. Also makes the object code a little smaller. Re-format one of the declarations. Add spaces between commas and make PostDivSet unsigned int to fixup checkpatch warnings. Signed-off-by: Colin Ian King --- drivers/video/fbdev/aty/aty128fb.c | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/video/fbdev/aty/aty128fb.c b/drivers/video/fbdev/aty/aty128fb.c index e6a48689c294..882e3cdb750d 100644 --- a/drivers/video/fbdev/aty/aty128fb.c +++ b/drivers/video/fbdev/aty/aty128fb.c @@ -952,7 +952,7 @@ static void aty128_timings(struct aty128fb_par *par) u32 x_mpll_ref_fb_div; u32 xclk_cntl; u32 Nx, M; - unsigned PostDivSet[] = { 0, 1, 2, 4, 8, 3, 6, 12 }; + static const unsigned int PostDivSet[] = { 0, 1, 2, 4, 8, 3, 6, 12 }; #endif if (!par->constants.ref_clk) @@ -1321,8 +1321,10 @@ static void aty128_set_pll(struct aty128_pll *pll, { u32 div3; - unsigned char post_conv[] = /* register values for post dividers */ -{ 2, 0, 1, 4, 2, 2, 6, 2, 3, 2, 2, 2, 7 }; + /* register values for post dividers */ + static const unsigned char post_conv[] = { + 2, 0, 1, 4, 2, 2, 6, 2, 3, 2, 2, 2, 7 + }; /* select PPLL_DIV_3 */ aty_st_le32(CLOCK_CNTL_INDEX, aty_ld_le32(CLOCK_CNTL_INDEX) | (3 << 8)); @@ -1360,7 +1362,7 @@ static int aty128_var_to_pll(u32 period_in_ps, struct aty128_pll *pll, const struct aty128fb_par *par) { const struct aty128_constants c = par->constants; - unsigned char post_dividers[] = {1,2,4,8,3,6,12}; + static const unsigned char post_dividers[] = { 1, 2, 4, 8, 3, 6, 12 }; u32 output_freq; u32 vclk;/* in .01 MHz */ int i = 0; -- 2.32.0
[PATCH v4, 01/15] media: mtk-vcodec: Add vdec enable/disable hardware helpers
Lock, power and clock are highly coupled operations. Adds vdec enable/disable hardware helpers and uses them. Signed-off-by: Yunfei Dong Reviewed-by: Tzung-Bi Shih --- .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 5 - .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c | 168 +++--- .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h | 6 +- .../media/platform/mtk-vcodec/vdec_drv_if.c | 20 +-- .../platform/mtk-vcodec/vdec_msg_queue.c | 2 + 5 files changed, 117 insertions(+), 84 deletions(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c index d44894fa2f6e..fc3e272d2059 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c @@ -195,9 +195,6 @@ static int fops_vcodec_open(struct file *file) mtk_vcodec_dec_set_default_params(ctx); if (v4l2_fh_is_singular(&ctx->fh)) { - ret = mtk_vcodec_dec_pw_on(dev, MTK_VDEC_LAT0); - if (ret < 0) - goto err_load_fw; /* * Does nothing if firmware was already loaded. */ @@ -254,8 +251,6 @@ static int fops_vcodec_release(struct file *file) v4l2_m2m_ctx_release(ctx->m2m_ctx); mtk_vcodec_dec_release(ctx); - if (v4l2_fh_is_singular(&ctx->fh)) - mtk_vcodec_dec_pw_off(dev, MTK_VDEC_LAT0); v4l2_fh_del(&ctx->fh); v4l2_fh_exit(&ctx->fh); v4l2_ctrl_handler_free(&ctx->ctrl_hdl); diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c index b9f5ef979c69..c2ed79bce686 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c @@ -80,74 +80,31 @@ int mtk_vcodec_init_dec_clk(struct platform_device *pdev, } EXPORT_SYMBOL_GPL(mtk_vcodec_init_dec_clk); -int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx) +static int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm) { - struct mtk_vdec_hw_dev *subdev_dev; - struct mtk_vcodec_pm *pm; int ret; - if (vdec_dev->vdec_pdata->is_subdev_supported) { - subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx); - if (!subdev_dev) { - mtk_v4l2_err("Failed to get hw dev\n"); - return -EINVAL; - } - pm = &subdev_dev->pm; - } else { - pm = &vdec_dev->pm; - } - ret = pm_runtime_resume_and_get(pm->dev); if (ret) mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret); return ret; } -EXPORT_SYMBOL_GPL(mtk_vcodec_dec_pw_on); -void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx) +static void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm) { - struct mtk_vdec_hw_dev *subdev_dev; - struct mtk_vcodec_pm *pm; int ret; - if (vdec_dev->vdec_pdata->is_subdev_supported) { - subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx); - if (!subdev_dev) { - mtk_v4l2_err("Failed to get hw dev\n"); - return; - } - pm = &subdev_dev->pm; - } else { - pm = &vdec_dev->pm; - } - ret = pm_runtime_put_sync(pm->dev); if (ret) mtk_v4l2_err("pm_runtime_put_sync fail %d", ret); } -EXPORT_SYMBOL_GPL(mtk_vcodec_dec_pw_off); -void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx) +static void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm) { - struct mtk_vdec_hw_dev *subdev_dev; - struct mtk_vcodec_pm *pm; struct mtk_vcodec_clk *dec_clk; int ret, i; - if (vdec_dev->vdec_pdata->is_subdev_supported) { - subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx); - if (!subdev_dev) { - mtk_v4l2_err("Failed to get hw dev\n"); - return; - } - pm = &subdev_dev->pm; - enable_irq(subdev_dev->dec_irq); - } else { - pm = &vdec_dev->pm; - enable_irq(vdec_dev->dec_irq); - } - dec_clk = &pm->vdec_clk; for (i = 0; i < dec_clk->clk_num; i++) { ret = clk_prepare_enable(dec_clk->clk_info[i].vcodec_clk); @@ -169,31 +126,120 @@ void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx) for (i -= 1; i >= 0; i--) clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk); } -EXPORT_SYMBOL_GPL(mtk_vcodec_dec_clock_on); -void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx) +static void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm) { - struct mtk_vdec_hw_dev *subdev_dev; - struct mtk_vcodec_pm *pm; struc
[PATCH v4, 00/15] media: mtk-vcodec: support for MT8192 decoder
This series adds support for mt8192 h264/vp8/vp9 decoder drivers. Firstly, refactor power/clock/interrupt interfaces for mt8192 is lat and core architecture. Secondly, add new functions to get frame buffer size and resolution according to decoder capability from scp side. Then add callback function to get/put capture buffer in order to enable lat and core decoder in parallel. Then add to support MT21C compressed mode and fix v4l2-compliance fail. Next, extract H264 request api driver to let mt8183 and mt8192 use the same code, and adds mt8192 frame based h264 driver for stateless decoder. Lastly, add vp8 and vp9 stateless decoder drivers. Patches 1 to refactor power/clock/interrupt interface. Patches 2~4 get frame buffer size and resolution according to decoder capability. Patches 5~6 enable lat and core decode in parallel. Patch 7~10 add to support MT21C compressed mode and fix v4l2-compliance fail. patch 11 record capture queue format type. Patch 12~13 extract h264 driver and add mt8192 frame based driver for h264 decoder. Patch 14~15 add vp8 and vp9 stateless decoder drivers. Dependents on "Support multi hardware decode using of_platform_populate"[1]. This patches are the second part used to add mt8192 h264 decoder. And the base part is [1]. [1]https://patchwork.linuxtv.org/project/linux-media/cover/20211215061552.8523-1-yunfei.d...@mediatek.com/ --- changes compared with v3: - remove enum mtk_chip for patch 2. - add vp8 stateless decoder drivers for patch 14. - add vp9 stateless decoder drivers for patch 15. changes compared with v2: - add new patch 11 to record capture queue format type. - separate patch 4 according to tzung-bi's suggestion. - re-write commit message for patch 5 according to tzung-bi's suggestion. changes compared with v1: - rewrite commit message for patch 12. - rewrite cover-letter message. --- Yunfei Dong (15): media: mtk-vcodec: Add vdec enable/disable hardware helpers media: mtk-vcodec: Using firmware type to separate different firmware architecture media: mtk-vcodec: get capture queue buffer size from scp media: mtk-vcodec: Read max resolution from dec_capability media: mtk-vcodec: Call v4l2_m2m_set_dst_buffered() set capture buffer buffered media: mtk-vcodec: Refactor get and put capture buffer flow media: mtk-vcodec: Refactor supported vdec formats and framesizes media: mtk-vcodec: Add format to support MT21C media: mtk-vcodec: disable vp8 4K capability media: mtk-vcodec: Fix v4l2-compliance fail media: mtk-vcodec: record capture queue format type media: mtk-vcodec: Extract H264 common code media: mtk-vcodec: Add h264 decoder driver for mt8192 media: mtk-vcodec: Add vp8 decoder driver for mt8192 media: mtk-vcodec: Add vp9 decoder driver for mt8192 drivers/media/platform/mtk-vcodec/Makefile|4 + .../platform/mtk-vcodec/mtk_vcodec_dec.c | 49 +- .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c |5 - .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c | 168 +- .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h |6 +- .../mtk-vcodec/mtk_vcodec_dec_stateful.c | 14 +- .../mtk-vcodec/mtk_vcodec_dec_stateless.c | 284 ++- .../platform/mtk-vcodec/mtk_vcodec_drv.h | 40 +- .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c |5 - .../media/platform/mtk-vcodec/mtk_vcodec_fw.c |6 + .../media/platform/mtk-vcodec/mtk_vcodec_fw.h |1 + .../mtk-vcodec/vdec/vdec_h264_req_common.c| 311 +++ .../mtk-vcodec/vdec/vdec_h264_req_common.h| 254 ++ .../mtk-vcodec/vdec/vdec_h264_req_if.c| 416 +--- .../mtk-vcodec/vdec/vdec_h264_req_multi_if.c | 605 + .../mtk-vcodec/vdec/vdec_vp8_req_if.c | 445 .../mtk-vcodec/vdec/vdec_vp9_req_lat_if.c | 2066 + .../media/platform/mtk-vcodec/vdec_drv_if.c | 36 +- .../media/platform/mtk-vcodec/vdec_drv_if.h |3 + .../media/platform/mtk-vcodec/vdec_ipi_msg.h | 37 + .../platform/mtk-vcodec/vdec_msg_queue.c |2 + .../media/platform/mtk-vcodec/vdec_vpu_if.c | 54 +- .../media/platform/mtk-vcodec/vdec_vpu_if.h | 15 + .../media/platform/mtk-vcodec/venc_vpu_if.c |2 +- include/linux/remoteproc/mtk_scp.h|2 + 25 files changed, 4248 insertions(+), 582 deletions(-) create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.h create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_req_if.c create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_req_lat_if.c -- 2.25.1
[PATCH v4, 03/15] media: mtk-vcodec: get capture queue buffer size from scp
Different capture buffer format has different buffer size, need to get real buffer size according to buffer type from scp. Signed-off-by: Yunfei Dong --- .../media/platform/mtk-vcodec/vdec_ipi_msg.h | 37 ++ .../media/platform/mtk-vcodec/vdec_vpu_if.c | 50 +++ .../media/platform/mtk-vcodec/vdec_vpu_if.h | 15 ++ 3 files changed, 102 insertions(+) diff --git a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h index 5daca8d52ebb..363d928be29f 100644 --- a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h +++ b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h @@ -20,6 +20,7 @@ enum vdec_ipi_msgid { AP_IPIMSG_DEC_RESET = 0xA004, AP_IPIMSG_DEC_CORE = 0xA005, AP_IPIMSG_DEC_CORE_END = 0xA006, + AP_IPIMSG_DEC_GET_PARAM = 0xA007, VPU_IPIMSG_DEC_INIT_ACK = 0xB000, VPU_IPIMSG_DEC_START_ACK = 0xB001, @@ -28,6 +29,7 @@ enum vdec_ipi_msgid { VPU_IPIMSG_DEC_RESET_ACK = 0xB004, VPU_IPIMSG_DEC_CORE_ACK = 0xB005, VPU_IPIMSG_DEC_CORE_END_ACK = 0xB006, + VPU_IPIMSG_DEC_GET_PARAM_ACK = 0xB007, }; /** @@ -114,4 +116,39 @@ struct vdec_vpu_ipi_init_ack { uint32_t inst_id; }; +/** + * struct vdec_ap_ipi_get_param - for AP_IPIMSG_DEC_GET_PARAM + * @msg_id : AP_IPIMSG_DEC_GET_PARAM + * @inst_id : instance ID. Used if the ABI version >= 2. + * @data : picture information + * @param_type : get param type + * @codec_type : Codec fourcc + */ +struct vdec_ap_ipi_get_param { + uint32_t msg_id; + uint32_t inst_id; + uint32_t data[4]; + uint32_t param_type; + uint32_t codec_type; +}; + + +/** + * struct vdec_vpu_ipi_get_param_ack - for VPU_IPIMSG_DEC_GET_PARAM_ACK + * @msg_id : VPU_IPIMSG_DEC_GET_PARAM_ACK + * @status : VPU exeuction result + * @ap_inst_addr : AP vcodec_vpu_inst instance address + * @data : picture information from SCP. + * @param_type : get param type + * @reserved : reserved param + */ +struct vdec_vpu_ipi_get_param_ack { + uint32_t msg_id; + int32_t status; + uint64_t ap_inst_addr; + uint32_t data[4]; + uint32_t param_type; + uint32_t reserved; +}; + #endif diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c index 21f6d9c5a371..816fd6a5556a 100644 --- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c +++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c @@ -6,6 +6,7 @@ #include "mtk_vcodec_drv.h" #include "mtk_vcodec_util.h" +#include "vdec_drv_if.h" #include "vdec_ipi_msg.h" #include "vdec_vpu_if.h" #include "mtk_vcodec_fw.h" @@ -54,6 +55,27 @@ static void handle_init_ack_msg(const struct vdec_vpu_ipi_init_ack *msg) } } +static void handle_get_param_msg_ack( + const struct vdec_vpu_ipi_get_param_ack *msg) +{ + struct vdec_vpu_inst *vpu = (struct vdec_vpu_inst *) + (unsigned long)msg->ap_inst_addr; + + mtk_vcodec_debug(vpu, "+ ap_inst_addr = 0x%llx", msg->ap_inst_addr); + + /* param_type is enum vdec_get_param_type */ + switch(msg->param_type) { + case GET_PARAM_PIC_INFO: + vpu->fb_sz[0] = msg->data[0]; + vpu->fb_sz[1] = msg->data[1]; + break; + default: + mtk_vcodec_err(vpu, "invalid get param type=%d", msg->param_type); + vpu->failure = 1; + break; + } +} + /* * vpu_dec_ipi_handler - Handler for VPU ipi message. * @@ -89,6 +111,9 @@ static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv) case VPU_IPIMSG_DEC_CORE_END_ACK: break; + case VPU_IPIMSG_DEC_GET_PARAM_ACK: + handle_get_param_msg_ack(data); + break; default: mtk_vcodec_err(vpu, "invalid msg=%X", msg->msg_id); break; @@ -217,6 +242,31 @@ int vpu_dec_start(struct vdec_vpu_inst *vpu, uint32_t *data, unsigned int len) return err; } +int vpu_dec_get_param(struct vdec_vpu_inst *vpu, uint32_t *data, + unsigned int len, unsigned int param_type) +{ + struct vdec_ap_ipi_get_param msg; + int err; + + mtk_vcodec_debug_enter(vpu); + + if (len > ARRAY_SIZE(msg.data)) { + mtk_vcodec_err(vpu, "invalid len = %d\n", len); + return -EINVAL; + } + + memset(&msg, 0, sizeof(msg)); + msg.msg_id = AP_IPIMSG_DEC_GET_PARAM; + msg.inst_id = vpu->inst_id; + memcpy(msg.data, data, sizeof(unsigned int) * len); + msg.param_type = param_type; + msg.codec_type = vpu->codec_type; + + err = vcodec_vpu_send_msg(vpu, (void *)&msg, sizeof(msg)); + mtk_vcodec_debug(vpu, "- ret=%d", err); + return err; +} + int vpu_dec_core(struct vdec_vpu_inst *vpu) { ret
[PATCH v4, 02/15] media: mtk-vcodec: Using firmware type to separate different firmware architecture
MT8173 platform use vpu firmware, mt8183/mt8192 will use scp firmware instead, using chip name is not reasonable to separate different firmware architecture. Using firmware type is much better. Signed-off-by: Yunfei Dong Reviewed-by: Tzung-Bi Shih Reviewed-by: AngeloGioacchino Del Regno --- .../platform/mtk-vcodec/mtk_vcodec_dec_stateful.c | 1 - .../platform/mtk-vcodec/mtk_vcodec_dec_stateless.c | 2 -- drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h | 13 - .../media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c | 5 - drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.c | 6 ++ drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.h | 1 + drivers/media/platform/mtk-vcodec/vdec_vpu_if.c | 4 ++-- drivers/media/platform/mtk-vcodec/venc_vpu_if.c | 2 +- 8 files changed, 10 insertions(+), 24 deletions(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c index 04ca43c77e5f..7966c132be8f 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c @@ -613,7 +613,6 @@ static struct vb2_ops mtk_vdec_frame_vb2_ops = { }; const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata = { - .chip = MTK_MT8173, .init_vdec_params = mtk_init_vdec_params, .ctrls_setup = mtk_vcodec_dec_ctrls_setup, .vdec_vb2_ops = &mtk_vdec_frame_vb2_ops, diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c index 23d997ac114d..5aebf88f997b 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c @@ -343,7 +343,6 @@ static struct vb2_ops mtk_vdec_request_vb2_ops = { }; const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = { - .chip = MTK_MT8183, .init_vdec_params = mtk_init_vdec_params, .ctrls_setup = mtk_vcodec_dec_ctrls_setup, .vdec_vb2_ops = &mtk_vdec_request_vb2_ops, @@ -362,7 +361,6 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = { /* This platform data is used for one lat and one core architecture. */ const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata = { - .chip = MTK_MT8192, .init_vdec_params = mtk_init_vdec_params, .ctrls_setup = mtk_vcodec_dec_ctrls_setup, .vdec_vb2_ops = &mtk_vdec_request_vb2_ops, diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h index 3fc747cea5c9..45d9e1be7063 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h @@ -335,13 +335,6 @@ struct mtk_vcodec_ctx { struct vdec_msg_queue msg_queue; }; -enum mtk_chip { - MTK_MT8173, - MTK_MT8183, - MTK_MT8192, - MTK_MT8195, -}; - /** * struct mtk_vdec_hw_arch - Used to separate different hardware architecture */ @@ -367,7 +360,6 @@ enum mtk_vdec_hw_arch { * @vdec_framesizes: supported video decoder frame sizes * @num_framesizes: count of video decoder frame sizes * - * @chip: chip this decoder is compatible with * @hw_arch: hardware arch is used to separate pure_sin_core and lat_sin_core * * @is_subdev_supported: whether support parent-node architecture(subdev) @@ -390,7 +382,6 @@ struct mtk_vcodec_dec_pdata { const struct mtk_codec_framesizes *vdec_framesizes; const int num_framesizes; - enum mtk_chip chip; enum mtk_vdec_hw_arch hw_arch; bool is_subdev_supported; @@ -400,8 +391,6 @@ struct mtk_vcodec_dec_pdata { /** * struct mtk_vcodec_enc_pdata - compatible data for each IC * - * @chip: chip this encoder is compatible with - * * @uses_ext: whether the encoder uses the extended firmware messaging format * @min_bitrate: minimum supported encoding bitrate * @max_bitrate: maximum supported encoding bitrate @@ -412,8 +401,6 @@ struct mtk_vcodec_dec_pdata { * @core_id: stand for h264 or vp8 encode index */ struct mtk_vcodec_enc_pdata { - enum mtk_chip chip; - bool uses_ext; unsigned long min_bitrate; unsigned long max_bitrate; diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c index 507ad1ea2104..3ac6969c54c0 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c @@ -378,7 +378,6 @@ static int mtk_vcodec_probe(struct platform_device *pdev) } static const struct mtk_vcodec_enc_pdata mt8173_avc_pdata = { - .chip = MTK_MT8173, .capture_formats = mtk_video_formats_capture_h264, .num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_h264), .output_formats = mtk_video_formats_output, @@ -389,7 +388,6 @@ static const struct mtk_vcodec_enc_pdata mt8
[PATCH v4, 04/15] media: mtk-vcodec: Read max resolution from dec_capability
Supported max resolution for different platforms are not the same: 2K or 4K, getting it according to dec_capability. Signed-off-by: Yunfei Dong Reviewed-by: Tzung-Bi Shih --- .../platform/mtk-vcodec/mtk_vcodec_dec.c | 31 +++ .../platform/mtk-vcodec/mtk_vcodec_drv.h | 4 +++ 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c index 130ecef2e766..65a224d788bf 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c @@ -152,13 +152,15 @@ void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx) q_data->coded_height = DFT_CFG_HEIGHT; q_data->fmt = ctx->dev->vdec_pdata->default_cap_fmt; q_data->field = V4L2_FIELD_NONE; + ctx->max_width = MTK_VDEC_MAX_W; + ctx->max_height = MTK_VDEC_MAX_H; v4l_bound_align_image(&q_data->coded_width, MTK_VDEC_MIN_W, - MTK_VDEC_MAX_W, 4, + ctx->max_width, 4, &q_data->coded_height, MTK_VDEC_MIN_H, - MTK_VDEC_MAX_H, 5, 6); + ctx->max_height, 5, 6); q_data->sizeimage[0] = q_data->coded_width * q_data->coded_height; q_data->bytesperline[0] = q_data->coded_width; @@ -217,17 +219,17 @@ static int vidioc_vdec_subscribe_evt(struct v4l2_fh *fh, } } -static int vidioc_try_fmt(struct v4l2_format *f, - const struct mtk_video_fmt *fmt) +static int vidioc_try_fmt(struct mtk_vcodec_ctx *ctx, + struct v4l2_format *f, const struct mtk_video_fmt *fmt) { struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; pix_fmt_mp->field = V4L2_FIELD_NONE; pix_fmt_mp->width = - clamp(pix_fmt_mp->width, MTK_VDEC_MIN_W, MTK_VDEC_MAX_W); + clamp(pix_fmt_mp->width, MTK_VDEC_MIN_W, ctx->max_width); pix_fmt_mp->height = - clamp(pix_fmt_mp->height, MTK_VDEC_MIN_H, MTK_VDEC_MAX_H); + clamp(pix_fmt_mp->height, MTK_VDEC_MIN_H, ctx->max_height); if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { pix_fmt_mp->num_planes = 1; @@ -245,16 +247,16 @@ static int vidioc_try_fmt(struct v4l2_format *f, tmp_h = pix_fmt_mp->height; v4l_bound_align_image(&pix_fmt_mp->width, MTK_VDEC_MIN_W, - MTK_VDEC_MAX_W, 6, + ctx->max_width, 6, &pix_fmt_mp->height, MTK_VDEC_MIN_H, - MTK_VDEC_MAX_H, 6, 9); + ctx->max_height, 6, 9); if (pix_fmt_mp->width < tmp_w && - (pix_fmt_mp->width + 64) <= MTK_VDEC_MAX_W) + (pix_fmt_mp->width + 64) <= ctx->max_width) pix_fmt_mp->width += 64; if (pix_fmt_mp->height < tmp_h && - (pix_fmt_mp->height + 64) <= MTK_VDEC_MAX_H) + (pix_fmt_mp->height + 64) <= ctx->max_height) pix_fmt_mp->height += 64; mtk_v4l2_debug(0, @@ -294,7 +296,7 @@ static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv, fmt = mtk_vdec_find_format(f, dec_pdata); } - return vidioc_try_fmt(f, fmt); + return vidioc_try_fmt(ctx, f, fmt); } static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv, @@ -317,7 +319,7 @@ static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv, return -EINVAL; } - return vidioc_try_fmt(f, fmt); + return vidioc_try_fmt(ctx, f, fmt); } static int vidioc_vdec_g_selection(struct file *file, void *priv, @@ -445,7 +447,7 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv, return -EINVAL; q_data->fmt = fmt; - vidioc_try_fmt(f, q_data->fmt); + vidioc_try_fmt(ctx, f, q_data->fmt); if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { q_data->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage; q_data->coded_width = pix_mp->width; @@ -545,6 +547,9 @@ static int vidioc_enum_framesizes(struct file *file, void *priv, fsize->stepwise.min_height, fsize->stepwise.max_height, fsize->stepwise.step_height); + + ctx->max_width = fsize->stepwise.max_width; + ctx->max_height = fsize->stepwise.max_height; return 0; } diff --git a/drivers/media/platform
[PATCH v4, 05/15] media: mtk-vcodec: Call v4l2_m2m_set_dst_buffered() set capture buffer buffered
lat thread: output queue \ -> lat hardware -> lat trans buffer lat trans buffer / core thread: capture queue \ ->core hardware -> capture queue lat trans buffer / Lat and core work in different thread, setting capture buffer buffered. Signed-off-by: Yunfei Dong --- drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c index 5aebf88f997b..23a154c4e321 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c @@ -314,6 +314,9 @@ static void mtk_init_vdec_params(struct mtk_vcodec_ctx *ctx) src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); + if (ctx->dev->vdec_pdata->hw_arch != MTK_VDEC_PURE_SINGLE_CORE) + v4l2_m2m_set_dst_buffered(ctx->m2m_ctx, 1); + /* Support request api for output plane */ src_vq->supports_requests = true; src_vq->requires_requests = true; -- 2.25.1
[PATCH v4, 06/15] media: mtk-vcodec: Refactor get and put capture buffer flow
For lat and core decode in parallel, need to get capture buffer when core start to decode and put put capture buffer to display list when core decode done. Signed-off-by: Yunfei Dong --- .../mtk-vcodec/mtk_vcodec_dec_stateless.c | 123 -- .../platform/mtk-vcodec/mtk_vcodec_drv.h | 5 +- .../mtk-vcodec/vdec/vdec_h264_req_if.c| 16 ++- 3 files changed, 104 insertions(+), 40 deletions(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c index 23a154c4e321..f3036c3f223b 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c @@ -108,37 +108,89 @@ static const struct mtk_codec_framesizes mtk_vdec_framesizes[] = { #define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_vdec_framesizes) -static void mtk_vdec_stateless_set_dst_payload(struct mtk_vcodec_ctx *ctx, - struct vdec_fb *fb) +static void mtk_vdec_stateless_out_to_done(struct mtk_vcodec_ctx *ctx, + struct mtk_vcodec_mem *bs, int error) { - struct mtk_video_dec_buf *vdec_frame_buf = - container_of(fb, struct mtk_video_dec_buf, frame_buffer); - struct vb2_v4l2_buffer *vb = &vdec_frame_buf->m2m_buf.vb; - unsigned int cap_y_size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[0]; + struct mtk_video_dec_buf *out_buf; + struct vb2_v4l2_buffer *vb; - vb2_set_plane_payload(&vb->vb2_buf, 0, cap_y_size); - if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) { - unsigned int cap_c_size = - ctx->q_data[MTK_Q_DATA_DST].sizeimage[1]; + if (!bs) { + mtk_v4l2_err("Free bitstream buffer fail."); + return; + } + out_buf = container_of(bs, struct mtk_video_dec_buf, bs_buffer); + vb = &out_buf->m2m_buf.vb; + + mtk_v4l2_debug(2, + "Free bitsteam buffer id = %d to done_list", + vb->vb2_buf.index); + + v4l2_m2m_src_buf_remove(ctx->m2m_ctx); + if (error) { + v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR); + if (error == -EIO) + out_buf->error = true; + } else { + v4l2_m2m_buf_done(vb, VB2_BUF_STATE_DONE); + } +} - vb2_set_plane_payload(&vb->vb2_buf, 1, cap_c_size); +static void mtk_vdec_stateless_cap_to_disp(struct mtk_vcodec_ctx *ctx, + struct vdec_fb *fb, int error) +{ + struct mtk_video_dec_buf *vdec_frame_buf; + struct vb2_v4l2_buffer *vb; + unsigned int cap_y_size, cap_c_size; + + if (!fb) { + mtk_v4l2_err("Free frame buffer fail."); + return; } + vdec_frame_buf = container_of(fb, struct mtk_video_dec_buf, + frame_buffer); + vb = &vdec_frame_buf->m2m_buf.vb; + + cap_y_size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[0]; + cap_c_size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[1]; + + v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); + + vb2_set_plane_payload(&vb->vb2_buf, 0, cap_y_size); + if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) + vb2_set_plane_payload(&vb->vb2_buf, 1, cap_c_size); + + mtk_v4l2_debug(2, + "Free frame buffer id = %d to done_list", + vb->vb2_buf.index); + if (error) + v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR); + else + v4l2_m2m_buf_done(vb, VB2_BUF_STATE_DONE); } -static struct vdec_fb *vdec_get_cap_buffer(struct mtk_vcodec_ctx *ctx, - struct vb2_v4l2_buffer *vb2_v4l2) +static struct vdec_fb *vdec_get_cap_buffer(struct mtk_vcodec_ctx *ctx) { - struct mtk_video_dec_buf *framebuf = - container_of(vb2_v4l2, struct mtk_video_dec_buf, m2m_buf.vb); - struct vdec_fb *pfb = &framebuf->frame_buffer; - struct vb2_buffer *dst_buf = &vb2_v4l2->vb2_buf; + struct mtk_video_dec_buf *framebuf; + struct vb2_v4l2_buffer *vb2_v4l2; + struct vb2_buffer *dst_buf; + struct vdec_fb *pfb; + + vb2_v4l2 = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); + if (!vb2_v4l2) { + mtk_v4l2_debug(1, "[%d] dst_buf empty!!", ctx->id); + return NULL; + } - pfb->base_y.va = NULL; + dst_buf = &vb2_v4l2->vb2_buf; + framebuf = container_of(vb2_v4l2, struct mtk_video_dec_buf, m2m_buf.vb); + + pfb = &framebuf->frame_buffer; + pfb->base_y.va = vb2_plane_vaddr(dst_buf, 0); pfb->base_y.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0); pfb->base_y.size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[0]; if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) { - pfb->base_c.va = NULL; +
[PATCH v4, 07/15] media: mtk-vcodec: Refactor supported vdec formats and framesizes
Supported output and capture format types for mt8192 are different with mt8183. Needs to get format types according to decoder capability. Signed-off-by: Yunfei Dong --- .../platform/mtk-vcodec/mtk_vcodec_dec.c | 8 +- .../mtk-vcodec/mtk_vcodec_dec_stateful.c | 13 +- .../mtk-vcodec/mtk_vcodec_dec_stateless.c | 117 +- .../platform/mtk-vcodec/mtk_vcodec_drv.h | 13 +- 4 files changed, 107 insertions(+), 44 deletions(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c index 65a224d788bf..519f2b9d9b5b 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c @@ -26,7 +26,7 @@ mtk_vdec_find_format(struct v4l2_format *f, const struct mtk_video_fmt *fmt; unsigned int k; - for (k = 0; k < dec_pdata->num_formats; k++) { + for (k = 0; k < *dec_pdata->num_formats; k++) { fmt = &dec_pdata->vdec_formats[k]; if (fmt->fourcc == f->fmt.pix_mp.pixelformat) return fmt; @@ -525,7 +525,7 @@ static int vidioc_enum_framesizes(struct file *file, void *priv, if (fsize->index != 0) return -EINVAL; - for (i = 0; i < dec_pdata->num_framesizes; ++i) { + for (i = 0; i < *dec_pdata->num_framesizes; ++i) { if (fsize->pixel_format != dec_pdata->vdec_framesizes[i].fourcc) continue; @@ -564,7 +564,7 @@ static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, void *priv, const struct mtk_video_fmt *fmt; int i, j = 0; - for (i = 0; i < dec_pdata->num_formats; i++) { + for (i = 0; i < *dec_pdata->num_formats; i++) { if (output_queue && dec_pdata->vdec_formats[i].type != MTK_FMT_DEC) continue; @@ -577,7 +577,7 @@ static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, void *priv, ++j; } - if (i == dec_pdata->num_formats) + if (i == *dec_pdata->num_formats) return -EINVAL; fmt = &dec_pdata->vdec_formats[i]; diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c index 7966c132be8f..3f33beb9c551 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c @@ -37,7 +37,9 @@ static const struct mtk_video_fmt mtk_video_formats[] = { }, }; -#define NUM_FORMATS ARRAY_SIZE(mtk_video_formats) +static const unsigned int num_supported_formats = + ARRAY_SIZE(mtk_video_formats); + #define DEFAULT_OUT_FMT_IDX 0 #define DEFAULT_CAP_FMT_IDX 3 @@ -59,7 +61,8 @@ static const struct mtk_codec_framesizes mtk_vdec_framesizes[] = { }, }; -#define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_vdec_framesizes) +static const unsigned int num_supported_framesize = + ARRAY_SIZE(mtk_vdec_framesizes); /* * This function tries to clean all display buffers, the buffers will return @@ -235,7 +238,7 @@ static void mtk_vdec_update_fmt(struct mtk_vcodec_ctx *ctx, unsigned int k; dst_q_data = &ctx->q_data[MTK_Q_DATA_DST]; - for (k = 0; k < NUM_FORMATS; k++) { + for (k = 0; k < num_supported_formats; k++) { fmt = &mtk_video_formats[k]; if (fmt->fourcc == pixelformat) { mtk_v4l2_debug(1, "Update cap fourcc(%d -> %d)", @@ -617,11 +620,11 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata = { .ctrls_setup = mtk_vcodec_dec_ctrls_setup, .vdec_vb2_ops = &mtk_vdec_frame_vb2_ops, .vdec_formats = mtk_video_formats, - .num_formats = NUM_FORMATS, + .num_formats = &num_supported_formats, .default_out_fmt = &mtk_video_formats[DEFAULT_OUT_FMT_IDX], .default_cap_fmt = &mtk_video_formats[DEFAULT_CAP_FMT_IDX], .vdec_framesizes = mtk_vdec_framesizes, - .num_framesizes = NUM_SUPPORTED_FRAMESIZE, + .num_framesizes = &num_supported_framesize, .worker = mtk_vdec_worker, .flush_decoder = mtk_vdec_flush_decoder, .is_subdev_supported = false, diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c index f3036c3f223b..01bb96f3b30e 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c @@ -81,33 +81,23 @@ static const struct mtk_stateless_control mtk_stateless_controls[] = { #define NUM_CTRLS ARRAY_SIZE(mtk_stateless_controls) -static const struct mtk_video_fmt mtk_video_formats[] = { - { - .fourcc = V4L2_PIX_FMT_H264_SLICE, - .type = MTK_FMT_DEC, - .num_planes = 1, - }, - { - .fourcc = V4L2_PIX_FMT_MM21, -
[PATCH v4, 09/15] media: mtk-vcodec: disable vp8 4K capability
For vp8 not support 4K, need to disable it. Signed-off-by: Yunfei Dong --- drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c index 519f2b9d9b5b..34ee4a0092ff 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c @@ -532,7 +532,8 @@ static int vidioc_enum_framesizes(struct file *file, void *priv, fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; fsize->stepwise = dec_pdata->vdec_framesizes[i].stepwise; if (!(ctx->dev->dec_capability & - VCODEC_CAPABILITY_4K_DISABLED)) { + VCODEC_CAPABILITY_4K_DISABLED) && + fsize->pixel_format != V4L2_PIX_FMT_VP8_FRAME) { mtk_v4l2_debug(3, "4K is enabled"); fsize->stepwise.max_width = VCODEC_DEC_4K_CODED_WIDTH; -- 2.25.1
[PATCH v4, 08/15] media: mtk-vcodec: Add format to support MT21C
Needs to use mediatek compressed mode for mt8192 decoder. Signed-off-by: Yunfei Dong --- .../media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c | 7 ++- drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c index 01bb96f3b30e..21895fbed4c5 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c @@ -81,7 +81,7 @@ static const struct mtk_stateless_control mtk_stateless_controls[] = { #define NUM_CTRLS ARRAY_SIZE(mtk_stateless_controls) -static struct mtk_video_fmt mtk_video_formats[2]; +static struct mtk_video_fmt mtk_video_formats[3]; static struct mtk_codec_framesizes mtk_vdec_framesizes[1]; static struct mtk_video_fmt default_out_format; @@ -361,6 +361,7 @@ static void mtk_vcodec_add_formats(unsigned int fourcc, num_framesizes++; break; case V4L2_PIX_FMT_MM21: + case V4L2_PIX_FMT_MT21C: mtk_video_formats[count_formats].fourcc = fourcc; mtk_video_formats[count_formats].type = MTK_FMT_FRAME; mtk_video_formats[count_formats].num_planes = 2; @@ -387,6 +388,10 @@ static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_ctx *ctx) mtk_vcodec_add_formats(V4L2_PIX_FMT_MM21, ctx); cap_format_count++; } + if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_MT21C) { + mtk_vcodec_add_formats(V4L2_PIX_FMT_MT21C, ctx); + cap_format_count++; + } if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_H264_SLICE) { mtk_vcodec_add_formats(V4L2_PIX_FMT_H264_SLICE, ctx); out_format_count++; diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h index cdc0a53eee4e..12a2baaf9e81 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h @@ -353,6 +353,7 @@ enum mtk_vdec_hw_arch { */ enum mtk_vdec_format_types { MTK_VDEC_FORMAT_MM21 = 0x20, + MTK_VDEC_FORMAT_MT21C = 0x40, MTK_VDEC_FORMAT_H264_SLICE = 0x100, }; -- 2.25.1
[PATCH v4, 10/15] media: mtk-vcodec: Fix v4l2-compliance fail
Need to use default pic info when get pic info fail. Signed-off-by: Yunfei Dong --- drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c index 34ee4a0092ff..75210eb829d0 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c @@ -478,11 +478,14 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv, ctx->picinfo.pic_w = pix_mp->width; ctx->picinfo.pic_h = pix_mp->height; + /* +* If get pic info fail, need to use the default pic info params, or +* v4l2-compliance will fail +*/ ret = vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo); if (ret) { mtk_v4l2_err("[%d]Error!! Get GET_PARAM_PICTURE_INFO Fail", ctx->id); - return -EINVAL; } ctx->last_decoded_picinfo = ctx->picinfo; -- 2.25.1
[PATCH v4, 11/15] media: mtk-vcodec: record capture queue format type
Capture queue format type is difference for different platform, need to calculate capture buffer size according to capture queue format type in scp. Signed-off-by: Yunfei Dong --- drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | 2 ++ drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c index 75210eb829d0..4533cb44551d 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c @@ -468,6 +468,8 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv, } ctx->state = MTK_STATE_INIT; } + } else { + ctx->capture_fourcc = fmt->fourcc; } /* diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h index 12a2baaf9e81..4981760226b5 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h @@ -277,6 +277,7 @@ struct vdec_pic_info { * to be used with encoder and stateful decoder. * @is_flushing: set to true if flushing is in progress. * @current_codec: current set input codec, in V4L2 pixel format + * @capture_fourcc: capture queue type in V4L2 pixel format * * @colorspace: enum v4l2_colorspace; supplemental to pixelformat * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding @@ -324,6 +325,7 @@ struct mtk_vcodec_ctx { bool is_flushing; u32 current_codec; + u32 capture_fourcc; enum v4l2_colorspace colorspace; enum v4l2_ycbcr_encoding ycbcr_enc; -- 2.25.1
[PATCH v4, 13/15] media: mtk-vcodec: support stateless H.264 decoding for mt8192
Adds h264 lat and core architecture driver for mt8192, and the decode mode is frame based for stateless decoder. Signed-off-by: Yunfei Dong --- drivers/media/platform/mtk-vcodec/Makefile| 1 + .../mtk-vcodec/vdec/vdec_h264_req_multi_if.c | 605 ++ .../media/platform/mtk-vcodec/vdec_drv_if.c | 8 +- .../media/platform/mtk-vcodec/vdec_drv_if.h | 1 + include/linux/remoteproc/mtk_scp.h| 2 + 5 files changed, 616 insertions(+), 1 deletion(-) create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile index 3f41d748eee5..22edb1c86598 100644 --- a/drivers/media/platform/mtk-vcodec/Makefile +++ b/drivers/media/platform/mtk-vcodec/Makefile @@ -10,6 +10,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \ vdec/vdec_vp9_if.o \ vdec/vdec_h264_req_if.o \ vdec/vdec_h264_req_common.o \ + vdec/vdec_h264_req_multi_if.o \ mtk_vcodec_dec_drv.o \ vdec_drv_if.o \ vdec_vpu_if.o \ diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c new file mode 100644 index ..b53c05507d75 --- /dev/null +++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c @@ -0,0 +1,605 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + * Author: Yunfei Dong + */ + +#include +#include +#include +#include +#include + +#include "../mtk_vcodec_util.h" +#include "../mtk_vcodec_dec.h" +#include "../mtk_vcodec_intr.h" +#include "../vdec_drv_base.h" +#include "../vdec_drv_if.h" +#include "../vdec_vpu_if.h" +#include "vdec_h264_req_common.h" + +/** + * enum vdec_h264_core_dec_err_type - core decode error type + * @TRANS_BUFFER_FULL : trans buffer is full + * @SLICE_HEADER_FULL : slice header buffer is full + */ +enum vdec_h264_core_dec_err_type { + TRANS_BUFFER_FULL = 1, + SLICE_HEADER_FULL, +}; + +/** + * struct vdec_h264_slice_lat_dec_param - parameters for decode current frame + * @sps : h264 sps syntax parameters + * @pps : h264 pps syntax parameters + * @slice_header: h264 slice header syntax parameters + * @scaling_matrix : h264 scaling list parameters + * @decode_params : decoder parameters of each frame used for hardware decode + * @h264_dpb_info : dpb reference list + */ +struct vdec_h264_slice_lat_dec_param { + struct mtk_h264_sps_param sps; + struct mtk_h264_pps_param pps; + struct mtk_h264_slice_hd_param slice_header; + struct slice_api_h264_scaling_matrix scaling_matrix; + struct slice_api_h264_decode_param decode_params; + struct mtk_h264_dpb_info h264_dpb_info[V4L2_H264_NUM_DPB_ENTRIES]; +}; + +/** + * struct vdec_h264_slice_info - decode information + * @nal_info: nal info of current picture + * @timeout : Decode timeout: 1 timeout, 0 no timeount + * @bs_buf_size : bitstream size + * @bs_buf_addr : bitstream buffer dma address + * @y_fb_dma: Y frame buffer dma address + * @c_fb_dma: C frame buffer dma address + * @vdec_fb_va : VDEC frame buffer struct virtual address + * @crc : Used to check whether hardware's status is right + */ +struct vdec_h264_slice_info { + uint16_t nal_info; + uint16_t timeout; + uint32_t bs_buf_size; + uint64_t bs_buf_addr; + uint64_t y_fb_dma; + uint64_t c_fb_dma; + uint64_t vdec_fb_va; + uint32_t crc[8]; +}; + +/** + * struct vdec_h264_slice_vsi - shared memory for decode information exchange + *between VPU and Host. The memory is allocated by VPU then mapping to + *Host in vdec_h264_slice_init() and freed in vdec_h264_slice_deinit() + *by VPU. AP-W/R : AP is writer/reader on this item. VPU-W/R: VPU is + *write/reader on this item. + * @wdma_err_addr : wdma error dma address + * @wdma_start_addr : wdma start dma address + * @wdma_end_addr : wdma end dma address + * @slice_bc_start_addr : slice bc start dma address + * @slice_bc_end_addr : slice bc end dma address + * @row_info_start_addr : row info start dma address + * @row_info_end_addr : row info end dma address + * @trans_start : trans start dma address + * @trans_end : trans end dma address + * @wdma_end_addr_offset: wdma end address offset + * @mv_buf_dma : HW working motion vector buffer + *dma address (AP-W, VPU-R) + * @dec : decode information (AP-R, VPU-W) + * @h264_slice_params : decode parameters for hw used + */ +struct vdec_h264_slice_vsi { + /* LAT dec addr */ + uint64_t wdma_err_addr; + uint64_t wdma_start_addr; + uint64_t wdma_end_addr; + uint64_t slice_bc_start_addr; + uint64_t slice_bc_end_addr; + uint64_t row_info_start_addr; + uint64_t ro
[PATCH v4, 14/15] media: mtk-vcodec: support stateless VP8 decoding
Add support for VP8 decoding using the stateless API, as supported by MT8192. Signed-off-by: Yunfei Dong --- drivers/media/platform/mtk-vcodec/Makefile| 1 + .../mtk-vcodec/mtk_vcodec_dec_stateless.c | 24 +- .../platform/mtk-vcodec/mtk_vcodec_drv.h | 1 + .../mtk-vcodec/vdec/vdec_vp8_req_if.c | 445 ++ .../media/platform/mtk-vcodec/vdec_drv_if.c | 4 + .../media/platform/mtk-vcodec/vdec_drv_if.h | 1 + 6 files changed, 474 insertions(+), 2 deletions(-) create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_req_if.c diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile index 22edb1c86598..b457daf2d196 100644 --- a/drivers/media/platform/mtk-vcodec/Makefile +++ b/drivers/media/platform/mtk-vcodec/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec-dec.o \ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \ vdec/vdec_vp8_if.o \ + vdec/vdec_vp8_req_if.o \ vdec/vdec_vp9_if.o \ vdec/vdec_h264_req_if.o \ vdec/vdec_h264_req_common.o \ diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c index 21895fbed4c5..019055a0807d 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c @@ -76,13 +76,28 @@ static const struct mtk_stateless_control mtk_stateless_controls[] = { .max = V4L2_STATELESS_H264_START_CODE_ANNEX_B, }, .codec_type = V4L2_PIX_FMT_H264_SLICE, + }, + { + .cfg = { + .id = V4L2_CID_STATELESS_VP8_FRAME, + }, + .codec_type = V4L2_PIX_FMT_VP8_FRAME, + }, + { + .cfg = { + .id = V4L2_CID_MPEG_VIDEO_VP8_PROFILE, + .min = V4L2_MPEG_VIDEO_VP8_PROFILE_0, + .def = V4L2_MPEG_VIDEO_VP8_PROFILE_0, + .max = V4L2_MPEG_VIDEO_VP8_PROFILE_3, + }, + .codec_type = V4L2_PIX_FMT_VP8_FRAME, } }; #define NUM_CTRLS ARRAY_SIZE(mtk_stateless_controls) -static struct mtk_video_fmt mtk_video_formats[3]; -static struct mtk_codec_framesizes mtk_vdec_framesizes[1]; +static struct mtk_video_fmt mtk_video_formats[4]; +static struct mtk_codec_framesizes mtk_vdec_framesizes[2]; static struct mtk_video_fmt default_out_format; static struct mtk_video_fmt default_cap_format; @@ -352,6 +367,7 @@ static void mtk_vcodec_add_formats(unsigned int fourcc, switch (fourcc) { case V4L2_PIX_FMT_H264_SLICE: + case V4L2_PIX_FMT_VP8_FRAME: mtk_video_formats[count_formats].fourcc = fourcc; mtk_video_formats[count_formats].type = MTK_FMT_DEC; mtk_video_formats[count_formats].num_planes = 1; @@ -396,6 +412,10 @@ static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_ctx *ctx) mtk_vcodec_add_formats(V4L2_PIX_FMT_H264_SLICE, ctx); out_format_count++; } + if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_VP8_FRAME) { + mtk_vcodec_add_formats(V4L2_PIX_FMT_VP8_FRAME, ctx); + out_format_count++; + } if (cap_format_count) default_cap_format = mtk_video_formats[cap_format_count - 1]; diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h index 4981760226b5..63ca6458929b 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h @@ -357,6 +357,7 @@ enum mtk_vdec_format_types { MTK_VDEC_FORMAT_MM21 = 0x20, MTK_VDEC_FORMAT_MT21C = 0x40, MTK_VDEC_FORMAT_H264_SLICE = 0x100, + MTK_VDEC_FORMAT_VP8_FRAME = 0x200, }; /** diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_req_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_req_if.c new file mode 100644 index ..0b0013c2f9ed --- /dev/null +++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_req_if.c @@ -0,0 +1,445 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + * Author: Yunfei Dong + */ + +#include +#include +#include +#include + +#include "../mtk_vcodec_util.h" +#include "../mtk_vcodec_dec.h" +#include "../mtk_vcodec_intr.h" +#include "../vdec_drv_base.h" +#include "../vdec_drv_if.h" +#include "../vdec_vpu_if.h" + +/* Decoding picture buffer size (3 reference frames plus current frame) */ +#define VP8_DPB_SIZE 4 + +/* HW working buffer size (bytes) */ +#define VP8_SEG_ID_SZ (256 * 1024) +#define VP8_PP_WRAPY_SZ(64 * 1024) +#define VP8_PP_WRAPC_SZ(64 * 1024) +#define VP8_VLD_PRED_SZ(64 * 1024
[PATCH v4, 12/15] media: mtk-vcodec: Extract H264 common code
Mt8192 can use some of common code with mt8183. Moves them to a new file in order to reuse. Signed-off-by: Yunfei Dong --- drivers/media/platform/mtk-vcodec/Makefile| 1 + .../mtk-vcodec/vdec/vdec_h264_req_common.c| 311 ++ .../mtk-vcodec/vdec/vdec_h264_req_common.h| 254 +++ .../mtk-vcodec/vdec/vdec_h264_req_if.c| 400 +- 4 files changed, 589 insertions(+), 377 deletions(-) create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.h diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile index 359619653a0e..3f41d748eee5 100644 --- a/drivers/media/platform/mtk-vcodec/Makefile +++ b/drivers/media/platform/mtk-vcodec/Makefile @@ -9,6 +9,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \ vdec/vdec_vp8_if.o \ vdec/vdec_vp9_if.o \ vdec/vdec_h264_req_if.o \ + vdec/vdec_h264_req_common.o \ mtk_vcodec_dec_drv.o \ vdec_drv_if.o \ vdec_vpu_if.o \ diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c new file mode 100644 index ..c8113ca251f5 --- /dev/null +++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c @@ -0,0 +1,311 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + * Author: Yunfei Dong + */ + +#include "vdec_h264_req_common.h" + +/* get used parameters for sps/pps */ +#define GET_MTK_VDEC_FLAG(cond, flag) \ + { dst_param->cond = ((src_param->flags & flag) ? (1) : (0)); } +#define GET_MTK_VDEC_PARAM(param) \ + { dst_param->param = src_param->param; } + +/* + * The firmware expects unused reflist entries to have the value 0x20. + */ +void mtk_vdec_h264_fixup_ref_list(u8 *ref_list, size_t num_valid) +{ + memset(&ref_list[num_valid], 0x20, 32 - num_valid); +} + +void *mtk_vdec_h264_get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id) +{ + struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, id); + + return ctrl->p_cur.p; +} + +void mtk_vdec_h264_fill_dpb_info(struct mtk_vcodec_ctx *ctx, + struct slice_api_h264_decode_param *decode_params, + struct mtk_h264_dpb_info *h264_dpb_info) +{ + struct vb2_queue *vq; + struct vb2_buffer *vb; + struct vb2_v4l2_buffer *vb2_v4l2; + int index; + + vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); + + for (index = 0; index < V4L2_H264_NUM_DPB_ENTRIES; index++) { + const struct slice_h264_dpb_entry *dpb; + int vb2_index; + + dpb = &decode_params->dpb[index]; + if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) { + h264_dpb_info[index].reference_flag = 0; + continue; + } + + vb2_index = vb2_find_timestamp(vq, dpb->reference_ts, 0); + if (vb2_index < 0) { + dev_err(&ctx->dev->plat_dev->dev, + "Reference invalid: dpb_index(%d) reference_ts(%lld)", + index, dpb->reference_ts); + continue; + } + + /* 1 for short term reference, 2 for long term reference */ + if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)) + h264_dpb_info[index].reference_flag = 1; + else + h264_dpb_info[index].reference_flag = 2; + + vb = vq->bufs[vb2_index]; + vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf); + h264_dpb_info[index].field = vb2_v4l2->field; + + h264_dpb_info[index].y_dma_addr = + vb2_dma_contig_plane_dma_addr(vb, 0); + if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) + h264_dpb_info[index].c_dma_addr = + vb2_dma_contig_plane_dma_addr(vb, 1); + else + h264_dpb_info[index].c_dma_addr = + h264_dpb_info[index].y_dma_addr + + ctx->picinfo.fb_sz[0]; + } +} + +void mtk_vdec_h264_copy_sps_params(struct mtk_h264_sps_param *dst_param, + const struct v4l2_ctrl_h264_sps *src_param) +{ + GET_MTK_VDEC_PARAM(chroma_format_idc); + GET_MTK_VDEC_PARAM(bit_depth_luma_minus8); + GET_MTK_VDEC_PARAM(bit_depth_chroma_minus8); + GET_MTK_VDEC_PARAM(log2_max_frame_num_minus4); + GET_MTK_VDEC_PARAM(pic_order_cnt_type); + GET_MTK_VDEC_PARAM(log2_max_pic_order_cnt_lsb_minus4); + GET_MTK_VDEC_PARAM(max_num_ref_frames); + GET_MTK_VDEC_PARAM(pic_width_in_mbs_minus1); + GET_MTK_VDEC_PARAM(pic_height_in_map_units
[PATCH v4, 15/15] media: mtk-vcodec: support stateless VP9 decoding
Add support for VP9 decoding using the stateless API, as supported by MT8192. And the drivers is lat and core architecture. Signed-off-by: George Sun Co-developed-by: Yunfei Dong --- drivers/media/platform/mtk-vcodec/Makefile|1 + .../mtk-vcodec/mtk_vcodec_dec_stateless.c | 26 +- .../platform/mtk-vcodec/mtk_vcodec_drv.h |1 + .../mtk-vcodec/vdec/vdec_vp9_req_lat_if.c | 2066 + .../media/platform/mtk-vcodec/vdec_drv_if.c |4 + .../media/platform/mtk-vcodec/vdec_drv_if.h |1 + 6 files changed, 2096 insertions(+), 3 deletions(-) create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_req_lat_if.c diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile index b457daf2d196..93e7a343b5b0 100644 --- a/drivers/media/platform/mtk-vcodec/Makefile +++ b/drivers/media/platform/mtk-vcodec/Makefile @@ -9,6 +9,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \ vdec/vdec_vp8_if.o \ vdec/vdec_vp8_req_if.o \ vdec/vdec_vp9_if.o \ + vdec/vdec_vp9_req_lat_if.o \ vdec/vdec_h264_req_if.o \ vdec/vdec_h264_req_common.o \ vdec/vdec_h264_req_multi_if.o \ diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c index 019055a0807d..03c1c873361a 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c @@ -91,13 +91,28 @@ static const struct mtk_stateless_control mtk_stateless_controls[] = { .max = V4L2_MPEG_VIDEO_VP8_PROFILE_3, }, .codec_type = V4L2_PIX_FMT_VP8_FRAME, - } + }, + { + .cfg = { + .id = V4L2_CID_MPEG_VIDEO_VP9_FRAME_DECODE_PARAMS, + }, + .codec_type = V4L2_PIX_FMT_VP9_FRAME, + }, + { + .cfg = { + .id = V4L2_CID_MPEG_VIDEO_VP9_PROFILE, + .min = V4L2_MPEG_VIDEO_VP9_PROFILE_0, + .def = V4L2_MPEG_VIDEO_VP9_PROFILE_0, + .max = V4L2_MPEG_VIDEO_VP9_PROFILE_3, + }, + .codec_type = V4L2_PIX_FMT_VP9_FRAME, + }, }; #define NUM_CTRLS ARRAY_SIZE(mtk_stateless_controls) -static struct mtk_video_fmt mtk_video_formats[4]; -static struct mtk_codec_framesizes mtk_vdec_framesizes[2]; +static struct mtk_video_fmt mtk_video_formats[5]; +static struct mtk_codec_framesizes mtk_vdec_framesizes[3]; static struct mtk_video_fmt default_out_format; static struct mtk_video_fmt default_cap_format; @@ -368,6 +383,7 @@ static void mtk_vcodec_add_formats(unsigned int fourcc, switch (fourcc) { case V4L2_PIX_FMT_H264_SLICE: case V4L2_PIX_FMT_VP8_FRAME: + case V4L2_PIX_FMT_VP9_FRAME: mtk_video_formats[count_formats].fourcc = fourcc; mtk_video_formats[count_formats].type = MTK_FMT_DEC; mtk_video_formats[count_formats].num_planes = 1; @@ -416,6 +432,10 @@ static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_ctx *ctx) mtk_vcodec_add_formats(V4L2_PIX_FMT_VP8_FRAME, ctx); out_format_count++; } + if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_VP9_FRAME) { + mtk_vcodec_add_formats(V4L2_PIX_FMT_VP9_FRAME, ctx); + out_format_count++; + } if (cap_format_count) default_cap_format = mtk_video_formats[cap_format_count - 1]; diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h index 63ca6458929b..24bfbd1a6b3a 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h @@ -358,6 +358,7 @@ enum mtk_vdec_format_types { MTK_VDEC_FORMAT_MT21C = 0x40, MTK_VDEC_FORMAT_H264_SLICE = 0x100, MTK_VDEC_FORMAT_VP8_FRAME = 0x200, + MTK_VDEC_FORMAT_VP9_FRAME = 0x400, }; /** diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_req_lat_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_req_lat_if.c new file mode 100644 index ..ca93bdc77165 --- /dev/null +++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_req_lat_if.c @@ -0,0 +1,2066 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + * Author: George Sun + */ + +#include +#include +#include + +#include "../mtk_vcodec_util.h" +#include "../mtk_vcodec_dec.h" +#include "../mtk_vcodec_intr.h" +#include "../vdec_drv_base.h" +#include "../vdec_drv_if.h" +#include "../vdec_vpu_if.h" + +/* reset_frame_context defined in VP9 spec */ +#define VP9_RESET_FRAME_CONTEXT_NONE0 0 +#define VP9_RESET_FRAME_CONTEXT_NONE1 1 +#define VP9_RESET_FRAME_CONTEXT_SPEC 2 +#defi
Re: [PATCH 2/3] arm64: dts: renesas: r8a77961: Add lvds0 device node
Hi Laurent, On Wed, Dec 29, 2021 at 5:56 PM Laurent Pinchart wrote: > On Fri, Dec 24, 2021 at 08:23:08AM +0300, Nikita Yushchenko wrote: > > Add the missing lvds0 node for the R-Car M3-W+ SoC. > > > > Signed-off-by: Nikita Yushchenko > > --- > > arch/arm64/boot/dts/renesas/r8a77961.dtsi | 27 +++ > > 1 file changed, 27 insertions(+) > > > > diff --git a/arch/arm64/boot/dts/renesas/r8a77961.dtsi > > b/arch/arm64/boot/dts/renesas/r8a77961.dtsi > > index 86d59e7e1a87..a34d5b1d6431 100644 > > --- a/arch/arm64/boot/dts/renesas/r8a77961.dtsi > > +++ b/arch/arm64/boot/dts/renesas/r8a77961.dtsi > > @@ -2718,6 +2718,33 @@ du_out_hdmi0: endpoint { > > port@2 { > > reg = <2>; > > du_out_lvds0: endpoint { > > + remote-endpoint = <&lvds0_in>; > > + }; > > + }; > > + }; > > + }; > > + > > + lvds0: lvds@feb9 { > > + compatible = "renesas,r8a77961-lvds"; > > + reg = <0 0xfeb9 0 0x14>; > > + clocks = <&cpg CPG_MOD 727>; > > + power-domains = <&sysc R8A77961_PD_ALWAYS_ON>; > > + resets = <&cpg 727>; > > + status = "disabled"; > > + > > + ports { > > + #address-cells = <1>; > > + #size-cells = <0>; > > + > > + port@0 { > > + reg = <0>; > > + lvds0_in: endpoint { > > + remote-endpoint = > > <&du_out_lvds0>; > > + }; > > + }; > > + port@1 { > > + reg = <1>; > > + lvds0_out: endpoint { > > }; > > Endpoints must have a remote-endpoint property. Let's drop the endpoint > here and keep the port only, the endpoint can be declared in board > files. > > If you're fine with this change I can make it when applying the patch. Isn't this patch for me to apply to renesas-devel? > Reviewed-by: Laurent Pinchart Thanks! Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
[PATCH v11 04/22] dt-bindings: reset: mt8195: add vdosys1 reset control bit
Add vdosys1 reset control bit for MT8195 platform. Signed-off-by: Nancy.Lin Reviewed-by: Chun-Kuang Hu --- include/dt-bindings/reset/mt8195-resets.h | 12 1 file changed, 12 insertions(+) diff --git a/include/dt-bindings/reset/mt8195-resets.h b/include/dt-bindings/reset/mt8195-resets.h index a26bccc8b957..aab8d74496a6 100644 --- a/include/dt-bindings/reset/mt8195-resets.h +++ b/include/dt-bindings/reset/mt8195-resets.h @@ -26,4 +26,16 @@ #define MT8195_TOPRGU_SW_RST_NUM 16 +/* VDOSYS1 */ +#define MT8195_VDOSYS1_SW0_RST_B_MERGE0_DL_ASYNC 25 +#define MT8195_VDOSYS1_SW0_RST_B_MERGE1_DL_ASYNC 26 +#define MT8195_VDOSYS1_SW0_RST_B_MERGE2_DL_ASYNC 27 +#define MT8195_VDOSYS1_SW0_RST_B_MERGE3_DL_ASYNC 28 +#define MT8195_VDOSYS1_SW0_RST_B_MERGE4_DL_ASYNC 29 +#define MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_FE0_DL_ASYNC 51 +#define MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_FE1_DL_ASYNC 52 +#define MT8195_VDOSYS1_SW1_RST_B_HDR_GFX_FE0_DL_ASYNC 53 +#define MT8195_VDOSYS1_SW1_RST_B_HDR_GFX_FE1_DL_ASYNC 54 +#define MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_BE_DL_ASYNC 55 + #endif /* _DT_BINDINGS_RESET_CONTROLLER_MT8195 */ -- 2.18.0
[PATCH v11 15/22] drm/mediatek: add display merge async reset control
Add merge async reset control in mtk_merge_stop. Async hw doesn't do self reset on each sof signal(start of frame), so need to reset the async to clear the hw status for the next merge start. Signed-off-by: Nancy.Lin Reviewed-by: CK Hu --- drivers/gpu/drm/mediatek/mtk_disp_merge.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c index 9dca145cfb71..177473fa8160 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include "mtk_drm_ddp_comp.h" @@ -79,6 +80,9 @@ void mtk_merge_stop(struct device *dev) struct mtk_disp_merge *priv = dev_get_drvdata(dev); mtk_merge_stop_cmdq(dev, NULL); + + if (priv->async_clk) + device_reset_optional(dev); } void mtk_merge_start_cmdq(struct device *dev, struct cmdq_pkt *cmdq_pkt) -- 2.18.0
[PATCH v11 03/22] dt-bindings: mediatek: add ethdr definition for mt8195
Add vdosys1 ETHDR definition. Signed-off-by: Nancy.Lin Reviewed-by: Chun-Kuang Hu --- .../display/mediatek/mediatek,ethdr.yaml | 147 ++ 1 file changed, 147 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml new file mode 100644 index ..131eed5eeeb7 --- /dev/null +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml @@ -0,0 +1,147 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/mediatek/mediatek,ethdr.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Mediatek Ethdr Device Tree Bindings + +maintainers: + - Chun-Kuang Hu + - Philipp Zabel + +description: | + ETHDR is designed for HDR video and graphics conversion in the external display path. + It handles multiple HDR input types and performs tone mapping, color space/color + format conversion, and then combine different layers, output the required HDR or + SDR signal to the subsequent display path. This engine is composed of two video + frontends, two graphic frontends, one video backend and a mixer. ETHDR has two + DMA function blocks, DS and ADL. These two function blocks read the pre-programmed + registers from DRAM and set them to HW in the v-blanking period. + +properties: + compatible: +items: + - const: mediatek,mt8195-disp-ethdr + reg: +maxItems: 7 + reg-names: +items: + - const: mixer + - const: vdo_fe0 + - const: vdo_fe1 + - const: gfx_fe0 + - const: gfx_fe1 + - const: vdo_be + - const: adl_ds + interrupts: +minItems: 1 + iommus: +description: The compatible property is DMA function blocks. + Should point to the respective IOMMU block with master port as argument, + see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for + details. +minItems: 1 +maxItems: 2 + clocks: +items: + - description: mixer clock + - description: video frontend 0 clock + - description: video frontend 1 clock + - description: graphic frontend 0 clock + - description: graphic frontend 1 clock + - description: video backend clock + - description: autodownload and menuload clock + - description: video frontend 0 async clock + - description: video frontend 1 async clock + - description: graphic frontend 0 async clock + - description: graphic frontend 1 async clock + - description: video backend async clock + - description: ethdr top clock + clock-names: +items: + - const: mixer + - const: vdo_fe0 + - const: vdo_fe1 + - const: gfx_fe0 + - const: gfx_fe1 + - const: vdo_be + - const: adl_ds + - const: vdo_fe0_async + - const: vdo_fe1_async + - const: gfx_fe0_async + - const: gfx_fe1_async + - const: vdo_be_async + - const: ethdr_top + power-domains: +maxItems: 1 + resets: +maxItems: 5 + mediatek,gce-client-reg: +$ref: /schemas/types.yaml#/definitions/phandle-array +description: The register of display function block to be set by gce. + There are 4 arguments in this property, gce node, subsys id, offset and + register size. The subsys id is defined in the gce header of each chips + include/include/dt-bindings/gce/-gce.h, mapping to the register of + display function block. + +required: + - compatible + - reg + - clocks + - clock-names + - interrupts + - power-domains + +additionalProperties: false + +examples: + - | + +disp_ethdr@1c114000 { +compatible = "mediatek,mt8195-disp-ethdr"; +reg = <0 0x1c114000 0 0x1000>, + <0 0x1c115000 0 0x1000>, + <0 0x1c117000 0 0x1000>, + <0 0x1c119000 0 0x1000>, + <0 0x1c11A000 0 0x1000>, + <0 0x1c11B000 0 0x1000>, + <0 0x1c11C000 0 0x1000>; +reg-names = "mixer", "vdo_fe0", "vdo_fe1", "gfx_fe0", "gfx_fe1", +"vdo_be", "adl_ds"; +mediatek,gce-client-reg = <&gce0 SUBSYS_1c11 0x4000 0x1000>, + <&gce0 SUBSYS_1c11 0x5000 0x1000>, + <&gce0 SUBSYS_1c11 0x7000 0x1000>, + <&gce0 SUBSYS_1c11 0x9000 0x1000>, + <&gce0 SUBSYS_1c11 0xA000 0x1000>, + <&gce0 SUBSYS_1c11 0xB000 0x1000>, + <&gce0 SUBSYS_1c11 0xC000 0x1000>; +clocks = <&vdosys1 CLK_VDO1_DISP_MIXER>, + <&vdosys1 CLK_VDO1_HDR_VDO_FE0>, + <&vdosys1 CLK_VDO1_HDR_VDO_FE1>, +
[PATCH v11 02/22] dt-bindings: mediatek: add vdosys1 MERGE property for mt8195
MT8195 vdosys1 merge1 to merge4 have HW mute function. Add MERGE additional mute property description. Signed-off-by: Nancy.Lin Reviewed-by: Chun-Kuang Hu Acked-By: AngeloGioacchino Del Regno --- .../devicetree/bindings/display/mediatek/mediatek,merge.yaml | 4 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml index 28be8ffeb429..f5b1e632bcd5 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml @@ -61,6 +61,10 @@ properties: command to SMI to speed up the data rate. type: boolean + mediatek,merge-mute: +description: Support mute function. Mute the content of merge output. +type: boolean + mediatek,gce-client-reg: description: The register of client driver can be configured by gce with 4 arguments -- 2.18.0
[PATCH v11 09/22] soc: mediatek: change the mutex defines and the mutex_mod type
This is a preparation for adding support for mt8195 vdosys1 mutex. The vdosys1 path component contains ovl_adaptor, merge5, and dp_intf1. Ovl_adaptor is composed of several sub-elements, so change it to support multi-bit control. Signed-off-by: Nancy.Lin --- drivers/soc/mediatek/mtk-mutex.c | 242 +++ 1 file changed, 121 insertions(+), 121 deletions(-) diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c index 36502b27fe20..ff2f74668e8a 100644 --- a/drivers/soc/mediatek/mtk-mutex.c +++ b/drivers/soc/mediatek/mtk-mutex.c @@ -29,113 +29,113 @@ #define INT_MUTEX BIT(1) -#define MT8167_MUTEX_MOD_DISP_PWM 1 -#define MT8167_MUTEX_MOD_DISP_OVL0 6 -#define MT8167_MUTEX_MOD_DISP_OVL1 7 -#define MT8167_MUTEX_MOD_DISP_RDMA08 -#define MT8167_MUTEX_MOD_DISP_RDMA19 -#define MT8167_MUTEX_MOD_DISP_WDMA010 -#define MT8167_MUTEX_MOD_DISP_CCORR11 -#define MT8167_MUTEX_MOD_DISP_COLOR12 -#define MT8167_MUTEX_MOD_DISP_AAL 13 -#define MT8167_MUTEX_MOD_DISP_GAMMA14 -#define MT8167_MUTEX_MOD_DISP_DITHER 15 -#define MT8167_MUTEX_MOD_DISP_UFOE 16 - -#define MT8192_MUTEX_MOD_DISP_OVL0 0 -#define MT8192_MUTEX_MOD_DISP_OVL0_2L 1 -#define MT8192_MUTEX_MOD_DISP_RDMA02 -#define MT8192_MUTEX_MOD_DISP_COLOR0 4 -#define MT8192_MUTEX_MOD_DISP_CCORR0 5 -#define MT8192_MUTEX_MOD_DISP_AAL0 6 -#define MT8192_MUTEX_MOD_DISP_GAMMA0 7 -#define MT8192_MUTEX_MOD_DISP_POSTMASK08 -#define MT8192_MUTEX_MOD_DISP_DITHER0 9 -#define MT8192_MUTEX_MOD_DISP_OVL2_2L 16 -#define MT8192_MUTEX_MOD_DISP_RDMA417 - -#define MT8183_MUTEX_MOD_DISP_RDMA00 -#define MT8183_MUTEX_MOD_DISP_RDMA11 -#define MT8183_MUTEX_MOD_DISP_OVL0 9 -#define MT8183_MUTEX_MOD_DISP_OVL0_2L 10 -#define MT8183_MUTEX_MOD_DISP_OVL1_2L 11 -#define MT8183_MUTEX_MOD_DISP_WDMA012 -#define MT8183_MUTEX_MOD_DISP_COLOR0 13 -#define MT8183_MUTEX_MOD_DISP_CCORR0 14 -#define MT8183_MUTEX_MOD_DISP_AAL0 15 -#define MT8183_MUTEX_MOD_DISP_GAMMA0 16 -#define MT8183_MUTEX_MOD_DISP_DITHER0 17 - -#define MT8173_MUTEX_MOD_DISP_OVL0 11 -#define MT8173_MUTEX_MOD_DISP_OVL1 12 -#define MT8173_MUTEX_MOD_DISP_RDMA013 -#define MT8173_MUTEX_MOD_DISP_RDMA114 -#define MT8173_MUTEX_MOD_DISP_RDMA215 -#define MT8173_MUTEX_MOD_DISP_WDMA016 -#define MT8173_MUTEX_MOD_DISP_WDMA117 -#define MT8173_MUTEX_MOD_DISP_COLOR0 18 -#define MT8173_MUTEX_MOD_DISP_COLOR1 19 -#define MT8173_MUTEX_MOD_DISP_AAL 20 -#define MT8173_MUTEX_MOD_DISP_GAMMA21 -#define MT8173_MUTEX_MOD_DISP_UFOE 22 -#define MT8173_MUTEX_MOD_DISP_PWM0 23 -#define MT8173_MUTEX_MOD_DISP_PWM1 24 -#define MT8173_MUTEX_MOD_DISP_OD 25 - -#define MT8195_MUTEX_MOD_DISP_OVL0 0 -#define MT8195_MUTEX_MOD_DISP_WDMA01 -#define MT8195_MUTEX_MOD_DISP_RDMA02 -#define MT8195_MUTEX_MOD_DISP_COLOR0 3 -#define MT8195_MUTEX_MOD_DISP_CCORR0 4 -#define MT8195_MUTEX_MOD_DISP_AAL0 5 -#define MT8195_MUTEX_MOD_DISP_GAMMA0 6 -#define MT8195_MUTEX_MOD_DISP_DITHER0 7 -#define MT8195_MUTEX_MOD_DISP_DSI0 8 -#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0 9 -#define MT8195_MUTEX_MOD_DISP_OVL1 10 -#define MT8195_MUTEX_MOD_DISP_WDMA111 -#define MT8195_MUTEX_MOD_DISP_RDMA112 -#define MT8195_MUTEX_MOD_DISP_COLOR1 13 -#define MT8195_MUTEX_MOD_DISP_CCORR1 14 -#define MT8195_MUTEX_MOD_DISP_AAL1 15 -#define MT8195_MUTEX_MOD_DISP_GAMMA1 16 -#define MT8195_MUTEX_MOD_DISP_DITHER1 17 -#define MT8195_MUTEX_MOD_DISP_DSI1 18 -#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE1 19 -#define MT8195_MUTEX_MOD_DISP_VPP_MERGE20 -#define MT8195_MUTEX_MOD_DISP_DP_INTF0 21 -#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY0 22 -#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY1 23 -#define MT8195_MUTEX_MOD_DISP_VDO1_DL_RELAY2 24 -#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY3 25 -#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY4 26 -#define MT8195_MUTEX_MOD_DISP_PWM0 27 -#define MT8195_MUTEX_MOD_DISP_PWM1 28 - -#define MT2712_MUTEX_MOD_DISP_PWM2 10 -#define MT2712_MUTEX_MOD_DISP_OVL0 11 -#define MT2712_MUTEX_MOD_DISP_OVL1 12 -#define MT2712_MUTEX_MOD_DISP_RDMA013 -#define MT2712_MUTEX_MOD_DISP_RDMA114 -#define MT2712_MUTEX_MOD_DISP_RDMA215 -#define MT2712_MUTEX_MOD_DISP_WDMA01
[PATCH v11 21/22] drm/mediatek: add mediatek-drm of vdosys1 support for MT8195
Add driver data of mt8195 vdosys1 to mediatek-drm. Signed-off-by: Nancy.Lin --- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 18 ++ 1 file changed, 18 insertions(+) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index 36430f956b4f..e851c56f00b1 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -190,6 +190,14 @@ static const enum mtk_ddp_comp_id mt8195_mtk_ddp_main[] = { DDP_COMPONENT_DP_INTF0, }; +static const enum mtk_ddp_comp_id mt8195_mtk_ddp_ext[] = { + DDP_COMPONENT_OVL_ADAPTOR, + DDP_COMPONENT_MERGE5, + DDP_COMPONENT_DP_INTF1, +}; + +static const int mt8195_vdosys1_mtk_cmdq_mbox[] = {-1, 0, -1}; + static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = { .main_path = mt2701_mtk_ddp_main, .main_len = ARRAY_SIZE(mt2701_mtk_ddp_main), @@ -254,6 +262,14 @@ static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = { .mmsys_dev_num = 2, }; +static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = { + .ext_path = mt8195_mtk_ddp_ext, + .ext_len = ARRAY_SIZE(mt8195_mtk_ddp_ext), + .mmsys_id = 1, + .mmsys_dev_num = 2, + .mbox_index = mt8195_vdosys1_mtk_cmdq_mbox, +}; + static const struct of_device_id mtk_drm_of_ids[] = { { .compatible = "mediatek,mt2701-mmsys", .data = &mt2701_mmsys_driver_data}, @@ -271,6 +287,8 @@ static const struct of_device_id mtk_drm_of_ids[] = { .data = &mt8192_mmsys_driver_data}, { .compatible = "mediatek,mt8195-vdosys0", .data = &mt8195_vdosys0_driver_data}, + { .compatible = "mediatek,mt8195-vdosys1", + .data = &mt8195_vdosys1_driver_data}, { } }; MODULE_DEVICE_TABLE(of, mtk_drm_of_ids); -- 2.18.0
[PATCH v11 07/22] soc: mediatek: add cmdq support of mtk-mmsys config API for mt8195 vdosys1
Add cmdq support for mtk-mmsys config API. The mmsys config register settings need to take effect with the other HW settings(like OVL_ADAPTOR...) at the same vblanking time. If we use CPU to write the mmsys reg, we can't guarantee all the settings can be written in the same vblanking time. Cmdq is used for this purpose. We prepare all the related HW settings in one cmdq packet. The first command in the packet is "wait stream done", and then following with all the HW settings. After the cmdq packet is flush to GCE HW. The GCE waits for the "stream done event" to coming and then starts flushing all the HW settings. This can guarantee all the settings flush in the same vblanking. Signed-off-by: Nancy.Lin --- drivers/soc/mediatek/mtk-mmsys.c | 29 -- include/linux/soc/mediatek/mtk-mmsys.h | 6 +- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c index 725a99fcbc6d..1b0024ee47a9 100644 --- a/drivers/soc/mediatek/mtk-mmsys.c +++ b/drivers/soc/mediatek/mtk-mmsys.c @@ -88,6 +88,7 @@ struct mtk_mmsys { const struct mtk_mmsys_driver_data *data; spinlock_t lock; /* protects mmsys_sw_rst_b reg */ struct reset_controller_dev rcdev; + struct cmdq_client_reg cmdq_base; }; void mtk_mmsys_ddp_connect(struct device *dev, @@ -180,7 +181,7 @@ static const struct reset_control_ops mtk_mmsys_reset_ops = { }; void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type config, - u32 id, u32 val) + u32 id, u32 val, struct cmdq_pkt *cmdq_pkt) { struct mtk_mmsys *mmsys = dev_get_drvdata(dev); const struct mtk_mmsys_config *mmsys_config = mmsys->data->config; @@ -188,7 +189,6 @@ void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type config, u32 mask; u32 offset; int i; - u32 tmp; if (!mmsys->data->num_configs) return; @@ -204,10 +204,20 @@ void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type config, mask = mmsys_config[i].mask; reg_val = val << mmsys_config[i].shift; - tmp = readl(mmsys->regs + offset); - - tmp = (tmp & ~mask) | reg_val; - writel(tmp, mmsys->regs + offset); +#if IS_REACHABLE(CONFIG_MTK_CMDQ) + if (cmdq_pkt && mmsys->cmdq_base.size) { + cmdq_pkt_write_mask(cmdq_pkt, mmsys->cmdq_base.subsys, + mmsys->cmdq_base.offset + offset, reg_val, + mask); + } else { +#endif + u32 tmp = readl(mmsys->regs + offset); + + tmp = (tmp & ~mask) | reg_val; + writel(tmp, mmsys->regs + offset); +#if IS_REACHABLE(CONFIG_MTK_CMDQ) + } +#endif } EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_config); @@ -243,6 +253,13 @@ static int mtk_mmsys_probe(struct platform_device *pdev) } mmsys->data = of_device_get_match_data(&pdev->dev); + +#if IS_REACHABLE(CONFIG_MTK_CMDQ) + ret = cmdq_dev_get_client_reg(dev, &mmsys->cmdq_base, 0); + if (ret) + dev_dbg(dev, "No mediatek,gce-client-reg!\n"); +#endif + platform_set_drvdata(pdev, mmsys); clks = platform_device_register_data(&pdev->dev, mmsys->data->clk_driver, diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h index b2d2310d7e7a..3e998bfb795a 100644 --- a/include/linux/soc/mediatek/mtk-mmsys.h +++ b/include/linux/soc/mediatek/mtk-mmsys.h @@ -6,6 +6,10 @@ #ifndef __MTK_MMSYS_H #define __MTK_MMSYS_H +#include +#include +#include + enum mtk_ddp_comp_id; struct device; @@ -78,6 +82,6 @@ void mtk_mmsys_ddp_disconnect(struct device *dev, enum mtk_ddp_comp_id next); void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type config, - u32 id, u32 val); + u32 id, u32 val, struct cmdq_pkt *cmdq_pkt); #endif /* __MTK_MMSYS_H */ -- 2.18.0
[PATCH v11 06/22] soc: mediatek: add mtk-mmsys config API for mt8195 vdosys1
Add mmsys config API. The config API is used for config mmsys reg. Some mmsys regs need to be setting according to the HW engine binding to the mmsys simultaneously. Signed-off-by: Nancy.Lin --- drivers/soc/mediatek/mt8195-mmsys.h| 62 ++ drivers/soc/mediatek/mtk-mmsys.c | 34 ++ drivers/soc/mediatek/mtk-mmsys.h | 10 + include/linux/soc/mediatek/mtk-mmsys.h | 16 +++ 4 files changed, 122 insertions(+) diff --git a/drivers/soc/mediatek/mt8195-mmsys.h b/drivers/soc/mediatek/mt8195-mmsys.h index 65da65754d6e..11ba79e3275e 100644 --- a/drivers/soc/mediatek/mt8195-mmsys.h +++ b/drivers/soc/mediatek/mt8195-mmsys.h @@ -229,6 +229,21 @@ #define MT8195_VDO1_MIXER_SOUT_SEL_IN 0xf68 #define MT8195_MIXER_SOUT_SEL_IN_FROM_DISP_MIXER 0 +#define MT8195_VDO1_MERGE0_ASYNC_CFG_WD0xe30 +#define MT8195_VDO1_MERGE1_ASYNC_CFG_WD0xe40 +#define MT8195_VDO1_MERGE2_ASYNC_CFG_WD0xe50 +#define MT8195_VDO1_MERGE3_ASYNC_CFG_WD0xe60 +#define MT8195_VDO1_HDRBE_ASYNC_CFG_WD 0xe70 +#define MT8195_VDO1_HDR_TOP_CFG0xd00 +#define MT8195_VDO1_MIXER_IN1_ALPHA0xd30 +#define MT8195_VDO1_MIXER_IN2_ALPHA0xd34 +#define MT8195_VDO1_MIXER_IN3_ALPHA0xd38 +#define MT8195_VDO1_MIXER_IN4_ALPHA0xd3c +#define MT8195_VDO1_MIXER_IN1_PAD 0xd40 +#define MT8195_VDO1_MIXER_IN2_PAD 0xd44 +#define MT8195_VDO1_MIXER_IN3_PAD 0xd48 +#define MT8195_VDO1_MIXER_IN4_PAD 0xd4c + static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = { { DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0, @@ -353,4 +368,51 @@ static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = { } }; +/* + * mtk_mmsys_config table is used for config mmsys reg in runtime. + * MMSYS_CONFIG_MERGE_ASYNC_WIDTH: config merge async width + * MMSYS_CONFIG_MERGE_ASYNC_HEIGHT: config merge async height + * MMSYS_CONFIG_HDR_BE_ASYNC_WIDTH: config hdr_be async width + * MMSYS_CONFIG_HDR_BE_ASYNC_HEIGHT: config hdr_be async height + * MMSYS_CONFIG_MIXER_IN_ALPHA_ODD: config mixer odd channel 9bit alpha value + * MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN: config mixer even channel 9bit alpha value + * MMSYS_CONFIG_MIXER_IN_CH_SWAP: config mixer input RGB channel swap + * MMSYS_CONFIG_HDR_ALPHA_SEL: config alpha source + * MMSYS_CONFIG_MIXER_IN_MODE: config mixer pad mode(bypass/even extend mode) + * MMSYS_CONFIG_MIXER_IN_BIWIDTH: config mixer pad width. formula: width / 2 - 1 + */ +static const struct mtk_mmsys_config mmsys_mt8195_config_table[] = { + { MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 0, MT8195_VDO1_MERGE0_ASYNC_CFG_WD, GENMASK(13, 0), 0}, + { MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 0, MT8195_VDO1_MERGE0_ASYNC_CFG_WD, GENMASK(29, 16), 16}, + { MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 1, MT8195_VDO1_MERGE1_ASYNC_CFG_WD, GENMASK(13, 0), 0}, + { MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 1, MT8195_VDO1_MERGE1_ASYNC_CFG_WD, GENMASK(29, 16), 16}, + { MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 2, MT8195_VDO1_MERGE2_ASYNC_CFG_WD, GENMASK(13, 0), 0}, + { MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 2, MT8195_VDO1_MERGE2_ASYNC_CFG_WD, GENMASK(29, 16), 16}, + { MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 3, MT8195_VDO1_MERGE3_ASYNC_CFG_WD, GENMASK(13, 0), 0}, + { MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 3, MT8195_VDO1_MERGE3_ASYNC_CFG_WD, GENMASK(29, 16), 16}, + { MMSYS_CONFIG_HDR_BE_ASYNC_WIDTH, 0, MT8195_VDO1_HDRBE_ASYNC_CFG_WD, GENMASK(13, 0), 0}, + { MMSYS_CONFIG_HDR_BE_ASYNC_HEIGHT, 0, MT8195_VDO1_HDRBE_ASYNC_CFG_WD, GENMASK(29, 16), 16}, + { MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 1, MT8195_VDO1_MIXER_IN1_ALPHA, GENMASK(8, 0), 0}, + { MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 1, MT8195_VDO1_MIXER_IN1_ALPHA, GENMASK(24, 16), 16}, + { MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 2, MT8195_VDO1_MIXER_IN2_ALPHA, GENMASK(8, 0), 0}, + { MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 2, MT8195_VDO1_MIXER_IN2_ALPHA, GENMASK(24, 16), 16}, + { MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 3, MT8195_VDO1_MIXER_IN3_ALPHA, GENMASK(8, 0), 0}, + { MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 3, MT8195_VDO1_MIXER_IN3_ALPHA, GENMASK(24, 16), 16}, + { MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 4, MT8195_VDO1_MIXER_IN4_ALPHA, GENMASK(8, 0), 0}, + { MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 4, MT8195_VDO1_MIXER_IN4_ALPHA, GENMASK(24, 16), 16}, + { MMSYS_CONFIG_MIXER_IN_CH_SWAP, 4, MT8195_VDO1_MIXER_IN4_PAD, GENMASK(4, 4), 4}, + { MMSYS_CONFIG_HDR_ALPHA_SEL, 1, MT8195_VDO1_HDR_TOP_CFG, GENMASK(20, 20), 20}, + { MMSYS_CONFIG_HDR_ALPHA_SEL, 2, MT8195_VDO1_HDR_TOP_CFG, GENMASK(21, 21), 21}, + { MMSYS_CONFIG_HDR_ALPHA_SEL, 3, MT8195_VDO1_HDR_TOP_CFG, GENMASK(22, 22), 22}, + { MMSYS_CONFIG_HDR_ALPHA_SEL, 4, MT8195_VDO1_HDR_TOP_CFG, GENMASK(23, 23), 23}, + { MMSYS_CONFIG_MIXER_IN_MODE, 1, MT8195_VDO1_MIXER_IN1_PAD, GENMASK(1, 0), 0}, + { MMSYS_CONFIG_MIXER_IN_MODE, 2, MT8195_VDO1_MIXER
[PATCH v11 18/22] drm/mediatek: add ovl_adaptor support for MT8195
Add ovl_adaptor driver for MT8195. Ovl_adaptor is an encapsulated module and designed for simplified DRM control flow. This module is composed of 8 RDMAs, 4 MERGEs and an ETHDR. Two RDMAs merge into one layer, so this module support 4 layers. Signed-off-by: Nancy.Lin Reviewed-by: Chun-Kuang Hu --- drivers/gpu/drm/mediatek/Makefile | 1 + drivers/gpu/drm/mediatek/mtk_disp_drv.h | 16 + .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c | 436 ++ drivers/gpu/drm/mediatek/mtk_drm_drv.h| 1 + 4 files changed, 454 insertions(+) create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile index fb158a1e7f06..3abd27d7c91d 100644 --- a/drivers/gpu/drm/mediatek/Makefile +++ b/drivers/gpu/drm/mediatek/Makefile @@ -6,6 +6,7 @@ mediatek-drm-y := mtk_disp_aal.o \ mtk_disp_gamma.o \ mtk_disp_merge.o \ mtk_disp_ovl.o \ + mtk_disp_ovl_adaptor.o \ mtk_disp_rdma.o \ mtk_drm_crtc.o \ mtk_drm_ddp_comp.o \ diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h index 224a710bb537..cd9827402626 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h @@ -112,6 +112,22 @@ void mtk_rdma_enable_vblank(struct device *dev, void *vblank_cb_data); void mtk_rdma_disable_vblank(struct device *dev); +int mtk_ovl_adaptor_clk_enable(struct device *dev); +void mtk_ovl_adaptor_clk_disable(struct device *dev); +void mtk_ovl_adaptor_config(struct device *dev, unsigned int w, + unsigned int h, unsigned int vrefresh, + unsigned int bpc, struct cmdq_pkt *cmdq_pkt); +void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx, + struct mtk_plane_state *state, + struct cmdq_pkt *cmdq_pkt); +void mtk_ovl_adaptor_enable_vblank(struct device *dev, + void (*vblank_cb)(void *), + void *vblank_cb_data); +void mtk_ovl_adaptor_disable_vblank(struct device *dev); +void mtk_ovl_adaptor_start(struct device *dev); +void mtk_ovl_adaptor_stop(struct device *dev); +unsigned int mtk_ovl_adaptor_layer_nr(struct device *dev); + int mtk_mdp_rdma_clk_enable(struct device *dev); void mtk_mdp_rdma_clk_disable(struct device *dev); void mtk_mdp_rdma_start(struct device *dev, struct cmdq_pkt *cmdq_pkt); diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c new file mode 100644 index ..2b91be1cf0f9 --- /dev/null +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c @@ -0,0 +1,436 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mtk_disp_drv.h" +#include "mtk_drm_crtc.h" +#include "mtk_drm_ddp_comp.h" +#include "mtk_drm_drv.h" +#include "mtk_ethdr.h" + +#define MTK_OVL_ADAPTOR_RDMA_MAX_WIDTH 1920 +#define MTK_OVL_ADAPTOR_LAYER_NUM 4 + +enum mtk_ovl_adaptor_comp_type { + OVL_ADAPTOR_TYPE_RDMA = 0, + OVL_ADAPTOR_TYPE_MERGE, + OVL_ADAPTOR_TYPE_ETHDR, + OVL_ADAPTOR_TYPE_NUM, +}; + +enum mtk_ovl_adaptor_comp_id { + OVL_ADAPTOR_MDP_RDMA0, + OVL_ADAPTOR_MDP_RDMA1, + OVL_ADAPTOR_MDP_RDMA2, + OVL_ADAPTOR_MDP_RDMA3, + OVL_ADAPTOR_MDP_RDMA4, + OVL_ADAPTOR_MDP_RDMA5, + OVL_ADAPTOR_MDP_RDMA6, + OVL_ADAPTOR_MDP_RDMA7, + OVL_ADAPTOR_MERGE0, + OVL_ADAPTOR_MERGE1, + OVL_ADAPTOR_MERGE2, + OVL_ADAPTOR_MERGE3, + OVL_ADAPTOR_ETHDR0, + OVL_ADAPTOR_ID_MAX +}; + +struct ovl_adaptor_comp_match { + enum mtk_ovl_adaptor_comp_type type; + int alias_id; +}; + +struct mtk_disp_ovl_adaptor { + struct device *ovl_adaptor_comp[OVL_ADAPTOR_ID_MAX]; + struct device *mmsys_dev; +}; + +static const char * const private_comp_stem[OVL_ADAPTOR_TYPE_NUM] = { + [OVL_ADAPTOR_TYPE_RDMA] = "vdo1_rdma", + [OVL_ADAPTOR_TYPE_MERGE]= "merge", + [OVL_ADAPTOR_TYPE_ETHDR]= "ethdr", +}; + +static const struct ovl_adaptor_comp_match comp_matches[OVL_ADAPTOR_ID_MAX] = { + [OVL_ADAPTOR_MDP_RDMA0] = { OVL_ADAPTOR_TYPE_RDMA, 0 }, + [OVL_ADAPTOR_MDP_RDMA1] = { OVL_ADAPTOR_TYPE_RDMA, 1 }, + [OVL_ADAPTOR_MDP_RDMA2] = { OVL_ADAPTOR_TYPE_RDMA, 2 }, + [OVL_ADAPTOR_MDP_RDMA3] = { OVL_ADAPTOR_TYPE_RDMA, 3 }, + [OVL_ADAPTOR_MDP_RDMA4] = { OVL_ADAPTOR_TYPE_RDMA, 4 }, + [OVL_ADAPTOR_MDP_RDMA5] = { OVL_ADAPTOR_TYPE_RDMA, 5 }, + [OVL_ADAPTOR_MDP_RDMA6] = { OVL_ADAPTOR_TYPE_RDMA, 6 }, + [OVL_ADAPTOR_MDP_RDMA7] = { OVL_ADAPTO
[PATCH v11 14/22] drm/mediatek: add display merge mute/unmute support for MT8195
Add merge mute/unmute setting for MT8195. MT8195 Vdosys1 merge1~merge4 support HW mute function. Signed-off-by: Nancy.Lin Reviewed-by: Chun-Kuang Hu --- drivers/gpu/drm/mediatek/mtk_disp_merge.c | 13 + 1 file changed, 13 insertions(+) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c index c0d9b43b2a66..9dca145cfb71 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c @@ -58,12 +58,15 @@ #define FLD_PREULTRA_TH_LOWGENMASK(15, 0) #define FLD_PREULTRA_TH_HIGH GENMASK(31, 16) +#define DISP_REG_MERGE_MUTE_0 0xf00 + struct mtk_disp_merge { void __iomem*regs; struct clk *clk; struct clk *async_clk; struct cmdq_client_reg cmdq_reg; boolfifo_en; + boolmute_support; }; void mtk_merge_start(struct device *dev) @@ -82,6 +85,10 @@ void mtk_merge_start_cmdq(struct device *dev, struct cmdq_pkt *cmdq_pkt) { struct mtk_disp_merge *priv = dev_get_drvdata(dev); + if (priv->mute_support) + mtk_ddp_write(cmdq_pkt, 0x0, &priv->cmdq_reg, priv->regs, + DISP_REG_MERGE_MUTE_0); + mtk_ddp_write(cmdq_pkt, 1, &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CTRL); } @@ -90,6 +97,10 @@ void mtk_merge_stop_cmdq(struct device *dev, struct cmdq_pkt *cmdq_pkt) { struct mtk_disp_merge *priv = dev_get_drvdata(dev); + if (priv->mute_support) + mtk_ddp_write(cmdq_pkt, 0x1, &priv->cmdq_reg, priv->regs, + DISP_REG_MERGE_MUTE_0); + mtk_ddp_write(cmdq_pkt, 0, &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CTRL); } @@ -264,6 +275,8 @@ static int mtk_disp_merge_probe(struct platform_device *pdev) priv->fifo_en = of_property_read_bool(dev->of_node, "mediatek,merge-fifo-en"); + priv->mute_support = of_property_read_bool(dev->of_node, + "mediatek,merge-mute"); platform_set_drvdata(pdev, priv); ret = component_add(dev, &mtk_disp_merge_component_ops); -- 2.18.0
[PATCH v11 10/22] soc: mediatek: add mtk-mutex support for mt8195 vdosys1
Add mtk-mutex support for mt8195 vdosys1. The vdosys1 path component contains ovl_adaptor, merge5, and dp_intf1. Ovl_adaptor is composed of several sub-elements. Signed-off-by: Nancy.Lin --- drivers/soc/mediatek/mtk-mutex.c | 54 1 file changed, 54 insertions(+) diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c index ff2f74668e8a..7767fedbd14f 100644 --- a/drivers/soc/mediatek/mtk-mutex.c +++ b/drivers/soc/mediatek/mtk-mutex.c @@ -112,6 +112,35 @@ #define MT8195_MUTEX_MOD_DISP_PWM0 BIT(27) #define MT8195_MUTEX_MOD_DISP_PWM1 BIT(28) +#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA0 BIT(0) +#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA1 BIT(1) +#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA2 BIT(2) +#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA3 BIT(3) +#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA4 BIT(4) +#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA5 BIT(5) +#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA6 BIT(6) +#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA7 BIT(7) +#define MT8195_MUTEX_MOD_DISP1_VPP_MERGE0 BIT(8) +#define MT8195_MUTEX_MOD_DISP1_VPP_MERGE1 BIT(9) +#define MT8195_MUTEX_MOD_DISP1_VPP_MERGE2 BIT(10) +#define MT8195_MUTEX_MOD_DISP1_VPP_MERGE3 BIT(11) +#define MT8195_MUTEX_MOD_DISP1_VPP_MERGE4 BIT(12) +#define MT8195_MUTEX_MOD_DISP1_VPP2_DL_RELAY BIT(13) +#define MT8195_MUTEX_MOD_DISP1_VPP3_DL_RELAY BIT(14) +#define MT8195_MUTEX_MOD_DISP1_VDO0_DSC_DL_ASYNC BIT(15) +#define MT8195_MUTEX_MOD_DISP1_VDO0_MERGE_DL_ASYNC BIT(16) +#define MT8195_MUTEX_MOD_DISP1_VDO1_OUT_DL_RELAY BIT(17) +#define MT8195_MUTEX_MOD_DISP1_DISP_MIXER BIT(18) +#define MT8195_MUTEX_MOD_DISP1_HDR_VDO_FE0 BIT(19) +#define MT8195_MUTEX_MOD_DISP1_HDR_VDO_FE1 BIT(20) +#define MT8195_MUTEX_MOD_DISP1_HDR_GFX_FE0 BIT(21) +#define MT8195_MUTEX_MOD_DISP1_HDR_GFX_FE1 BIT(22) +#define MT8195_MUTEX_MOD_DISP1_HDR_VDO_BE0 BIT(23) +#define MT8195_MUTEX_MOD_DISP1_HDR_MLOAD BIT(24) +#define MT8195_MUTEX_MOD_DISP1_DPI0BIT(25) +#define MT8195_MUTEX_MOD_DISP1_DPI1BIT(26) +#define MT8195_MUTEX_MOD_DISP1_DP_INTF0BIT(27) + #define MT2712_MUTEX_MOD_DISP_PWM2 BIT(10) #define MT2712_MUTEX_MOD_DISP_OVL0 BIT(11) #define MT2712_MUTEX_MOD_DISP_OVL1 BIT(12) @@ -302,6 +331,27 @@ static const unsigned long mt8195_mutex_mod[DDP_COMPONENT_ID_MAX] = { [DDP_COMPONENT_DSI0] = MT8195_MUTEX_MOD_DISP_DSI0, [DDP_COMPONENT_PWM0] = MT8195_MUTEX_MOD_DISP_PWM0, [DDP_COMPONENT_DP_INTF0] = MT8195_MUTEX_MOD_DISP_DP_INTF0, + [DDP_COMPONENT_OVL_ADAPTOR] = MT8195_MUTEX_MOD_DISP1_MDP_RDMA0 | + MT8195_MUTEX_MOD_DISP1_MDP_RDMA1 | + MT8195_MUTEX_MOD_DISP1_MDP_RDMA2 | + MT8195_MUTEX_MOD_DISP1_MDP_RDMA3 | + MT8195_MUTEX_MOD_DISP1_MDP_RDMA4 | + MT8195_MUTEX_MOD_DISP1_MDP_RDMA5 | + MT8195_MUTEX_MOD_DISP1_MDP_RDMA6 | + MT8195_MUTEX_MOD_DISP1_MDP_RDMA7 | + MT8195_MUTEX_MOD_DISP1_VPP_MERGE0 | + MT8195_MUTEX_MOD_DISP1_VPP_MERGE1 | + MT8195_MUTEX_MOD_DISP1_VPP_MERGE2 | + MT8195_MUTEX_MOD_DISP1_VPP_MERGE3 | + MT8195_MUTEX_MOD_DISP1_HDR_VDO_FE0 | + MT8195_MUTEX_MOD_DISP1_HDR_VDO_FE1 | + MT8195_MUTEX_MOD_DISP1_HDR_GFX_FE0 | + MT8195_MUTEX_MOD_DISP1_HDR_GFX_FE1 | + MT8195_MUTEX_MOD_DISP1_HDR_VDO_BE0 | + MT8195_MUTEX_MOD_DISP1_HDR_MLOAD | + MT8195_MUTEX_MOD_DISP1_DISP_MIXER, + [DDP_COMPONENT_MERGE5] = MT8195_MUTEX_MOD_DISP1_VPP_MERGE4, + [DDP_COMPONENT_DP_INTF1] = MT8195_MUTEX_MOD_DISP1_DP_INTF0, }; static const unsigned int mt2712_mutex_sof[DDP_MUTEX_SOF_MAX] = { @@ -466,6 +516,9 @@ void mtk_mutex_add_comp(struct mtk_mutex *mutex, case DDP_COMPONENT_DP_INTF0: sof_id = MUTEX_SOF_DP_INTF0; break; + case DDP_COMPONENT_DP_INTF1: + sof_id = MUTEX_SOF_DP_INTF1; + break; default: if (mtx->data->mutex_mod[id] <= BIT(31)) { offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg, @@ -506,6 +559,7 @@ void mtk_mutex_remove_comp(struct mtk_mutex *mutex, case DDP_COMPONENT_DPI0: case DDP_COMPONENT_DPI1: case DDP_COMPONENT_DP_INTF0: + case DDP_COMPONENT_DP_INTF1: writel_relaxed(MUTEX_SOF_SINGLE_MODE,
[PATCH v11 13/22] drm/mediatek: add display merge start/stop API for cmdq support
Add merge start/stop API for cmdq support. The ovl_adaptor merges are configured with each drm plane update. Need to enable/disable merge with cmdq making sure all the settings taken effect in the same vblank. Signed-off-by: Nancy.Lin Reviewed-by: Chun-Kuang Hu --- drivers/gpu/drm/mediatek/mtk_disp_drv.h | 2 ++ drivers/gpu/drm/mediatek/mtk_disp_merge.c | 20 +--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h index c2de53a5892e..224a710bb537 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h @@ -66,6 +66,8 @@ void mtk_merge_stop(struct device *dev); void mtk_merge_advance_config(struct device *dev, unsigned int l_w, unsigned int r_w, unsigned int h, unsigned int vrefresh, unsigned int bpc, struct cmdq_pkt *cmdq_pkt); +void mtk_merge_start_cmdq(struct device *dev, struct cmdq_pkt *cmdq_pkt); +void mtk_merge_stop_cmdq(struct device *dev, struct cmdq_pkt *cmdq_pkt); void mtk_ovl_bgclr_in_on(struct device *dev); void mtk_ovl_bgclr_in_off(struct device *dev); diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c index 40da0555416d..c0d9b43b2a66 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c @@ -67,17 +67,31 @@ struct mtk_disp_merge { }; void mtk_merge_start(struct device *dev) +{ + mtk_merge_start_cmdq(dev, NULL); +} + +void mtk_merge_stop(struct device *dev) { struct mtk_disp_merge *priv = dev_get_drvdata(dev); - writel(MERGE_EN, priv->regs + DISP_REG_MERGE_CTRL); + mtk_merge_stop_cmdq(dev, NULL); } -void mtk_merge_stop(struct device *dev) +void mtk_merge_start_cmdq(struct device *dev, struct cmdq_pkt *cmdq_pkt) +{ + struct mtk_disp_merge *priv = dev_get_drvdata(dev); + + mtk_ddp_write(cmdq_pkt, 1, &priv->cmdq_reg, priv->regs, + DISP_REG_MERGE_CTRL); +} + +void mtk_merge_stop_cmdq(struct device *dev, struct cmdq_pkt *cmdq_pkt) { struct mtk_disp_merge *priv = dev_get_drvdata(dev); - writel(0x0, priv->regs + DISP_REG_MERGE_CTRL); + mtk_ddp_write(cmdq_pkt, 0, &priv->cmdq_reg, priv->regs, + DISP_REG_MERGE_CTRL); } static void mtk_merge_fifo_setting(struct mtk_disp_merge *priv, -- 2.18.0
[PATCH v11 20/22] drm/mediatek: add drm ovl_adaptor sub driver for MT8195
Add drm ovl_adaptor sub driver. Bring up ovl_adaptor sub driver if the component exists in the path. Signed-off-by: Nancy.Lin --- drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 16 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 30 --- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 1 + drivers/gpu/drm/mediatek/mtk_drm_drv.c | 41 +++-- 4 files changed, 62 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index fe2871aca859..62529a954b62 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -877,15 +877,13 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev, node = priv->comp_node[comp_id]; comp = &priv->ddp_comp[comp_id]; - if (!node) { - dev_info(dev, -"Not creating crtc %d because component %d is disabled or missing\n", -crtc_i, comp_id); - return 0; - } - - if (!comp->dev) { - dev_err(dev, "Component %pOF not initialized\n", node); + /* Not all drm components have a DTS device node, such as ovl_adaptor, +* which is the drm bring up sub driver +*/ + if (!node && !comp->dev) { + dev_err(dev, + "Not creating crtc %d because component %d is disabled, missing or not initialized\n", + crtc_i, comp_id); return -ENODEV; } } diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c index 26d197da41c0..ce40bab9c56b 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c @@ -385,6 +385,18 @@ static const struct mtk_ddp_comp_funcs ddp_ufoe = { .start = mtk_ufoe_start, }; +static const struct mtk_ddp_comp_funcs ddp_ovl_adaptor = { + .clk_enable = mtk_ovl_adaptor_clk_enable, + .clk_disable = mtk_ovl_adaptor_clk_disable, + .config = mtk_ovl_adaptor_config, + .start = mtk_ovl_adaptor_start, + .stop = mtk_ovl_adaptor_stop, + .layer_nr = mtk_ovl_adaptor_layer_nr, + .layer_config = mtk_ovl_adaptor_layer_config, + .enable_vblank = mtk_ovl_adaptor_enable_vblank, + .disable_vblank = mtk_ovl_adaptor_disable_vblank, +}; + static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = { [MTK_DISP_AAL] = "aal", [MTK_DISP_BLS] = "bls", @@ -398,6 +410,7 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = { [MTK_DISP_OD] = "od", [MTK_DISP_OVL] = "ovl", [MTK_DISP_OVL_2L] = "ovl-2l", + [MTK_DISP_OVL_ADAPTOR] = "ovl_adaptor", [MTK_DISP_POSTMASK] = "postmask", [MTK_DISP_PWM] = "pwm", [MTK_DISP_RDMA] = "rdma", @@ -443,6 +456,7 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = { [DDP_COMPONENT_OVL_2L0] = { MTK_DISP_OVL_2L,0, &ddp_ovl }, [DDP_COMPONENT_OVL_2L1] = { MTK_DISP_OVL_2L,1, &ddp_ovl }, [DDP_COMPONENT_OVL_2L2] = { MTK_DISP_OVL_2L,2, &ddp_ovl }, + [DDP_COMPONENT_OVL_ADAPTOR] = { MTK_DISP_OVL_ADAPTOR, 0, &ddp_ovl_adaptor }, [DDP_COMPONENT_POSTMASK0] = { MTK_DISP_POSTMASK, 0, &ddp_postmask }, [DDP_COMPONENT_PWM0]= { MTK_DISP_PWM, 0, NULL }, [DDP_COMPONENT_PWM1]= { MTK_DISP_PWM, 1, NULL }, @@ -548,12 +562,17 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp, comp->id = comp_id; comp->funcs = mtk_ddp_matches[comp_id].funcs; - comp_pdev = of_find_device_by_node(node); - if (!comp_pdev) { - DRM_INFO("Waiting for device %s\n", node->full_name); - return -EPROBE_DEFER; + /* Not all drm components have a DTS device node, such as ovl_adaptor, +* which is the drm bring up sub driver +*/ + if (node) { + comp_pdev = of_find_device_by_node(node); + if (!comp_pdev) { + DRM_INFO("Waiting for device %s\n", node->full_name); + return -EPROBE_DEFER; + } + comp->dev = &comp_pdev->dev; } - comp->dev = &comp_pdev->dev; /* Only DMA capable components need the LARB property */ if (type == MTK_DISP_OVL || @@ -573,6 +592,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp, type == MTK_DISP_MERGE || type == MTK_DISP_OVL || type == MTK_DISP_OVL_2L || + type == MTK_DISP_OVL_ADAPTOR || type == MTK_DISP_PWM || type == MTK_DISP_RDMA ||
[PATCH v11 00/22] Add MediaTek SoC DRM (vdosys1) support for mt8195
The hardware path of vdosys1 with DPTx output need to go through by several modules, such as, OVL_ADAPTOR and MERGE. Add DRM and these modules support by the patches below: Changes in v11: - remove ethdr vblank spin lock - refine ovl_adaptor print message Changes in v10: - refine ethdr reset control using devm_reset_control_array_get_optional_exclusive - fix ovl_adaptor mtk_ovl_adaptor_clk_enable error handle issue Changes in v9: - rebase on kernel-5.16-rc1 - rebase on vdosys0 series v13. (ref [5]) - fix ovl_adaptor sub driver is brought up unintentionally - fix clang build test fail- duplicate ethdr/mdp_rdma init_module/cleanup_module symbol issue Changes in v8: - separate merge async reset to new patch. - separate drm ovl_adaptor sub driver to new patch. - fix reviewer comment in v7. Changes in v7: - rebase on vdosys0 series v12 (ref[5]) - add dma description in ethdr binding document. - refine vdosys1 bit definition of mmsys routing table. - separate merge modification into 3 pathces. - separate mutex modification into 2 patches. - add plane color coding for mdp_rdma csc. - move mdp_rdma pm control to ovl_adaptor. - fix reviewer comment in v6. Changes in v6: - rebase on kernel-5.15-rc1. - change mbox label to gce0 for dts node of vdosys1. - modify mmsys reset num for mt8195. - rebase on vdosys0 series v10. (ref [5]) - use drm to bring up ovl_adaptor driver. - move drm iommu/mutex check from kms init to drm bind. - modify rdma binding doc location. (Documentation/devicetree/bindings/arm/) - modify for reviewer's comment in v5. Changes in v5: - add mmsys reset controller reference. Changes in v4: - use merge common driver for merge1~4. - refine ovl_adaptor rdma driver. - use ovl_adaptor ddp_comp function instead of ethdr. - modify for reviewer's comment in v3. Changes in v3: - modify for reviewer's comment in v2. - add vdosys1 2 pixels align limit. - add mixer odd offset support. Changes in v2: - Merge PSEUDO_OVL and ETHDR into one DRM component. - Add mmsys config API for vdosys1 hardware setting. - Add mmsys reset control using linux reset framework. Signed-off-by: Nancy.Lin This series are based on the following patch: [1] arm64: dts: Add Mediatek SoC MT8195 and evaluation board dts and Makefile https://patchwork.kernel.org/project/linux-mediatek/patch/20210601075350.31515-2-seiya.w...@mediatek.com/ [2] arm64: dts: mt8195: add IOMMU and smi nodes https://patchwork.kernel.org/project/linux-mediatek/patch/20210615173233.26682-15-tinghan.s...@mediatek.com/ [3] [01/24] dt-bindings: mediatek: mt8195: Add binding for MM IOMMU https://patchwork.kernel.org/project/linux-mediatek/patch/20210630023504.18177-2-yong...@mediatek.com/ [4] Add gce support for mt8195 https://patchwork.kernel.org/project/linux-mediatek/list/?series=537069 [5] Add MediaTek SoC DRM (vdosys0) support for mt8195 https://patchwork.kernel.org/project/linux-mediatek/list/?series=587313 [6] [v8,1/2] dt-bindings: reset: mt8195: add toprgu reset-controller header file https://patchwork.kernel.org/project/linux-mediatek/patch/20210806023606.16867-2-christine@mediatek.com/ Nancy.Lin (22): dt-bindings: mediatek: add vdosys1 RDMA definition for mt8195 dt-bindings: mediatek: add vdosys1 MERGE property for mt8195 dt-bindings: mediatek: add ethdr definition for mt8195 dt-bindings: reset: mt8195: add vdosys1 reset control bit soc: mediatek: add mtk-mmsys support for mt8195 vdosys1 soc: mediatek: add mtk-mmsys config API for mt8195 vdosys1 soc: mediatek: add cmdq support of mtk-mmsys config API for mt8195 vdosys1 soc: mediatek: mmsys: modify reset controller for MT8195 vdosys1 soc: mediatek: change the mutex defines and the mutex_mod type soc: mediatek: add mtk-mutex support for mt8195 vdosys1 drm/mediatek: add display MDP RDMA support for MT8195 drm/mediatek: add display merge advance config API for MT8195 drm/mediatek: add display merge start/stop API for cmdq support drm/mediatek: add display merge mute/unmute support for MT8195 drm/mediatek: add display merge async reset control drm/mediatek: add ETHDR support for MT8195 drm/mediatek: add mediatek-drm plane color encoding info drm/mediatek: add ovl_adaptor support for MT8195 drm/mediatek: modify mediatek-drm for mt8195 multi mmsys support drm/mediatek: add drm ovl_adaptor sub driver for MT8195 drm/mediatek: add mediatek-drm of vdosys1 support for MT8195 arm64: dts: mt8195: add display node for vdosys1 .../arm/mediatek/mediatek,mdp-rdma.yaml | 77 .../display/mediatek/mediatek,ethdr.yaml | 147 ++ .../display/mediatek/mediatek,merge.yaml | 4 + arch/arm64/boot/dts/mediatek/mt8195.dtsi | 222 + drivers/gpu/drm/mediatek/Makefile | 5 +- drivers/gpu/drm/mediatek/mtk_disp_drv.h | 28 ++ drivers/gpu/drm/mediatek/mtk_disp_merge.c | 89 +++- .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c | 436 ++ drivers/gpu/drm/mediatek/mtk_dr
[PATCH v11 12/22] drm/mediatek: add display merge advance config API for MT8195
Add merge new advance config API. The original merge API is mtk_ddp_comp_funcs function prototype. The API interface parameters cannot be modified, so add a new config API for extension. This is the preparation for ovl_adaptor merge control. Signed-off-by: Nancy.Lin Reviewed-by: Chun-Kuang Hu --- drivers/gpu/drm/mediatek/mtk_disp_drv.h | 3 ++ drivers/gpu/drm/mediatek/mtk_disp_merge.c | 52 --- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h index b3a372cab0bd..c2de53a5892e 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h @@ -63,6 +63,9 @@ void mtk_merge_config(struct device *dev, unsigned int width, unsigned int bpc, struct cmdq_pkt *cmdq_pkt); void mtk_merge_start(struct device *dev); void mtk_merge_stop(struct device *dev); +void mtk_merge_advance_config(struct device *dev, unsigned int l_w, unsigned int r_w, + unsigned int h, unsigned int vrefresh, unsigned int bpc, + struct cmdq_pkt *cmdq_pkt); void mtk_ovl_bgclr_in_on(struct device *dev); void mtk_ovl_bgclr_in_off(struct device *dev); diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c index 45face638153..40da0555416d 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c @@ -17,6 +17,7 @@ #define DISP_REG_MERGE_CTRL0x000 #define MERGE_EN 1 #define DISP_REG_MERGE_CFG_0 0x010 +#define DISP_REG_MERGE_CFG_1 0x014 #define DISP_REG_MERGE_CFG_4 0x020 #define DISP_REG_MERGE_CFG_10 0x038 /* no swap */ @@ -25,9 +26,12 @@ #define DISP_REG_MERGE_CFG_12 0x040 #define CFG_10_10_1PI_2PO_BUF_MODE 6 #define CFG_10_10_2PI_2PO_BUF_MODE 8 +#define CFG_11_10_1PI_2PO_MERGE18 #define FLD_CFG_MERGE_MODE GENMASK(4, 0) #define DISP_REG_MERGE_CFG_24 0x070 #define DISP_REG_MERGE_CFG_25 0x074 +#define DISP_REG_MERGE_CFG_26 0x078 +#define DISP_REG_MERGE_CFG_27 0x07c #define DISP_REG_MERGE_CFG_36 0x0a0 #define ULTRA_EN BIT(0) #define PREULTRA_ENBIT(4) @@ -98,12 +102,19 @@ static void mtk_merge_fifo_setting(struct mtk_disp_merge *priv, void mtk_merge_config(struct device *dev, unsigned int w, unsigned int h, unsigned int vrefresh, unsigned int bpc, struct cmdq_pkt *cmdq_pkt) +{ + mtk_merge_advance_config(dev, w, 0, h, vrefresh, bpc, cmdq_pkt); +} + +void mtk_merge_advance_config(struct device *dev, unsigned int l_w, unsigned int r_w, + unsigned int h, unsigned int vrefresh, unsigned int bpc, + struct cmdq_pkt *cmdq_pkt) { struct mtk_disp_merge *priv = dev_get_drvdata(dev); unsigned int mode = CFG_10_10_1PI_2PO_BUF_MODE; - if (!h || !w) { - dev_err(dev, "%s: input width(%d) or height(%d) is invalid\n", __func__, w, h); + if (!h || !l_w) { + dev_err(dev, "%s: input width(%d) or height(%d) is invalid\n", __func__, l_w, h); return; } @@ -112,14 +123,41 @@ void mtk_merge_config(struct device *dev, unsigned int w, mode = CFG_10_10_2PI_2PO_BUF_MODE; } - mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs, + if (r_w) + mode = CFG_11_10_1PI_2PO_MERGE; + + mtk_ddp_write(cmdq_pkt, h << 16 | l_w, &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_0); - mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs, + mtk_ddp_write(cmdq_pkt, h << 16 | r_w, &priv->cmdq_reg, priv->regs, + DISP_REG_MERGE_CFG_1); + mtk_ddp_write(cmdq_pkt, h << 16 | (l_w + r_w), &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_4); - mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs, + /* +* DISP_REG_MERGE_CFG_24 is merge SRAM0 w/h +* DISP_REG_MERGE_CFG_25 is merge SRAM1 w/h. +* If r_w > 0, the merge is in merge mode (input0 and input1 merge together), +* the input0 goes to SRAM0, and input1 goes to SRAM1. +* If r_w = 0, the merge is in buffer mode, the input goes through SRAM0 and +* then to SRAM1. Both SRAM0 and SRAM1 are set to the same size. +*/ + mtk_ddp_write(cmdq_pkt, h << 16 | l_w, &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_24); - mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs, - DISP_REG_MERGE_CFG_25); + if (r_w) + mtk_ddp_write(cmdq_pkt, h << 16 | r_w, &priv->cmdq
[PATCH v11 22/22] arm64: dts: mt8195: add display node for vdosys1
Add display node for vdosys1. Signed-off-by: Nancy.Lin --- arch/arm64/boot/dts/mediatek/mt8195.dtsi | 222 +++ 1 file changed, 222 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi index e136761345db..a69a7b57e070 100644 --- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi @@ -10,6 +10,7 @@ #include #include #include +#include / { compatible = "mediatek,mt8195"; @@ -20,6 +21,22 @@ aliases { gce0 = &gce0; gce1 = &gce1; + ethdr0 = ðdr0; + mutex0 = &mutex; + mutex1 = &mutex1; + merge1 = &merge1; + merge2 = &merge2; + merge3 = &merge3; + merge4 = &merge4; + merge5 = &merge5; + vdo1_rdma0 = &vdo1_rdma0; + vdo1_rdma1 = &vdo1_rdma1; + vdo1_rdma2 = &vdo1_rdma2; + vdo1_rdma3 = &vdo1_rdma3; + vdo1_rdma4 = &vdo1_rdma4; + vdo1_rdma5 = &vdo1_rdma5; + vdo1_rdma6 = &vdo1_rdma6; + vdo1_rdma7 = &vdo1_rdma7; }; clocks { @@ -1235,7 +1252,212 @@ vdosys1: syscon@1c10 { compatible = "mediatek,mt8195-vdosys1", "syscon"; reg = <0 0x1c10 0 0x1000>; + mboxes = <&gce0 1 CMDQ_THR_PRIO_4>; + mediatek,gce-client-reg = <&gce0 SUBSYS_1c10 0x 0x1000>; #clock-cells = <1>; + #reset-cells = <1>; + }; + + mutex1: disp_mutex0@1c101000 { + compatible = "mediatek,mt8195-disp-mutex"; + reg = <0 0x1c101000 0 0x1000>; + reg-names = "vdo1_mutex"; + interrupts = ; + power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; + clocks = <&vdosys1 CLK_VDO1_DISP_MUTEX>; + clock-names = "vdo1_mutex"; + mediatek,gce-events = ; + }; + + vdo1_rdma0: vdo1_rdma@1c104000 { + compatible = "mediatek,mt8195-vdo1-rdma"; + reg = <0 0x1c104000 0 0x1000>; + interrupts = ; + clocks = <&vdosys1 CLK_VDO1_MDP_RDMA0>; + power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; + iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA0>; + mediatek,gce-client-reg = <&gce0 SUBSYS_1c10 0x4000 0x1000>; + }; + + vdo1_rdma1: vdo1_rdma@1c105000 { + compatible = "mediatek,mt8195-vdo1-rdma"; + reg = <0 0x1c105000 0 0x1000>; + interrupts = ; + clocks = <&vdosys1 CLK_VDO1_MDP_RDMA1>; + power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; + iommus = <&iommu_vpp M4U_PORT_L3_MDP_RDMA1>; + mediatek,gce-client-reg = <&gce0 SUBSYS_1c10 0x5000 0x1000>; + }; + + vdo1_rdma2: vdo1_rdma@1c106000 { + compatible = "mediatek,mt8195-vdo1-rdma"; + reg = <0 0x1c106000 0 0x1000>; + interrupts = ; + clocks = <&vdosys1 CLK_VDO1_MDP_RDMA2>; + power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; + iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA2>; + mediatek,gce-client-reg = <&gce0 SUBSYS_1c10 0x6000 0x1000>; + }; + + vdo1_rdma3: vdo1_rdma@1c107000 { + compatible = "mediatek,mt8195-vdo1-rdma"; + reg = <0 0x1c107000 0 0x1000>; + interrupts = ; + clocks = <&vdosys1 CLK_VDO1_MDP_RDMA3>; + power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; + iommus = <&iommu_vpp M4U_PORT_L3_MDP_RDMA3>; + mediatek,gce-client-reg = <&gce0 SUBSYS_1c10 0x7000 0x1000>; + }; + + vdo1_rdma4: vdo1_rdma@1c108000 { + compatible = "mediatek,mt8195-vdo1-rdma"; + reg = <0 0x1c108000 0 0x1000>; + interrupts = ; + clocks = <&vdosys1 CLK_VDO1_MDP_RDMA4>; + power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; + iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA4>; + mediatek,gce-client-reg = <&gce0 SUBSYS_1c10 0x8000 0x1000>; + }; + + vdo1_rdma5: vdo1_rdma@1c109000 { + compatible = "mediatek,mt8195-vdo1-rdma"; +
[PATCH v11 08/22] soc: mediatek: mmsys: modify reset controller for MT8195 vdosys1
MT8195 vdosys1 has more than 32 reset bits and a different reset base than other chips. Modify mmsys for support 64 bit and different reset base. Signed-off-by: Nancy.Lin --- drivers/soc/mediatek/mt8195-mmsys.h | 1 + drivers/soc/mediatek/mtk-mmsys.c| 21 - drivers/soc/mediatek/mtk-mmsys.h| 2 ++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/soc/mediatek/mt8195-mmsys.h b/drivers/soc/mediatek/mt8195-mmsys.h index 11ba79e3275e..628098260f61 100644 --- a/drivers/soc/mediatek/mt8195-mmsys.h +++ b/drivers/soc/mediatek/mt8195-mmsys.h @@ -229,6 +229,7 @@ #define MT8195_VDO1_MIXER_SOUT_SEL_IN 0xf68 #define MT8195_MIXER_SOUT_SEL_IN_FROM_DISP_MIXER 0 +#define MT8195_VDO1_SW0_RST_B 0x1d0 #define MT8195_VDO1_MERGE0_ASYNC_CFG_WD0xe30 #define MT8195_VDO1_MERGE1_ASYNC_CFG_WD0xe40 #define MT8195_VDO1_MERGE2_ASYNC_CFG_WD0xe50 diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c index 1b0024ee47a9..3f85171c980e 100644 --- a/drivers/soc/mediatek/mtk-mmsys.c +++ b/drivers/soc/mediatek/mtk-mmsys.c @@ -19,6 +19,8 @@ #include "mt8195-mmsys.h" #include "mt8365-mmsys.h" +#define MMSYS_SW_RESET_PER_REG 32 + static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = { .clk_driver = "clk-mt2701-mm", .routes = mmsys_default_routing_table, @@ -49,12 +51,16 @@ static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = { .clk_driver = "clk-mt8173-mm", .routes = mmsys_default_routing_table, .num_routes = ARRAY_SIZE(mmsys_default_routing_table), + .sw_reset_start = MMSYS_SW0_RST_B, + .num_resets = 32, }; static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = { .clk_driver = "clk-mt8183-mm", .routes = mmsys_mt8183_routing_table, .num_routes = ARRAY_SIZE(mmsys_mt8183_routing_table), + .sw_reset_start = MMSYS_SW0_RST_B, + .num_resets = 32, }; static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = { @@ -75,6 +81,8 @@ static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = { .num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table), .config = mmsys_mt8195_config_table, .num_configs = ARRAY_SIZE(mmsys_mt8195_config_table), + .sw_reset_start = MT8195_VDO1_SW0_RST_B, + .num_resets = 64, }; static const struct mtk_mmsys_driver_data mt8365_mmsys_driver_data = { @@ -133,18 +141,22 @@ static int mtk_mmsys_reset_update(struct reset_controller_dev *rcdev, unsigned l { struct mtk_mmsys *mmsys = container_of(rcdev, struct mtk_mmsys, rcdev); unsigned long flags; + u32 offset; u32 reg; + offset = (id / MMSYS_SW_RESET_PER_REG) * sizeof(u32); + id = id % MMSYS_SW_RESET_PER_REG; + spin_lock_irqsave(&mmsys->lock, flags); - reg = readl_relaxed(mmsys->regs + MMSYS_SW0_RST_B); + reg = readl_relaxed(mmsys->regs + mmsys->data->sw_reset_start + offset); if (assert) reg &= ~BIT(id); else reg |= BIT(id); - writel_relaxed(reg, mmsys->regs + MMSYS_SW0_RST_B); + writel_relaxed(reg, mmsys->regs + mmsys->data->sw_reset_start + offset); spin_unlock_irqrestore(&mmsys->lock, flags); @@ -240,10 +252,11 @@ static int mtk_mmsys_probe(struct platform_device *pdev) return ret; } + mmsys->data = of_device_get_match_data(&pdev->dev); spin_lock_init(&mmsys->lock); mmsys->rcdev.owner = THIS_MODULE; - mmsys->rcdev.nr_resets = 32; + mmsys->rcdev.nr_resets = mmsys->data->num_resets; mmsys->rcdev.ops = &mtk_mmsys_reset_ops; mmsys->rcdev.of_node = pdev->dev.of_node; ret = devm_reset_controller_register(&pdev->dev, &mmsys->rcdev); @@ -252,8 +265,6 @@ static int mtk_mmsys_probe(struct platform_device *pdev) return ret; } - mmsys->data = of_device_get_match_data(&pdev->dev); - #if IS_REACHABLE(CONFIG_MTK_CMDQ) ret = cmdq_dev_get_client_reg(dev, &mmsys->cmdq_base, 0); if (ret) diff --git a/drivers/soc/mediatek/mtk-mmsys.h b/drivers/soc/mediatek/mtk-mmsys.h index 2694021435d2..4842102cd451 100644 --- a/drivers/soc/mediatek/mtk-mmsys.h +++ b/drivers/soc/mediatek/mtk-mmsys.h @@ -102,6 +102,8 @@ struct mtk_mmsys_driver_data { const unsigned int num_routes; const struct mtk_mmsys_config *config; const unsigned int num_configs; + u32 sw_reset_start; + u32 num_resets; }; /* -- 2.18.0
[PATCH v11 11/22] drm/mediatek: add display MDP RDMA support for MT8195
Add MDP_RDMA driver for MT8195. MDP_RDMA is the DMA engine of the ovl_adaptor component. Signed-off-by: Nancy.Lin Reviewed-by: Chun-Kuang Hu --- drivers/gpu/drm/mediatek/Makefile | 3 +- drivers/gpu/drm/mediatek/mtk_disp_drv.h | 7 + drivers/gpu/drm/mediatek/mtk_drm_drv.c | 1 + drivers/gpu/drm/mediatek/mtk_drm_drv.h | 1 + drivers/gpu/drm/mediatek/mtk_mdp_rdma.c | 315 drivers/gpu/drm/mediatek/mtk_mdp_rdma.h | 20 ++ 6 files changed, 346 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/mediatek/mtk_mdp_rdma.c create mode 100644 drivers/gpu/drm/mediatek/mtk_mdp_rdma.h diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile index a38e88e82d12..6e604a933ed0 100644 --- a/drivers/gpu/drm/mediatek/Makefile +++ b/drivers/gpu/drm/mediatek/Makefile @@ -13,7 +13,8 @@ mediatek-drm-y := mtk_disp_aal.o \ mtk_drm_gem.o \ mtk_drm_plane.o \ mtk_dsi.o \ - mtk_dpi.o + mtk_dpi.o \ + mtk_mdp_rdma.o obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h index a33b13fe2b6e..b3a372cab0bd 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h @@ -8,6 +8,7 @@ #include #include "mtk_drm_plane.h" +#include "mtk_mdp_rdma.h" int mtk_aal_clk_enable(struct device *dev); void mtk_aal_clk_disable(struct device *dev); @@ -106,4 +107,10 @@ void mtk_rdma_enable_vblank(struct device *dev, void *vblank_cb_data); void mtk_rdma_disable_vblank(struct device *dev); +int mtk_mdp_rdma_clk_enable(struct device *dev); +void mtk_mdp_rdma_clk_disable(struct device *dev); +void mtk_mdp_rdma_start(struct device *dev, struct cmdq_pkt *cmdq_pkt); +void mtk_mdp_rdma_stop(struct device *dev, struct cmdq_pkt *cmdq_pkt); +void mtk_mdp_rdma_config(struct device *dev, struct mtk_mdp_rdma_cfg *cfg, +struct cmdq_pkt *cmdq_pkt); #endif diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index 274a5bb10851..fa41306422df 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -743,6 +743,7 @@ static struct platform_driver * const mtk_drm_drivers[] = { &mtk_dpi_driver, &mtk_drm_platform_driver, &mtk_dsi_driver, + &mtk_mdp_rdma_driver, }; static int __init mtk_drm_init(void) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h index a58cebd01d35..64a1f66df26a 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h @@ -55,5 +55,6 @@ extern struct platform_driver mtk_disp_ovl_driver; extern struct platform_driver mtk_disp_rdma_driver; extern struct platform_driver mtk_dpi_driver; extern struct platform_driver mtk_dsi_driver; +extern struct platform_driver mtk_mdp_rdma_driver; #endif /* MTK_DRM_DRV_H */ diff --git a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c new file mode 100644 index ..eecfa98ff52e --- /dev/null +++ b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c @@ -0,0 +1,315 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mtk_disp_drv.h" +#include "mtk_drm_drv.h" +#include "mtk_mdp_rdma.h" + +#define MDP_RDMA_EN0x000 +#define FLD_ROT_ENABLE BIT(0) +#define MDP_RDMA_RESET 0x008 +#define MDP_RDMA_CON 0x020 +#define FLD_OUTPUT_10B BIT(5) +#define FLD_SIMPLE_MODEBIT(4) +#define MDP_RDMA_GMCIF_CON 0x028 +#define FLD_COMMAND_DIVBIT(0) +#define FLD_EXT_PREULTRA_ENBIT(3) +#define FLD_RD_REQ_TYPEGENMASK(7, 4) +#define VAL_RD_REQ_TYPE_BURST_8_ACCESS 7 +#define FLD_ULTRA_EN GENMASK(13, 12) +#define VAL_ULTRA_EN_ENABLE1 +#define FLD_PRE_ULTRA_EN GENMASK(17, 16) +#define VAL_PRE_ULTRA_EN_ENABLE1 +#define FLD_EXT_ULTRA_EN BIT(18) +#define MDP_RDMA_SRC_CON 0x030 +#define FLD_OUTPUT_ARGBBIT(25) +#define FLD_BIT_NUMBER GENMASK(19, 18) +#define FLD_SWAP BIT(14) +#define FLD_UNIFORM_CONFIG BIT(17) +#define RDMA_INPUT_10BIT BIT(18) +#define FLD_SRC_FORMAT GENMASK(3, 0) +#define MDP_RDMA_COMP_CON 0x038 +#define FLD_AFBC_ENBIT(22) +#define FLD_AFBC_YUV_TRANSFORM
[PATCH v11 01/22] dt-bindings: mediatek: add vdosys1 RDMA definition for mt8195
Add vdosys1 RDMA definition. Signed-off-by: Nancy.Lin --- .../arm/mediatek/mediatek,mdp-rdma.yaml | 77 +++ 1 file changed, 77 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mdp-rdma.yaml diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mdp-rdma.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mdp-rdma.yaml new file mode 100644 index ..d70b81ec1914 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mdp-rdma.yaml @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/arm/mediatek/mediatek,mdp-rdma.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Mediatek MDP RDMA + +maintainers: + - Matthias Brugger + +description: | + The mediatek MDP RDMA stands for Read Direct Memory Access. + It provides real time data to the back-end panel driver, such as DSI, + DPI and DP_INTF. + It contains one line buffer to store the sufficient pixel data. + RDMA device node must be siblings to the central MMSYS_CONFIG node. + For a description of the MMSYS_CONFIG binding, see + Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details. + +properties: + compatible: +oneOf: + - items: + - const: mediatek,mt8195-vdo1-rdma + + reg: +maxItems: 1 + + interrupts: +maxItems: 1 + + power-domains: +description: A phandle and PM domain specifier as defined by bindings of + the power controller specified by phandle. See + Documentation/devicetree/bindings/power/power-domain.yaml for details. + + clocks: +items: + - description: RDMA Clock + + iommus: +description: + This property should point to the respective IOMMU block with master port as argument, + see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details. + + mediatek,gce-client-reg: +description: + The register of display function block to be set by gce. There are 4 arguments, + such as gce node, subsys id, offset and register size. The subsys id that is + mapping to the register of display function blocks is defined in the gce header + include/include/dt-bindings/gce/-gce.h of each chips. +$ref: /schemas/types.yaml#/definitions/phandle-array +maxItems: 1 + +required: + - compatible + - reg + - power-domains + - clocks + - iommus + +additionalProperties: false + +examples: + - | + +vdo1_rdma0: vdo1_rdma@1c104000 { +compatible = "mediatek,mt8195-vdo1-rdma"; +reg = <0 0x1c104000 0 0x1000>; +interrupts = ; +clocks = <&vdosys1 CLK_VDO1_MDP_RDMA0>; +power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; +iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA0>; +mediatek,gce-client-reg = <&gce0 SUBSYS_1c10 0x4000 0x1000>; +}; + -- 2.18.0
[PATCH v11 19/22] drm/mediatek: modify mediatek-drm for mt8195 multi mmsys support
MT8195 have two mmsys. Modify drm for MT8195 multi-mmsys support. The two mmsys (vdosys0 and vdosys1) will bring up two drm drivers, only one drm driver register as the drm device. Each drm driver binds its own component. The last bind drm driver allocates and registers the drm device to drm core. Each crtc path is created with the corresponding drm driver data. Signed-off-by: Nancy.Lin --- drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 24 +- drivers/gpu/drm/mediatek/mtk_drm_crtc.h | 3 +- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 300 ++-- drivers/gpu/drm/mediatek/mtk_drm_drv.h | 10 +- 4 files changed, 246 insertions(+), 91 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index d661edf7e0fe..fe2871aca859 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -847,21 +847,28 @@ static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev, } int mtk_drm_crtc_create(struct drm_device *drm_dev, - const enum mtk_ddp_comp_id *path, unsigned int path_len) + const enum mtk_ddp_comp_id *path, unsigned int path_len, + int priv_data_index) { struct mtk_drm_private *priv = drm_dev->dev_private; struct device *dev = drm_dev->dev; struct mtk_drm_crtc *mtk_crtc; unsigned int num_comp_planes = 0; - int pipe = priv->num_pipes; int ret; int i; bool has_ctm = false; uint gamma_lut_size = 0; + struct drm_crtc *tmp; + int crtc_i = 0; if (!path) return 0; + priv = priv->all_drm_private[priv_data_index]; + + drm_for_each_crtc(tmp, drm_dev) + crtc_i++; + for (i = 0; i < path_len; i++) { enum mtk_ddp_comp_id comp_id = path[i]; struct device_node *node; @@ -873,7 +880,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev, if (!node) { dev_info(dev, "Not creating crtc %d because component %d is disabled or missing\n", -pipe, comp_id); +crtc_i, comp_id); return 0; } @@ -926,29 +933,28 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev, for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) { ret = mtk_drm_crtc_init_comp_planes(drm_dev, mtk_crtc, i, - pipe); + crtc_i); if (ret) return ret; } - ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, pipe); + ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, crtc_i); if (ret < 0) return ret; if (gamma_lut_size) drm_mode_crtc_set_gamma_size(&mtk_crtc->base, gamma_lut_size); drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, has_ctm, gamma_lut_size); - priv->num_pipes++; mutex_init(&mtk_crtc->hw_lock); #if IS_REACHABLE(CONFIG_MTK_CMDQ) + i = (priv->data->mbox_index) ? priv->data->mbox_index[drm_crtc_index(&mtk_crtc->base)] : 0; mtk_crtc->cmdq_client.client.dev = mtk_crtc->mmsys_dev; mtk_crtc->cmdq_client.client.tx_block = false; mtk_crtc->cmdq_client.client.knows_txdone = true; mtk_crtc->cmdq_client.client.rx_callback = ddp_cmdq_cb; mtk_crtc->cmdq_client.chan = - mbox_request_channel(&mtk_crtc->cmdq_client.client, -drm_crtc_index(&mtk_crtc->base)); + mbox_request_channel(&mtk_crtc->cmdq_client.client, i); if (IS_ERR(mtk_crtc->cmdq_client.chan)) { dev_dbg(dev, "mtk_crtc %d failed to create mailbox client, writing register by CPU now\n", drm_crtc_index(&mtk_crtc->base)); @@ -958,7 +964,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev, if (mtk_crtc->cmdq_client.chan) { ret = of_property_read_u32_index(priv->mutex_node, "mediatek,gce-events", - drm_crtc_index(&mtk_crtc->base), +i, &mtk_crtc->cmdq_event); if (ret) { dev_dbg(dev, "mtk_crtc %d failed to get mediatek,gce-events property\n", diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h index cb9a36c48d4f..a57eb12d7c05 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h @@ -17,7 +17,8 @@ void mtk_drm_crtc_commit(struct drm_crtc *crtc); int mtk_drm_crtc_create(struct drm_device *drm_dev, const enum m
[PATCH v11 16/22] drm/mediatek: add ETHDR support for MT8195
ETHDR is a part of ovl_adaptor. ETHDR is designed for HDR video and graphics conversion in the external display path. It handles multiple HDR input types and performs tone mapping, color space/color format conversion, and then combine different layers, output the required HDR or SDR signal to the subsequent display path. Signed-off-by: Nancy.Lin Reviewed-by: Chun-Kuang Hu --- drivers/gpu/drm/mediatek/Makefile | 1 + drivers/gpu/drm/mediatek/mtk_drm_drv.c | 1 + drivers/gpu/drm/mediatek/mtk_drm_drv.h | 1 + drivers/gpu/drm/mediatek/mtk_ethdr.c | 376 + drivers/gpu/drm/mediatek/mtk_ethdr.h | 25 ++ 5 files changed, 404 insertions(+) create mode 100644 drivers/gpu/drm/mediatek/mtk_ethdr.c create mode 100644 drivers/gpu/drm/mediatek/mtk_ethdr.h diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile index 6e604a933ed0..fb158a1e7f06 100644 --- a/drivers/gpu/drm/mediatek/Makefile +++ b/drivers/gpu/drm/mediatek/Makefile @@ -14,6 +14,7 @@ mediatek-drm-y := mtk_disp_aal.o \ mtk_drm_plane.o \ mtk_dsi.o \ mtk_dpi.o \ + mtk_ethdr.o \ mtk_mdp_rdma.o obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index fa41306422df..390cda4bae57 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -743,6 +743,7 @@ static struct platform_driver * const mtk_drm_drivers[] = { &mtk_dpi_driver, &mtk_drm_platform_driver, &mtk_dsi_driver, + &mtk_ethdr_driver, &mtk_mdp_rdma_driver, }; diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h index 64a1f66df26a..3fb85776b8b3 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h @@ -55,6 +55,7 @@ extern struct platform_driver mtk_disp_ovl_driver; extern struct platform_driver mtk_disp_rdma_driver; extern struct platform_driver mtk_dpi_driver; extern struct platform_driver mtk_dsi_driver; +extern struct platform_driver mtk_ethdr_driver; extern struct platform_driver mtk_mdp_rdma_driver; #endif /* MTK_DRM_DRV_H */ diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.c b/drivers/gpu/drm/mediatek/mtk_ethdr.c new file mode 100644 index ..d36a0a5c3d9e --- /dev/null +++ b/drivers/gpu/drm/mediatek/mtk_ethdr.c @@ -0,0 +1,376 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mtk_drm_crtc.h" +#include "mtk_drm_ddp_comp.h" +#include "mtk_drm_drv.h" +#include "mtk_ethdr.h" + +#define MIX_INTEN 0x4 +#define MIX_FME_CPL_INTEN BIT(1) +#define MIX_INTSTA 0x8 +#define MIX_EN 0xc +#define MIX_RST0x14 +#define MIX_ROI_SIZE 0x18 +#define MIX_DATAPATH_CON 0x1c +#define OUTPUT_NO_RND BIT(3) +#define SOURCE_RGB_SEL BIT(7) +#define BACKGROUND_RELAY (4 << 9) +#define MIX_ROI_BGCLR 0x20 +#define BGCLR_BLACK0xff00 +#define MIX_SRC_CON0x24 +#define MIX_SRC_L0_EN BIT(0) +#define MIX_L_SRC_CON(n) (0x28 + 0x18 * (n)) +#define NON_PREMULTI_SOURCE(2 << 12) +#define MIX_L_SRC_SIZE(n) (0x30 + 0x18 * (n)) +#define MIX_L_SRC_OFFSET(n)(0x34 + 0x18 * (n)) +#define MIX_FUNC_DCM0 0x120 +#define MIX_FUNC_DCM1 0x124 +#define MIX_FUNC_DCM_ENABLE0x + +#define HDR_VDO_FE_0804_HDR_DM_FE 0x804 +#define HDR_VDO_FE_0804_BYPASS_ALL 0xfd +#define HDR_GFX_FE_0204_GFX_HDR_FE 0x204 +#define HDR_GFX_FE_0204_BYPASS_ALL 0xfd +#define HDR_VDO_BE_0204_VDO_DM_BE 0x204 +#define HDR_VDO_BE_0204_BYPASS_ALL 0x7e + +#define MIXER_INX_MODE_BYPASS 0 +#define MIXER_INX_MODE_EVEN_EXTEND 1 +#define DEFAULT_9BIT_ALPHA 0x100 +#defineMIXER_ALPHA_AEN BIT(8) +#defineMIXER_ALPHA 0xff +#define ETHDR_CLK_NUM 13 + +enum mtk_ethdr_comp_id { + ETHDR_MIXER, + ETHDR_VDO_FE0, + ETHDR_VDO_FE1, + ETHDR_GFX_FE0, + ETHDR_GFX_FE1, + ETHDR_VDO_BE, + ETHDR_ADL_DS, + ETHDR_ID_MAX +}; + +struct mtk_ethdr_comp { + struct device *dev; + void __iomem*regs; + struct cmdq_client_reg cmdq_base; +}; + +struct mtk_ethdr { + struct mtk_ethdr_comp ethdr_comp[ETHDR_ID_MAX]; + struct clk_bulk_data
[PATCH v11 17/22] drm/mediatek: add mediatek-drm plane color encoding info
Add plane color encoding information for color space conversion. It's a preparation for adding support for mt8195 ovl_adaptor mdp_rdma csc control. Signed-off-by: Nancy.Lin Reviewed-by: Chun-Kuang Hu --- drivers/gpu/drm/mediatek/mtk_drm_plane.c | 1 + drivers/gpu/drm/mediatek/mtk_drm_plane.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c index 734a1fb052df..81bd5d6e8df5 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c @@ -137,6 +137,7 @@ static void mtk_plane_update_new_state(struct drm_plane_state *new_state, mtk_plane_state->pending.width = drm_rect_width(&new_state->dst); mtk_plane_state->pending.height = drm_rect_height(&new_state->dst); mtk_plane_state->pending.rotation = new_state->rotation; + mtk_plane_state->pending.color_encoding = new_state->color_encoding; } static void mtk_plane_atomic_async_update(struct drm_plane *plane, diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.h b/drivers/gpu/drm/mediatek/mtk_drm_plane.h index d454bece9535..2d5ec66e3df1 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_plane.h +++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.h @@ -24,6 +24,7 @@ struct mtk_plane_pending_state { booldirty; boolasync_dirty; boolasync_config; + enum drm_color_encoding color_encoding; }; struct mtk_plane_state { -- 2.18.0
[PATCH v11 05/22] soc: mediatek: add mtk-mmsys support for mt8195 vdosys1
Add mt8195 vdosys1 clock driver name and routing table to the driver data of mtk-mmsys. Signed-off-by: Nancy.Lin --- drivers/soc/mediatek/mt8195-mmsys.h| 136 + drivers/soc/mediatek/mtk-mmsys.c | 10 ++ include/linux/soc/mediatek/mtk-mmsys.h | 2 + 3 files changed, 148 insertions(+) diff --git a/drivers/soc/mediatek/mt8195-mmsys.h b/drivers/soc/mediatek/mt8195-mmsys.h index e04cabdfa2dc..65da65754d6e 100644 --- a/drivers/soc/mediatek/mt8195-mmsys.h +++ b/drivers/soc/mediatek/mt8195-mmsys.h @@ -165,6 +165,70 @@ #define MT8195_SOUT_DSC_WRAP1_OUT_TO_SINA_VIRTUAL0 BIT(17) #define MT8195_SOUT_DSC_WRAP1_OUT_TO_VPP_MERGE (BIT(17) | BIT(16)) +#define MT8195_VDO1_VPP_MERGE0_P0_SEL_IN 0xf04 +#define MT8195_VPP_MERGE0_P0_SEL_IN_FROM_MDP_RDMA0 1 + +#define MT8195_VDO1_VPP_MERGE0_P1_SEL_IN 0xf08 +#define MT8195_VPP_MERGE0_P1_SEL_IN_FROM_MDP_RDMA1 1 + +#define MT8195_VDO1_DISP_DPI1_SEL_IN 0xf10 +#define MT8195_DISP_DPI1_SEL_IN_FROM_VPP_MERGE4_MOUT 0 + +#define MT8195_VDO1_DISP_DP_INTF0_SEL_IN 0xf14 +#define MT8195_DISP_DP_INTF0_SEL_IN_FROM_VPP_MERGE4_MOUT 0 + +#define MT8195_VDO1_MERGE4_SOUT_SEL0xf18 +#define MT8195_MERGE4_SOUT_TO_DPI1_SEL 2 +#define MT8195_MERGE4_SOUT_TO_DP_INTF0_SEL 3 + +#define MT8195_VDO1_MIXER_IN1_SEL_IN 0xf24 +#define MT8195_MIXER_IN1_SEL_IN_FROM_MERGE0_ASYNC_SOUT 1 + +#define MT8195_VDO1_MIXER_IN2_SEL_IN 0xf28 +#define MT8195_MIXER_IN2_SEL_IN_FROM_MERGE1_ASYNC_SOUT 1 + +#define MT8195_VDO1_MIXER_IN3_SEL_IN 0xf2c +#define MT8195_MIXER_IN3_SEL_IN_FROM_MERGE2_ASYNC_SOUT 1 + +#define MT8195_VDO1_MIXER_IN4_SEL_IN 0xf30 +#define MT8195_MIXER_IN4_SEL_IN_FROM_MERGE3_ASYNC_SOUT 1 + +#define MT8195_VDO1_MIXER_OUT_SOUT_SEL 0xf34 +#define MT8195_MIXER_SOUT_TO_MERGE4_ASYNC_SEL 1 + +#define MT8195_VDO1_VPP_MERGE1_P0_SEL_IN 0xf3c +#define MT8195_VPP_MERGE1_P0_SEL_IN_FROM_MDP_RDMA2 1 + +#define MT8195_VDO1_MERGE0_ASYNC_SOUT_SEL 0xf40 +#define MT8195_SOUT_TO_MIXER_IN1_SEL 1 + +#define MT8195_VDO1_MERGE1_ASYNC_SOUT_SEL 0xf44 +#define MT8195_SOUT_TO_MIXER_IN2_SEL 1 + +#define MT8195_VDO1_MERGE2_ASYNC_SOUT_SEL 0xf48 +#define MT8195_SOUT_TO_MIXER_IN3_SEL 1 + +#define MT8195_VDO1_MERGE3_ASYNC_SOUT_SEL 0xf4c +#define MT8195_SOUT_TO_MIXER_IN4_SEL 1 + +#define MT8195_VDO1_MERGE4_ASYNC_SEL_IN0xf50 +#define MT8195_MERGE4_ASYNC_SEL_IN_FROM_MIXER_OUT_SOUT 1 + +#define MT8195_VDO1_MIXER_IN1_SOUT_SEL 0xf58 +#define MT8195_MIXER_IN1_SOUT_TO_DISP_MIXER0 + +#define MT8195_VDO1_MIXER_IN2_SOUT_SEL 0xf5c +#define MT8195_MIXER_IN2_SOUT_TO_DISP_MIXER0 + +#define MT8195_VDO1_MIXER_IN3_SOUT_SEL 0xf60 +#define MT8195_MIXER_IN3_SOUT_TO_DISP_MIXER0 + +#define MT8195_VDO1_MIXER_IN4_SOUT_SEL 0xf64 +#define MT8195_MIXER_IN4_SOUT_TO_DISP_MIXER0 + +#define MT8195_VDO1_MIXER_SOUT_SEL_IN 0xf68 +#define MT8195_MIXER_SOUT_SEL_IN_FROM_DISP_MIXER 0 + static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = { { DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0, @@ -214,6 +278,78 @@ static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = { DDP_COMPONENT_MERGE0, DDP_COMPONENT_DP_INTF0, MT8195_VDO0_SEL_OUT, MT8195_SOUT_VPP_MERGE_TO_DP_INTF0, MT8195_SOUT_VPP_MERGE_TO_DP_INTF0 + }, { + DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5, + MT8195_VDO1_VPP_MERGE0_P0_SEL_IN, GENMASK(0, 0), + MT8195_VPP_MERGE0_P0_SEL_IN_FROM_MDP_RDMA0 + }, { + DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5, + MT8195_VDO1_VPP_MERGE0_P1_SEL_IN, GENMASK(0, 0), + MT8195_VPP_MERGE0_P1_SEL_IN_FROM_MDP_RDMA1 + }, { + DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5, + MT8195_VDO1_VPP_MERGE1_P0_SEL_IN, GENMASK(0, 0), + MT8195_VPP_MERGE1_P0_SEL_IN_FROM_MDP_RDMA2 + }, { + DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5, + MT8195_VDO1_MERGE0_A
Re: [PATCH 2/3] arm64: dts: renesas: r8a77961: Add lvds0 device node
Hi Geert, On Mon, Jan 10, 2022 at 09:43:58AM +0100, Geert Uytterhoeven wrote: > On Wed, Dec 29, 2021 at 5:56 PM Laurent Pinchart wrote: > > On Fri, Dec 24, 2021 at 08:23:08AM +0300, Nikita Yushchenko wrote: > > > Add the missing lvds0 node for the R-Car M3-W+ SoC. > > > > > > Signed-off-by: Nikita Yushchenko > > > --- > > > arch/arm64/boot/dts/renesas/r8a77961.dtsi | 27 +++ > > > 1 file changed, 27 insertions(+) > > > > > > diff --git a/arch/arm64/boot/dts/renesas/r8a77961.dtsi > > > b/arch/arm64/boot/dts/renesas/r8a77961.dtsi > > > index 86d59e7e1a87..a34d5b1d6431 100644 > > > --- a/arch/arm64/boot/dts/renesas/r8a77961.dtsi > > > +++ b/arch/arm64/boot/dts/renesas/r8a77961.dtsi > > > @@ -2718,6 +2718,33 @@ du_out_hdmi0: endpoint { > > > port@2 { > > > reg = <2>; > > > du_out_lvds0: endpoint { > > > + remote-endpoint = > > > <&lvds0_in>; > > > + }; > > > + }; > > > + }; > > > + }; > > > + > > > + lvds0: lvds@feb9 { > > > + compatible = "renesas,r8a77961-lvds"; > > > + reg = <0 0xfeb9 0 0x14>; > > > + clocks = <&cpg CPG_MOD 727>; > > > + power-domains = <&sysc R8A77961_PD_ALWAYS_ON>; > > > + resets = <&cpg 727>; > > > + status = "disabled"; > > > + > > > + ports { > > > + #address-cells = <1>; > > > + #size-cells = <0>; > > > + > > > + port@0 { > > > + reg = <0>; > > > + lvds0_in: endpoint { > > > + remote-endpoint = > > > <&du_out_lvds0>; > > > + }; > > > + }; > > > + port@1 { > > > + reg = <1>; > > > + lvds0_out: endpoint { > > > }; > > > > Endpoints must have a remote-endpoint property. Let's drop the endpoint > > here and keep the port only, the endpoint can be declared in board > > files. > > > > If you're fine with this change I can make it when applying the patch. > > Isn't this patch for me to apply to renesas-devel? Even better indeed :-) > > Reviewed-by: Laurent Pinchart -- Regards, Laurent Pinchart
Re: [PATCH 2/3] arm64: dts: renesas: r8a77961: Add lvds0 device node
On Fri, Dec 24, 2021 at 6:23 AM Nikita Yushchenko wrote: > Add the missing lvds0 node for the R-Car M3-W+ SoC. > > Signed-off-by: Nikita Yushchenko Reviewed-by: Geert Uytterhoeven i.e. will queue in renesas-devel for v5.18. Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Re: [PATCH 3/6] drm/meson: venc: add ENCL encoder setup for MIPI-DSI output
On 07/01/2022 23:33, Martin Blumenstingl wrote: > Hi Neil, > > On Fri, Jan 7, 2022 at 3:57 PM Neil Armstrong wrote: >> >> This adds supports for the ENCL encoder connected to a MIPI-DSI transceiver >> on the >> Amlogic AXG SoCs> Should this be "AXG and newer SoCs" or is this really AXG >> specific? Yup should be, thanks for noting > > [...] >> +#define GAMMA_VCOM_POL7 /* RW */ >> +#define GAMMA_RVS_OUT 6 /* RW */ >> +#define ADR_RDY 5 /* Read Only */ >> +#define WR_RDY4 /* Read Only */ >> +#define RD_RDY3 /* Read Only */ >> +#define GAMMA_TR 2 /* RW */ >> +#define GAMMA_SET 1 /* RW */ >> +#define GAMMA_EN 0 /* RW */ >> + >> +#define H_RD 12 >> +#define H_AUTO_INC11 >> +#define H_SEL_R 10 >> +#define H_SEL_G 9 >> +#define H_SEL_B 8 > I think all values above can be wrapped in the BIT() macro, then you > don't need that below. yep > >> +#define HADR_MSB 7/* 7:0 */ >> +#define HADR 0/* 7:0 */ > Here GENMASK(7, 0) can be used for HADR > > Also I think prefixing all macros above with their register name > (L_GAMMA_CNTL_PORT_ or L_GAMMA_ADDR_PORT_) will make the code easier > to read. > > [...] >> + writel_relaxed(0x8000, priv->io_base + _REG(ENCL_VIDEO_MODE)); > The public S905 datasheet calls 0x8000 ENCL_PX_LN_CNT_SHADOW_EN Thanks for searching ! > >> + writel_relaxed(0x0418, priv->io_base + _REG(ENCL_VIDEO_MODE_ADV)); > According to the public S905 datasheet this is: > - BIT(3): ENCL_VIDEO_MODE_ADV_VFIFO_EN > - BIT(4): ENCL_VIDEO_MODE_ADV_GAIN_HDTV > - BIT(10): ENCL_SEL_GAMMA_RGB_IN > >> + writel_relaxed(0x1000, priv->io_base + _REG(ENCL_VIDEO_FILT_CTRL)); > I don't know the exact name but the 32-bit vendor kernel sources have > a comment [0] saying that 0x1000 is "bypass filter" > But maybe we can simply call it ENCL_VIDEO_FILT_CTRL_BYPASS_FILTER Yep > > [...] >> + writel_relaxed(3, priv->io_base + _REG(ENCL_VIDEO_RGBIN_CTRL)); > The public S905 datasheet says: > - BIT(0): USE RGB data from VIU, furthermore a comment in the 3.10 > kernel sources make this more clear: bit[0] 1:RGB, 0:YUV > - BIT(1): CFG_VIDEO_RGBIN_ZBLK > >> + /* default black pattern */ >> + writel_relaxed(0, priv->io_base + _REG(ENCL_TST_MDSEL)); >> + writel_relaxed(0, priv->io_base + _REG(ENCL_TST_Y)); >> + writel_relaxed(0, priv->io_base + _REG(ENCL_TST_CB)); >> + writel_relaxed(0, priv->io_base + _REG(ENCL_TST_CR)); >> + writel_relaxed(1, priv->io_base + _REG(ENCL_TST_EN)); >> + writel_bits_relaxed(BIT(3), 0, priv->io_base + >> _REG(ENCL_VIDEO_MODE_ADV)); > same as above: ENCL_VIDEO_MODE_ADV_VFIFO_EN > >> + >> + writel_relaxed(1, priv->io_base + _REG(ENCL_VIDEO_EN)); >> + >> + writel_relaxed(0, priv->io_base + _REG(L_RGB_BASE_ADDR)); >> + writel_relaxed(0x400, priv->io_base + _REG(L_RGB_COEFF_ADDR)); > note to self: L_RGB_COEFF_ADDR seems to contain some "magic" value, > there's no further info in the 3.10 kernel sources or datasheet > >> + writel_relaxed(0x400, priv->io_base + _REG(L_DITH_CNTL_ADDR)); > According to the public S905 datasheet BIT(10) is DITH10_EN (10-bits > Dithering to 8 Bits Enable). > I am not sure if this would belong to the selected video mode/bit depth. > I'll let other reviewers decide if this is relevant or not because I don't > know. it would probably for pre-GXL when the pipeline was 8bit, would probably need to add a comment if someone wants to us DPI/LVDS on pre-GXL. > > [...] >> + writel_relaxed(0, priv->io_base + _REG(L_INV_CNT_ADDR)); >> + writel_relaxed(BIT(4) | BIT(5), >> + priv->io_base + _REG(L_TCON_MISC_SEL_ADDR)); > the public S905 datasheet states: > - BIT(4): STV1_SEL (STV1 is frame Signal) > - BIT(5): STV2_SEL (STV2 is frame Signal) > This doesn't seem helpful to me though, but maybe you can still create > preprocessor macros for this (for consistency)? yep > > [...] >> + switch (priv->venc.current_mode) { >> + case MESON_VENC_MODE_MIPI_DSI: >> + writel_relaxed(0x200, >> + priv->io_base + _REG(VENC_INTCTRL)); > the public S905 datasheet documents this as: > - BIT(9): ENCP_LNRST_INT_EN (Progressive encoder filed change interrupt > enable) > Please add a preprocessor macro to make it consistent with > VENC_INTCTRL_ENCI_LNRST_INT_EN which already exists and is used below. Yep Thanks for the review :-) Neil > > > Best regards, > Martin >
Re: [PATCH 5/6] drm/meson: add DSI encoder
On 07/01/2022 23:35, Martin Blumenstingl wrote: > Hi Neil, > > On Fri, Jan 7, 2022 at 3:57 PM Neil Armstrong wrote: > > [...] >> + writel_bits_relaxed(BIT(3), BIT(3), priv->io_base + >> _REG(ENCL_VIDEO_MODE_ADV)); > see my comment on patch #3 from this series for BIT(3) > Yep, thanks, Neil > > Best regards, > Martin >
Re: [PATCH 6/6] drm/meson: add support for MIPI-DSI transceiver
On 07/01/2022 23:49, Martin Blumenstingl wrote: > Hi Neil, > > some high-level comments from me below. > > On Fri, Jan 7, 2022 at 3:58 PM Neil Armstrong wrote: > [...] >> +/* MIPI DSI Relative REGISTERs Definitions */ >> +/* For MIPI_DSI_TOP_CNTL */ >> +#define BIT_DPI_COLOR_MODE20 >> +#define BIT_IN_COLOR_MODE 16 >> +#define BIT_CHROMA_SUBSAMPLE 14 >> +#define BIT_COMP2_SEL 12 >> +#define BIT_COMP1_SEL 10 >> +#define BIT_COMP0_SEL 8 >> +#define BIT_DE_POL 6 >> +#define BIT_HSYNC_POL 5 >> +#define BIT_VSYNC_POL 4 >> +#define BIT_DPICOLORM 3 >> +#define BIT_DPISHUTDN 2 >> +#define BIT_EDPITE_INTR_PULSE 1 >> +#define BIT_ERR_INTR_PULSE 0 > Why not use BIT() and GENMASK() for these and prefixing them with > MIPI_DSI_TOP_CNTL_? > That would make them consistent with other parts of the meson sub-driver. Yeah it was a lousy copy-paste from vendor driver, and I was lazy, but I'll fix this. > > [...] >> +static void meson_dw_mipi_dsi_hw_init(struct meson_dw_mipi_dsi *mipi_dsi) >> +{ >> + writel_relaxed((1 << 4) | (1 << 5) | (0 << 6), >> + mipi_dsi->base + MIPI_DSI_TOP_CNTL); > please use the macros from above > >> + writel_bits_relaxed(0xf, 0xf, mipi_dsi->base + >> MIPI_DSI_TOP_SW_RESET); >> + writel_bits_relaxed(0xf, 0, mipi_dsi->base + MIPI_DSI_TOP_SW_RESET); > > [...] >> + phy_power_on(mipi_dsi->phy); > Please propagate the error code here. > Also shouldn't this go to a new dw_mipi_dsi_phy_power_on() as the PHY > driver uses the updated settings from phy_configure only in it's > .power_on callback? Good point, let me check that. > > [...] >> + phy_configure(mipi_dsi->phy, &mipi_dsi->phy_opts); > please propagate the error code here as the PHY driver has some > explicit code to return an error in it's .phy_configure callback > > [...] >> + phy_init(mipi_dsi->phy); > please propagate the error code here > > [...] >> + phy_exit(mipi_dsi->phy); > please propagate the error code here ok for the 3 > > [...] >> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); >> + mipi_dsi->base = devm_ioremap_resource(&pdev->dev, res); > other parts of the meson DRM driver have been converted to use > devm_platform_ioremap_resource() > I suggest updating this as well to simplify the code here Yep, again lazyness > > [...] >> + mipi_dsi->phy = devm_phy_get(&pdev->dev, "dphy"); >> + if (IS_ERR(mipi_dsi->phy)) { >> + ret = PTR_ERR(mipi_dsi->phy); >> + dev_err(&pdev->dev, "failed to get mipi dphy: %d\n", ret); >> + return ret; > you can simplify this with: > return dev_err_probe(&pdev->dev, PTR_ERR(mipi_dsi->phy, "failed to > get mipi dphy\n"); > > [...] >> + mipi_dsi->px_clk = devm_clk_get(&pdev->dev, "px_clk"); >> + if (IS_ERR(mipi_dsi->px_clk)) { >> + dev_err(&pdev->dev, "Unable to get PLL clk\n"); >> + return PTR_ERR(mipi_dsi->px_clk); > you can simplify this with: > return dev_err_probe(&pdev->dev, PTR_ERR(mipi_dsi->px_clk, "Unable > to get PLL clk\n"); > Also should it say s/PLL clk/px clock/? > > [...] >> + top_rst = devm_reset_control_get_exclusive(&pdev->dev, "top"); >> + if (IS_ERR(top_rst)) { >> + ret = PTR_ERR(top_rst); >> + >> + if (ret != -EPROBE_DEFER) >> + dev_err(&pdev->dev, "Unable to get reset control: >> %d\n", ret); >> + >> + return ret; > you can simplify this with: > return dev_err_probe(&pdev->dev, PTR_ERR(top_rst, "Unable to get > reset control\n"); > > [...] >> + mipi_dsi->dmd = dw_mipi_dsi_probe(pdev, &mipi_dsi->pdata); >> + if (IS_ERR(mipi_dsi->dmd)) { >> + ret = PTR_ERR(mipi_dsi->dmd); >> + if (ret != -EPROBE_DEFER) >> + dev_err(&pdev->dev, >> + "Failed to probe dw_mipi_dsi: %d\n", ret); > you can simplify this with: > dev_err_probe(&pdev->dev, ret, "Failed to probe dw_mipi_dsi\n"); > Again 4 lazyness effects, will fix ! Thanks, Neil > > Best regards, > Martin >
Re: [PATCH 2/3] arm64: dts: renesas: r8a77961: Add lvds0 device node
Hi Nikita, On Mon, Jan 10, 2022 at 10:51 AM Nikita Yushchenko wrote: > > i.e. will queue in renesas-devel for v5.18. > > that is, for current + 2 ? That is correct, as the merge window for v5.17 has already opened. The deadline for new features to be accepted for v5.17 in the soc tree was around v5.16-rc6. Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
[PATCH v2 0/2] video: A couple of fixes for the vga16fb driver
This patch series contains two fixes for the vga16fb driver. I looked at the driver due a regression reported [0], caused by commit d391c5827107 ("drivers/firmware: move x86 Generic System Framebuffers support"). The mentioned commit didn't change any logic but just moved the platform device registration that matches the vesafb and efifb drivers to happen later. And this caused the vga16fb driver to be probed even in machines that don't have an EGA or VGA video adapter. This is a v2 of the patch series that addresses issues pointed out by Geert Uytterhoeven. Patch #1 is fixing the wrong check to determine if either EGA or VGA is used and patch #2 adds a check to the driver to only be loaded for EGA and VGA 16 color graphic cards. [0]: https://bugzilla.kernel.org/show_bug.cgi?id=215001 Best regards, Javier Changes in v2: - Make the change only for x86 (Geert Uytterhoeven) - Only check the suppported video mode for x86 (Geert Uytterhoeven). Javier Martinez Canillas (2): video: vga16fb: Fix logic that checks for the display standard video: vga16fb: Only probe for EGA and VGA 16 color graphic cards drivers/video/fbdev/vga16fb.c | 29 + 1 file changed, 29 insertions(+) -- 2.33.1
[PATCH v2 2/2] video: vga16fb: Only probe for EGA and VGA 16 color graphic cards
The vga16fb framebuffer driver only supports Enhanced Graphics Adapter (EGA) and Video Graphics Array (VGA) 16 color graphic cards. But it doesn't check if the adapter is one of those or if a VGA16 mode is used. This means that the driver will be probed even if a VESA BIOS Extensions (VBE) or Graphics Output Protocol (GOP) interface is used. This issue has been present for a long time but it was only exposed by commit d391c5827107 ("drivers/firmware: move x86 Generic System Framebuffers support") since the platform device registration to match the {vesa,efi}fb drivers is done later as a consequence of that change. All non-x86 architectures though treat orig_video_isVGA as a boolean so only do the supported video mode check for x86 and not for other arches. Link: https://bugzilla.kernel.org/show_bug.cgi?id=215001 Fixes: d391c5827107 ("drivers/firmware: move x86 Generic System Framebuffers support") Reported-by: Kris Karas Cc: # 5.15.x Signed-off-by: Javier Martinez Canillas Tested-by: Kris Karas --- Changes in v2: - Only check the suppported video mode for x86 (Geert Uytterhoeven). drivers/video/fbdev/vga16fb.c | 24 1 file changed, 24 insertions(+) diff --git a/drivers/video/fbdev/vga16fb.c b/drivers/video/fbdev/vga16fb.c index 8c464409eb99..d21f68f3ee44 100644 --- a/drivers/video/fbdev/vga16fb.c +++ b/drivers/video/fbdev/vga16fb.c @@ -184,6 +184,25 @@ static inline void setindex(int index) vga_io_w(VGA_GFX_I, index); } +/* Check if the video mode is supported by the driver */ +static inline int check_mode_supported(void) +{ + /* non-x86 architectures treat orig_video_isVGA as a boolean flag */ +#if defined(CONFIG_X86) + /* only EGA and VGA in 16 color graphic mode are supported */ + if (screen_info.orig_video_isVGA != VIDEO_TYPE_EGAC && + screen_info.orig_video_isVGA != VIDEO_TYPE_VGAC) + return -ENODEV; + + if (screen_info.orig_video_mode != 0x0D && /* 320x200/4 (EGA) */ + screen_info.orig_video_mode != 0x0E && /* 640x200/4 (EGA) */ + screen_info.orig_video_mode != 0x10 && /* 640x350/4 (EGA) */ + screen_info.orig_video_mode != 0x12)/* 640x480/4 (VGA) */ + return -ENODEV; +#endif + return 0; +} + static void vga16fb_pan_var(struct fb_info *info, struct fb_var_screeninfo *var) { @@ -1427,6 +1446,11 @@ static int __init vga16fb_init(void) vga16fb_setup(option); #endif + + ret = check_mode_supported(); + if (ret) + return ret; + ret = platform_driver_register(&vga16fb_driver); if (!ret) { -- 2.33.1
[PATCH v2 1/2] video: vga16fb: Fix logic that checks for the display standard
The vga16fb framebuffer driver supports both Enhanced Graphics Adapter (EGA) and Video Graphics Array (VGA) 16 color graphic cards. But the logic to check whether the EGA or VGA standard are used is not correct. It just checks if screen_info.orig_video_isVGA is set, but it should check if is set to VIDEO_TYPE_VGAC instead. This means that it assumes to be VGA even if is set to VIDEO_TYPE_EGAC. All non-x86 architectures though treat orig_video_isVGA as a boolean so only do the change for x86 and keep the old logic for the other arches. Signed-off-by: Javier Martinez Canillas --- Changes in v2: - Make the change only for x86 (Geert Uytterhoeven) drivers/video/fbdev/vga16fb.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/video/fbdev/vga16fb.c b/drivers/video/fbdev/vga16fb.c index e2757ff1c23d..8c464409eb99 100644 --- a/drivers/video/fbdev/vga16fb.c +++ b/drivers/video/fbdev/vga16fb.c @@ -1332,7 +1332,12 @@ static int vga16fb_probe(struct platform_device *dev) printk(KERN_INFO "vga16fb: mapped to 0x%p\n", info->screen_base); par = info->par; +#if defined(CONFIG_X86) + par->isVGA = screen_info.orig_video_isVGA == VIDEO_TYPE_VGAC; +#else + /* non-x86 architectures treat orig_video_isVGA as a boolean flag */ par->isVGA = screen_info.orig_video_isVGA; +#endif par->palette_blanked = 0; par->vesa_blanked = 0; -- 2.33.1
Re: [PATCH v3 3/3] drm/bridge: anx7625: add audio codec .get_eld support
Applied series to drm-misc-next
Re: [PATCH] drm: bridge: adv7511: Fix ADV7535 HPD enablement
Hey Jagan, Thanks for submitting this fix. On Sun, 9 Jan 2022 at 18:30, Jagan Teki wrote: > > Existing HPD enablement logic is not compatible with ADV7535 > bridge, thus any runtime plug-in of HDMI cable is not working > on these bridge designs. > > Unlike other ADV7511 family of bridges, the ADV7535 require > HPD_OVERRIDE bit to set and reset for proper handling of HPD > functionality. > > Fix it. > > Fixes: 8501fe4b14a3 ("drm: bridge: adv7511: Add support for ADV7535") > Signed-off-by: Jagan Teki > --- > drivers/gpu/drm/bridge/adv7511/adv7511.h | 1 + > drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 29 +++- > 2 files changed, 23 insertions(+), 7 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h > b/drivers/gpu/drm/bridge/adv7511/adv7511.h > index 592ecfcf00ca..6a882891d91c 100644 > --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h > +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h > @@ -169,6 +169,7 @@ > #define ADV7511_PACKET_ENABLE_SPARE2 BIT(1) > #define ADV7511_PACKET_ENABLE_SPARE1 BIT(0) > > +#define ADV7535_REG_POWER2_HPD_OVERRIDEBIT(6) > #define ADV7511_REG_POWER2_HPD_SRC_MASK0xc0 > #define ADV7511_REG_POWER2_HPD_SRC_BOTH0x00 > #define ADV7511_REG_POWER2_HPD_SRC_HPD 0x40 > diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c > b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c > index f8e5da148599..77118c3395bf 100644 > --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c > +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c > @@ -351,11 +351,17 @@ static void __adv7511_power_on(struct adv7511 *adv7511) > * from standby or are enabled. When the HPD goes low the adv7511 is > * reset and the outputs are disabled which might cause the monitor to > * go to standby again. To avoid this we ignore the HPD pin for the > -* first few seconds after enabling the output. > +* first few seconds after enabling the output. On the other hand > +* adv7535 require to enable HPD Override bit for proper HPD. > */ > - regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, > - ADV7511_REG_POWER2_HPD_SRC_MASK, > - ADV7511_REG_POWER2_HPD_SRC_NONE); > + if (adv7511->type == ADV7535) > + regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, > + ADV7535_REG_POWER2_HPD_OVERRIDE, > + ADV7535_REG_POWER2_HPD_OVERRIDE); > + else > + regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, > + ADV7511_REG_POWER2_HPD_SRC_MASK, > + ADV7511_REG_POWER2_HPD_SRC_NONE); > } > > static void adv7511_power_on(struct adv7511 *adv7511) > @@ -375,6 +381,10 @@ static void adv7511_power_on(struct adv7511 *adv7511) > static void __adv7511_power_off(struct adv7511 *adv7511) > { > /* TODO: setup additional power down modes */ > + if (adv7511->type == ADV7535) > + regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, > + ADV7535_REG_POWER2_HPD_OVERRIDE, 0); > + > regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER, >ADV7511_POWER_POWER_DOWN, >ADV7511_POWER_POWER_DOWN); > @@ -672,9 +682,14 @@ adv7511_detect(struct adv7511 *adv7511, struct > drm_connector *connector) > status = connector_status_disconnected; > } else { > /* Renable HPD sensing */ > - regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, > - ADV7511_REG_POWER2_HPD_SRC_MASK, > - ADV7511_REG_POWER2_HPD_SRC_BOTH); > + if (adv7511->type == ADV7535) > + regmap_update_bits(adv7511->regmap, > ADV7511_REG_POWER2, > + ADV7535_REG_POWER2_HPD_OVERRIDE, > + ADV7535_REG_POWER2_HPD_OVERRIDE); > + else > + regmap_update_bits(adv7511->regmap, > ADV7511_REG_POWER2, > + ADV7511_REG_POWER2_HPD_SRC_MASK, > + ADV7511_REG_POWER2_HPD_SRC_BOTH); > } > > adv7511->status = status; > -- > 2.25.1 > Reviewed-by: Robert Foss Applied to drm-misc-next
Re: [PATCH v4 0/6] drm: exynos: dsi: Convert drm bridge
Hi Marek, On Thu, Dec 23, 2021 at 2:45 PM Marek Szyprowski wrote: > > Hi Jagan, > > On 18.12.2021 00:16, Marek Szyprowski wrote: > > On 15.12.2021 15:56, Jagan Teki wrote: > >> On Wed, Dec 15, 2021 at 7:49 PM Marek Szyprowski > >> wrote: > >>> On 15.12.2021 13:57, Jagan Teki wrote: > On Wed, Dec 15, 2021 at 5:31 PM Marek Szyprowski > wrote: > > On 15.12.2021 11:15, Jagan Teki wrote: > >> Updated series about drm bridge conversion of exynos dsi. > >> Previous version can be accessible, here [1]. > >> > >> Patch 1: connector reset > >> > >> Patch 2: panel_bridge API > >> > >> Patch 3: Bridge conversion > >> > >> Patch 4: Atomic functions > >> > >> Patch 5: atomic_set > >> > >> Patch 6: DSI init in enable > > There is a little progress! :) > > > > Devices with a simple display pipeline (only a DSI panel, like > > Trats/Trats2) works till the last patch. Then, after applying > > ("[PATCH > > v4 6/6] drm: exynos: dsi: Move DSI init in bridge enable"), I get no > > display at all. > > > > A TM2e board with in-bridge (Exynos MIC) stops displaying anything > > after > > applying patch "[PATCH v4 2/6] drm: exynos: dsi: Use drm > > panel_bridge API". > > > > In case of the Arndale board with tc358764 bridge, no much > > progress. The > > display is broken just after applying the "[PATCH v2] drm: bridge: > > tc358764: Use drm panel_bridge API" patch on top of linux-next. > > > > In all cases the I had "drm: of: Lookup if child node has panel or > > bridge" patch applied. > Just skip the 6/6 for now. > > Apply > - > https://protect2.fireeye.com/v1/url?k=a24f3f76-fdd40659-a24eb439-0cc47a31cdf8-97ea12b4c5258d11&q=1&e=37a169bf-7ca5-4362-aad7-486018c7a708&u=https%3A%2F%2Fpatchwork.amarulasolutions.com%2Fpatch%2F1825%2F > - > https://protect2.fireeye.com/v1/url?k=a226360f-fdbd0f20-a227bd40-0cc47a31cdf8-ebd66aebee1058d7&q=1&e=37a169bf-7ca5-4362-aad7-486018c7a708&u=https%3A%2F%2Fpatchwork.amarulasolutions.com%2Fpatch%2F1823%2F > > Then apply 1/6 to 5/6. and update the status? > >>> Okay, my fault, I didn't check that case on Arndale. > >>> > >>> I've checked and indeed, Trats/Trats2 and Arndale works after the above > >>> 2 patches AND patches 1-5. > >>> > >>> The only problem is now on TM2e, which uses Exynos MIC as in-bridge for > >>> Exynos DSI: > >>> > >>> [4.068866] [drm] Exynos DRM: using 1380.decon device for DMA > >>> mapping operations > >>> [4.069183] exynos-drm exynos-drm: bound 1380.decon (ops > >>> decon_component_ops) > >>> [4.128983] exynos-drm exynos-drm: bound 1388.decon (ops > >>> decon_component_ops) > >>> [4.129261] exynos-drm exynos-drm: bound 1393.mic (ops > >>> exynos_mic_component_ops) > >>> [4.133508] exynos-dsi 1390.dsi: [drm:exynos_dsi_host_attach] > >>> *ERROR* failed to find the bridge: -19 > >>> [4.136392] exynos-drm exynos-drm: bound 1390.dsi (ops > >>> exynos_dsi_component_ops) > >>> [4.145499] rc_core: Couldn't load IR keymap rc-cec > >>> [4.145666] Registered IR keymap rc-empty > >>> [4.148402] rc rc0: sii8620 as /devices/virtual/rc/rc0 > >>> [4.156051] input: sii8620 as /devices/virtual/rc/rc0/input1 > >>> [4.160647] exynos-drm exynos-drm: bound 1397.hdmi (ops > >>> hdmi_component_ops) > >>> [4.169923] exynos-drm exynos-drm: [drm] Cannot find any crtc or > >>> sizes > >>> [4.173958] exynos-drm exynos-drm: [drm] Cannot find any crtc or > >>> sizes > >>> [4.182304] [drm] Initialized exynos 1.1.0 20180330 for > >>> exynos-drm on > >>> minor 0 > >>> > >>> The display pipeline for TM2e is: > >>> > >>> Exynos5433 Decon -> Exynos MIC -> Exynos DSI -> s6e3ha2 DSI panel > >> If Trats/Trats2 is working then it has to work. I don't see any > >> difference in output pipeline. Can you please share the full log, I > >> cannot see host_attach print saying "Attached.." > > > > Well, there is a failure message about the panel: > > > > exynos-dsi 1390.dsi: [drm:exynos_dsi_host_attach] *ERROR* failed > > to find the bridge: -19 > > > > however it looks that something might be broken in dts. The in-bridge > > (Exynos MIC) is on port 0 and the panel is @0, what imho might cause > > the issue. > > > > I've tried to change in in-bridge ('mic_to_dsi') port to 1 in > > exynos5433.dtsi. Then the panel has been attached: > > > > exynos-dsi 1390.dsi: [drm:exynos_dsi_host_attach] Attached s6e3hf2 > > device > > > > but the display is still not working, probably due to lack of proper > > Exynos MIC handling. I will investigate it later and let You know. > > > I've played a bit with the Exynos DRM code and finally I made it working > on TM2(e). There are basically 3 different issues that need to be fixed > to get it working with the $subject patchset: > > 1. Port numbers in exynos5433 dsi/dts are broken. For all pre-Exynos5433 > board
Re: [PATCH] drm/hisilicon/hibmc: Allow to be built if COMPILE_TEST is enabled
On 12/16/21 22:09, Javier Martinez Canillas wrote: > The commit feeb07d0ca5a ("drm/hisilicon/hibmc: Make CONFIG_DRM_HISI_HIBMC > depend on ARM64") made the driver Kconfig symbol to depend on ARM64 since > it only supports that architecture and loading the module on others would > lead to incorrect video modes being used. > > But it also prevented the driver to be built on other architectures which > is useful to have compile test coverage when doing subsystem wide changes. > > Make the dependency instead to be (ARM64 || COMPILE_TEST), so the driver > is buildable when the CONFIG_COMPILE_TEST option is enabled. > > Signed-off-by: Javier Martinez Canillas > --- > > drivers/gpu/drm/hisilicon/hibmc/Kconfig | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/hisilicon/hibmc/Kconfig > b/drivers/gpu/drm/hisilicon/hibmc/Kconfig > index 43943e980203..073adfe438dd 100644 > --- a/drivers/gpu/drm/hisilicon/hibmc/Kconfig > +++ b/drivers/gpu/drm/hisilicon/hibmc/Kconfig > @@ -1,7 +1,7 @@ > # SPDX-License-Identifier: GPL-2.0-only > config DRM_HISI_HIBMC > tristate "DRM Support for Hisilicon Hibmc" > - depends on DRM && PCI && ARM64 > + depends on DRM && PCI && (ARM64 || COMPILE_TEST) > select DRM_KMS_HELPER > select DRM_VRAM_HELPER > select DRM_TTM Any comments on this patch? Best regards, -- Javier Martinez Canillas Linux Engineering Red Hat
Re: [PATCH 1/2] drm: exynos: dsi: Convert to bridge driver
Hi Robert, On Mon, Nov 22, 2021 at 9:34 PM Marek Szyprowski wrote: > > On 22.11.2021 16:07, Marek Szyprowski wrote: > > On 22.11.2021 15:55, Jagan Teki wrote: > >> On Mon, Nov 22, 2021 at 7:59 PM Jagan Teki > >> wrote: > >>> On Mon, Nov 22, 2021 at 7:51 PM Jagan Teki > >>> wrote: > On Mon, Nov 22, 2021 at 7:45 PM Marek Szyprowski > wrote: > > On 22.11.2021 08:06, Jagan Teki wrote: > >> Some display panels would come up with a non-DSI output, those > >> can have an option to connect the DSI host by means of interface > >> bridge converter. > >> > >> This DSI to non-DSI interface bridge converter would requires > >> DSI Host to handle drm bridge functionalities in order to DSI > >> Host to Interface bridge. > >> > >> This patch convert the existing to a drm bridge driver with a > >> built-in encoder support for compatibility with existing > >> component drivers. > >> > >> Signed-off-by: Jagan Teki > >> --- > >> Note: > >> Hi Marek Szyprowski, > >> > >> Please test this on Panel and Bridge hardware. > > I don't have good news, t crashes: > > > > [drm] Exynos DRM: using 1380.decon device for DMA mapping > > operations > > exynos-drm exynos-drm: bound 1380.decon (ops decon_component_ops) > > exynos-drm exynos-drm: bound 1388.decon (ops decon_component_ops) > > exynos-drm exynos-drm: bound 1393.mic (ops > > exynos_mic_component_ops) > > [drm:drm_bridge_attach] *ERROR* failed to attach bridge > > /soc@0/dsi@1390 to encoder TMDS-67: -22 > > exynos-drm exynos-drm: failed to bind 1390.dsi (ops > > exynos_dsi_component_ops): -22 > > Internal error: synchronous external abort: 96000210 [#1] PREEMPT SMP > > Modules linked in: > > CPU: 2 PID: 74 Comm: kworker/u16:1 Not tainted 5.16.0-rc1+ #4141 > > Hardware name: Samsung TM2E board (DT) > > Workqueue: events_unbound deferred_probe_work_func > > pstate: 8005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) > > pc : decon_atomic_disable+0x58/0xd4 > > lr : decon_atomic_disable+0x28/0xd4 > > sp : 80001390b940 > > x29: 80001390b940 x28: 80001259a000 x27: 27f39e80 > > input: stmfts as > > /devices/platform/soc@0/14ed.hsi2c/i2c-3/3-0049/input/input0 > > x26: ffea x25: 25a40280 x24: 0001 > > x23: 800011b55f98 x22: 315dc000 x21: 2695d100 > > x20: 27e7a080 x19: 315e6000 x18: > > x17: 645f736f6e797865 x16: 2073706f28206973 x15: 00028ee0 > > x14: 0028 x13: 0001 x12: 0040 > > x11: 23c18920 x10: 23c18922 x9 : 8000126352f0 > > x8 : 23c00270 x7 : x6 : 23c00268 > > x5 : 27e7a3a0 x4 : 0001 x3 : 27e7a080 > > x2 : 0024 x1 : 800013bc8024 x0 : 246117c0 > > Call trace: > >decon_atomic_disable+0x58/0xd4 > >decon_unbind+0x1c/0x3c > >component_unbind+0x38/0x60 > >component_bind_all+0x16c/0x25c > >exynos_drm_bind+0x104/0x1bc > >try_to_bring_up_master+0x164/0x1d0 > >__component_add+0xa8/0x174 > >component_add+0x14/0x20 > >hdmi_probe+0x438/0x710 > >platform_probe+0x68/0xe0 > >really_probe.part.0+0x9c/0x31c > >__driver_probe_device+0x98/0x144 > >driver_probe_device+0xc8/0x160 > >__device_attach_driver+0xb8/0x120 > >bus_for_each_drv+0x78/0xd0 > >__device_attach+0xd8/0x180 > >device_initial_probe+0x14/0x20 > >bus_probe_device+0x9c/0xa4 > >deferred_probe_work_func+0x88/0xc4 > >process_one_work+0x288/0x6f0 > >worker_thread+0x74/0x470 > >kthread+0x188/0x194 > >ret_from_fork+0x10/0x20 > > Code: 11002042 f9481c61 531e7442 8b020021 (88dffc21) > > ---[ end trace d73aff585b108954 ]--- > > Kernel panic - not syncing: synchronous external abort: Fatal > > exception > > SMP: stopping secondary CPUs > > Kernel Offset: disabled > > CPU features: 0x2,300071c2,0846 > > Memory Limit: none > > ---[ end Kernel panic - not syncing: synchronous external abort: > > Fatal > > exception ]--- > Is this with Bridge or normal DSI panel? > >>> Can you apply this patch and check? > >>> https://protect2.fireeye.com/v1/url?k=aad62f08-f54d1627-aad7a447-0cc47a31cdf8-ea5858ddb7f0ecfe&q=1&e=2d730862-2c56-4988-a252-8febd02da578&u=https%3A%2F%2Fgithub.com%2Fopenedev%2Flinux%2Fcommit%2F412f226acd774356e8188c9e62b653672926ee0d > >>> > >> Any news on this? just asking in case if you missed it. > > > > It is somehow better. System doesn't crash, but the DRM is not bound: > > > > # cat /sys/kernel/debug/device_component/exynos-drm > > master namestatus > > ---
Re: [PATCH v5 03/32] component: Move struct aggregate_device out to header file
On Fri, 07 Jan 2022, Stephen Boyd wrote: > Quoting Jani Nikula (2022-01-07 05:07:59) >> On Thu, 06 Jan 2022, Stephen Boyd wrote: >> > This allows aggregate driver writers to use the device passed to their >> > probe/remove/shutdown functions properly instead of treating it as an >> > opaque pointer. >> >> You say it like having opaque pointers with interfaces instead of >> exposed data is a bad thing. > > I didn't intend to convey that message at all and in fact I didn't write > that opaque pointers are a bad thing. > >> >> Data is not an interface. IMO if you can get by with keeping the types >> private, go for it. Unless I'm missing something, you only need the >> parent dev pointer. Maybe add a helper function for it? > > Sure I'll add a function for that. > >> >> It's trivial to expose the guts like this, but it's usually a lot of >> hard work to go the other way. Look at the dependencies of component.h >> now. To keep it self-contained, i.e. buildable without implicit >> dependencies, you'd need to add #include , which goes on to >> include the world. Then have a look at [1]. >> >> Please at least let's not do this lightly. >> > > Got it. Thanks! How does this look? Thanks, I think this is better. BR, Jani. > > ---8<--- > diff --git a/drivers/base/component.c b/drivers/base/component.c > index cd50137753b4..e8f09945c261 100644 > --- a/drivers/base/component.c > +++ b/drivers/base/component.c > @@ -56,6 +56,27 @@ struct component_match { > struct component_match_array *compare; > }; > > +struct aggregate_device { > + const struct component_master_ops *ops; > + struct device *parent; > + struct device dev; > + struct component_match *match; > + struct aggregate_driver *adrv; > + > + int id; > +}; > + > +static inline struct aggregate_device *to_aggregate_device(struct device *d) > +{ > + return container_of(d, struct aggregate_device, dev); > +} > + > +struct device *aggregate_device_parent(struct aggregate_device *adev) > +{ > + return adev->parent; > +} > +EXPORT_SYMBOL_GPL(aggregate_device_parent); > + > struct component { > struct list_head node; > struct aggregate_device *adev; > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c > b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c > index 0463386a6ed2..5fa868cf9825 100644 > --- a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c > @@ -27,7 +27,7 @@ struct komeda_dev *dev_to_mdev(struct device *dev) > > static void komeda_unbind(struct aggregate_device *adev) > { > - struct device *dev = adev->parent; > + struct device *dev = aggregate_device_parent(adev); > struct komeda_drv *mdrv = dev_get_drvdata(dev); > > if (!mdrv) > @@ -48,7 +48,7 @@ static void komeda_unbind(struct aggregate_device *adev) > > static int komeda_bind(struct aggregate_device *adev) > { > - struct device *dev = adev->parent; > + struct device *dev = aggregate_device_parent(adev); > struct komeda_drv *mdrv; > int err; > > diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c > index 5c03eb98d814..e3ed925797d5 100644 > --- a/drivers/gpu/drm/arm/hdlcd_drv.c > +++ b/drivers/gpu/drm/arm/hdlcd_drv.c > @@ -272,7 +272,7 @@ static const struct drm_driver hdlcd_driver = { > > static int hdlcd_drm_bind(struct aggregate_device *adev) > { > - struct device *dev = adev->parent; > + struct device *dev = aggregate_device_parent(adev); > struct drm_device *drm; > struct hdlcd_drm_private *hdlcd; > int ret; > @@ -347,7 +347,7 @@ static int hdlcd_drm_bind(struct aggregate_device *adev) > > static void hdlcd_drm_unbind(struct aggregate_device *adev) > { > - struct device *dev = adev->parent; > + struct device *dev = aggregate_device_parent(adev); > struct drm_device *drm = dev_get_drvdata(dev); > struct hdlcd_drm_private *hdlcd = drm->dev_private; > > diff --git a/drivers/gpu/drm/arm/malidp_drv.c > b/drivers/gpu/drm/arm/malidp_drv.c > index e6ee4d1e3bb8..7b946b962b22 100644 > --- a/drivers/gpu/drm/arm/malidp_drv.c > +++ b/drivers/gpu/drm/arm/malidp_drv.c > @@ -704,7 +704,7 @@ static int malidp_runtime_pm_resume(struct device *dev) > > static int malidp_bind(struct aggregate_device *adev) > { > - struct device *dev = adev->parent; > + struct device *dev = aggregate_device_parent(adev); > struct resource *res; > struct drm_device *drm; > struct malidp_drm *malidp; > @@ -897,7 +897,7 @@ static int malidp_bind(struct aggregate_device *adev) > > static void malidp_unbind(struct aggregate_device *adev) > { > - struct device *dev = adev->parent; > + struct device *dev = aggregate_device_parent(adev); > struct drm_device *drm = dev_get_drvdata(dev); > struct malidp_drm *malidp = drm->dev_private; > struct malidp_hw_device *hwdev = malidp->dev; > diff --git a/drivers/gpu/drm/armada/armada_drv.c > b/drivers/gpu/drm/ar
Re: [PATCH v5 1/3] drm/privacy_screen: Add drvdata in drm_privacy_screen
Hi All, On 1/7/22 20:02, Rajat Jain wrote: > Allow a privacy screen provider to stash its private data pointer in the > drm_privacy_screen, and update the drm_privacy_screen_register() call to > accept that. Also introduce a *_get_drvdata() so that it can retrieved > back when needed. > > This also touches the IBM Thinkpad platform driver, the only user of > privacy screen today, to pass NULL for now to the updated API. > > Signed-off-by: Rajat Jain > Reviewed-by: Hans de Goede I've pushed this series to drm-misc-next now. Regards, Hans > --- > v5: Same as v4 > v4: Added "Reviewed-by" from Hans > v3: Initial version. Came up due to review comments on v2 of other patches. > v2: No v2 > v1: No v1 > > drivers/gpu/drm/drm_privacy_screen.c| 5 - > drivers/platform/x86/thinkpad_acpi.c| 2 +- > include/drm/drm_privacy_screen_driver.h | 13 - > 3 files changed, 17 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/drm_privacy_screen.c > b/drivers/gpu/drm/drm_privacy_screen.c > index beaf99e9120a..03b149cc455b 100644 > --- a/drivers/gpu/drm/drm_privacy_screen.c > +++ b/drivers/gpu/drm/drm_privacy_screen.c > @@ -387,7 +387,8 @@ static void drm_privacy_screen_device_release(struct > device *dev) > * * An ERR_PTR(errno) on failure. > */ > struct drm_privacy_screen *drm_privacy_screen_register( > - struct device *parent, const struct drm_privacy_screen_ops *ops) > + struct device *parent, const struct drm_privacy_screen_ops *ops, > + void *data) > { > struct drm_privacy_screen *priv; > int ret; > @@ -404,6 +405,7 @@ struct drm_privacy_screen *drm_privacy_screen_register( > priv->dev.parent = parent; > priv->dev.release = drm_privacy_screen_device_release; > dev_set_name(&priv->dev, "privacy_screen-%s", dev_name(parent)); > + priv->drvdata = data; > priv->ops = ops; > > priv->ops->get_hw_state(priv); > @@ -439,6 +441,7 @@ void drm_privacy_screen_unregister(struct > drm_privacy_screen *priv) > mutex_unlock(&drm_privacy_screen_devs_lock); > > mutex_lock(&priv->lock); > + priv->drvdata = NULL; > priv->ops = NULL; > mutex_unlock(&priv->lock); > > diff --git a/drivers/platform/x86/thinkpad_acpi.c > b/drivers/platform/x86/thinkpad_acpi.c > index 341655d711ce..ccbfda2b0095 100644 > --- a/drivers/platform/x86/thinkpad_acpi.c > +++ b/drivers/platform/x86/thinkpad_acpi.c > @@ -9782,7 +9782,7 @@ static int tpacpi_lcdshadow_init(struct ibm_init_struct > *iibm) > return 0; > > lcdshadow_dev = drm_privacy_screen_register(&tpacpi_pdev->dev, > - &lcdshadow_ops); > + &lcdshadow_ops, NULL); > if (IS_ERR(lcdshadow_dev)) > return PTR_ERR(lcdshadow_dev); > > diff --git a/include/drm/drm_privacy_screen_driver.h > b/include/drm/drm_privacy_screen_driver.h > index 24591b607675..4ef246d5706f 100644 > --- a/include/drm/drm_privacy_screen_driver.h > +++ b/include/drm/drm_privacy_screen_driver.h > @@ -73,10 +73,21 @@ struct drm_privacy_screen { >* for more info. >*/ > enum drm_privacy_screen_status hw_state; > + /** > + * @drvdata: Private data owned by the privacy screen provider > + */ > + void *drvdata; > }; > > +static inline > +void *drm_privacy_screen_get_drvdata(struct drm_privacy_screen *priv) > +{ > + return priv->drvdata; > +} > + > struct drm_privacy_screen *drm_privacy_screen_register( > - struct device *parent, const struct drm_privacy_screen_ops *ops); > + struct device *parent, const struct drm_privacy_screen_ops *ops, > + void *data); > void drm_privacy_screen_unregister(struct drm_privacy_screen *priv); > > void drm_privacy_screen_call_notifier_chain(struct drm_privacy_screen *priv); >
[PATCH] drm: bridge: chipone-icn6211: Drop unnecessary bridge type
Explicit assignment of connector to bridge type during bridge addition is optional. Some of the bridges like ICN6211 has panel to be connected and that panel driver has taken care of associated connector type of it. Drop it. Signed-off-by: Jagan Teki --- drivers/gpu/drm/bridge/chipone-icn6211.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c b/drivers/gpu/drm/bridge/chipone-icn6211.c index 23c34039ac48..c60170865b74 100644 --- a/drivers/gpu/drm/bridge/chipone-icn6211.c +++ b/drivers/gpu/drm/bridge/chipone-icn6211.c @@ -238,7 +238,6 @@ static int chipone_probe(struct mipi_dsi_device *dsi) return ret; icn->bridge.funcs = &chipone_bridge_funcs; - icn->bridge.type = DRM_MODE_CONNECTOR_DPI; icn->bridge.of_node = dev->of_node; drm_bridge_add(&icn->bridge); -- 2.25.1
[PATCH v4 4/7] drm/i915: Add i915_vma_unbind_unlocked, and take obj lock for i915_vma_unbind, v2.
We want to remove more members of i915_vma, which requires the locking to be held more often. Start requiring gem object lock for i915_vma_unbind, as it's one of the callers that may unpin pages. Some special care is needed when evicting, because the last reference to the object may be held by the VMA, so after __i915_vma_unbind, vma may be garbage, and we need to cache vma->obj before unlocking. Changes since v1: - Make trylock failing a WARN. (Matt) - Remove double i915_vma_wait_for_bind() (Matt) - Move atomic_set to right before mutex_unlock(), to make it more clear they belong together. (Matt) Signed-off-by: Maarten Lankhorst Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/display/intel_fb_pin.c | 2 +- .../gpu/drm/i915/gem/selftests/huge_pages.c | 2 +- .../i915/gem/selftests/i915_gem_client_blt.c | 2 +- .../drm/i915/gem/selftests/i915_gem_mman.c| 6 +++ drivers/gpu/drm/i915/gt/intel_ggtt.c | 49 --- drivers/gpu/drm/i915/i915_gem.c | 2 + drivers/gpu/drm/i915/i915_vma.c | 27 +- drivers/gpu/drm/i915/i915_vma.h | 1 + drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 22 - drivers/gpu/drm/i915/selftests/i915_vma.c | 8 +-- 10 files changed, 95 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.c b/drivers/gpu/drm/i915/display/intel_fb_pin.c index 31c15e5fca95..9c555f6d1958 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_pin.c +++ b/drivers/gpu/drm/i915/display/intel_fb_pin.c @@ -47,7 +47,7 @@ intel_pin_fb_obj_dpt(struct drm_framebuffer *fb, goto err; if (i915_vma_misplaced(vma, 0, alignment, 0)) { - ret = i915_vma_unbind(vma); + ret = i915_vma_unbind_unlocked(vma); if (ret) { vma = ERR_PTR(ret); goto err; diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c index 11f0aa65f8a3..b14c4e0a58d8 100644 --- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c +++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c @@ -647,7 +647,7 @@ static int igt_mock_ppgtt_misaligned_dma(void *arg) * pages. */ for (offset = 4096; offset < page_size; offset += 4096) { - err = i915_vma_unbind(vma); + err = i915_vma_unbind_unlocked(vma); if (err) goto out_unpin; diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c index c08f766e6e15..c8ff8bf0986d 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c @@ -318,7 +318,7 @@ static int pin_buffer(struct i915_vma *vma, u64 addr) int err; if (drm_mm_node_allocated(&vma->node) && vma->node.start != addr) { - err = i915_vma_unbind(vma); + err = i915_vma_unbind_unlocked(vma); if (err) return err; } diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c index f61356b72b1c..ba29767348be 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c @@ -166,7 +166,9 @@ static int check_partial_mapping(struct drm_i915_gem_object *obj, kunmap(p); out: + i915_gem_object_lock(obj, NULL); __i915_vma_put(vma); + i915_gem_object_unlock(obj); return err; } @@ -261,7 +263,9 @@ static int check_partial_mappings(struct drm_i915_gem_object *obj, if (err) return err; + i915_gem_object_lock(obj, NULL); __i915_vma_put(vma); + i915_gem_object_unlock(obj); if (igt_timeout(end_time, "%s: timed out after tiling=%d stride=%d\n", @@ -1352,7 +1356,9 @@ static int __igt_mmap_revoke(struct drm_i915_private *i915, * for other objects. Ergo we have to revoke the previous mmap PTE * access as it no longer points to the same object. */ + i915_gem_object_lock(obj, NULL); err = i915_gem_object_unbind(obj, I915_GEM_OBJECT_UNBIND_ACTIVE); + i915_gem_object_unlock(obj); if (err) { pr_err("Failed to unbind object!\n"); goto out_unmap; diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c index e416e1f12d1a..e73d453a0d6b 100644 --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c @@ -129,22 +129,49 @@ void i915_ggtt_suspend_vm(struct i915_address_space *vm) drm_WARN_ON(&vm->i915->drm, !vm->is_ggtt && !vm->is_dpt); +retry: + i915_gem_drain_free
[PATCH v4 0/7] drm/i915: Remove short term pins from execbuf by requiring lock to unbind.
Previously, short term pinning in execbuf was required because i915_vma was effectively independent from objects, and has its own refcount, locking, lifetime rules and pinning. This series removes the separate locking, by requiring vma->obj->resv to be held when pinning and unbinding. This will also be required for VM_BIND work. Some patches have already been merged, but this contains the mremainder of the conversion. With pinning required for pinning and unbinding, the lock is enough to prevent unbinding when trying to pin with the lock held, for example in execbuf. This makes binding/unbinding similar to ttm_bo_validate()'s use, which just cares that an object is in a certain place, without pinning it in place. Having the VMA part of gem bo removes a lot of the vma refcounting, and makes i915_vma more a part of the bo, instead of its own floating object that just happens to be part of a bo. This is also required to make it more compatible with TTM, and migration in general. For future work, it makes things a lot simpler and clear. We want to end up with i915_vma just being a specific mapping of the BO, just like is the case in other drivers. i915_vma->active removal is the next step there, and makes it when object is destroyed, the bindings are destroyed (after idle), instead of object being destroyed when bindings are idle. Maarten Lankhorst (7): drm/i915: Call i915_gem_evict_vm in vm_fault_gtt to prevent new ENOSPC errors, v2. drm/i915: Add locking to i915_gem_evict_vm() drm/i915: Add object locking to i915_gem_evict_for_node and i915_gem_evict_something drm/i915: Add i915_vma_unbind_unlocked, and take obj lock for i915_vma_unbind, v2. drm/i915: Remove assert_object_held_shared drm/i915: Remove support for unlocked i915_vma unbind drm/i915: Remove short-term pins from execbuf, v6. drivers/gpu/drm/i915/display/intel_fb_pin.c | 2 +- .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 220 +- drivers/gpu/drm/i915/gem/i915_gem_mman.c | 17 +- drivers/gpu/drm/i915/gem/i915_gem_object.c| 4 +- drivers/gpu/drm/i915/gem/i915_gem_object.h| 14 -- drivers/gpu/drm/i915/gem/i915_gem_pages.c | 10 +- drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 2 +- .../gpu/drm/i915/gem/selftests/huge_pages.c | 2 +- .../i915/gem/selftests/i915_gem_client_blt.c | 2 +- .../drm/i915/gem/selftests/i915_gem_mman.c| 6 + drivers/gpu/drm/i915/gt/intel_ggtt.c | 51 +++- drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c | 1 - drivers/gpu/drm/i915/gt/selftest_hangcheck.c | 2 +- drivers/gpu/drm/i915/gvt/aperture_gm.c| 2 +- drivers/gpu/drm/i915/i915_drv.h | 5 +- drivers/gpu/drm/i915/i915_gem.c | 2 + drivers/gpu/drm/i915/i915_gem_evict.c | 64 - drivers/gpu/drm/i915/i915_gem_gtt.c | 8 +- drivers/gpu/drm/i915/i915_gem_gtt.h | 4 + drivers/gpu/drm/i915/i915_vgpu.c | 2 +- drivers/gpu/drm/i915/i915_vma.c | 122 +- drivers/gpu/drm/i915/i915_vma.h | 1 + .../gpu/drm/i915/selftests/i915_gem_evict.c | 27 ++- drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 36 +-- drivers/gpu/drm/i915/selftests/i915_vma.c | 8 +- 25 files changed, 361 insertions(+), 253 deletions(-) -- 2.34.1
[PATCH v4 2/7] drm/i915: Add locking to i915_gem_evict_vm()
i915_gem_evict_vm will need to be able to evict objects that are locked by the current ctx. By testing if the current context already locked the object, we can do this correctly. This allows us to evict the entire vm even if we already hold some objects' locks. Previously, this was spread over several commits, but it makes more sense to commit the changes to i915_gem_evict_vm separately from the changes to i915_gem_evict_something() and i915_gem_evict_for_node(). Signed-off-by: Maarten Lankhorst --- .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 2 +- drivers/gpu/drm/i915/gem/i915_gem_mman.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 3 +- drivers/gpu/drm/i915/i915_gem_evict.c | 30 +-- drivers/gpu/drm/i915/i915_vma.c | 7 - .../gpu/drm/i915/selftests/i915_gem_evict.c | 10 +-- 6 files changed, 46 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index 5ecc85b96a3d..da35a143af36 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -766,7 +766,7 @@ static int eb_reserve(struct i915_execbuffer *eb) case 1: /* Too fragmented, unbind everything and retry */ mutex_lock(&eb->context->vm->mutex); - err = i915_gem_evict_vm(eb->context->vm); + err = i915_gem_evict_vm(eb->context->vm, &eb->ww); mutex_unlock(&eb->context->vm->mutex); if (err) return err; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c index 4337f3c1400c..4afad1604a6a 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c @@ -366,7 +366,7 @@ static vm_fault_t vm_fault_gtt(struct vm_fault *vmf) if (vma == ERR_PTR(-ENOSPC)) { ret = mutex_lock_interruptible(&ggtt->vm.mutex); if (!ret) { - ret = i915_gem_evict_vm(&ggtt->vm); + ret = i915_gem_evict_vm(&ggtt->vm, &ww); mutex_unlock(&ggtt->vm.mutex); } if (ret) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 2f9336302e6c..ef121ddef418 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1729,7 +1729,8 @@ int __must_check i915_gem_evict_something(struct i915_address_space *vm, int __must_check i915_gem_evict_for_node(struct i915_address_space *vm, struct drm_mm_node *node, unsigned int flags); -int i915_gem_evict_vm(struct i915_address_space *vm); +int i915_gem_evict_vm(struct i915_address_space *vm, + struct i915_gem_ww_ctx *ww); /* i915_gem_internal.c */ struct drm_i915_gem_object * diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index 2b73ddb11c66..bfd66f539fc1 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c @@ -367,7 +367,7 @@ int i915_gem_evict_for_node(struct i915_address_space *vm, * To clarify: This is for freeing up virtual address space, not for freeing * memory in e.g. the shrinker. */ -int i915_gem_evict_vm(struct i915_address_space *vm) +int i915_gem_evict_vm(struct i915_address_space *vm, struct i915_gem_ww_ctx *ww) { int ret = 0; @@ -388,24 +388,50 @@ int i915_gem_evict_vm(struct i915_address_space *vm) do { struct i915_vma *vma, *vn; LIST_HEAD(eviction_list); + LIST_HEAD(locked_eviction_list); list_for_each_entry(vma, &vm->bound_list, vm_link) { if (i915_vma_is_pinned(vma)) continue; + /* +* If we already own the lock, trylock fails. In case the resv +* is shared among multiple objects, we still need the object ref. +*/ + if (ww && (dma_resv_locking_ctx(vma->obj->base.resv) == &ww->ctx)) { + __i915_vma_pin(vma); + list_add(&vma->evict_link, &locked_eviction_list); + continue; + } + + if (!i915_gem_object_trylock(vma->obj, ww)) + continue; + __i915_vma_pin(vma); list_add(&vma->evict_link, &eviction_list); } - if (list_empty(&eviction_list)) + if (list_empty(&eviction_list) && list_empty(&locked_eviction_list))
[PATCH v4 1/7] drm/i915: Call i915_gem_evict_vm in vm_fault_gtt to prevent new ENOSPC errors, v2.
Now that we cannot unbind kill the currently locked object directly because we're removing short term pinning, we may have to unbind the object from gtt manually, using a i915_gem_evict_vm() call. Changes since v1: - Remove -ENOSPC warning, can still happen with concurrent mmaps where we can't unbind the other mmap because of the lock held. This fixes the gem_mmap_gtt@cpuset tests. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/gem/i915_gem_mman.c | 17 +++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c index 5ac2506f4ee8..4337f3c1400c 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c @@ -358,8 +358,21 @@ static vm_fault_t vm_fault_gtt(struct vm_fault *vmf) vma = i915_gem_object_ggtt_pin_ww(obj, &ww, &view, 0, 0, flags); } - /* The entire mappable GGTT is pinned? Unexpected! */ - GEM_BUG_ON(vma == ERR_PTR(-ENOSPC)); + /* +* The entire mappable GGTT is pinned? Unexpected! +* Try to evict the object we locked too, as normally we skip it +* due to lack of short term pinning inside execbuf. +*/ + if (vma == ERR_PTR(-ENOSPC)) { + ret = mutex_lock_interruptible(&ggtt->vm.mutex); + if (!ret) { + ret = i915_gem_evict_vm(&ggtt->vm); + mutex_unlock(&ggtt->vm.mutex); + } + if (ret) + goto err_reset; + vma = i915_gem_object_ggtt_pin_ww(obj, &ww, &view, 0, 0, flags); + } } if (IS_ERR(vma)) { ret = PTR_ERR(vma); -- 2.34.1
[PATCH v4 3/7] drm/i915: Add object locking to i915_gem_evict_for_node and i915_gem_evict_something
Because we will start to require the obj->resv lock for unbinding, ensure these shrinker functions also take the lock. This requires some function signature changes, to ensure that the ww context is passed around, but is mostly straightforward. Previously this was split up into several patches, but reworking should allow for easier bisection. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/gt/intel_ggtt.c | 2 +- drivers/gpu/drm/i915/gt/selftest_hangcheck.c | 2 +- drivers/gpu/drm/i915/gvt/aperture_gm.c| 2 +- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_gem_evict.c | 34 +++ drivers/gpu/drm/i915/i915_gem_gtt.c | 8 +++-- drivers/gpu/drm/i915/i915_gem_gtt.h | 3 ++ drivers/gpu/drm/i915/i915_vgpu.c | 2 +- drivers/gpu/drm/i915/i915_vma.c | 9 ++--- .../gpu/drm/i915/selftests/i915_gem_evict.c | 17 +- drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 14 11 files changed, 63 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c index ab6c4322dc08..e416e1f12d1a 100644 --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c @@ -504,7 +504,7 @@ static int ggtt_reserve_guc_top(struct i915_ggtt *ggtt) GEM_BUG_ON(ggtt->vm.total <= GUC_GGTT_TOP); size = ggtt->vm.total - GUC_GGTT_TOP; - ret = i915_gem_gtt_reserve(&ggtt->vm, &ggtt->uc_fw, size, + ret = i915_gem_gtt_reserve(&ggtt->vm, NULL, &ggtt->uc_fw, size, GUC_GGTT_TOP, I915_COLOR_UNEVICTABLE, PIN_NOEVICT); if (ret) diff --git a/drivers/gpu/drm/i915/gt/selftest_hangcheck.c b/drivers/gpu/drm/i915/gt/selftest_hangcheck.c index 15d63435ec4d..9c21b55b927b 100644 --- a/drivers/gpu/drm/i915/gt/selftest_hangcheck.c +++ b/drivers/gpu/drm/i915/gt/selftest_hangcheck.c @@ -1382,7 +1382,7 @@ static int evict_vma(void *data) complete(&arg->completion); mutex_lock(&vm->mutex); - err = i915_gem_evict_for_node(vm, &evict, 0); + err = i915_gem_evict_for_node(vm, NULL, &evict, 0); mutex_unlock(&vm->mutex); return err; diff --git a/drivers/gpu/drm/i915/gvt/aperture_gm.c b/drivers/gpu/drm/i915/gvt/aperture_gm.c index 0d6d59871308..c08098a167e9 100644 --- a/drivers/gpu/drm/i915/gvt/aperture_gm.c +++ b/drivers/gpu/drm/i915/gvt/aperture_gm.c @@ -63,7 +63,7 @@ static int alloc_gm(struct intel_vgpu *vgpu, bool high_gm) mutex_lock(>->ggtt->vm.mutex); mmio_hw_access_pre(gt); - ret = i915_gem_gtt_insert(>->ggtt->vm, node, + ret = i915_gem_gtt_insert(>->ggtt->vm, NULL, node, size, I915_GTT_PAGE_SIZE, I915_COLOR_UNEVICTABLE, start, end, flags); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ef121ddef418..88eb203a0742 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1722,11 +1722,13 @@ i915_gem_vm_lookup(struct drm_i915_file_private *file_priv, u32 id) /* i915_gem_evict.c */ int __must_check i915_gem_evict_something(struct i915_address_space *vm, + struct i915_gem_ww_ctx *ww, u64 min_size, u64 alignment, unsigned long color, u64 start, u64 end, unsigned flags); int __must_check i915_gem_evict_for_node(struct i915_address_space *vm, +struct i915_gem_ww_ctx *ww, struct drm_mm_node *node, unsigned int flags); int i915_gem_evict_vm(struct i915_address_space *vm, diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index bfd66f539fc1..f502a617b35c 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c @@ -51,6 +51,7 @@ static int ggtt_flush(struct intel_gt *gt) static bool mark_free(struct drm_mm_scan *scan, + struct i915_gem_ww_ctx *ww, struct i915_vma *vma, unsigned int flags, struct list_head *unwind) @@ -58,6 +59,9 @@ mark_free(struct drm_mm_scan *scan, if (i915_vma_is_pinned(vma)) return false; + if (!i915_gem_object_trylock(vma->obj, ww)) + return false; + list_add(&vma->evict_link, unwind); return drm_mm_scan_add_block(scan, &vma->node); } @@ -98,6 +102,7 @@ static bool defer_evict(struct i915_vma *vma) */ int i915_gem_evict_something(struct i915_address_space *vm, +struct i915_gem_ww_ctx *ww, u64 min_size, u64 al
[PATCH v4 7/7] drm/i915: Remove short-term pins from execbuf, v6.
Add a flag PIN_VALIDATE, to indicate we don't need to pin and only protected by the object lock. This removes the need to unpin, which is done by just releasing the lock. eb_reserve is slightly reworked for readability, but the same steps are still done: - First pass pins with NONBLOCK. - Second pass unbinds all objects first, then pins. - Third pass is only called when not all objects are softpinned, and unbinds all objects, then calls i915_gem_evict_vm(), then pins. Changes since v1: - Split out eb_reserve() into separate functions for readability. Changes since v2: - Make batch buffer mappable on platforms where only GGTT is available, to prevent moving the batch buffer during relocations. Changes since v3: - Preserve current behavior for batch buffer, instead be cautious when calling i915_gem_object_ggtt_pin_ww, and re-use the current batch vma if it's inside ggtt and map-and-fenceable. - Remove impossible condition check from eb_reserve. (Matt) Changes since v5: - Do not even temporarily pin, just call i915_gem_evict_vm() and mark all vma's as unpinned. Signed-off-by: Maarten Lankhorst Reviewed-by: Matthew Auld --- .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 220 +- drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c | 1 - drivers/gpu/drm/i915/i915_gem_gtt.h | 1 + drivers/gpu/drm/i915/i915_vma.c | 24 +- 4 files changed, 128 insertions(+), 118 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index da35a143af36..cfff194d90e7 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -441,7 +441,7 @@ eb_pin_vma(struct i915_execbuffer *eb, else pin_flags = entry->offset & PIN_OFFSET_MASK; - pin_flags |= PIN_USER | PIN_NOEVICT | PIN_OFFSET_FIXED; + pin_flags |= PIN_USER | PIN_NOEVICT | PIN_OFFSET_FIXED | PIN_VALIDATE; if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_GTT)) pin_flags |= PIN_GLOBAL; @@ -459,17 +459,15 @@ eb_pin_vma(struct i915_execbuffer *eb, entry->pad_to_size, entry->alignment, eb_pin_flags(entry, ev->flags) | -PIN_USER | PIN_NOEVICT); +PIN_USER | PIN_NOEVICT | PIN_VALIDATE); if (unlikely(err)) return err; } if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_FENCE)) { err = i915_vma_pin_fence(vma); - if (unlikely(err)) { - i915_vma_unpin(vma); + if (unlikely(err)) return err; - } if (vma->fence) ev->flags |= __EXEC_OBJECT_HAS_FENCE; @@ -485,13 +483,9 @@ eb_pin_vma(struct i915_execbuffer *eb, static inline void eb_unreserve_vma(struct eb_vma *ev) { - if (!(ev->flags & __EXEC_OBJECT_HAS_PIN)) - return; - if (unlikely(ev->flags & __EXEC_OBJECT_HAS_FENCE)) __i915_vma_unpin_fence(ev->vma); - __i915_vma_unpin(ev->vma); ev->flags &= ~__EXEC_OBJECT_RESERVED; } @@ -684,10 +678,8 @@ static int eb_reserve_vma(struct i915_execbuffer *eb, if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_FENCE)) { err = i915_vma_pin_fence(vma); - if (unlikely(err)) { - i915_vma_unpin(vma); + if (unlikely(err)) return err; - } if (vma->fence) ev->flags |= __EXEC_OBJECT_HAS_FENCE; @@ -699,85 +691,95 @@ static int eb_reserve_vma(struct i915_execbuffer *eb, return 0; } -static int eb_reserve(struct i915_execbuffer *eb) +static bool eb_unbind(struct i915_execbuffer *eb, bool force) { const unsigned int count = eb->buffer_count; - unsigned int pin_flags = PIN_USER | PIN_NONBLOCK; + unsigned int i; struct list_head last; + bool unpinned = false; + + /* Resort *all* the objects into priority order */ + INIT_LIST_HEAD(&eb->unbound); + INIT_LIST_HEAD(&last); + + for (i = 0; i < count; i++) { + struct eb_vma *ev = &eb->vma[i]; + unsigned int flags = ev->flags; + + if (!force && flags & EXEC_OBJECT_PINNED && + flags & __EXEC_OBJECT_HAS_PIN) + continue; + + unpinned = true; + eb_unreserve_vma(ev); + + if (flags & EXEC_OBJECT_PINNED) + /* Pinned must have their slot */ + list_add(&ev->bind_link, &eb->unbound); + else if (flags & __EXEC_OBJECT_NEEDS_MAP) + /* Map require the lowest 256MiB (apert
[PATCH v4 6/7] drm/i915: Remove support for unlocked i915_vma unbind
Now that we require the object lock for all ops, some code handling race conditions can be removed. This is required to not take short-term pins inside execbuf. Signed-off-by: Maarten Lankhorst Acked-by: Niranjana Vishwanathapura --- drivers/gpu/drm/i915/i915_vma.c | 55 + 1 file changed, 8 insertions(+), 47 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 11e10e0d628c..8859feb7d131 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -777,7 +777,6 @@ i915_vma_detach(struct i915_vma *vma) static bool try_qad_pin(struct i915_vma *vma, unsigned int flags) { unsigned int bound; - bool pinned = true; bound = atomic_read(&vma->flags); do { @@ -787,34 +786,10 @@ static bool try_qad_pin(struct i915_vma *vma, unsigned int flags) if (unlikely(bound & (I915_VMA_OVERFLOW | I915_VMA_ERROR))) return false; - if (!(bound & I915_VMA_PIN_MASK)) - goto unpinned; - GEM_BUG_ON(((bound + 1) & I915_VMA_PIN_MASK) == 0); } while (!atomic_try_cmpxchg(&vma->flags, &bound, bound + 1)); return true; - -unpinned: - /* -* If pin_count==0, but we are bound, check under the lock to avoid -* racing with a concurrent i915_vma_unbind(). -*/ - mutex_lock(&vma->vm->mutex); - do { - if (unlikely(bound & (I915_VMA_OVERFLOW | I915_VMA_ERROR))) { - pinned = false; - break; - } - - if (unlikely(flags & ~bound)) { - pinned = false; - break; - } - } while (!atomic_try_cmpxchg(&vma->flags, &bound, bound + 1)); - mutex_unlock(&vma->vm->mutex); - - return pinned; } static struct scatterlist * @@ -1153,7 +1128,6 @@ static int __i915_vma_get_pages(struct i915_vma *vma) { struct sg_table *pages; - int ret; /* * The vma->pages are only valid within the lifespan of the borrowed @@ -1186,18 +1160,16 @@ __i915_vma_get_pages(struct i915_vma *vma) break; } - ret = 0; if (IS_ERR(pages)) { - ret = PTR_ERR(pages); - pages = NULL; drm_err(&vma->vm->i915->drm, - "Failed to get pages for VMA view type %u (%d)!\n", - vma->ggtt_view.type, ret); + "Failed to get pages for VMA view type %u (%ld)!\n", + vma->ggtt_view.type, PTR_ERR(pages)); + return PTR_ERR(pages); } vma->pages = pages; - return ret; + return 0; } I915_SELFTEST_EXPORT int i915_vma_get_pages(struct i915_vma *vma) @@ -1229,25 +1201,14 @@ I915_SELFTEST_EXPORT int i915_vma_get_pages(struct i915_vma *vma) static void __vma_put_pages(struct i915_vma *vma, unsigned int count) { /* We allocate under vma_get_pages, so beware the shrinker */ - struct sg_table *pages = READ_ONCE(vma->pages); - GEM_BUG_ON(atomic_read(&vma->pages_count) < count); if (atomic_sub_return(count, &vma->pages_count) == 0) { - /* -* The atomic_sub_return is a read barrier for the READ_ONCE of -* vma->pages above. -* -* READ_ONCE is safe because this is either called from the same -* function (i915_vma_pin_ww), or guarded by vma->vm->mutex. -* -* TODO: We're leaving vma->pages dangling, until vma->obj->resv -* lock is required. -*/ - if (pages != vma->obj->mm.pages) { - sg_free_table(pages); - kfree(pages); + if (vma->pages != vma->obj->mm.pages) { + sg_free_table(vma->pages); + kfree(vma->pages); } + vma->pages = NULL; i915_gem_object_unpin_pages(vma->obj); } -- 2.34.1
[PATCH v4 5/7] drm/i915: Remove assert_object_held_shared
This duck tape workaround is no longer required, unbind and destroy are fixed to take the obj->resv mutex before destroying and obj->mm.lock has been removed, always requiring obj->resv as well. Signed-off-by: Maarten Lankhorst Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/gem/i915_gem_object.c | 4 ++-- drivers/gpu/drm/i915/gem/i915_gem_object.h | 14 -- drivers/gpu/drm/i915/gem/i915_gem_pages.c | 10 +- drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 2 +- drivers/gpu/drm/i915/i915_vma.c | 6 +++--- 5 files changed, 11 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c index d87b508b59b1..fd34b1a115c4 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c @@ -550,7 +550,7 @@ bool i915_gem_object_has_struct_page(const struct drm_i915_gem_object *obj) #ifdef CONFIG_LOCKDEP if (IS_DGFX(to_i915(obj->base.dev)) && i915_gem_object_evictable((void __force *)obj)) - assert_object_held_shared(obj); + assert_object_held(obj); #endif return obj->mem_flags & I915_BO_FLAG_STRUCT_PAGE; } @@ -569,7 +569,7 @@ bool i915_gem_object_has_iomem(const struct drm_i915_gem_object *obj) #ifdef CONFIG_LOCKDEP if (IS_DGFX(to_i915(obj->base.dev)) && i915_gem_object_evictable((void __force *)obj)) - assert_object_held_shared(obj); + assert_object_held(obj); #endif return obj->mem_flags & I915_BO_FLAG_IOMEM; } diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index bc448f895ae8..c1cdfaf2d1e3 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -157,20 +157,6 @@ i915_gem_object_put(struct drm_i915_gem_object *obj) #define assert_object_held(obj) dma_resv_assert_held((obj)->base.resv) -/* - * If more than one potential simultaneous locker, assert held. - */ -static inline void assert_object_held_shared(const struct drm_i915_gem_object *obj) -{ - /* -* Note mm list lookup is protected by -* kref_get_unless_zero(). -*/ - if (IS_ENABLED(CONFIG_LOCKDEP) && - kref_read(&obj->base.refcount) > 0) - assert_object_held(obj); -} - static inline int __i915_gem_object_lock(struct drm_i915_gem_object *obj, struct i915_gem_ww_ctx *ww, bool intr) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c index 7d2211fbe548..a1a785068779 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c @@ -19,7 +19,7 @@ void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, bool shrinkable; int i; - assert_object_held_shared(obj); + assert_object_held(obj); if (i915_gem_object_is_volatile(obj)) obj->mm.madv = I915_MADV_DONTNEED; @@ -95,7 +95,7 @@ int i915_gem_object_get_pages(struct drm_i915_gem_object *obj) struct drm_i915_private *i915 = to_i915(obj->base.dev); int err; - assert_object_held_shared(obj); + assert_object_held(obj); if (unlikely(obj->mm.madv != I915_MADV_WILLNEED)) { drm_dbg(&i915->drm, @@ -122,7 +122,7 @@ int __i915_gem_object_get_pages(struct drm_i915_gem_object *obj) assert_object_held(obj); - assert_object_held_shared(obj); + assert_object_held(obj); if (unlikely(!i915_gem_object_has_pages(obj))) { GEM_BUG_ON(i915_gem_object_has_pinned_pages(obj)); @@ -191,7 +191,7 @@ __i915_gem_object_unset_pages(struct drm_i915_gem_object *obj) { struct sg_table *pages; - assert_object_held_shared(obj); + assert_object_held(obj); pages = fetch_and_zero(&obj->mm.pages); if (IS_ERR_OR_NULL(pages)) @@ -222,7 +222,7 @@ int __i915_gem_object_put_pages(struct drm_i915_gem_object *obj) return -EBUSY; /* May be called by shrinker from within get_pages() (on another bo) */ - assert_object_held_shared(obj); + assert_object_held(obj); i915_gem_object_release_mmap_offset(obj); diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c index 3cc01c30dd62..8a0da441225b 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c @@ -109,7 +109,7 @@ static void i915_gem_object_userptr_drop_ref(struct drm_i915_gem_object *obj) { struct page **pvec = NULL; - assert_object_held_shared(obj); + assert_object_held(obj); if (!--obj->userptr.page_ref) { pvec = obj->userptr.pvec; diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i
Re: [PATCH v6 4/6] drm/i915: Use vma resources for async unbinding
On 07/01/2022 14:23, Thomas Hellström wrote: Implement async (non-blocking) unbinding by not syncing the vma before calling unbind on the vma_resource. Add the resulting unbind fence to the object's dma_resv from where it is picked up by the ttm migration code. Ideally these unbind fences should be coalesced with the migration blit fence to avoid stalling the migration blit waiting for unbind, as they can certainly go on in parallel, but since we don't yet have a reasonable data structure to use to coalesce fences and attach the resulting fence to a timeline, we defer that for now. Note that with async unbinding, even while the unbind waits for the preceding bind to complete before unbinding, the vma itself might have been destroyed in the process, clearing the vma pages. Therefore we can only allow async unbinding if we have a refcounted sg-list and keep a refcount on that for the vma resource pages to stay intact until binding occurs. If this condition is not met, a request for an async unbind is diverted to a sync unbind. v2: - Use a separate kmem_cache for vma resources for now to isolate their memory allocation and aid debugging. - Move the check for vm closed to the actual unbinding thread. Regardless of whether the vm is closed, we need the unbind fence to properly wait for capture. - Clear vma_res::vm on unbind and update its documentation. v4: - Take cache coloring into account when searching for vma resources pending unbind. (Matthew Auld) v5: - Fix timeout and error check in i915_vma_resource_bind_dep_await(). - Avoid taking a reference on the object for async binding if async unbind capable. - Fix braces around a single-line if statement. v6: - Fix up the cache coloring adjustment. (Kernel test robot ) - Don't allow async unbinding if the vma_res pages are not the same as the object pages. Signed-off-by: Thomas Hellström --- drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c | 11 +- drivers/gpu/drm/i915/gt/intel_ggtt.c | 2 +- drivers/gpu/drm/i915/gt/intel_gtt.c | 4 + drivers/gpu/drm/i915/gt/intel_gtt.h | 3 + drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_gem.c | 12 +- drivers/gpu/drm/i915/i915_module.c | 3 + drivers/gpu/drm/i915/i915_vma.c | 205 +-- drivers/gpu/drm/i915/i915_vma.h | 3 +- drivers/gpu/drm/i915/i915_vma_resource.c | 354 +-- drivers/gpu/drm/i915/i915_vma_resource.h | 48 +++ 11 files changed, 579 insertions(+), 67 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c index 8653855d808b..1de306c03aaf 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c @@ -142,7 +142,16 @@ int i915_ttm_move_notify(struct ttm_buffer_object *bo) struct drm_i915_gem_object *obj = i915_ttm_to_gem(bo); int ret; - ret = i915_gem_object_unbind(obj, I915_GEM_OBJECT_UNBIND_ACTIVE); + /* +* Note: The async unbinding here will actually transform the +* blocking wait for unbind into a wait before finally submitting +* evict / migration blit and thus stall the migration timeline +* which may not be good for overall throughput. We should make +* sure we await the unbind fences *after* the migration blit +* instead of *before* as we currently do. +*/ + ret = i915_gem_object_unbind(obj, I915_GEM_OBJECT_UNBIND_ACTIVE | +I915_GEM_OBJECT_UNBIND_ASYNC); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c index e49b6250c4b7..a1b2761bc16e 100644 --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c @@ -142,7 +142,7 @@ void i915_ggtt_suspend_vm(struct i915_address_space *vm) continue; if (!i915_vma_is_bound(vma, I915_VMA_GLOBAL_BIND)) { - __i915_vma_evict(vma); + __i915_vma_evict(vma, false); drm_mm_remove_node(&vma->node); } } diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.c b/drivers/gpu/drm/i915/gt/intel_gtt.c index a94be0306464..46be4197b93f 100644 --- a/drivers/gpu/drm/i915/gt/intel_gtt.c +++ b/drivers/gpu/drm/i915/gt/intel_gtt.c @@ -161,6 +161,9 @@ static void __i915_vm_release(struct work_struct *work) struct i915_address_space *vm = container_of(work, struct i915_address_space, release_work); + /* Synchronize async unbinds. */ + i915_vma_resource_bind_dep_sync_all(vm); + vm->cleanup(vm); i915_address_space_fini(vm); @@ -189,6 +192,7 @@ void i915_address_space_init(struct i915_address_space *vm, int subclass) if (!kref_read(&vm->resv_ref)) kref_init(&vm->resv_ref); +
Re: [PATCH v6 5/6] drm/i915: Asynchronous migration selftest
On 07/01/2022 14:23, Thomas Hellström wrote: Add a selftest to exercise asynchronous migration and -unbining. Extend the gem_migrate selftest to perform the migrations while depending on a spinner and a bound vma set up on the migrated buffer object. Signed-off-by: Thomas Hellström --- drivers/gpu/drm/i915/gem/i915_gem_object.c| 12 ++ drivers/gpu/drm/i915/gem/i915_gem_object.h| 3 + .../drm/i915/gem/selftests/i915_gem_migrate.c | 192 -- 3 files changed, 192 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c index d87b508b59b1..1a9e1f940a7d 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c @@ -756,6 +756,18 @@ i915_gem_object_get_moving_fence(struct drm_i915_gem_object *obj) return dma_fence_get(i915_gem_to_ttm(obj)->moving); } +void i915_gem_object_set_moving_fence(struct drm_i915_gem_object *obj, + struct dma_fence *fence) +{ + struct dma_fence **moving = &i915_gem_to_ttm(obj)->moving; + + if (*moving == fence) + return; + + dma_fence_put(*moving); + *moving = dma_fence_get(fence); +} + /** * i915_gem_object_wait_moving_fence - Wait for the object's moving fence if any * @obj: The object whose moving fence to wait for. diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index f66d46882ea7..1d178236 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -524,6 +524,9 @@ i915_gem_object_finish_access(struct drm_i915_gem_object *obj) struct dma_fence * i915_gem_object_get_moving_fence(struct drm_i915_gem_object *obj); +void i915_gem_object_set_moving_fence(struct drm_i915_gem_object *obj, + struct dma_fence *fence); + int i915_gem_object_wait_moving_fence(struct drm_i915_gem_object *obj, bool intr); diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c index ecb691c81d1e..d534141b2cf7 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c @@ -4,8 +4,13 @@ */ #include "gt/intel_migrate.h" +#include "gt/intel_gpu_commands.h" #include "gem/i915_gem_ttm_move.h" +#include "i915_deps.h" + +#include "selftests/igt_spinner.h" + static int igt_fill_check_buffer(struct drm_i915_gem_object *obj, bool fill) { @@ -101,7 +106,8 @@ static int igt_same_create_migrate(void *arg) } static int lmem_pages_migrate_one(struct i915_gem_ww_ctx *ww, - struct drm_i915_gem_object *obj) + struct drm_i915_gem_object *obj, + struct i915_vma *vma) { int err; @@ -109,6 +115,24 @@ static int lmem_pages_migrate_one(struct i915_gem_ww_ctx *ww, if (err) return err; + if (vma) { + err = i915_vma_pin_ww(vma, ww, obj->base.size, 0, + 0UL | PIN_OFFSET_FIXED | + PIN_USER); + if (err) { + if (err != -EINTR && err != ERESTARTSYS && + err != -EDEADLK) + pr_err("Failed to pin vma.\n"); + return err; + } + + i915_vma_unpin(vma); + } + + /* +* Migration will implicitly unbind (asynchronously) any bound +* vmas. +*/ if (i915_gem_object_is_lmem(obj)) { err = i915_gem_object_migrate(obj, ww, INTEL_REGION_SMEM); if (err) { @@ -149,11 +173,15 @@ static int lmem_pages_migrate_one(struct i915_gem_ww_ctx *ww, return err; } -static int igt_lmem_pages_migrate(void *arg) +static int __igt_lmem_pages_migrate(struct intel_gt *gt, + struct i915_address_space *vm, + struct i915_deps *deps, + struct igt_spinner *spin, + struct dma_fence *spin_fence) { - struct intel_gt *gt = arg; struct drm_i915_private *i915 = gt->i915; struct drm_i915_gem_object *obj; + struct i915_vma *vma = NULL; struct i915_gem_ww_ctx ww; struct i915_request *rq; int err; @@ -165,6 +193,14 @@ static int igt_lmem_pages_migrate(void *arg) if (IS_ERR(obj)) return PTR_ERR(obj); + if (vm) { + vma = i915_vma_instance(obj, vm, NULL); + if (IS_ERR(vma)) { + err = PTR_ERR(vma); + goto out_put; + } +
Re: [v2 1/3] dt-bindings: msm/dsi: Add 10nm dsi phy tuning properties
On Mon, 10 Jan 2022 at 15:56, Rajeev Nandan wrote: > > In most cases, the default values of DSI PHY tuning registers should be > sufficient as they are fully optimized. However, in some cases where > extreme board parasitics cause the eye shape to degrade, the override > bits can be used to improve the signal quality. > > The general guidelines for DSI PHY tuning include: > - High and moderate data rates may benefit from the drive strength and > drive level tuning. > - Drive strength tuning will affect the output impedance and may be used > for matching optimization. > - Drive level tuning will affect the output levels without affecting the > impedance. > > The clock and data lanes have a calibration circuitry feature. The drive > strength tuning can be done by adjusting rescode offset for hstop/hsbot, > and the drive level tuning can be done by adjusting the LDO output level > for the HSTX drive. > > Signed-off-by: Rajeev Nandan > --- > > Changes in v2: > - More details in the commit text (Stephen Boyd) > - Use human understandable values (Stephen Boyd, Dmitry Baryshkov) > - Do not take values that are going to be unused (Dmitry Baryshkov) > > .../bindings/display/msm/dsi-phy-10nm.yaml | 33 > ++ > 1 file changed, 33 insertions(+) > > diff --git a/Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml > b/Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml > index 4399715..d0eb8f6 100644 > --- a/Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml > +++ b/Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml > @@ -35,6 +35,35 @@ properties: >Connected to DSI0_MIPI_DSI_PLL_VDDA0P9 pin for sc7180 target and >connected to VDDA_MIPI_DSI_0_PLL_0P9 pin for sdm845 target Generic note: I think these properties should be prefixed with "qcom," prefix. > > + phy-rescode-offset-top: > +$ref: /schemas/types.yaml#/definitions/uint8-array > +minItems: 5 > +maxItems: 5 > +description: > + Integer array of offset for pull-up legs rescode for all five lanes. > + To offset the drive strength from the calibrated value in an increasing > + or decreasing manner, use 6 bit two’s complement values. dtc should support negative values, google hints that <(-2)> should work. > + > + phy-rescode-offset-bot: > +$ref: /schemas/types.yaml#/definitions/uint8-array > +minItems: 5 > +maxItems: 5 > +description: > + Integer array of offset for pull-down legs rescode for all five lanes. > + To offset the drive strength from the calibrated value in an increasing > + or decreasing manner, use 6 bit two’s complement values. > + > + phy-drive-ldo-level: > +$ref: /schemas/types.yaml#/definitions/uint8 > +minimum: 0 > +maximum: 7 > +description: > + The PHY LDO has an amplitude tuning feature to adjust the LDO output > + for the HSTX drive. To offset the drive level from the default value, > + supported levels are with the following mapping: > + 0 = 375mV, 1 = 400mV, 2 = 425mV, 3 = 450mV, 4 = 475mV, 5 = 500mV, > + 6 = 500mV, 7 = 500mV No encoding please. Specify the values in the dts and convert them into the register values in the driver. > + > required: >- compatible >- reg > @@ -64,5 +93,9 @@ examples: > clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, ><&rpmhcc RPMH_CXO_CLK>; > clock-names = "iface", "ref"; > + > + phy-resocde-offset-top = /bits/ 8 <0x0 0x0 0x0 0x0 0x0>; > + phy-rescode-offset-bot = /bits/ 8 <0x0 0x0 0x0 0x0 0x0>; > + phy-drive-ldo-level = /bits/ 8 <1>; -- With best wishes Dmitry
Re: [v2 2/3] drm/msm/dsi: Add dsi phy tuning configuration support
On Mon, 10 Jan 2022 at 15:56, Rajeev Nandan wrote: > > Add support for MSM DSI PHY tuning configuration. Current design is > to support drive strength and drive level/amplitude tuning for > 10nm PHY version, but this can be extended to other PHY versions. > > Signed-off-by: Rajeev Nandan > --- > > Changes in v2: > - New. > - Split into generic code and 10nm-specific part (Dmitry Baryshkov) > > drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 3 +++ > drivers/gpu/drm/msm/dsi/phy/dsi_phy.h | 16 > 2 files changed, 19 insertions(+) > > diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c > b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c > index 8c65ef6..ee3739d 100644 > --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c > +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c > @@ -739,6 +739,9 @@ static int dsi_phy_driver_probe(struct platform_device > *pdev) > } > } > > + if (phy->cfg->ops.tuning_cfg_init) > + phy->cfg->ops.tuning_cfg_init(phy); Please rename to parse_dt_properties() or something like that. > + > ret = dsi_phy_regulator_init(phy); > if (ret) > goto fail; > diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h > b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h > index b91303a..b559a2b 100644 > --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h > +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h > @@ -25,6 +25,7 @@ struct msm_dsi_phy_ops { > void (*save_pll_state)(struct msm_dsi_phy *phy); > int (*restore_pll_state)(struct msm_dsi_phy *phy); > bool (*set_continuous_clock)(struct msm_dsi_phy *phy, bool enable); > + void (*tuning_cfg_init)(struct msm_dsi_phy *phy); > }; > > struct msm_dsi_phy_cfg { > @@ -81,6 +82,20 @@ struct msm_dsi_dphy_timing { > #define DSI_PIXEL_PLL_CLK 1 > #define NUM_PROVIDED_CLKS 2 > > +#define DSI_LANE_MAX 5 > + > +/** > + * struct msm_dsi_phy_tuning_cfg - Holds PHY tuning config parameters. > + * @rescode_offset_top: Offset for pull-up legs rescode. > + * @rescode_offset_bot: Offset for pull-down legs rescode. > + * @vreg_ctrl: vreg ctrl to drive LDO level > + */ > +struct msm_dsi_phy_tuning_cfg { > + u8 rescode_offset_top[DSI_LANE_MAX]; > + u8 rescode_offset_bot[DSI_LANE_MAX]; > + u8 vreg_ctrl; > +}; How generic is this? In other words, you are adding a struct with the generic name to the generic structure. I'd expect that it would be common to several PHY generations. > + > struct msm_dsi_phy { > struct platform_device *pdev; > void __iomem *base; > @@ -98,6 +113,7 @@ struct msm_dsi_phy { > > struct msm_dsi_dphy_timing timing; > const struct msm_dsi_phy_cfg *cfg; > + struct msm_dsi_phy_tuning_cfg tuning_cfg; > > enum msm_dsi_phy_usecase usecase; > bool regulator_ldo_mode; > -- > 2.7.4 > -- With best wishes Dmitry
Re: [PATCH 2/2] drm/panfrost: adjusted job affinity for dual core group GPUs
On 24/12/2021 08:56, Alexey Sheplyakov wrote: > Hi, > > On 23.12.2021 18:11, Alyssa Rosenzweig wrote: >>> The kernel driver itself can't guess which jobs need a such a strict >>> affinity, so setting proper requirements is the responsibility of >>> the userspace (Mesa). However the userspace is not smart enough [yet]. >>> Therefore this patch applies the above affinity rule to all jobs on >>> dual core group GPUs. >> >> What does Mesa need to do for this to work "properly"? > > I don't know. > The blob restricts affinity of jobs with JD_REQ_COHERENT_GROUP requirement. > In theory jobs without such a requirement can run on any core, but in > practice all jobs in slots 0, 1 are assigned to core group 0 (with workloads > I've run - i.e. weston, firefox, glmark2, perhaps it's also SoC dependent). > So I've forced all jobs in slots 0, 1 to core group 0. Surprisingly this > (and memory attributes adjustment) appeared to be enough to get panfrost > working with T628 (on some SoCs). Without these patches GPU locks up in > a few seconds. Let me fill in a few details here. The T628 is pretty unique in that it has two core groups, i.e. more than one L2 cache. Previous designs (i.e. T604) didn't have enough cores to require a second core group, and later designs with sufficient cores have coherent L2 caches so act as a single core group (although the hardware has multiple L2s it only reports a single one as they act as if a single cache). Note that technically the T608, T658 and T678 also exist and have this problem - but I don't believe any products were produced with these (so unless you're in ARM with a very unusual FPGA they can be ignored). The blob/kbase handle this situation with a new flag JD_REQ_COHERENT_GROUP which specifies that the affinity of a job must land on a single (coherent) core group, and JD_REQ_SPECIFIC_COHERENT_GROUP which allows user space to target a specific group. In theory fragment shading can be performed over all cores (because a fragment shader job doesn't need coherency between threads), so doesn't need the JD_REQ_COHERENT_GROUP flag, vertex shading however requires to be run on the same core group as the tiler (which always lives in core group 0). Of course there are various 'tricks' that can happen even within a fragment shader which might require coherency. So the expected sequence is that vertex+tiling is restricted to core group 0, and fragment shading can be run over all cores. Although there can be issues with performance doing this naïvely because the Job Manager doesn't necessarily share the GPUs cores fairly between vertex and fragment jobs. Also note that a cache flush is needed between running the vertex+tiling and the fragment job to ensure that the extra core group is coherent - this can be expensive, so it may not be worth using the second core group in some situations. I'm not sure what logic the Blob uses for that. Finally there's GPU compute (i.e. OpenCL): here coherency is usually required, but there's often more information about the amount of coherency needed. In this case it is possible to run different job chains on each core group. This is the only situation there slot 2 is used, and is the reason for the JS_REQ_SPECIFIC_COHERENT_GROUP flag. It's also a nightmare for scheduling as the hardware gets upset if the affinity masks for slot 1 and slot 2 overlap. >> What are the limitations of the approach implemented here? > > Suboptimal performance. > > 1) There might be job chains which don't care about affinity >(I haven't seen any of these yet on systems I've got). You are effectively throwing away half the cores if everything is pinned to core group 0, so I'm pretty sure the Blob manages to run (some) fragment jobs without the COHERENT_GROUP flag. But equally this is a reasonable first step for the kernel driver - we can make the GPU look like ever other GPU by pretending the second core group doesn't exist. > 2) There might be dual core group GPUs which don't need such a strict > affinity. >(I haven't seen any dual core group T[78]xx GPUs yet. This doesn't mean > such > GPUs don't exist). They should all be a single core group (fully coherent L2s). >> If we need to extend it down the line with a UABI change, what would that >> look like? > > I have no idea. And I'm not sure if it's worth the effort (since most jobs > end up on core group 0 anyway). Whether it's worth the effort depends on whether anyone really cares about getting the full performance out of this particular GPU. At this stage I think the main UABI change would be to add the opposite flag to kbase, (e.g. "PANFROST_JD_DOESNT_NEED_COHERENCY_ON_GPU"[1]) to opt-in to allowing the job to run across all cores. The second change would be to allow compute jobs to be run on the second core group, so another flag: PANFROST_RUN_ON_SECOND_CORE_GROUP. But clearly there's little point adding such flags until someone steps up to do the Mesa work. Steve [1] Bike-shedding the
Re: [Intel-gfx] [PATCH v6 6/6] drm/i915: Use struct vma_resource instead of struct vma_snapshot
On Fri, 7 Jan 2022 at 14:24, Thomas Hellström wrote: > > There is always a struct vma_resource guaranteed to be alive when we > access a corresponding struct vma_snapshot. > > So ditch the latter and instead of allocating vma_snapshots, reference > the already existning vma_resource. > > This requires a couple of extra members in struct vma_resource but that's > a small price to pay for the simplification. > > v2: > - Fix a missing include and declaration (kernel test robot ) > > Signed-off-by: Thomas Hellström Reviewed-by: Matthew Auld
Re: [PATCH v6 5/6] drm/i915: Asynchronous migration selftest
On 1/10/22 14:59, Matthew Auld wrote: On 07/01/2022 14:23, Thomas Hellström wrote: Add a selftest to exercise asynchronous migration and -unbining. Extend the gem_migrate selftest to perform the migrations while depending on a spinner and a bound vma set up on the migrated buffer object. Signed-off-by: Thomas Hellström --- drivers/gpu/drm/i915/gem/i915_gem_object.c | 12 ++ drivers/gpu/drm/i915/gem/i915_gem_object.h | 3 + .../drm/i915/gem/selftests/i915_gem_migrate.c | 192 -- 3 files changed, 192 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c index d87b508b59b1..1a9e1f940a7d 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c @@ -756,6 +756,18 @@ i915_gem_object_get_moving_fence(struct drm_i915_gem_object *obj) return dma_fence_get(i915_gem_to_ttm(obj)->moving); } +void i915_gem_object_set_moving_fence(struct drm_i915_gem_object *obj, + struct dma_fence *fence) +{ + struct dma_fence **moving = &i915_gem_to_ttm(obj)->moving; + + if (*moving == fence) + return; + + dma_fence_put(*moving); + *moving = dma_fence_get(fence); +} + /** * i915_gem_object_wait_moving_fence - Wait for the object's moving fence if any * @obj: The object whose moving fence to wait for. diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index f66d46882ea7..1d178236 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -524,6 +524,9 @@ i915_gem_object_finish_access(struct drm_i915_gem_object *obj) struct dma_fence * i915_gem_object_get_moving_fence(struct drm_i915_gem_object *obj); +void i915_gem_object_set_moving_fence(struct drm_i915_gem_object *obj, + struct dma_fence *fence); + int i915_gem_object_wait_moving_fence(struct drm_i915_gem_object *obj, bool intr); diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c index ecb691c81d1e..d534141b2cf7 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c @@ -4,8 +4,13 @@ */ #include "gt/intel_migrate.h" +#include "gt/intel_gpu_commands.h" #include "gem/i915_gem_ttm_move.h" +#include "i915_deps.h" + +#include "selftests/igt_spinner.h" + static int igt_fill_check_buffer(struct drm_i915_gem_object *obj, bool fill) { @@ -101,7 +106,8 @@ static int igt_same_create_migrate(void *arg) } static int lmem_pages_migrate_one(struct i915_gem_ww_ctx *ww, - struct drm_i915_gem_object *obj) + struct drm_i915_gem_object *obj, + struct i915_vma *vma) { int err; @@ -109,6 +115,24 @@ static int lmem_pages_migrate_one(struct i915_gem_ww_ctx *ww, if (err) return err; + if (vma) { + err = i915_vma_pin_ww(vma, ww, obj->base.size, 0, + 0UL | PIN_OFFSET_FIXED | + PIN_USER); + if (err) { + if (err != -EINTR && err != ERESTARTSYS && + err != -EDEADLK) + pr_err("Failed to pin vma.\n"); + return err; + } + + i915_vma_unpin(vma); + } + + /* + * Migration will implicitly unbind (asynchronously) any bound + * vmas. + */ if (i915_gem_object_is_lmem(obj)) { err = i915_gem_object_migrate(obj, ww, INTEL_REGION_SMEM); if (err) { @@ -149,11 +173,15 @@ static int lmem_pages_migrate_one(struct i915_gem_ww_ctx *ww, return err; } -static int igt_lmem_pages_migrate(void *arg) +static int __igt_lmem_pages_migrate(struct intel_gt *gt, + struct i915_address_space *vm, + struct i915_deps *deps, + struct igt_spinner *spin, + struct dma_fence *spin_fence) { - struct intel_gt *gt = arg; struct drm_i915_private *i915 = gt->i915; struct drm_i915_gem_object *obj; + struct i915_vma *vma = NULL; struct i915_gem_ww_ctx ww; struct i915_request *rq; int err; @@ -165,6 +193,14 @@ static int igt_lmem_pages_migrate(void *arg) if (IS_ERR(obj)) return PTR_ERR(obj); + if (vm) { + vma = i915_vma_instance(obj, vm, NULL); + if (IS_ERR(vma)) { + err = PTR_ERR(vma); + goto out_put; + } + } + /* Initial GPU fill, sync, CPU initialization. */ for_i915_gem_ww(&ww, err, true) { err = i915_gem_object_lock(obj, &ww); @@ -175,25 +211,23 @@ static int igt_lmem_pages_migrate(void *arg) if (err) continue; - err = intel_migrate_clear(>->migrate, &ww, NULL, + err = intel_migrate_clear(>->m
Re: [PATCH v6 5/6] drm/i915: Asynchronous migration selftest
On 10/01/2022 14:36, Thomas Hellström wrote: On 1/10/22 14:59, Matthew Auld wrote: On 07/01/2022 14:23, Thomas Hellström wrote: Add a selftest to exercise asynchronous migration and -unbining. Extend the gem_migrate selftest to perform the migrations while depending on a spinner and a bound vma set up on the migrated buffer object. Signed-off-by: Thomas Hellström --- drivers/gpu/drm/i915/gem/i915_gem_object.c | 12 ++ drivers/gpu/drm/i915/gem/i915_gem_object.h | 3 + .../drm/i915/gem/selftests/i915_gem_migrate.c | 192 -- 3 files changed, 192 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c index d87b508b59b1..1a9e1f940a7d 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c @@ -756,6 +756,18 @@ i915_gem_object_get_moving_fence(struct drm_i915_gem_object *obj) return dma_fence_get(i915_gem_to_ttm(obj)->moving); } +void i915_gem_object_set_moving_fence(struct drm_i915_gem_object *obj, + struct dma_fence *fence) +{ + struct dma_fence **moving = &i915_gem_to_ttm(obj)->moving; + + if (*moving == fence) + return; + + dma_fence_put(*moving); + *moving = dma_fence_get(fence); +} + /** * i915_gem_object_wait_moving_fence - Wait for the object's moving fence if any * @obj: The object whose moving fence to wait for. diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index f66d46882ea7..1d178236 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -524,6 +524,9 @@ i915_gem_object_finish_access(struct drm_i915_gem_object *obj) struct dma_fence * i915_gem_object_get_moving_fence(struct drm_i915_gem_object *obj); +void i915_gem_object_set_moving_fence(struct drm_i915_gem_object *obj, + struct dma_fence *fence); + int i915_gem_object_wait_moving_fence(struct drm_i915_gem_object *obj, bool intr); diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c index ecb691c81d1e..d534141b2cf7 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c @@ -4,8 +4,13 @@ */ #include "gt/intel_migrate.h" +#include "gt/intel_gpu_commands.h" #include "gem/i915_gem_ttm_move.h" +#include "i915_deps.h" + +#include "selftests/igt_spinner.h" + static int igt_fill_check_buffer(struct drm_i915_gem_object *obj, bool fill) { @@ -101,7 +106,8 @@ static int igt_same_create_migrate(void *arg) } static int lmem_pages_migrate_one(struct i915_gem_ww_ctx *ww, - struct drm_i915_gem_object *obj) + struct drm_i915_gem_object *obj, + struct i915_vma *vma) { int err; @@ -109,6 +115,24 @@ static int lmem_pages_migrate_one(struct i915_gem_ww_ctx *ww, if (err) return err; + if (vma) { + err = i915_vma_pin_ww(vma, ww, obj->base.size, 0, + 0UL | PIN_OFFSET_FIXED | + PIN_USER); + if (err) { + if (err != -EINTR && err != ERESTARTSYS && + err != -EDEADLK) + pr_err("Failed to pin vma.\n"); + return err; + } + + i915_vma_unpin(vma); + } + + /* + * Migration will implicitly unbind (asynchronously) any bound + * vmas. + */ if (i915_gem_object_is_lmem(obj)) { err = i915_gem_object_migrate(obj, ww, INTEL_REGION_SMEM); if (err) { @@ -149,11 +173,15 @@ static int lmem_pages_migrate_one(struct i915_gem_ww_ctx *ww, return err; } -static int igt_lmem_pages_migrate(void *arg) +static int __igt_lmem_pages_migrate(struct intel_gt *gt, + struct i915_address_space *vm, + struct i915_deps *deps, + struct igt_spinner *spin, + struct dma_fence *spin_fence) { - struct intel_gt *gt = arg; struct drm_i915_private *i915 = gt->i915; struct drm_i915_gem_object *obj; + struct i915_vma *vma = NULL; struct i915_gem_ww_ctx ww; struct i915_request *rq; int err; @@ -165,6 +193,14 @@ static int igt_lmem_pages_migrate(void *arg) if (IS_ERR(obj)) return PTR_ERR(obj); + if (vm) { + vma = i915_vma_instance(obj, vm, NULL); + if (IS_ERR(vma)) { + err = PTR_ERR(vma); + goto out_put; + } + } + /* Initial GPU fill, sync, CPU initialization. */ for_i915_gem_ww(&ww, err, true) { err = i915_gem_object_lock(obj, &ww); @@ -175,25 +211,23 @@ static int igt_lmem_pages_migrate(void *arg) if (err) continue; - err = intel_migrate_clear(>->migrate, &ww,
Re: [PATCH v6 4/6] drm/i915: Use vma resources for async unbinding
On 1/10/22 14:21, Matthew Auld wrote: On 07/01/2022 14:23, Thomas Hellström wrote: Implement async (non-blocking) unbinding by not syncing the vma before calling unbind on the vma_resource. Add the resulting unbind fence to the object's dma_resv from where it is picked up by the ttm migration code. Ideally these unbind fences should be coalesced with the migration blit fence to avoid stalling the migration blit waiting for unbind, as they can certainly go on in parallel, but since we don't yet have a reasonable data structure to use to coalesce fences and attach the resulting fence to a timeline, we defer that for now. Note that with async unbinding, even while the unbind waits for the preceding bind to complete before unbinding, the vma itself might have been destroyed in the process, clearing the vma pages. Therefore we can only allow async unbinding if we have a refcounted sg-list and keep a refcount on that for the vma resource pages to stay intact until binding occurs. If this condition is not met, a request for an async unbind is diverted to a sync unbind. v2: - Use a separate kmem_cache for vma resources for now to isolate their memory allocation and aid debugging. - Move the check for vm closed to the actual unbinding thread. Regardless of whether the vm is closed, we need the unbind fence to properly wait for capture. - Clear vma_res::vm on unbind and update its documentation. v4: - Take cache coloring into account when searching for vma resources pending unbind. (Matthew Auld) v5: - Fix timeout and error check in i915_vma_resource_bind_dep_await(). - Avoid taking a reference on the object for async binding if async unbind capable. - Fix braces around a single-line if statement. v6: - Fix up the cache coloring adjustment. (Kernel test robot ) - Don't allow async unbinding if the vma_res pages are not the same as the object pages. Signed-off-by: Thomas Hellström --- drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c | 11 +- drivers/gpu/drm/i915/gt/intel_ggtt.c | 2 +- drivers/gpu/drm/i915/gt/intel_gtt.c | 4 + drivers/gpu/drm/i915/gt/intel_gtt.h | 3 + drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_gem.c | 12 +- drivers/gpu/drm/i915/i915_module.c | 3 + drivers/gpu/drm/i915/i915_vma.c | 205 +-- drivers/gpu/drm/i915/i915_vma.h | 3 +- drivers/gpu/drm/i915/i915_vma_resource.c | 354 +-- drivers/gpu/drm/i915/i915_vma_resource.h | 48 +++ 11 files changed, 579 insertions(+), 67 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c index 8653855d808b..1de306c03aaf 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c @@ -142,7 +142,16 @@ int i915_ttm_move_notify(struct ttm_buffer_object *bo) struct drm_i915_gem_object *obj = i915_ttm_to_gem(bo); int ret; - ret = i915_gem_object_unbind(obj, I915_GEM_OBJECT_UNBIND_ACTIVE); + /* + * Note: The async unbinding here will actually transform the + * blocking wait for unbind into a wait before finally submitting + * evict / migration blit and thus stall the migration timeline + * which may not be good for overall throughput. We should make + * sure we await the unbind fences *after* the migration blit + * instead of *before* as we currently do. + */ + ret = i915_gem_object_unbind(obj, I915_GEM_OBJECT_UNBIND_ACTIVE | + I915_GEM_OBJECT_UNBIND_ASYNC); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c index e49b6250c4b7..a1b2761bc16e 100644 --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c @@ -142,7 +142,7 @@ void i915_ggtt_suspend_vm(struct i915_address_space *vm) continue; if (!i915_vma_is_bound(vma, I915_VMA_GLOBAL_BIND)) { - __i915_vma_evict(vma); + __i915_vma_evict(vma, false); drm_mm_remove_node(&vma->node); } } diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.c b/drivers/gpu/drm/i915/gt/intel_gtt.c index a94be0306464..46be4197b93f 100644 --- a/drivers/gpu/drm/i915/gt/intel_gtt.c +++ b/drivers/gpu/drm/i915/gt/intel_gtt.c @@ -161,6 +161,9 @@ static void __i915_vm_release(struct work_struct *work) struct i915_address_space *vm = container_of(work, struct i915_address_space, release_work); + /* Synchronize async unbinds. */ + i915_vma_resource_bind_dep_sync_all(vm); + vm->cleanup(vm); i915_address_space_fini(vm); @@ -189,6 +192,7 @@ void i915_address_space_init(struct i915_address_space *vm, int subclass) if (!kref_read(&vm->resv_ref)) kref_init(&vm->resv_ref); + vm->pending_unbind = RB_ROOT_CACHED; INIT_WORK(&vm->rele
Re: [PATCH 1/2] drm: exynos: dsi: Convert to bridge driver
Hey Jagan, This is a mistake on my end, I must have been looking at reviewing this series and then accidentally included it with another batch of patches. Thank you for catching this. I would suggest reverting these two patches[1][2]. Is that ok with you? [1] https://cgit.freedesktop.org/drm/drm-misc/commit/?id=92e794fab87af0793403d5e4a547f0be94a0e656 [2] https://cgit.freedesktop.org/drm/drm-misc/commit/?id=aee039e66035b66f0c587cc1b0dd32fb04c9a892 On Mon, 10 Jan 2022 at 12:17, Jagan Teki wrote: > > Hi Robert, > > On Mon, Nov 22, 2021 at 9:34 PM Marek Szyprowski > wrote: > > > > On 22.11.2021 16:07, Marek Szyprowski wrote: > > > On 22.11.2021 15:55, Jagan Teki wrote: > > >> On Mon, Nov 22, 2021 at 7:59 PM Jagan Teki > > >> wrote: > > >>> On Mon, Nov 22, 2021 at 7:51 PM Jagan Teki > > >>> wrote: > > On Mon, Nov 22, 2021 at 7:45 PM Marek Szyprowski > > wrote: > > > On 22.11.2021 08:06, Jagan Teki wrote: > > >> Some display panels would come up with a non-DSI output, those > > >> can have an option to connect the DSI host by means of interface > > >> bridge converter. > > >> > > >> This DSI to non-DSI interface bridge converter would requires > > >> DSI Host to handle drm bridge functionalities in order to DSI > > >> Host to Interface bridge. > > >> > > >> This patch convert the existing to a drm bridge driver with a > > >> built-in encoder support for compatibility with existing > > >> component drivers. > > >> > > >> Signed-off-by: Jagan Teki > > >> --- > > >> Note: > > >> Hi Marek Szyprowski, > > >> > > >> Please test this on Panel and Bridge hardware. > > > I don't have good news, t crashes: > > > > > > [drm] Exynos DRM: using 1380.decon device for DMA mapping > > > operations > > > exynos-drm exynos-drm: bound 1380.decon (ops decon_component_ops) > > > exynos-drm exynos-drm: bound 1388.decon (ops decon_component_ops) > > > exynos-drm exynos-drm: bound 1393.mic (ops > > > exynos_mic_component_ops) > > > [drm:drm_bridge_attach] *ERROR* failed to attach bridge > > > /soc@0/dsi@1390 to encoder TMDS-67: -22 > > > exynos-drm exynos-drm: failed to bind 1390.dsi (ops > > > exynos_dsi_component_ops): -22 > > > Internal error: synchronous external abort: 96000210 [#1] PREEMPT SMP > > > Modules linked in: > > > CPU: 2 PID: 74 Comm: kworker/u16:1 Not tainted 5.16.0-rc1+ #4141 > > > Hardware name: Samsung TM2E board (DT) > > > Workqueue: events_unbound deferred_probe_work_func > > > pstate: 8005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) > > > pc : decon_atomic_disable+0x58/0xd4 > > > lr : decon_atomic_disable+0x28/0xd4 > > > sp : 80001390b940 > > > x29: 80001390b940 x28: 80001259a000 x27: 27f39e80 > > > input: stmfts as > > > /devices/platform/soc@0/14ed.hsi2c/i2c-3/3-0049/input/input0 > > > x26: ffea x25: 25a40280 x24: 0001 > > > x23: 800011b55f98 x22: 315dc000 x21: 2695d100 > > > x20: 27e7a080 x19: 315e6000 x18: > > > x17: 645f736f6e797865 x16: 2073706f28206973 x15: 00028ee0 > > > x14: 0028 x13: 0001 x12: 0040 > > > x11: 23c18920 x10: 23c18922 x9 : 8000126352f0 > > > x8 : 23c00270 x7 : x6 : 23c00268 > > > x5 : 27e7a3a0 x4 : 0001 x3 : 27e7a080 > > > x2 : 0024 x1 : 800013bc8024 x0 : 246117c0 > > > Call trace: > > >decon_atomic_disable+0x58/0xd4 > > >decon_unbind+0x1c/0x3c > > >component_unbind+0x38/0x60 > > >component_bind_all+0x16c/0x25c > > >exynos_drm_bind+0x104/0x1bc > > >try_to_bring_up_master+0x164/0x1d0 > > >__component_add+0xa8/0x174 > > >component_add+0x14/0x20 > > >hdmi_probe+0x438/0x710 > > >platform_probe+0x68/0xe0 > > >really_probe.part.0+0x9c/0x31c > > >__driver_probe_device+0x98/0x144 > > >driver_probe_device+0xc8/0x160 > > >__device_attach_driver+0xb8/0x120 > > >bus_for_each_drv+0x78/0xd0 > > >__device_attach+0xd8/0x180 > > >device_initial_probe+0x14/0x20 > > >bus_probe_device+0x9c/0xa4 > > >deferred_probe_work_func+0x88/0xc4 > > >process_one_work+0x288/0x6f0 > > >worker_thread+0x74/0x470 > > >kthread+0x188/0x194 > > >ret_from_fork+0x10/0x20 > > > Code: 11002042 f9481c61 531e7442 8b020021 (88dffc21) > > > ---[ end trace d73aff585b108954 ]--- > > > Kernel panic - not syncing: synchronous external abort: Fatal > > > exception > > > SMP: stopping secondary CPUs > > > Kernel Offset: disabled > > > CPU features: 0x2,300071c2,0846 > > > Memory Limit: none > > > ---[ end Ke
Re: [PATCH 1/2] drm: exynos: dsi: Convert to bridge driver
Hi Robert, On Mon, Jan 10, 2022 at 9:02 PM Robert Foss wrote: > > Hey Jagan, > > This is a mistake on my end, I must have been looking at reviewing > this series and then accidentally included it with another batch of > patches. Thank you for catching this. Thanks for the response. > > I would suggest reverting these two patches[1][2]. Is that ok with you? May be I will revert 1/2. but 2/2 is valid. Please let me know, if you have any concerns on reverting 1/2. Thanks, Jagan.
Re: [git pull] drm final fixes for 5.16
On Fri, Jan 7, 2022 at 6:42 PM Linus Torvalds wrote: > > On Thu, Jan 6, 2022 at 7:23 PM Dave Airlie wrote: > > > > There is only the amdgpu runtime pm regression fix in here. > > Thanks, from a quick test it works for me - the backlight actually > does eventually go away. > > It does so only on the second time the monitors say "no signal, going > to power save", but that has been true before too. > > So I think there's still some confusion in this area, but it might be > elsewhere - who knows what Wayland and friends do. At least it doesn't > look like a regression to me any more. Well it's not a true fix, just a "go back to exact old behaviour, but limited to relevant gpus for amdgpu only" so that i915 doesn't regress. I think there's some more debug to do here and Alex/Harry&team can look at leisure now :-) Cheers, Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch
Re: [PATCH 1/2] drm: exynos: dsi: Convert to bridge driver
On Mon, 10 Jan 2022 at 16:35, Jagan Teki wrote: > > Hi Robert, > > On Mon, Jan 10, 2022 at 9:02 PM Robert Foss wrote: > > > > Hey Jagan, > > > > This is a mistake on my end, I must have been looking at reviewing > > this series and then accidentally included it with another batch of > > patches. Thank you for catching this. > > Thanks for the response. > > > > > I would suggest reverting these two patches[1][2]. Is that ok with you? > > May be I will revert 1/2. but 2/2 is valid. Please let me know, if you > have any concerns on reverting 1/2. Please go ahead!
Re: [PATCH 3/3] drm/atomic: Make private objs proper objects
On Fri, Dec 31, 2021 at 03:23:31PM +0200, Jani Nikula wrote: > On Wed, 12 Jul 2017, ville.syrj...@linux.intel.com wrote: > > From: Ville Syrjälä > > > > Make the atomic private object stuff less special by introducing proper > > base classes for the object and its state. Drivers can embed these in > > their own appropriate objects, after which these things will work > > exactly like the plane/crtc/connector states during atomic operations. > > > > v2: Reorder to not depend on drm_dynarray (Daniel) > > > > Cc: Dhinakaran Pandiyan > > Cc: Daniel Vetter > > Reviewed-by: Daniel Vetter #v1 > > Signed-off-by: Ville Syrjälä > > Stumbled upon an old commit > > commit a4370c777406c2810e37fafd166ccddecdb2a60c > Author: Ville Syrjälä > Date: Wed Jul 12 18:51:02 2017 +0300 > > drm/atomic: Make private objs proper objects > > which is this patch. > > > @@ -3050,8 +3043,7 @@ struct drm_dp_mst_topology_state > > *drm_atomic_get_mst_topology_state(struct drm_a > > struct drm_device *dev = mgr->dev; > > > > WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); > > - return drm_atomic_get_private_obj_state(state, mgr, > > - &mst_state_funcs); > > + return to_dp_mst_topology_state(drm_atomic_get_private_obj_state(state, > > &mgr->base)); > > } > > EXPORT_SYMBOL(drm_atomic_get_mst_topology_state); > > I don't think this combines well with... > > > diff --git a/include/drm/drm_dp_mst_helper.h > > b/include/drm/drm_dp_mst_helper.h > > index 177ab6f86855..d55abb75f29a 100644 > > --- a/include/drm/drm_dp_mst_helper.h > > +++ b/include/drm/drm_dp_mst_helper.h > > @@ -404,12 +404,17 @@ struct drm_dp_payload { > > int vcpi; > > }; > > > > +#define to_dp_mst_topology_state(x) container_of(x, struct > > drm_dp_mst_topology_state, base) > > ...this in case of error pointers that > drm_atomic_get_private_obj_state() may return. offsetof(base)==0 so should work in practice. -- Ville Syrjälä Intel
Re: [Intel-gfx] [PATCH 1/2] drm/dp: note that DPCD 0x2002-0x2003 match 0x200-0x201
On Tue, Jan 04, 2022 at 08:48:56PM +0200, Jani Nikula wrote: > DP_SINK_COUNT_ESI and DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 have the same > contents as DP_SINK_COUNT and DP_DEVICE_SERVICE_IRQ_VECTOR, > respectively. IIRC there was an oversight in the earlier spec revisions that showed bit 7 as reserved for one of the locations. But looks like that got fixed. Reviewed-by: Ville Syrjälä > > Signed-off-by: Jani Nikula > --- > include/drm/drm_dp_helper.h | 7 ++- > 1 file changed, 2 insertions(+), 5 deletions(-) > > diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h > index 30359e434c3f..98d020835b49 100644 > --- a/include/drm/drm_dp_helper.h > +++ b/include/drm/drm_dp_helper.h > @@ -1038,11 +1038,8 @@ struct drm_panel; > #define DP_SIDEBAND_MSG_UP_REQ_BASE 0x1600 /* 1.2 MST */ > > /* DPRX Event Status Indicator */ > -#define DP_SINK_COUNT_ESI0x2002 /* 1.2 */ > -/* 0-5 sink count */ > -# define DP_SINK_COUNT_CP_READY (1 << 6) > - > -#define DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 0x2003 /* 1.2 */ > +#define DP_SINK_COUNT_ESI 0x2002 /* same as 0x200 */ > +#define DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 0x2003 /* same as 0x201 */ > > #define DP_DEVICE_SERVICE_IRQ_VECTOR_ESI1 0x2004 /* 1.2 */ > # define DP_RX_GTC_MSTR_REQ_STATUS_CHANGE(1 << 0) > -- > 2.30.2 -- Ville Syrjälä Intel
Re: [Intel-gfx] [PATCH 2/2] drm/mst: use DP_GET_SINK_COUNT() for sink count in ESI
On Tue, Jan 04, 2022 at 08:48:57PM +0200, Jani Nikula wrote: > Take bit 7 into account when reading sink count from > DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0. > > Signed-off-by: Jani Nikula > --- > drivers/gpu/drm/drm_dp_mst_topology.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c > b/drivers/gpu/drm/drm_dp_mst_topology.c > index f3d79eda94bb..ab4372e9fe43 100644 > --- a/drivers/gpu/drm/drm_dp_mst_topology.c > +++ b/drivers/gpu/drm/drm_dp_mst_topology.c > @@ -4196,7 +4196,7 @@ int drm_dp_mst_hpd_irq(struct drm_dp_mst_topology_mgr > *mgr, u8 *esi, bool *handl > int ret = 0; > int sc; > *handled = false; > - sc = esi[0] & 0x3f; > + sc = DP_GET_SINK_COUNT(esi[0]); I wouldn't mind a s/sc/sink_count/ as well. Reviewed-by: Ville Syrjälä > > if (sc != mgr->sink_count) { > mgr->sink_count = sc; > -- > 2.30.2 -- Ville Syrjälä Intel
Re: [PATCH] drm/amd/display: invalid parameter check in dmub_hpd_callback
On 2022-01-09 13:42, José Expósito wrote: > The function performs a check on the "adev" input parameter, however, it > is used before the check. > > Initialize the "dev" variable after the sanity check to avoid a possible > NULL pointer dereference. > > Fixes: e27c41d5b0681 ("drm/amd/display: Support for DMUB HPD interrupt > handling") > Addresses-Coverity-ID: 1493909 ("Null pointer dereference") > Signed-off-by: José Expósito Reviewed-by: Harry Wentland Harry > --- > drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > 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 e727f1dd2a9a..7fbded7a6d9c 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > @@ -656,7 +656,7 @@ void dmub_hpd_callback(struct amdgpu_device *adev, struct > dmub_notification *not > struct drm_connector_list_iter iter; > struct dc_link *link; > uint8_t link_index = 0; > - struct drm_device *dev = adev->dm.ddev; > + struct drm_device *dev; > > if (adev == NULL) > return; > @@ -673,6 +673,7 @@ void dmub_hpd_callback(struct amdgpu_device *adev, struct > dmub_notification *not > > link_index = notify->link_index; > link = adev->dm.dc->links[link_index]; > + dev = adev->dm.ddev; > > drm_connector_list_iter_begin(dev, &iter); > drm_for_each_connector_iter(connector, &iter) {
Re: [PATCH] drm/panfrost: Update create_bo flags comment
On 09/01/2022 16:37, Alyssa Rosenzweig wrote: > Update a comment stating create_bo took no flags, since it now takes a > bit mask of optional flags NOEXEC and HEAP. > > Signed-off-by: Alyssa Rosenzweig Reviewed-by: Steven Price I'll push this to drm-misc-next. Thanks, Steve > --- > include/uapi/drm/panfrost_drm.h | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/include/uapi/drm/panfrost_drm.h b/include/uapi/drm/panfrost_drm.h > index 061e700dd06c..9e40277d8185 100644 > --- a/include/uapi/drm/panfrost_drm.h > +++ b/include/uapi/drm/panfrost_drm.h > @@ -84,14 +84,14 @@ struct drm_panfrost_wait_bo { > __s64 timeout_ns; /* absolute */ > }; > > +/* Valid flags to pass to drm_panfrost_create_bo */ > #define PANFROST_BO_NOEXEC 1 > #define PANFROST_BO_HEAP 2 > > /** > * struct drm_panfrost_create_bo - ioctl argument for creating Panfrost BOs. > * > - * There are currently no values for the flags argument, but it may be > - * used in a future extension. > + * The flags argument is a bit mask of PANFROST_BO_* flags. > */ > struct drm_panfrost_create_bo { > __u32 size; >
Re: [git pull] drm fixes for 5.16-rc3
On Sun, Jan 9, 2022 at 11:38 PM Geert Uytterhoeven wrote: > > The commit that merged this branch made a seemingly innocent change to > the top Makefile: "Seemingly" innocent? Or something darker and more sinister, related to the unrelenting slaughter of flightless fowl? You be the judge. Linus
Re: [v2 1/3] dt-bindings: msm/dsi: Add 10nm dsi phy tuning properties
On Mon, 10 Jan 2022 18:25:35 +0530, Rajeev Nandan wrote: > In most cases, the default values of DSI PHY tuning registers should be > sufficient as they are fully optimized. However, in some cases where > extreme board parasitics cause the eye shape to degrade, the override > bits can be used to improve the signal quality. > > The general guidelines for DSI PHY tuning include: > - High and moderate data rates may benefit from the drive strength and > drive level tuning. > - Drive strength tuning will affect the output impedance and may be used > for matching optimization. > - Drive level tuning will affect the output levels without affecting the > impedance. > > The clock and data lanes have a calibration circuitry feature. The drive > strength tuning can be done by adjusting rescode offset for hstop/hsbot, > and the drive level tuning can be done by adjusting the LDO output level > for the HSTX drive. > > Signed-off-by: Rajeev Nandan > --- > > Changes in v2: > - More details in the commit text (Stephen Boyd) > - Use human understandable values (Stephen Boyd, Dmitry Baryshkov) > - Do not take values that are going to be unused (Dmitry Baryshkov) > > .../bindings/display/msm/dsi-phy-10nm.yaml | 33 > ++ > 1 file changed, 33 insertions(+) > My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check' on your patch (DT_CHECKER_FLAGS is new in v5.13): yamllint warnings/errors: ./Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml:63:54: [error] syntax error: mapping values are not allowed here (syntax) dtschema/dtc warnings/errors: ./Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml: mapping values are not allowed in this context in "", line 63, column 54 make[1]: *** Deleting file 'Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.example.dts' Traceback (most recent call last): File "/usr/local/bin/dt-extract-example", line 46, in binding = yaml.load(open(args.yamlfile, encoding='utf-8').read()) File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/main.py", line 434, in load return constructor.get_single_data() File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/constructor.py", line 119, in get_single_data node = self.composer.get_single_node() File "_ruamel_yaml.pyx", line 706, in _ruamel_yaml.CParser.get_single_node File "_ruamel_yaml.pyx", line 724, in _ruamel_yaml.CParser._compose_document File "_ruamel_yaml.pyx", line 775, in _ruamel_yaml.CParser._compose_node File "_ruamel_yaml.pyx", line 889, in _ruamel_yaml.CParser._compose_mapping_node File "_ruamel_yaml.pyx", line 775, in _ruamel_yaml.CParser._compose_node File "_ruamel_yaml.pyx", line 889, in _ruamel_yaml.CParser._compose_mapping_node File "_ruamel_yaml.pyx", line 775, in _ruamel_yaml.CParser._compose_node File "_ruamel_yaml.pyx", line 891, in _ruamel_yaml.CParser._compose_mapping_node File "_ruamel_yaml.pyx", line 904, in _ruamel_yaml.CParser._parse_next_event ruamel.yaml.scanner.ScannerError: mapping values are not allowed in this context in "", line 63, column 54 make[1]: *** [Documentation/devicetree/bindings/Makefile:25: Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.example.dts] Error 1 make[1]: *** Waiting for unfinished jobs /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml: ignoring, error parsing file make: *** [Makefile:1413: dt_binding_check] Error 2 doc reference errors (make refcheckdocs): See https://patchwork.ozlabs.org/patch/1577891 This check can fail if there are any dependencies. The base for a patch series is generally the most recent rc1. If you already ran 'make dt_binding_check' and didn't see the above error(s), then make sure 'yamllint' is installed and dt-schema is up to date: pip3 install dtschema --upgrade Please check and re-submit.
Re: [RFC PATCH] drm/panfrost: Handle IDVS_GROUP_SIZE feature
On 09/01/2022 17:12, Alyssa Rosenzweig wrote: > The IDVS group size feature was missing. It is used on some Bifrost and > Valhall GPUs, and is the last kernel-relevant Bifrost feature we're > missing. > > This feature adds an extra IDVS group size field to the JM_CONFIG > register. In kbase, the value is configurable via the device tree; kbase > uses 0xF as a default if no value is specified. Until we find a device > demanding otherwise, let's always set the 0xF default on devices which > support this feature mimicking kbase's behaviour. This is a performance thing - so I don't think it will break anything if this is wrong, it just won't be optimal. > As JM_CONFIG is an undocumented register, it's not clear to me what > happens if we fail to include this handling. Index-driven vertex shading > already works on Bifrost boards with this feature without this handling. > Perhaps this has performance implications? Patch untested for the > moment, wanted to give Steven a chance to comment. As it's a performance thing you shouldn't see correctness issues with not setting it. But 0xF seems to have been chosen as it gave the best overall performance (although for individual test content this can vary). AFAICT the performance impact isn't massive either. > Applies on top of my feature clean up series which should go in first. > (That's pure cleaunp, this is a behaviour change RFC needing > discussion.) > > Signed-off-by: Alyssa Rosenzweig Reviewed-by: Steven Price Since you've tagged this RFC I won't merge it now, but it looks correct to me. Thanks, Steve > --- > drivers/gpu/drm/panfrost/panfrost_features.h | 3 +++ > drivers/gpu/drm/panfrost/panfrost_gpu.c | 3 +++ > drivers/gpu/drm/panfrost/panfrost_regs.h | 1 + > 3 files changed, 7 insertions(+) > > diff --git a/drivers/gpu/drm/panfrost/panfrost_features.h > b/drivers/gpu/drm/panfrost/panfrost_features.h > index 34f2bae1ec8c..36fadcf9634e 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_features.h > +++ b/drivers/gpu/drm/panfrost/panfrost_features.h > @@ -20,6 +20,7 @@ enum panfrost_hw_feature { > HW_FEATURE_AARCH64_MMU, > HW_FEATURE_TLS_HASHING, > HW_FEATURE_THREAD_GROUP_SPLIT, > + HW_FEATURE_IDVS_GROUP_SIZE, > HW_FEATURE_3BIT_EXT_RW_L2_MMU_CONFIG, > }; > > @@ -74,6 +75,7 @@ enum panfrost_hw_feature { > BIT_ULL(HW_FEATURE_FLUSH_REDUCTION) | \ > BIT_ULL(HW_FEATURE_PROTECTED_MODE) | \ > BIT_ULL(HW_FEATURE_PROTECTED_DEBUG_MODE) | \ > + BIT_ULL(HW_FEATURE_IDVS_GROUP_SIZE) | \ > BIT_ULL(HW_FEATURE_COHERENCY_REG)) > > #define hw_features_g76 (\ > @@ -87,6 +89,7 @@ enum panfrost_hw_feature { > BIT_ULL(HW_FEATURE_COHERENCY_REG) | \ > BIT_ULL(HW_FEATURE_AARCH64_MMU) | \ > BIT_ULL(HW_FEATURE_TLS_HASHING) | \ > + BIT_ULL(HW_FEATURE_IDVS_GROUP_SIZE) | \ > BIT_ULL(HW_FEATURE_3BIT_EXT_RW_L2_MMU_CONFIG)) > > #define hw_features_g31 (\ > diff --git a/drivers/gpu/drm/panfrost/panfrost_gpu.c > b/drivers/gpu/drm/panfrost/panfrost_gpu.c > index bbe628b306ee..50c8922694d7 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_gpu.c > +++ b/drivers/gpu/drm/panfrost/panfrost_gpu.c > @@ -145,6 +145,9 @@ static void panfrost_gpu_init_quirks(struct > panfrost_device *pfdev) > quirks |= (COHERENCY_ACE_LITE | COHERENCY_ACE) << > JM_FORCE_COHERENCY_FEATURES_SHIFT; > > + if (panfrost_has_hw_feature(pfdev, HW_FEATURE_IDVS_GROUP_SIZE)) > + quirks |= JM_DEFAULT_IDVS_GROUP_SIZE << > JM_IDVS_GROUP_SIZE_SHIFT; > + > if (quirks) > gpu_write(pfdev, GPU_JM_CONFIG, quirks); > > diff --git a/drivers/gpu/drm/panfrost/panfrost_regs.h > b/drivers/gpu/drm/panfrost/panfrost_regs.h > index 6c5a11ef1ee8..16e776cc82ea 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_regs.h > +++ b/drivers/gpu/drm/panfrost/panfrost_regs.h > @@ -208,6 +208,7 @@ > #define JM_MAX_JOB_THROTTLE_LIMIT0x3F > #define JM_FORCE_COHERENCY_FEATURES_SHIFT 2 > #define JM_IDVS_GROUP_SIZE_SHIFT 16 > +#define JM_DEFAULT_IDVS_GROUP_SIZE 0xF > #define JM_MAX_IDVS_GROUP_SIZE 0x3F > > >
[PATCH v7 0/6] drm/i915: Asynchronous vma unbinding
This patch series introduces infrastructure for asynchronous vma unbinding. The single enabled use-case is initially at buffer object migration where we otherwise sync when unbinding vmas before migration. This in theory allows us to pipeline any number of migrations, but in practice the number is restricted by a sync wait when filling the migration context ring. We might want to look at that moving forward if needed. The other main use-case is to be able to pipeline vma evictions, for example with softpinning where a new vma wants to reuse the vm range of an already active vma. We can't support this just yet because we need dma_resv locking around vma eviction for that, which is under implementation. Patch 1 introduces vma resource first for error capture purposes Patch 2 changes the vm backend interface to take vma resources rather than vmas Patch 3 removes and unneeded page pinning Patch 4 introduces the async unbinding itself, and finally Patch 5 introduces a selftest Patch 6 realizes we have duplicated functionality and removes the vma snapshots v2: -- Some kernel test robot reports addressed. -- kmem cache for vma resources, See patch 4 -- Various fixes all over the place. See separate commit messages. v3: -- Re-add a missing i915_vma_resource_put() -- Remove a stray debug printout v4: -- Patch series split in two. This is the second part. -- Take cache coloring into account when searching for vma_resources pending unbind. (Matthew Auld) v5: -- Add a selftest. -- Remove page pinning while sync binding. -- A couple of fixes in i915_vma_resource_bind_dep_await() v6: -- Some documentation updates -- Remove I915_VMA_ALLOC_BIT (Matthew Auld) -- Change some members of struct i915_vma_resource from unsigned long to u64 (Matthew Auld) -- Fix up the cache coloring adjustment. (Kernel test robot ) -- Don't allow async unbinding if the vma_res pages are not the same as the object pages. (Matthew Auld) v7: -- More s/unsigned long/u64/ changes (Matthew Auld) Thomas Hellström (6): drm/i915: Initial introduction of vma resources drm/i915: Use the vma resource as argument for gtt binding / unbinding drm/i915: Don't pin the object pages during pending vma binds drm/i915: Use vma resources for async unbinding drm/i915: Asynchronous migration selftest drm/i915: Use struct vma_resource instead of struct vma_snapshot drivers/gpu/drm/i915/Makefile | 2 +- drivers/gpu/drm/i915/display/intel_dpt.c | 27 +- .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 17 +- drivers/gpu/drm/i915/gem/i915_gem_object.c| 12 + drivers/gpu/drm/i915/gem/i915_gem_object.h| 3 + .../gpu/drm/i915/gem/i915_gem_object_types.h | 27 +- drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c | 11 +- .../gpu/drm/i915/gem/selftests/huge_pages.c | 37 +- .../drm/i915/gem/selftests/i915_gem_migrate.c | 192 +++- drivers/gpu/drm/i915/gt/gen6_ppgtt.c | 19 +- drivers/gpu/drm/i915/gt/gen8_ppgtt.c | 37 +- drivers/gpu/drm/i915/gt/intel_engine_cs.c | 9 +- drivers/gpu/drm/i915/gt/intel_ggtt.c | 72 +-- drivers/gpu/drm/i915/gt/intel_gtt.c | 4 + drivers/gpu/drm/i915/gt/intel_gtt.h | 19 +- drivers/gpu/drm/i915/gt/intel_ppgtt.c | 22 +- drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 13 +- drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h | 2 +- drivers/gpu/drm/i915/i915_debugfs.c | 3 +- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_gem.c | 12 +- drivers/gpu/drm/i915/i915_gpu_error.c | 87 ++-- drivers/gpu/drm/i915/i915_module.c| 3 + drivers/gpu/drm/i915/i915_request.c | 12 +- drivers/gpu/drm/i915/i915_request.h | 6 +- drivers/gpu/drm/i915/i915_vma.c | 241 +- drivers/gpu/drm/i915/i915_vma.h | 33 +- drivers/gpu/drm/i915/i915_vma_resource.c | 417 ++ drivers/gpu/drm/i915/i915_vma_resource.h | 234 ++ drivers/gpu/drm/i915/i915_vma_snapshot.c | 134 -- drivers/gpu/drm/i915/i915_vma_snapshot.h | 112 - drivers/gpu/drm/i915/i915_vma_types.h | 19 +- drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 159 --- drivers/gpu/drm/i915/selftests/mock_gtt.c | 12 +- 34 files changed, 1421 insertions(+), 589 deletions(-) create mode 100644 drivers/gpu/drm/i915/i915_vma_resource.c create mode 100644 drivers/gpu/drm/i915/i915_vma_resource.h delete mode 100644 drivers/gpu/drm/i915/i915_vma_snapshot.c delete mode 100644 drivers/gpu/drm/i915/i915_vma_snapshot.h -- 2.31.1
[PATCH v7 1/6] drm/i915: Initial introduction of vma resources
Introduce vma resources, sort of similar to TTM resources, needed for asynchronous bind management. Initially we will use them to hold completion of unbinding when we capture data from a vma, but they will be used extensively in upcoming patches for asynchronous vma unbinding. v6: - Some documentation updates Signed-off-by: Thomas Hellström Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/Makefile | 1 + .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 2 +- drivers/gpu/drm/i915/i915_vma.c | 55 +++- drivers/gpu/drm/i915/i915_vma.h | 19 ++- drivers/gpu/drm/i915/i915_vma_resource.c | 124 ++ drivers/gpu/drm/i915/i915_vma_resource.h | 69 ++ drivers/gpu/drm/i915/i915_vma_snapshot.c | 15 +-- drivers/gpu/drm/i915/i915_vma_snapshot.h | 7 +- drivers/gpu/drm/i915/i915_vma_types.h | 5 + drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 99 -- 10 files changed, 333 insertions(+), 63 deletions(-) create mode 100644 drivers/gpu/drm/i915/i915_vma_resource.c create mode 100644 drivers/gpu/drm/i915/i915_vma_resource.h diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 1b62b9f65196..98433ad74194 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -174,6 +174,7 @@ i915-y += \ i915_trace_points.o \ i915_ttm_buddy_manager.o \ i915_vma.o \ + i915_vma_resource.o \ i915_vma_snapshot.o \ intel_wopcm.o diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index 9e221ce42707..3e359de0e460 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -1424,7 +1424,7 @@ eb_relocate_entry(struct i915_execbuffer *eb, mutex_lock(&vma->vm->mutex); err = i915_vma_bind(target->vma, target->vma->obj->cache_level, - PIN_GLOBAL, NULL); + PIN_GLOBAL, NULL, NULL); mutex_unlock(&vma->vm->mutex); reloc_cache_remap(&eb->reloc_cache, ev->vma->obj); if (err) diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 81a611b7d36f..05dcbc259b82 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -38,6 +38,7 @@ #include "i915_sw_fence_work.h" #include "i915_trace.h" #include "i915_vma.h" +#include "i915_vma_resource.h" static struct kmem_cache *slab_vmas; @@ -381,6 +382,8 @@ static int i915_vma_verify_bind_complete(struct i915_vma *vma) * @cache_level: mapping cache level * @flags: flags like global or local mapping * @work: preallocated worker for allocating and binding the PTE + * @vma_res: pointer to a preallocated vma resource. The resource is either + * consumed or freed. * * DMA addresses are taken from the scatter-gather table of this object (or of * this VMA in case of non-default GGTT views) and PTE entries set up. @@ -389,7 +392,8 @@ static int i915_vma_verify_bind_complete(struct i915_vma *vma) int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level, u32 flags, - struct i915_vma_work *work) + struct i915_vma_work *work, + struct i915_vma_resource *vma_res) { u32 bind_flags; u32 vma_flags; @@ -400,11 +404,15 @@ int i915_vma_bind(struct i915_vma *vma, if (GEM_DEBUG_WARN_ON(range_overflows(vma->node.start, vma->node.size, - vma->vm->total))) + vma->vm->total))) { + kfree(vma_res); return -ENODEV; + } - if (GEM_DEBUG_WARN_ON(!flags)) + if (GEM_DEBUG_WARN_ON(!flags)) { + kfree(vma_res); return -EINVAL; + } bind_flags = flags; bind_flags &= I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND; @@ -413,11 +421,21 @@ int i915_vma_bind(struct i915_vma *vma, vma_flags &= I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND; bind_flags &= ~vma_flags; - if (bind_flags == 0) + if (bind_flags == 0) { + kfree(vma_res); return 0; + } GEM_BUG_ON(!atomic_read(&vma->pages_count)); + if (vma->resource || !vma_res) { + /* Rebinding with an additional I915_VMA_*_BIND */ + GEM_WARN_ON(!vma_flags); + kfree(vma_res); + } else { + i915_vma_resource_init(vma_res); + vma->resource = vma_res; + } trace_i915_vma_bind(vma, bind_flags); if (work && bind_flags & vma->v
[PATCH v7 2/6] drm/i915: Use the vma resource as argument for gtt binding / unbinding
When introducing asynchronous unbinding, the vma itself may no longer be alive when the actual binding or unbinding takes place. Update the gtt i915_vma_ops accordingly to take a struct i915_vma_resource instead of a struct i915_vma for the bind_vma() and unbind_vma() ops. Similarly change the insert_entries() op for struct i915_address_space. Replace a couple of i915_vma_snapshot members with their newly introduced i915_vma_resource counterparts, since they have the same lifetime. Also make sure to avoid changing the struct i915_vma_flags (in particular the bind flags) async. That should now only be done sync under the vm mutex. v2: - Update the vma_res::bound_flags when binding to the aliased ggtt v6: - Remove I915_VMA_ALLOC_BIT (Matthew Auld) - Change some members of struct i915_vma_resource from unsigned long to u64 (Matthew Auld) v7: - Fix vma resource size parameters to be u64 rather than unsigned long (Matthew Auld) Signed-off-by: Thomas Hellström Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/display/intel_dpt.c | 27 ++--- .../gpu/drm/i915/gem/i915_gem_object_types.h | 27 + .../gpu/drm/i915/gem/selftests/huge_pages.c | 37 +++ drivers/gpu/drm/i915/gt/gen6_ppgtt.c | 19 ++-- drivers/gpu/drm/i915/gt/gen8_ppgtt.c | 37 +++ drivers/gpu/drm/i915/gt/intel_engine_cs.c | 4 +- drivers/gpu/drm/i915/gt/intel_ggtt.c | 70 ++--- drivers/gpu/drm/i915/gt/intel_gtt.h | 16 +-- drivers/gpu/drm/i915/gt/intel_ppgtt.c | 22 +++-- drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 13 ++- drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h | 2 +- drivers/gpu/drm/i915/i915_debugfs.c | 3 +- drivers/gpu/drm/i915/i915_gpu_error.c | 6 +- drivers/gpu/drm/i915/i915_vma.c | 24 - drivers/gpu/drm/i915/i915_vma.h | 11 +-- drivers/gpu/drm/i915/i915_vma_resource.c | 9 +- drivers/gpu/drm/i915/i915_vma_resource.h | 99 ++- drivers/gpu/drm/i915/i915_vma_snapshot.c | 4 - drivers/gpu/drm/i915/i915_vma_snapshot.h | 8 -- drivers/gpu/drm/i915/i915_vma_types.h | 14 ++- drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 64 drivers/gpu/drm/i915/selftests/mock_gtt.c | 12 +-- 22 files changed, 314 insertions(+), 214 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c b/drivers/gpu/drm/i915/display/intel_dpt.c index 8f674745e7e0..63a83d5f85a1 100644 --- a/drivers/gpu/drm/i915/display/intel_dpt.c +++ b/drivers/gpu/drm/i915/display/intel_dpt.c @@ -48,7 +48,7 @@ static void dpt_insert_page(struct i915_address_space *vm, } static void dpt_insert_entries(struct i915_address_space *vm, - struct i915_vma *vma, + struct i915_vma_resource *vma_res, enum i915_cache_level level, u32 flags) { @@ -64,8 +64,8 @@ static void dpt_insert_entries(struct i915_address_space *vm, * not to allow the user to override access to a read only page. */ - i = vma->node.start / I915_GTT_PAGE_SIZE; - for_each_sgt_daddr(addr, sgt_iter, vma->pages) + i = vma_res->start / I915_GTT_PAGE_SIZE; + for_each_sgt_daddr(addr, sgt_iter, vma_res->bi.pages) gen8_set_pte(&base[i++], pte_encode | addr); } @@ -76,35 +76,38 @@ static void dpt_clear_range(struct i915_address_space *vm, static void dpt_bind_vma(struct i915_address_space *vm, struct i915_vm_pt_stash *stash, -struct i915_vma *vma, +struct i915_vma_resource *vma_res, enum i915_cache_level cache_level, u32 flags) { - struct drm_i915_gem_object *obj = vma->obj; u32 pte_flags; + if (vma_res->bound_flags) + return; + /* Applicable to VLV (gen8+ do not support RO in the GGTT) */ pte_flags = 0; - if (vma->vm->has_read_only && i915_gem_object_is_readonly(obj)) + if (vm->has_read_only && vma_res->bi.readonly) pte_flags |= PTE_READ_ONLY; - if (i915_gem_object_is_lmem(obj)) + if (vma_res->bi.lmem) pte_flags |= PTE_LM; - vma->vm->insert_entries(vma->vm, vma, cache_level, pte_flags); + vm->insert_entries(vm, vma_res, cache_level, pte_flags); - vma->page_sizes.gtt = I915_GTT_PAGE_SIZE; + vma_res->page_sizes_gtt = I915_GTT_PAGE_SIZE; /* * Without aliasing PPGTT there's no difference between * GLOBAL/LOCAL_BIND, it's all the same ptes. Hence unconditionally * upgrade to both bound if we bind either to avoid double-binding. */ - atomic_or(I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND, &vma->flags); + vma_res->bound_flags = I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND; } -static void dpt_unbind_vma(struct i915_address_space *
[PATCH v7 3/6] drm/i915: Don't pin the object pages during pending vma binds
A pin-count is already held by vma->pages so taking an additional pin during async binds is not necessary. When we introduce async unbinding we have other means of keeping the object pages alive. Signed-off-by: Thomas Hellström Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/i915_vma.c | 5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 42fff9ddf096..29c770a764aa 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -306,10 +306,8 @@ static void __vma_release(struct dma_fence_work *work) { struct i915_vma_work *vw = container_of(work, typeof(*vw), base); - if (vw->pinned) { - __i915_gem_object_unpin_pages(vw->pinned); + if (vw->pinned) i915_gem_object_put(vw->pinned); - } i915_vm_free_pt_stash(vw->vm, &vw->stash); i915_vm_put(vw->vm); @@ -478,7 +476,6 @@ int i915_vma_bind(struct i915_vma *vma, work->base.dma.error = 0; /* enable the queue_work() */ - __i915_gem_object_pin_pages(vma->obj); work->pinned = i915_gem_object_get(vma->obj); } else { if (vma->obj) { -- 2.31.1
[PATCH v7 4/6] drm/i915: Use vma resources for async unbinding
Implement async (non-blocking) unbinding by not syncing the vma before calling unbind on the vma_resource. Add the resulting unbind fence to the object's dma_resv from where it is picked up by the ttm migration code. Ideally these unbind fences should be coalesced with the migration blit fence to avoid stalling the migration blit waiting for unbind, as they can certainly go on in parallel, but since we don't yet have a reasonable data structure to use to coalesce fences and attach the resulting fence to a timeline, we defer that for now. Note that with async unbinding, even while the unbind waits for the preceding bind to complete before unbinding, the vma itself might have been destroyed in the process, clearing the vma pages. Therefore we can only allow async unbinding if we have a refcounted sg-list and keep a refcount on that for the vma resource pages to stay intact until binding occurs. If this condition is not met, a request for an async unbind is diverted to a sync unbind. v2: - Use a separate kmem_cache for vma resources for now to isolate their memory allocation and aid debugging. - Move the check for vm closed to the actual unbinding thread. Regardless of whether the vm is closed, we need the unbind fence to properly wait for capture. - Clear vma_res::vm on unbind and update its documentation. v4: - Take cache coloring into account when searching for vma resources pending unbind. (Matthew Auld) v5: - Fix timeout and error check in i915_vma_resource_bind_dep_await(). - Avoid taking a reference on the object for async binding if async unbind capable. - Fix braces around a single-line if statement. v6: - Fix up the cache coloring adjustment. (Kernel test robot ) - Don't allow async unbinding if the vma_res pages are not the same as the object pages. (Matthew Auld) v7: - s/unsigned long/u64/ in a number of places (Matthew Auld) Signed-off-by: Thomas Hellström Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c | 11 +- drivers/gpu/drm/i915/gt/intel_ggtt.c | 2 +- drivers/gpu/drm/i915/gt/intel_gtt.c | 4 + drivers/gpu/drm/i915/gt/intel_gtt.h | 3 + drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_gem.c | 12 +- drivers/gpu/drm/i915/i915_module.c | 3 + drivers/gpu/drm/i915/i915_vma.c | 205 +-- drivers/gpu/drm/i915/i915_vma.h | 3 +- drivers/gpu/drm/i915/i915_vma_resource.c | 354 +-- drivers/gpu/drm/i915/i915_vma_resource.h | 48 +++ 11 files changed, 579 insertions(+), 67 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c index 8653855d808b..1de306c03aaf 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c @@ -142,7 +142,16 @@ int i915_ttm_move_notify(struct ttm_buffer_object *bo) struct drm_i915_gem_object *obj = i915_ttm_to_gem(bo); int ret; - ret = i915_gem_object_unbind(obj, I915_GEM_OBJECT_UNBIND_ACTIVE); + /* +* Note: The async unbinding here will actually transform the +* blocking wait for unbind into a wait before finally submitting +* evict / migration blit and thus stall the migration timeline +* which may not be good for overall throughput. We should make +* sure we await the unbind fences *after* the migration blit +* instead of *before* as we currently do. +*/ + ret = i915_gem_object_unbind(obj, I915_GEM_OBJECT_UNBIND_ACTIVE | +I915_GEM_OBJECT_UNBIND_ASYNC); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c index e49b6250c4b7..a1b2761bc16e 100644 --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c @@ -142,7 +142,7 @@ void i915_ggtt_suspend_vm(struct i915_address_space *vm) continue; if (!i915_vma_is_bound(vma, I915_VMA_GLOBAL_BIND)) { - __i915_vma_evict(vma); + __i915_vma_evict(vma, false); drm_mm_remove_node(&vma->node); } } diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.c b/drivers/gpu/drm/i915/gt/intel_gtt.c index a94be0306464..46be4197b93f 100644 --- a/drivers/gpu/drm/i915/gt/intel_gtt.c +++ b/drivers/gpu/drm/i915/gt/intel_gtt.c @@ -161,6 +161,9 @@ static void __i915_vm_release(struct work_struct *work) struct i915_address_space *vm = container_of(work, struct i915_address_space, release_work); + /* Synchronize async unbinds. */ + i915_vma_resource_bind_dep_sync_all(vm); + vm->cleanup(vm); i915_address_space_fini(vm); @@ -189,6 +192,7 @@ void i915_address_space_init(struct i915_address_space *vm, int subclass) if (!kref_read(&vm->