[PATCH] drm: bridge: it66121: Added it66121 chip external screen status judgment
In the actual tests, the IT66121 chip sometimes misjudged whether it had an external screen, so, reference the it66121_user_guid.pdf about Audio/Video data is stable or not A typical initialization of HDMI link should be based on interrupt signal and appropriate register probing. Recommended flow is detailed in IT66121 Programming Guide. Simply put, the microcontroller should monitor the HPD status first. Upon valid HPD event, move on to check RxSENDetect register to see if the receiver chip is ready for further handshaking. When RxSENDetect is asserted, start reading EDID data through DDC channels and carry on the rest of the handshaking subsequently.If the micro-controller makes no use of the interrupt signal as well as the above-mentioned status registers, the link establishment might fail. Please do follow the suggested initialization flow recommended in IT66121 Programming Guide. So, I add the IT66121_SYS_STATUS_SENDECTECT register status detection. Signed-off-by: Yunlongli --- drivers/gpu/drm/bridge/ite-it66121.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c index 2f2a09adb4bc..9ed4fa298d11 100644 --- a/drivers/gpu/drm/bridge/ite-it66121.c +++ b/drivers/gpu/drm/bridge/ite-it66121.c @@ -523,7 +523,7 @@ static bool it66121_is_hpd_detect(struct it66121_ctx *ctx) if (regmap_read(ctx->regmap, IT66121_SYS_STATUS_REG, &val)) return false; - return val & IT66121_SYS_STATUS_HPDETECT; + return ((val & IT66121_SYS_STATUS_HPDETECT) && (val & IT66121_SYS_STATUS_SENDECTECT)); } static int it66121_bridge_attach(struct drm_bridge *bridge, -- 2.20.1
Re: [PATCH] drm: bridge: it66121: Added it66121 chip external screen status judgment
Hi, On 21/09/2021 09:54, Yunlongli wrote: > In the actual tests, the IT66121 chip sometimes misjudged whether > it had an external screen, so, reference the it66121_user_guid.pdf > about Audio/Video data is stable or not A typical initialization > of HDMI link should be based on interrupt signal and appropriate > register probing. Recommended flow is detailed in IT66121 > Programming Guide. Simply put, the microcontroller should monitor > the HPD status first. Upon valid HPD event, move on to check > RxSENDetect register to see if the receiver chip is ready for > further handshaking. When RxSENDetect is asserted, start reading EDID > data through DDC channels and carry on the rest of the handshaking > subsequently.If the micro-controller makes no use of the interrupt > signal as well as the above-mentioned status registers, the link > establishment might fail. Please do follow the suggested > initialization flow recommended in IT66121 Programming Guide. > So, I add the IT66121_SYS_STATUS_SENDECTECT register status detection. Ok, the RxSENDetect is the "rx-sense" detection bit as described in the same doc: Receiver detection circuit reports the presence or absence of an active termination at the TMDS Clock Channel (RxSENDetect) The usage of the rx-sense signal in hpd_detect() is not clear because this would break detection of "Fake" EDID dongles or idle monitors. The dw-hdmi handles the rx-sense, but only to power-on/off the HDMI TX, but only returns the HPD status to DRM without the RX SENSE state, so it only saves power and doesn't change anything on DRM HPD detection. So not sure if we should merge this as-is. Neil > > Signed-off-by: Yunlongli > --- > drivers/gpu/drm/bridge/ite-it66121.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/bridge/ite-it66121.c > b/drivers/gpu/drm/bridge/ite-it66121.c > index 2f2a09adb4bc..9ed4fa298d11 100644 > --- a/drivers/gpu/drm/bridge/ite-it66121.c > +++ b/drivers/gpu/drm/bridge/ite-it66121.c > @@ -523,7 +523,7 @@ static bool it66121_is_hpd_detect(struct it66121_ctx *ctx) > if (regmap_read(ctx->regmap, IT66121_SYS_STATUS_REG, &val)) > return false; > > - return val & IT66121_SYS_STATUS_HPDETECT; > + return ((val & IT66121_SYS_STATUS_HPDETECT) && (val & > IT66121_SYS_STATUS_SENDECTECT)); > } > > static int it66121_bridge_attach(struct drm_bridge *bridge, >
Re: [PATCH v2 0/4] CMDQ refinement of Mediatek DRM driver
Hi Chun-Kuang, Missatge de Chun-Kuang Hu del dia dj., 12 d’ag. 2021 a les 2:13: > Chun-Kuang Hu 於 2021年8月9日 週一 上午7:47寫道: > > > > These refinements include using standard mailbox callback interface, > > timeout detection, and a fixed cmdq_handle. > > For this series, applied to mediatek-drm-next [1]. > > [1] > https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux.git/log/?h=mediatek-drm-next > > These patches seem to break the display on the Acer Chromebook R 13 (MT8173) in the current mainline. After running a bisection it pointed me to the following commit commit f4be17cd5b14dd73545b0e014a63ebe9ab5ef837 Author: Chun-Kuang Hu Date: Sun Jul 4 15:36:48 2021 +0800 drm/mediatek: Remove struct cmdq_client Reverting this patch alone is not trivial, so I ended up reverting the full series, and I can confirm that reverting the full series makes the display work again. Unfortunately, after the merge window, different things broke for this device, and I didn't finish isolating them, and it is not clear to me yet whether the logs I'm getting are useful for this specific issue or not. Basically with this series merged the kernel seems to be stuck, and the display is not working. Latest message is [ 12.329173] mtk-iommu 10205000.iommu: Partial TLB flush timed out, falling back to full flush Without the series, the kernel goes far and display works, however there are other issues affecting the cros-ec, but I think that's another issue. I'll try to dig a bit more, but, meanwhile, if you have any idea please let me know. Thanks, Enric > Regards, > Chun-Kuang. > > > > > Changes in v2: > > 1. Define mtk_drm_cmdq_pkt_create() and mtk_drm_cmdq_pkt_destroy() > >when CONFIG_MTK_CMDQ is reachable. > > > > Chun-Kuang Hu (4): > > drm/mediatek: Use mailbox rx_callback instead of cmdq_task_cb > > drm/mediatek: Remove struct cmdq_client > > drm/mediatek: Detect CMDQ execution timeout > > drm/mediatek: Add cmdq_handle in mtk_crtc > > > > drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 110 > > 1 file changed, 91 insertions(+), 19 deletions(-) > > > > -- > > 2.25.1 > > >
Re: [PATCH v2 0/4] CMDQ refinement of Mediatek DRM driver
Hi Chun-Kuang, (again without html format, sorry for the noise) Missatge de Chun-Kuang Hu del dia dj., 12 d’ag. 2021 a les 2:13: > > Chun-Kuang Hu 於 2021年8月9日 週一 上午7:47寫道: > > > > These refinements include using standard mailbox callback interface, > > timeout detection, and a fixed cmdq_handle. > > For this series, applied to mediatek-drm-next [1]. > > [1] > https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux.git/log/?h=mediatek-drm-next > These patches seem to break the display on the Acer Chromebook R 13 (MT8173) in the current mainline. After running a bisection it pointed me to the following commit commit f4be17cd5b14dd73545b0e014a63ebe9ab5ef837 Author: Chun-Kuang Hu Date: Sun Jul 4 15:36:48 2021 +0800 drm/mediatek: Remove struct cmdq_client Reverting this patch alone is not trivial, so I ended up reverting the full series, and I can confirm that reverting the full series makes the display work again. Unfortunately, after the merge window, different things broke for this device, and I didn't finish isolating them, and it is not clear to me yet whether the logs I'm getting are useful for this specific issue or not. Basically with this series merged the kernel seems to be stuck, and the display is not working. Latest message is [ 12.329173] mtk-iommu 10205000.iommu: Partial TLB flush timed out, falling back to full flush Without the series, the kernel goes far and display works, however there are other issues affecting the cros-ec, but I think that's another issue. I'll try to dig a bit more, but, meanwhile, if you have any idea please let me know. Thanks, Enric > Regards, > Chun-Kuang. > > > > > Changes in v2: > > 1. Define mtk_drm_cmdq_pkt_create() and mtk_drm_cmdq_pkt_destroy() > >when CONFIG_MTK_CMDQ is reachable. > > > > Chun-Kuang Hu (4): > > drm/mediatek: Use mailbox rx_callback instead of cmdq_task_cb > > drm/mediatek: Remove struct cmdq_client > > drm/mediatek: Detect CMDQ execution timeout > > drm/mediatek: Add cmdq_handle in mtk_crtc > > > > drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 110 > > 1 file changed, 91 insertions(+), 19 deletions(-) > > > > -- > > 2.25.1 > >
Re: [PATCH v3 00/13] drm/i915/dp: dp 2.0 enabling prep work
On Fri, 17 Sep 2021, Maxime Ripard wrote: > On Fri, Sep 17, 2021 at 03:54:23PM +0300, Jani Nikula wrote: >> On Thu, 09 Sep 2021, Jani Nikula wrote: >> > v3 of https://patchwork.freedesktop.org/series/93800/ with minor tweaks >> > and the already merged patches obviously dropped. >> > >> > Jani Nikula (13): >> > drm/dp: add DP 2.0 UHBR link rate and bw code conversions >> > drm/dp: use more of the extended receiver cap >> > drm/dp: add LTTPR DP 2.0 DPCD addresses >> > drm/dp: add helper for extracting adjust 128b/132b TX FFE preset >> >> Maarten, Maxime, Thomas, can I get an ack to merge these four patches >> via drm-intel please, or would you prefer a topic branch instead? > > Yes, you can merge them through drm-intel Thanks, I've done that. BR, Jani. -- Jani Nikula, Intel Open Source Graphics Center
Re: [PATCH v3 12/13] drm/i915/dg2: configure TRANS_DP2_VFREQ{HIGH, LOW} for 128b/132b
On Fri, 17 Sep 2021, Ville Syrjälä wrote: > On Thu, Sep 09, 2021 at 03:52:04PM +0300, Jani Nikula wrote: >> There's a new register pair for 128b/132b mode where you need to set the >> pixel clock in Hz. >> >> v2: Fix UHBR rate check, use intel_dp_is_uhbr() helper >> >> Bspec: 54128 >> Signed-off-by: Jani Nikula > > Reviewed-by: Ville Syrjälä Thanks for the reviews, pushed up to and including this one. BR, Jani. > >> --- >> drivers/gpu/drm/i915/display/intel_dp_mst.c | 11 +++ >> 1 file changed, 11 insertions(+) >> >> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c >> b/drivers/gpu/drm/i915/display/intel_dp_mst.c >> index d104441344c0..97af19fd9780 100644 >> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c >> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c >> @@ -550,6 +550,17 @@ static void intel_mst_enable_dp(struct >> intel_atomic_state *state, >> >> clear_act_sent(encoder, pipe_config); >> >> +if (intel_dp_is_uhbr(pipe_config)) { >> +const struct drm_display_mode *adjusted_mode = >> +&pipe_config->hw.adjusted_mode; >> +u64 crtc_clock_hz = KHz(adjusted_mode->crtc_clock); >> + >> +intel_de_write(dev_priv, >> TRANS_DP2_VFREQHIGH(pipe_config->cpu_transcoder), >> + TRANS_DP2_VFREQ_PIXEL_CLOCK(crtc_clock_hz >> >> 24)); >> +intel_de_write(dev_priv, >> TRANS_DP2_VFREQLOW(pipe_config->cpu_transcoder), >> + TRANS_DP2_VFREQ_PIXEL_CLOCK(crtc_clock_hz & >> 0xff)); >> +} >> + >> intel_ddi_enable_transcoder_func(encoder, pipe_config); >> >> intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL(trans), 0, >> -- >> 2.30.2 -- Jani Nikula, Intel Open Source Graphics Center
Re: [PATCH 2/2] Add drm buddy manager support to amdgpu driver
Am 20.09.21 um 21:21 schrieb Arunpravin: Replace drm_mm with drm buddy manager for VRAM memory management Signed-off-by: Arunpravin --- .../gpu/drm/amd/amdgpu/amdgpu_res_cursor.h| 78 +-- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h | 3 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 216 ++ 3 files changed, 189 insertions(+), 108 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h index acfa207cf970..ba24052e9062 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h @@ -30,12 +30,25 @@ #include #include +struct amdgpu_vram_mgr_node { + struct ttm_range_mgr_node tnode; NAK, don't base this on ttm_range_mgr_node. Instead use ttm_resource. And please name the member base instead. + struct list_head blocks; +}; + +static inline struct amdgpu_vram_mgr_node * +to_amdgpu_vram_mgr_node(struct ttm_resource *res) +{ + return container_of(container_of(res, struct ttm_range_mgr_node, base), + struct amdgpu_vram_mgr_node, tnode); +} + Maybe stuff that in a separate amdgpu_vram_mgr.h file together with all the other defines for the vram manager. /* state back for walking over vram_mgr and gtt_mgr allocations */ struct amdgpu_res_cursor { uint64_tstart; uint64_tsize; uint64_tremaining; - struct drm_mm_node *node; + void*node; + uint32_tmem_type; }; /** @@ -52,8 +65,6 @@ static inline void amdgpu_res_first(struct ttm_resource *res, uint64_t start, uint64_t size, struct amdgpu_res_cursor *cur) { - struct drm_mm_node *node; - if (!res || res->mem_type == TTM_PL_SYSTEM) { cur->start = start; cur->size = size; @@ -65,14 +76,39 @@ static inline void amdgpu_res_first(struct ttm_resource *res, BUG_ON(start + size > res->num_pages << PAGE_SHIFT); - node = to_ttm_range_mgr_node(res)->mm_nodes; - while (start >= node->size << PAGE_SHIFT) - start -= node++->size << PAGE_SHIFT; + cur->mem_type = res->mem_type; + + if (cur->mem_type == TTM_PL_VRAM) { Rather use a switch/case here. + struct drm_buddy_block *block; + struct list_head *head, *next; + + head = &to_amdgpu_vram_mgr_node(res)->blocks; + + block = list_first_entry_or_null(head, struct drm_buddy_block, link); + while (start >= block->size << PAGE_SHIFT) { + start -= block->size << PAGE_SHIFT; + + next = block->link.next; + if (next != head) + block = list_entry(next, struct drm_buddy_block, link); + } - cur->start = (node->start << PAGE_SHIFT) + start; - cur->size = min((node->size << PAGE_SHIFT) - start, size); - cur->remaining = size; - cur->node = node; + cur->start = (block->start << PAGE_SHIFT) + start; + cur->size = min((block->size << PAGE_SHIFT) - start, size); + cur->remaining = size; + cur->node = block; + } else if (cur->mem_type == TTM_PL_TT) { + struct drm_mm_node *node; + + node = to_ttm_range_mgr_node(res)->mm_nodes; + while (start >= node->size << PAGE_SHIFT) + start -= node++->size << PAGE_SHIFT; + + cur->start = (node->start << PAGE_SHIFT) + start; + cur->size = min((node->size << PAGE_SHIFT) - start, size); + cur->remaining = size; + cur->node = node; With a default handling for other placement types. + } } /** @@ -85,8 +121,6 @@ static inline void amdgpu_res_first(struct ttm_resource *res, */ static inline void amdgpu_res_next(struct amdgpu_res_cursor *cur, uint64_t size) { - struct drm_mm_node *node = cur->node; - BUG_ON(size > cur->remaining); cur->remaining -= size; @@ -99,9 +133,23 @@ static inline void amdgpu_res_next(struct amdgpu_res_cursor *cur, uint64_t size) return; } - cur->node = ++node; - cur->start = node->start << PAGE_SHIFT; - cur->size = min(node->size << PAGE_SHIFT, cur->remaining); + if (cur->mem_type == TTM_PL_VRAM) { + struct drm_buddy_block *block = cur->node; + struct list_head *next; + + next = block->link.next; + block = list_entry(next, struct drm_buddy_block, link); + + cur->node = block; + cur->start = block->start << PAGE_SHIFT; + cur->size = min(block->size << PAGE_SHIFT, cur->remaining); + } else if (cur->mem_type == TTM
Re: [PATCH v3] drm/rockchip: Update crtc fixup to account for fractional clk change
On Thu, 16 Sep 2021 15:29:07 -0500, Chris Morgan wrote: > After commit 928f9e268611 ("clk: fractional-divider: Hide > clk_fractional_divider_ops from wide audience") was merged it appears > that the DSI panel on my Odroid Go Advance stopped working. Upon closer > examination of the problem, it looks like it was the fixup in the > rockchip_drm_vop.c file was causing the issue. The changes made to the > clk driver appear to change some assumptions made in the fixup. > > [...] Applied, thanks! [1/1] drm/rockchip: Update crtc fixup to account for fractional clk change commit: e93a3ccf76996df53ff6c2c03626b70bb0b0d55d Best regards, -- Heiko Stuebner
[PATCH] drm/nouveau/fifo/ga102: initialise chid on return from channel creation
From: Ben Skeggs Turns out caller isn't zero-initialised after-all. Fixes: 6b457230bfa1 ("drm/nouveau/ga102-: support ttm buffer moves via copy engine") Reported-by: Karol Herbst Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c index f897bef13acf..c630dbd2911a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c @@ -179,6 +179,9 @@ ga102_chan_new(struct nvkm_device *device, return -ENODEV; chan->ctrl.chan = nvkm_rd32(device, chan->ctrl.runl + 0x004) & 0xfff0; + + args->chid = 0; + args->inst = 0; args->token = nvkm_rd32(device, chan->ctrl.runl + 0x008) & 0x; ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000, true, &chan->mthd); -- 2.31.1
Re: [PATCH v2] drm/rockchip: cdn-dp-core: Fix cdn_dp_resume unused warning
On Fri, 10 Sep 2021 20:43:18 -0700, Palmer Dabbelt wrote: > cdn_dp_resume is only used under PM_SLEEP, and now that it's static an > unused function warning is triggered undner !PM_SLEEP. This marks the > function as possibly unused, to avoid triggering compiler warnings. Applied, thanks! [1/1] drm/rockchip: cdn-dp-core: Fix cdn_dp_resume unused warning commit: f7c57a4566115657c16fd6603b6ef8a21bae5194 Best regards, -- Heiko Stuebner
Re: [Intel-gfx] [PATCH 13/26] drm/i915: use the new iterator in i915_gem_busy_ioctl
Am 20.09.21 um 12:33 schrieb Tvrtko Ursulin: On 20/09/2021 11:13, Christian König wrote: Am 20.09.21 um 10:45 schrieb Tvrtko Ursulin: On 17/09/2021 13:35, Christian König wrote: This makes the function much simpler since the complex retry logic is now handled else where. Signed-off-by: Christian König --- drivers/gpu/drm/i915/gem/i915_gem_busy.c | 32 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_busy.c b/drivers/gpu/drm/i915/gem/i915_gem_busy.c index 6234e17259c1..b1cb7ba688da 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_busy.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_busy.c @@ -82,8 +82,8 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, { struct drm_i915_gem_busy *args = data; struct drm_i915_gem_object *obj; - struct dma_resv_list *list; - unsigned int seq; + struct dma_resv_iter cursor; + struct dma_fence *fence; int err; err = -ENOENT; @@ -109,27 +109,17 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, * to report the overall busyness. This is what the wait-ioctl does. * */ -retry: - seq = raw_read_seqcount(&obj->base.resv->seq); - - /* Translate the exclusive fence to the READ *and* WRITE engine */ - args->busy = busy_check_writer(dma_resv_excl_fence(obj->base.resv)); - - /* Translate shared fences to READ set of engines */ - list = dma_resv_shared_list(obj->base.resv); - if (list) { - unsigned int shared_count = list->shared_count, i; - - for (i = 0; i < shared_count; ++i) { - struct dma_fence *fence = - rcu_dereference(list->shared[i]); - + args->busy = false; + dma_resv_iter_begin(&cursor, obj->base.resv, true); + dma_resv_for_each_fence_unlocked(&cursor, fence) { You did not agree with my suggestion to reset args->busy on restart and so preserve current behaviour? No, I want to keep the restart behavior internally to the dma_resv object and as far as I can see it should not make a difference here. To be clear, on paper difference between old and new implementation is if the restart happens while processing the shared fences. Old implementation unconditionally goes to "args->busy = >>> busy_check_writer(dma_resv_excl_fence(obj->base.resv));" and so overwrites the set of flags returned to userspace. New implementation can merge new read flags to the old set of flags and so return a composition of past and current fences. Maybe it does not matter hugely in this case, depends if userspace typically just restarts until flags are clear. But I am not sure. On the higher level - what do you mean with wanting to keep the restart behaviour internal? Not providing iterators users means of detecting it? I think it has to be provided. Ok I will adjust that for now to get the patch set upstream. But in general when somebody outside of the dma_resv code base depends on the restart behavior then that's a bug inside the design of that code. The callers should only care about what unsignaled fences are inside the dma_resv container and it shouldn't matter if those fences are presented once or multiple times because of a reset.. When this makes a difference we have a bug in the handling and should probably consider taking the dma_resv.lock instead. Regards, Christian. Regards, Tvrtko Regards, Christian. Regards, Tvrtko + if (dma_resv_iter_is_exclusive(&cursor)) + /* Translate the exclusive fence to the READ *and* WRITE engine */ + args->busy = busy_check_writer(fence); + else + /* Translate shared fences to READ set of engines */ args->busy |= busy_check_reader(fence); - } } - - if (args->busy && read_seqcount_retry(&obj->base.resv->seq, seq)) - goto retry; + dma_resv_iter_end(&cursor); err = 0; out:
Re: [PATCH v2 3/6] drm/edid: Add cea_sad helpers for freq/length
On Mon, 20 Sep 2021, Markus Schneider-Pargmann wrote: > This patch adds two helper functions that extract the frequency and word > length from a struct cea_sad. > > For these helper functions new defines are added that help translate the > 'freq' and 'byte2' fields into real numbers. > > Signed-off-by: Markus Schneider-Pargmann > --- > > Notes: > Changes v1 -> v2: > - Use const struct pointers. > - Add a check whether the format is actually uncompressed or not. > > drivers/gpu/drm/drm_edid.c | 74 ++ > include/drm/drm_edid.h | 18 -- > 2 files changed, 90 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c > index 6325877c5fd6..28df422fbc03 100644 > --- a/drivers/gpu/drm/drm_edid.c > +++ b/drivers/gpu/drm/drm_edid.c > @@ -4666,6 +4666,80 @@ int drm_edid_to_speaker_allocation(struct edid *edid, > u8 **sadb) > } > EXPORT_SYMBOL(drm_edid_to_speaker_allocation); > > +/** > + * drm_cea_sad_get_sample_rate - Extract the sample rate from cea_sad > + * @sad: Pointer to the cea_sad struct > + * > + * Extracts the cea_sad frequency field and returns the sample rate in Hz. > + * > + * Return: Sample rate in Hz or a negative errno if parsing failed. > + */ > +int drm_cea_sad_get_sample_rate(const struct cea_sad *sad) > +{ > + switch (sad->freq) { > + case CEA_SAD_FREQ_32KHZ: > + return 32000; > + case CEA_SAD_FREQ_44KHZ: > + return 44100; > + case CEA_SAD_FREQ_48KHZ: > + return 48000; > + case CEA_SAD_FREQ_88KHZ: > + return 88200; > + case CEA_SAD_FREQ_96KHZ: > + return 96000; > + case CEA_SAD_FREQ_176KHZ: > + return 176400; > + case CEA_SAD_FREQ_192KHZ: > + return 192000; > + default: > + return -EINVAL; > + } > +} > +EXPORT_SYMBOL(drm_cea_sad_get_sample_rate); > + > +static bool drm_cea_sad_is_uncompressed(const struct cea_sad *sad) > +{ > + switch (sad->format) { > + case HDMI_AUDIO_CODING_TYPE_STREAM: > + case HDMI_AUDIO_CODING_TYPE_PCM: > + return true; > + default: > + return false; > + } > +} > + > +/** > + * drm_cea_sad_get_uncompressed_word_length - Extract word length > + * @sad: Pointer to the cea_sad struct > + * > + * Extracts the cea_sad byte2 field and returns the word length for an > + * uncompressed stream. > + * > + * Note: This function may only be called for uncompressed audio. > + * > + * Return: Word length in bits or a negative errno if parsing failed. > + */ > +int drm_cea_sad_get_uncompressed_word_length(const struct cea_sad *sad) > +{ > + if (!drm_cea_sad_is_uncompressed(sad)) { > + DRM_WARN("Unable to get the uncompressed word length for a > compressed format: %u\n", > + sad->format); > + return -EINVAL; > + } > + > + switch (sad->byte2) { > + case CEA_SAD_UNCOMPRESSED_WORD_16BIT: > + return 16; > + case CEA_SAD_UNCOMPRESSED_WORD_20BIT: > + return 20; > + case CEA_SAD_UNCOMPRESSED_WORD_24BIT: > + return 24; > + default: > + return -EINVAL; > + } > +} > +EXPORT_SYMBOL(drm_cea_sad_get_uncompressed_word_length); > + > /** > * drm_av_sync_delay - compute the HDMI/DP sink audio-video sync delay > * @connector: connector associated with the HDMI/DP sink > diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h > index deccfd39e6db..7b7d71a7154d 100644 > --- a/include/drm/drm_edid.h > +++ b/include/drm/drm_edid.h > @@ -361,12 +361,24 @@ struct edid { > > /* Short Audio Descriptor */ > struct cea_sad { > - u8 format; > + u8 format; /* See HDMI_AUDIO_CODING_TYPE_* */ > u8 channels; /* max number of channels - 1 */ > - u8 freq; > + u8 freq; /* See CEA_SAD_FREQ_* */ > u8 byte2; /* meaning depends on format */ > }; > > +#define CEA_SAD_FREQ_32KHZ BIT(0) > +#define CEA_SAD_FREQ_44KHZ BIT(1) > +#define CEA_SAD_FREQ_48KHZ BIT(2) > +#define CEA_SAD_FREQ_88KHZ BIT(3) > +#define CEA_SAD_FREQ_96KHZ BIT(4) > +#define CEA_SAD_FREQ_176KHZ BIT(5) > +#define CEA_SAD_FREQ_192KHZ BIT(6) > + > +#define CEA_SAD_UNCOMPRESSED_WORD_16BIT BIT(0) > +#define CEA_SAD_UNCOMPRESSED_WORD_20BIT BIT(1) > +#define CEA_SAD_UNCOMPRESSED_WORD_24BIT BIT(2) I suggest adding DRM_ prefixes here. BR, Jani. > + > struct drm_encoder; > struct drm_connector; > struct drm_connector_state; > @@ -374,6 +386,8 @@ struct drm_display_mode; > > int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads); > int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb); > +int drm_cea_sad_get_sample_rate(const struct cea_sad *sad); > +int drm_cea_sad_get_uncompressed_word_length(const struct cea_sad *sad); > int drm_av_sync_delay(struct drm_connector *connector, > const struct drm_display_mode *mode); -- Jani Nikula, Intel Open Source Graphics Cent
Re: [PATCH] doc: gpu: drm-internals: Create reference to DRM mm
On Mon, 20 Sep 2021, Markus Schneider-Pargmann wrote: > Hi Jani, > > On Mon, Sep 20, 2021 at 02:01:57PM +0300, Jani Nikula wrote: >> On Mon, 20 Sep 2021, Markus Schneider-Pargmann wrote: >> > This short sentence references nothing for details about memory manager. >> > Replace it with the documentation file for DRM memory management. >> > >> > Cc: Jani Nikula >> > Signed-off-by: Markus Schneider-Pargmann >> > --- >> > Documentation/gpu/drm-internals.rst | 4 ++-- >> > 1 file changed, 2 insertions(+), 2 deletions(-) >> > >> > diff --git a/Documentation/gpu/drm-internals.rst >> > b/Documentation/gpu/drm-internals.rst >> > index 06af044c882f..bdcdfc4ede04 100644 >> > --- a/Documentation/gpu/drm-internals.rst >> > +++ b/Documentation/gpu/drm-internals.rst >> > @@ -126,8 +126,8 @@ Memory Manager Initialization >> > Every DRM driver requires a memory manager which must be initialized at >> > load time. DRM currently contains two memory managers, the Translation >> > Table Manager (TTM) and the Graphics Execution Manager (GEM). This >> > -document describes the use of the GEM memory manager only. See ? for >> > -details. >> > +document describes the use of the GEM memory manager only. See >> > +Documentation/gpu/drm-mm.rst for details. >> >> Please use rst references instead of a file reference. > > Thanks for your comment. Could you please explain it a bit more to me? > > I am new to the kernel sphinx documentation so I looked it up in > Documentation/doc-guide/sphinx.rst 'Cross-referencing'. It is listed as > the preferred way to reference other documents if I understand it > correctly. > > Should the doc-guide be updated then if a rst reference is preferred? Please go with what the doc-guide says, sorry for the noise. BR, Jani. -- Jani Nikula, Intel Open Source Graphics Center
Re: [PATCH] drm/rockchip: Check iommu itself instead of it's parent for device_is_available
On Sun, 27 Jun 2021 16:47:37 +0800, Andy Yan wrote: > When iommu itself is disabled in dts, we should > fallback to non-iommu buffer, check iommu parent > is meanless here. Applied, thanks! [1/1] drm/rockchip: Check iommu itself instead of it's parent for device_is_available commit: e1202c7a65b10258f9a11c1d2613c2aa91fe11cd Best regards, -- Heiko Stuebner
Re: [PATCH] drm/rockchip: add DRM_BRIDGE_ATTACH_NO_CONNECTOR flag to drm_bridge_attach
On Mon, 13 Sep 2021 14:51:08 +0200, Alex Bee wrote: > Commit a25b988ff83f ("drm/bridge: Extend bridge API to disable connector > creation") > added DRM_BRIDGE_ATTACH_NO_CONNECTOR bridge flag and all bridges handle > this flag in some way since then. > Newly added bridge drivers must no longer contain the connector creation and > will fail probing if this flag isn't set. > > In order to be able to connect to those newly added bridges as well, > make use of drm_bridge_connector API and have the connector initialized > by the display controller. Applied, thanks! [1/1] drm/rockchip: add DRM_BRIDGE_ATTACH_NO_CONNECTOR flag to drm_bridge_attach commit: 2e87bf389e1396b9f1360e1a7cdc27f423f56463 Best regards, -- Heiko Stuebner
Re: [PATCH] drm/rockchip: dsi: Fix duplicate included linux/phy/phy.h
On Fri, 20 Aug 2021 18:18:49 +0800, Jiapeng Chong wrote: > Clean up the following includecheck warning: > > ./drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c: linux/phy/phy.h is > included more than once. Applied, thanks! [1/1] drm/rockchip: dsi: Fix duplicate included linux/phy/phy.h commit: d90def98f90fb166191f19b41620e1a54b6dac75 Best regards, -- Heiko Stuebner
Re: [PATCH] drm/rockchip: handle non-platform devices in rockchip_drm_endpoint_is_subdriver
On Tue, 14 Sep 2021 17:07:56 +0200, Alex Bee wrote: > As discussed at [1] rockchip_drm_endpoint_is_subdriver will currently always > return -ENODEV for non-platform-devices (e.g. external i2c bridges), what > makes them never being considered in rockchip_rgb_init. > > As suggested at [1] this additionally adds a of_device_is_available for > the node found, which will work for both platform and non-platform devices. > Also we can return early for non-platform-devices if they are enabled, > as rockchip_sub_drivers contains exclusively platform-devices. > > [...] Applied, thanks! [1/1] drm/rockchip: handle non-platform devices in rockchip_drm_endpoint_is_subdriver commit: 37825e07ab413187e1ea078bc33dcdb835008be2 Best regards, -- Heiko Stuebner
Re: [PATCH] drm/rockchip: Make use of the helper function devm_platform_ioremap_resource()
On Tue, 31 Aug 2021 21:57:21 +0800, Cai Huoqing wrote: > Use the devm_platform_ioremap_resource() helper instead of > calling platform_get_resource() and devm_ioremap_resource() > separately Applied, thanks! [1/1] drm/rockchip: Make use of the helper function devm_platform_ioremap_resource() commit: 61735698103fafb5bc0df4ab208fc140c27cabc6 Best regards, -- Heiko Stuebner
Re: [PATCH] drm/rockchip: dsi: make hstt_table static
On Fri, 6 Aug 2021 10:57:44 +0800, Jiapeng Chong wrote: > This symbol is not used outside of dw-mipi-dsi-rockchip.c, so marks > it static. > > Fix the following sparse warning: > > drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c:646:13: warning: symbol > 'hstt_table' was not declared. Should it be static? Applied, thanks! [1/1] drm/rockchip: dsi: make hstt_table static commit: adfeef9370ff8b53c5f73cda3a63531d92b1ca64 Best regards, -- Heiko Stuebner
Re: [PATCH] drm/rockchip: remove unused psr_list{,_lock}
On Wed, 15 Sep 2021 13:50:11 -0700, Brian Norris wrote: > Some leftover cleanup from commit 6c836d965bad ("drm/rockchip: Use the > helpers for PSR"). Applied, thanks! [1/1] drm/rockchip: remove unused psr_list{,_lock} commit: d3e2ec6cd1636ced67c6f57d95d8ad24f964691d Best regards, -- Heiko Stuebner
Re: [PATCH] drm/rockchip: remove of_match_ptr() from vop_driver_dt_match
On Tue, 8 Jun 2021 00:38:00 +0530, Souptick Joarder wrote: > kernel test robot throws warning when CONFIG_OF not set. > > >> drivers/gpu/drm/rockchip/rockchip_vop_reg.c:1038:34: > warning: unused variable 'vop_driver_dt_match' [-Wunused-const-variable] >static const struct of_device_id vop_driver_dt_match[] = { > > Fixed it by removing of_match_ptr(). Applied, thanks! [1/1] drm/rockchip: remove of_match_ptr() from vop_driver_dt_match commit: 87185cc823693933308bd33a190032e9c262c75f Best regards, -- Heiko Stuebner
Re: [PATCH v2] drm/rockchip: remove of_match_ptr()
On Tue, 8 Jun 2021 00:18:36 +0530, Souptick Joarder wrote: > Kernel test robot throws below warning when CONFIG_OF > is not set. > > >> drivers/gpu/drm/rockchip/analogix_dp-rockchip.c:457:34: > warning: unused variable 'rockchip_dp_dt_ids' [-Wunused-const-variable] >static const struct of_device_id rockchip_dp_dt_ids[] = { > > [...] Applied, thanks! [1/1] drm/rockchip: remove of_match_ptr() commit: f7fc7a79bdbf20f2edef69dc62666a4f0cdac0e3 Best regards, -- Heiko Stuebner
Re: [PATCH v2 3/6] drm/edid: Add cea_sad helpers for freq/length
Hi Jani, On Tue, Sep 21, 2021 at 12:49:31PM +0300, Jani Nikula wrote: > On Mon, 20 Sep 2021, Markus Schneider-Pargmann wrote: > > This patch adds two helper functions that extract the frequency and word > > length from a struct cea_sad. > > > > For these helper functions new defines are added that help translate the > > 'freq' and 'byte2' fields into real numbers. > > > > Signed-off-by: Markus Schneider-Pargmann > > --- > > > > Notes: > > Changes v1 -> v2: > > - Use const struct pointers. > > - Add a check whether the format is actually uncompressed or not. > > > > drivers/gpu/drm/drm_edid.c | 74 ++ > > include/drm/drm_edid.h | 18 -- > > 2 files changed, 90 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c > > index 6325877c5fd6..28df422fbc03 100644 > > --- a/drivers/gpu/drm/drm_edid.c > > +++ b/drivers/gpu/drm/drm_edid.c > > @@ -4666,6 +4666,80 @@ int drm_edid_to_speaker_allocation(struct edid > > *edid, u8 **sadb) > > } > > EXPORT_SYMBOL(drm_edid_to_speaker_allocation); > > > > +/** > > + * drm_cea_sad_get_sample_rate - Extract the sample rate from cea_sad > > + * @sad: Pointer to the cea_sad struct > > + * > > + * Extracts the cea_sad frequency field and returns the sample rate in Hz. > > + * > > + * Return: Sample rate in Hz or a negative errno if parsing failed. > > + */ > > +int drm_cea_sad_get_sample_rate(const struct cea_sad *sad) > > +{ > > + switch (sad->freq) { > > + case CEA_SAD_FREQ_32KHZ: > > + return 32000; > > + case CEA_SAD_FREQ_44KHZ: > > + return 44100; > > + case CEA_SAD_FREQ_48KHZ: > > + return 48000; > > + case CEA_SAD_FREQ_88KHZ: > > + return 88200; > > + case CEA_SAD_FREQ_96KHZ: > > + return 96000; > > + case CEA_SAD_FREQ_176KHZ: > > + return 176400; > > + case CEA_SAD_FREQ_192KHZ: > > + return 192000; > > + default: > > + return -EINVAL; > > + } > > +} > > +EXPORT_SYMBOL(drm_cea_sad_get_sample_rate); > > + > > +static bool drm_cea_sad_is_uncompressed(const struct cea_sad *sad) > > +{ > > + switch (sad->format) { > > + case HDMI_AUDIO_CODING_TYPE_STREAM: > > + case HDMI_AUDIO_CODING_TYPE_PCM: > > + return true; > > + default: > > + return false; > > + } > > +} > > + > > +/** > > + * drm_cea_sad_get_uncompressed_word_length - Extract word length > > + * @sad: Pointer to the cea_sad struct > > + * > > + * Extracts the cea_sad byte2 field and returns the word length for an > > + * uncompressed stream. > > + * > > + * Note: This function may only be called for uncompressed audio. > > + * > > + * Return: Word length in bits or a negative errno if parsing failed. > > + */ > > +int drm_cea_sad_get_uncompressed_word_length(const struct cea_sad *sad) > > +{ > > + if (!drm_cea_sad_is_uncompressed(sad)) { > > + DRM_WARN("Unable to get the uncompressed word length for a > > compressed format: %u\n", > > +sad->format); > > + return -EINVAL; > > + } > > + > > + switch (sad->byte2) { > > + case CEA_SAD_UNCOMPRESSED_WORD_16BIT: > > + return 16; > > + case CEA_SAD_UNCOMPRESSED_WORD_20BIT: > > + return 20; > > + case CEA_SAD_UNCOMPRESSED_WORD_24BIT: > > + return 24; > > + default: > > + return -EINVAL; > > + } > > +} > > +EXPORT_SYMBOL(drm_cea_sad_get_uncompressed_word_length); > > + > > /** > > * drm_av_sync_delay - compute the HDMI/DP sink audio-video sync delay > > * @connector: connector associated with the HDMI/DP sink > > diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h > > index deccfd39e6db..7b7d71a7154d 100644 > > --- a/include/drm/drm_edid.h > > +++ b/include/drm/drm_edid.h > > @@ -361,12 +361,24 @@ struct edid { > > > > /* Short Audio Descriptor */ > > struct cea_sad { > > - u8 format; > > + u8 format; /* See HDMI_AUDIO_CODING_TYPE_* */ > > u8 channels; /* max number of channels - 1 */ > > - u8 freq; > > + u8 freq; /* See CEA_SAD_FREQ_* */ > > u8 byte2; /* meaning depends on format */ > > }; > > > > +#define CEA_SAD_FREQ_32KHZ BIT(0) > > +#define CEA_SAD_FREQ_44KHZ BIT(1) > > +#define CEA_SAD_FREQ_48KHZ BIT(2) > > +#define CEA_SAD_FREQ_88KHZ BIT(3) > > +#define CEA_SAD_FREQ_96KHZ BIT(4) > > +#define CEA_SAD_FREQ_176KHZ BIT(5) > > +#define CEA_SAD_FREQ_192KHZ BIT(6) > > + > > +#define CEA_SAD_UNCOMPRESSED_WORD_16BIT BIT(0) > > +#define CEA_SAD_UNCOMPRESSED_WORD_20BIT BIT(1) > > +#define CEA_SAD_UNCOMPRESSED_WORD_24BIT BIT(2) > > I suggest adding DRM_ prefixes here. Thanks, will do that. Best, Markus > > BR, > Jani. > > > + > > struct drm_encoder; > > struct drm_connector; > > struct drm_connector_state; > > @@ -374,6 +386,8 @@ struct drm_display_mode; > > > > int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads); > > int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sa
Re: [PATCH v1] drm/i915/bdb: Fix version check
pon., 20 wrz 2021 o 22:47 Souza, Jose napisał(a): > > On Mon, 2021-09-20 at 16:11 +0200, Lukasz Majczak wrote: > > With patch "drm/i915/vbt: Fix backlight parsing for VBT 234+" > > the size of bdb_lfp_backlight_data structure has been increased, > > causing if-statement in the parse_lfp_backlight function > > that comapres this structure size to the one retrieved from BDB, > > always to fail for older revisions. > > This patch fixes it by comparing a total size of all fileds from > > the structure (present before the change) with the value gathered from BDB. > > Tested on Chromebook Pixelbook (Nocturne) (reports bdb->version = 221) > > > > Cc: # 5.4+ > > Tested-by: Lukasz Majczak > > Signed-off-by: Lukasz Majczak > > --- > > drivers/gpu/drm/i915/display/intel_bios.c | 4 +++- > > drivers/gpu/drm/i915/display/intel_vbt_defs.h | 5 + > > 2 files changed, 8 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/gpu/drm/i915/display/intel_bios.c > > b/drivers/gpu/drm/i915/display/intel_bios.c > > index 3c25926092de..052a19b455d1 100644 > > --- a/drivers/gpu/drm/i915/display/intel_bios.c > > +++ b/drivers/gpu/drm/i915/display/intel_bios.c > > @@ -452,7 +452,9 @@ parse_lfp_backlight(struct drm_i915_private *i915, > > > > i915->vbt.backlight.type = INTEL_BACKLIGHT_DISPLAY_DDI; > > if (bdb->version >= 191 && > > - get_blocksize(backlight_data) >= sizeof(*backlight_data)) { > > + get_blocksize(backlight_data) >= > > (sizeof(backlight_data->entry_size) + > > + sizeof(backlight_data->data) + > > + sizeof(backlight_data->level))) > > { > > Missing sizeof(backlight_data->backlight_control) but this is getting very > verbose. > Would be better have a expected size variable set each version set in the > beginning of this function. > > something like: > switch (bdb->version) { > case 191: > expected_size = x; > break; > case 234: > expected_size = x; > break; > case 236: > default: > expected_size = x; > } > > > > const struct lfp_backlight_control_method *method; > > > > method = &backlight_data->backlight_control[panel_type]; > > diff --git a/drivers/gpu/drm/i915/display/intel_vbt_defs.h > > b/drivers/gpu/drm/i915/display/intel_vbt_defs.h > > index 330077c2e588..fff456bf8783 100644 > > --- a/drivers/gpu/drm/i915/display/intel_vbt_defs.h > > +++ b/drivers/gpu/drm/i915/display/intel_vbt_defs.h > > @@ -814,6 +814,11 @@ struct lfp_brightness_level { > > u16 reserved; > > } __packed; > > > > +/* > > + * Changing struct bdb_lfp_backlight_data might affect its > > + * size comparation to the value hold in BDB. > > + * (e.g. in parse_lfp_backlight()) > > + */ > > This is true for all the blocks so I don't think we need this comment. > > > struct bdb_lfp_backlight_data { > > u8 entry_size; > > struct lfp_backlight_data_entry data[16]; > Hi Jose, Jani Jani - you are right - I was working on 5.4 with a backported patch - I'm sorry for this confusion. Jose, Regarding expected_size, I couldn't find documentation that could described this structure size changes among revisions, so all I could do is to do an educated guess, basing on comments at this structure, like: (gdb) ptype /o struct bdb_lfp_backlight_data /* offset| size */ type = struct bdb_lfp_backlight_data { /*0 | 1 */u8 entry_size; /*1 |96 */struct lfp_backlight_data_entry data[16]; /* 97 |16 */u8 level[16]; /* 113 |16 */struct lfp_backlight_control_method backlight_control[16]; /* 129 |64 */struct lfp_brightness_level brightness_level[16]; /* 234+ */ /* 193 |64 */struct lfp_brightness_level brightness_min_level[16]; /* 234+ */ /* 257 |16 */u8 brightness_precision_bits[16]; /* 236+ */ /* total size (bytes): 273 */ } if (revision <= 234) expected_size = 129; else if (revision > 234 && revision <=236) expected_size = 257; else /* revision > 236 */ expected_size = 273; Is this approach ok? Otherwise I think I would need help from you to get exact numbers for each revision... Best regards, Lukasz
Re: [PATCH v1] drm/i915/bdb: Fix version check
On Tue, 21 Sep 2021, Radosław Biernacki wrote: > - dropping stable > > ... > >> > diff --git a/drivers/gpu/drm/i915/display/intel_vbt_defs.h >> > b/drivers/gpu/drm/i915/display/intel_vbt_defs.h >> > index 330077c2e588..fff456bf8783 100644 >> > --- a/drivers/gpu/drm/i915/display/intel_vbt_defs.h >> > +++ b/drivers/gpu/drm/i915/display/intel_vbt_defs.h >> > @@ -814,6 +814,11 @@ struct lfp_brightness_level { >> > u16 reserved; >> > } __packed; >> > >> > +/* >> > + * Changing struct bdb_lfp_backlight_data might affect its >> > + * size comparation to the value hold in BDB. >> > + * (e.g. in parse_lfp_backlight()) >> > + */ >> >> This is true for all the blocks so I don't think we need this comment. > > Lack of such comment was probable cause of this overlook. > As this is an example of the consequence (bricking platforms dependent > on mentioned conditions) IMO we need some comment here, or this will > probably happen again. The whole file is full of __packed structs with the sole purpose of parsing VBT data in memory. People are generally well aware of the consequences of changing the size, and this is the only such mistake I can recall. BR, Jani. > > >> >> > struct bdb_lfp_backlight_data { >> > u8 entry_size; >> > struct lfp_backlight_data_entry data[16]; >> -- Jani Nikula, Intel Open Source Graphics Center
[PATCH v4 01/14] drm/ttm: stop calling tt_swapin in vm_access
In commit: commit 09ac4fcb3f255e9225967c75f5893325c116cdbe Author: Felix Kuehling Date: Thu Jul 13 17:01:16 2017 -0400 drm/ttm: Implement vm_operations_struct.access v2 we added the vm_access hook, where we also directly call tt_swapin for some reason. If something is swapped-out then the ttm_tt must also be unpopulated, and since access_kmap should also call tt_populate, if needed, then swapping-in will already be handled there. If anything, calling tt_swapin directly here would likely always fail since the tt->pages won't yet be populated, or worse since the tt->pages array is never actually cleared in unpopulate this might lead to a nasty uaf. Fixes: 09ac4fcb3f25 ("drm/ttm: Implement vm_operations_struct.access v2") Signed-off-by: Matthew Auld Cc: Thomas Hellström Cc: Christian König --- drivers/gpu/drm/ttm/ttm_bo_vm.c | 5 - 1 file changed, 5 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index f56be5bc0861..5b9b7fd01a69 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -519,11 +519,6 @@ int ttm_bo_vm_access(struct vm_area_struct *vma, unsigned long addr, switch (bo->resource->mem_type) { case TTM_PL_SYSTEM: - if (unlikely(bo->ttm->page_flags & TTM_PAGE_FLAG_SWAPPED)) { - ret = ttm_tt_swapin(bo->ttm); - if (unlikely(ret != 0)) - return ret; - } fallthrough; case TTM_PL_TT: ret = ttm_bo_vm_access_kmap(bo, offset, buf, len, write); -- 2.26.3
[PATCH v4 02/14] drm/ttm: stop setting page->index for the ttm_tt
In commit: commit 58aa6622d32af7d2c08d45085f44c54554a16ed7 Author: Thomas Hellstrom Date: Fri Jan 3 11:47:23 2014 +0100 drm/ttm: Correctly set page mapping and -index members we started setting the page->mapping and page->index to point to the virtual address space, if the pages were faulted with TTM. Apparently this was needed for core-mm to able to reverse lookup the virtual address given the struct page, and potentially unmap it from the page tables. However as pointed out by Thomas, since we are now using PFN_MAP, instead of say PFN_MIXED, this should no longer be the case. There was also apparently some usecase in vmwgfx which needed this for dirty tracking, but that also doesn't appear to be the case anymore, as pointed out by Thomas. We still need keep the page->mapping for now, since that is still needed for different reasons, but we try to address that in the next patch. Signed-off-by: Matthew Auld Cc: Thomas Hellström Cc: Christian König Reviewed-by: Christian König --- drivers/gpu/drm/ttm/ttm_bo_vm.c | 2 -- drivers/gpu/drm/ttm/ttm_tt.c| 4 +--- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index 5b9b7fd01a69..9a2119fe4bdd 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -346,8 +346,6 @@ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf, } else if (unlikely(!page)) { break; } - page->index = drm_vma_node_start(&bo->base.vma_node) + - page_offset; pfn = page_to_pfn(page); } diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index dae52433beeb..1cc04c224988 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c @@ -367,10 +367,8 @@ static void ttm_tt_clear_mapping(struct ttm_tt *ttm) if (ttm->page_flags & TTM_PAGE_FLAG_SG) return; - for (i = 0; i < ttm->num_pages; ++i) { + for (i = 0; i < ttm->num_pages; ++i) (*page)->mapping = NULL; - (*page++)->index = 0; - } } void ttm_tt_unpopulate(struct ttm_device *bdev, struct ttm_tt *ttm) -- 2.26.3
[PATCH v4 03/14] drm/ttm: move ttm_tt_{add, clear}_mapping into amdgpu
Now that setting page->index shouldn't be needed anymore, we are just left with setting page->mapping, and here it looks like amdgpu is the only user, where pointing the page->mapping at the dev_mapping is used to verify that the pages do indeed belong to the device, if userspace later tries to touch them. v2(Christian): - Drop the functions altogether and just inline modifying the page->mapping Signed-off-by: Matthew Auld Cc: Thomas Hellström Cc: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 15 ++- drivers/gpu/drm/ttm/ttm_tt.c| 25 - 2 files changed, 14 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 820fcb24231f..438377a89aa3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -1119,6 +1119,8 @@ static int amdgpu_ttm_tt_populate(struct ttm_device *bdev, { struct amdgpu_device *adev = amdgpu_ttm_adev(bdev); struct amdgpu_ttm_tt *gtt = (void *)ttm; + pgoff_t i; + int ret; /* user pages are bound by amdgpu_ttm_tt_pin_userptr() */ if (gtt->userptr) { @@ -1131,7 +1133,14 @@ static int amdgpu_ttm_tt_populate(struct ttm_device *bdev, if (ttm->page_flags & TTM_PAGE_FLAG_SG) return 0; - return ttm_pool_alloc(&adev->mman.bdev.pool, ttm, ctx); + ret = ttm_pool_alloc(&adev->mman.bdev.pool, ttm, ctx); + if (ret) + return ret; + + for (i = 0; i < ttm->num_pages; ++i) + ttm->pages[i]->mapping = bdev->dev_mapping; + + return 0; } /* @@ -1145,6 +1154,7 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_device *bdev, { struct amdgpu_ttm_tt *gtt = (void *)ttm; struct amdgpu_device *adev; + pgoff_t i; amdgpu_ttm_backend_unbind(bdev, ttm); @@ -1158,6 +1168,9 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_device *bdev, if (ttm->page_flags & TTM_PAGE_FLAG_SG) return; + for (i = 0; i < ttm->num_pages; ++i) + ttm->pages[i]->mapping = NULL; + adev = amdgpu_ttm_adev(bdev); return ttm_pool_free(&adev->mman.bdev.pool, ttm); } diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index 1cc04c224988..980ecb079b2c 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c @@ -289,17 +289,6 @@ int ttm_tt_swapout(struct ttm_device *bdev, struct ttm_tt *ttm, return ret; } -static void ttm_tt_add_mapping(struct ttm_device *bdev, struct ttm_tt *ttm) -{ - pgoff_t i; - - if (ttm->page_flags & TTM_PAGE_FLAG_SG) - return; - - for (i = 0; i < ttm->num_pages; ++i) - ttm->pages[i]->mapping = bdev->dev_mapping; -} - int ttm_tt_populate(struct ttm_device *bdev, struct ttm_tt *ttm, struct ttm_operation_ctx *ctx) { @@ -336,7 +325,6 @@ int ttm_tt_populate(struct ttm_device *bdev, if (ret) goto error; - ttm_tt_add_mapping(bdev, ttm); ttm->page_flags |= TTM_PAGE_FLAG_PRIV_POPULATED; if (unlikely(ttm->page_flags & TTM_PAGE_FLAG_SWAPPED)) { ret = ttm_tt_swapin(ttm); @@ -359,24 +347,11 @@ int ttm_tt_populate(struct ttm_device *bdev, } EXPORT_SYMBOL(ttm_tt_populate); -static void ttm_tt_clear_mapping(struct ttm_tt *ttm) -{ - pgoff_t i; - struct page **page = ttm->pages; - - if (ttm->page_flags & TTM_PAGE_FLAG_SG) - return; - - for (i = 0; i < ttm->num_pages; ++i) - (*page)->mapping = NULL; -} - void ttm_tt_unpopulate(struct ttm_device *bdev, struct ttm_tt *ttm) { if (!ttm_tt_is_populated(ttm)) return; - ttm_tt_clear_mapping(ttm); if (bdev->funcs->ttm_tt_unpopulate) bdev->funcs->ttm_tt_unpopulate(bdev, ttm); else -- 2.26.3
[PATCH v4 04/14] drm/ttm: remove TTM_PAGE_FLAG_NO_RETRY
No longer used it seems. Signed-off-by: Matthew Auld Cc: Thomas Hellström Cc: Christian König Reviewed-by: Christian König --- include/drm/ttm/ttm_tt.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/drm/ttm/ttm_tt.h b/include/drm/ttm/ttm_tt.h index 89b15d673b22..842ce756213c 100644 --- a/include/drm/ttm/ttm_tt.h +++ b/include/drm/ttm/ttm_tt.h @@ -41,7 +41,6 @@ struct ttm_operation_ctx; #define TTM_PAGE_FLAG_SWAPPED (1 << 4) #define TTM_PAGE_FLAG_ZERO_ALLOC (1 << 6) #define TTM_PAGE_FLAG_SG (1 << 8) -#define TTM_PAGE_FLAG_NO_RETRY (1 << 9) #define TTM_PAGE_FLAG_PRIV_POPULATED (1 << 31) -- 2.26.3
[PATCH v4 05/14] drm/ttm: s/FLAG_SG/FLAG_EXTERNAL/
It covers more than just ttm_bo_type_sg usage, like with say dma-buf, since one other user is userptr in amdgpu, and in the future we might have some more. Hence EXTERNAL is likely a more suitable name. v2(Christian): - Rename these to TTM_TT_FLAGS_* - Fix up all the holes in the flag values Suggested-by: Christian König Signed-off-by: Matthew Auld Cc: Thomas Hellström Cc: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 10 +- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 6 +++--- drivers/gpu/drm/nouveau/nouveau_bo.c| 4 ++-- drivers/gpu/drm/radeon/radeon_ttm.c | 8 drivers/gpu/drm/ttm/ttm_bo.c| 4 ++-- drivers/gpu/drm/ttm/ttm_bo_util.c | 4 ++-- drivers/gpu/drm/ttm/ttm_bo_vm.c | 2 +- drivers/gpu/drm/ttm/ttm_pool.c | 2 +- drivers/gpu/drm/ttm/ttm_tt.c| 24 include/drm/ttm/ttm_device.h| 2 +- include/drm/ttm/ttm_tt.h| 18 +- 11 files changed, 42 insertions(+), 42 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 438377a89aa3..0cf94421665f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -894,7 +894,7 @@ static int amdgpu_ttm_backend_bind(struct ttm_device *bdev, DRM_ERROR("failed to pin userptr\n"); return r; } - } else if (ttm->page_flags & TTM_PAGE_FLAG_SG) { + } else if (ttm->page_flags & TTM_TT_FLAG_EXTERNAL) { if (!ttm->sg) { struct dma_buf_attachment *attach; struct sg_table *sgt; @@ -1130,7 +1130,7 @@ static int amdgpu_ttm_tt_populate(struct ttm_device *bdev, return 0; } - if (ttm->page_flags & TTM_PAGE_FLAG_SG) + if (ttm->page_flags & TTM_TT_FLAG_EXTERNAL) return 0; ret = ttm_pool_alloc(&adev->mman.bdev.pool, ttm, ctx); @@ -1165,7 +1165,7 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_device *bdev, return; } - if (ttm->page_flags & TTM_PAGE_FLAG_SG) + if (ttm->page_flags & TTM_TT_FLAG_EXTERNAL) return; for (i = 0; i < ttm->num_pages; ++i) @@ -1198,8 +1198,8 @@ int amdgpu_ttm_tt_set_userptr(struct ttm_buffer_object *bo, return -ENOMEM; } - /* Set TTM_PAGE_FLAG_SG before populate but after create. */ - bo->ttm->page_flags |= TTM_PAGE_FLAG_SG; + /* Set TTM_TT_FLAG_EXTERNAL before populate but after create. */ + bo->ttm->page_flags |= TTM_TT_FLAG_EXTERNAL; gtt = (void *)bo->ttm; gtt->userptr = addr; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c index 2f672f06b169..fd5b925b27c5 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -182,7 +182,7 @@ static struct ttm_tt *i915_ttm_tt_create(struct ttm_buffer_object *bo, if (obj->flags & I915_BO_ALLOC_CPU_CLEAR && man->use_tt) - page_flags |= TTM_PAGE_FLAG_ZERO_ALLOC; + page_flags |= TTM_TT_FLAG_ZERO_ALLOC; ret = ttm_tt_init(&i915_tt->ttm, bo, page_flags, i915_ttm_select_tt_caching(obj)); @@ -546,7 +546,7 @@ static int i915_ttm_move(struct ttm_buffer_object *bo, bool evict, } /* Populate ttm with pages if needed. Typically system memory. */ - if (ttm && (dst_man->use_tt || (ttm->page_flags & TTM_PAGE_FLAG_SWAPPED))) { + if (ttm && (dst_man->use_tt || (ttm->page_flags & TTM_TT_FLAG_SWAPPED))) { ret = ttm_tt_populate(bo->bdev, ttm, ctx); if (ret) return ret; @@ -557,7 +557,7 @@ static int i915_ttm_move(struct ttm_buffer_object *bo, bool evict, return PTR_ERR(dst_st); clear = !cpu_maps_iomem(bo->resource) && (!ttm || !ttm_tt_is_populated(ttm)); - if (!(clear && ttm && !(ttm->page_flags & TTM_PAGE_FLAG_ZERO_ALLOC))) + if (!(clear && ttm && !(ttm->page_flags & TTM_TT_FLAG_ZERO_ALLOC))) __i915_ttm_move(bo, clear, dst_mem, dst_st); ttm_bo_move_sync_cleanup(bo, dst_mem); diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index d3b21d318b42..12b107acb6ee 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -1250,7 +1250,7 @@ nouveau_ttm_tt_populate(struct ttm_device *bdev, struct ttm_tt *ttm_dma = (void *)ttm; struct nouveau_drm *drm; struct device *dev; - bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG); + bool slave = !!(ttm->page_flags & TTM_TT_FLAG_EXTERNAL); if (ttm_tt_is_populated(ttm)) return 0; @@ -1273,7 +1273,7 @@ nouveau_ttm_tt_unpopulate(struct ttm_
[PATCH v4 06/14] drm/ttm: add some kernel-doc for TTM_TT_FLAG_*
Move it to inline kernel-doc, otherwise we can't add empty lines it seems. Also drop the kernel-doc for pages_list, which doesn't seem to exist. Signed-off-by: Matthew Auld Cc: Thomas Hellström Cc: Christian König --- include/drm/ttm/ttm_tt.h | 57 ++-- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/include/drm/ttm/ttm_tt.h b/include/drm/ttm/ttm_tt.h index b023cd58ff38..f3ef568da651 100644 --- a/include/drm/ttm/ttm_tt.h +++ b/include/drm/ttm/ttm_tt.h @@ -38,35 +38,54 @@ struct ttm_resource; struct ttm_buffer_object; struct ttm_operation_ctx; -#define TTM_TT_FLAG_SWAPPED(1 << 0) -#define TTM_TT_FLAG_ZERO_ALLOC (1 << 1) -#define TTM_TT_FLAG_EXTERNAL (1 << 2) - -#define TTM_TT_FLAG_PRIV_POPULATED (1 << 31) - /** - * struct ttm_tt - * - * @pages: Array of pages backing the data. - * @page_flags: see TTM_TT_FLAG_* - * @num_pages: Number of pages in the page array. - * @sg: for SG objects via dma-buf - * @dma_address: The DMA (bus) addresses of the pages - * @swap_storage: Pointer to shmem struct file for swap storage. - * @pages_list: used by some page allocation backend - * @caching: The current caching state of the pages, see enum ttm_caching. - * - * This is a structure holding the pages, caching- and aperture binding - * status for a buffer object that isn't backed by fixed (VRAM / AGP) + * struct ttm_tt - This is a structure holding the pages, caching- and aperture + * binding status for a buffer object that isn't backed by fixed (VRAM / AGP) * memory. */ struct ttm_tt { + /** @pages: Array of pages backing the data. */ struct page **pages; + /** +* @page_flags: The page flags. +* +* Supported values: +* +* TTM_TT_FLAG_SWAPPED: Set if the pages have been swapped out. +* Calling ttm_tt_populate() will swap the pages back in, and unset the +* flag. +* +* TTM_TT_FLAG_ZERO_ALLOC: Set if the pages will be zeroed on +* allocation. +* +* TTM_TT_FLAG_EXTERNAL: Set if the underlying pages were allocated +* externally, like with dma-buf or userptr. This effectively disables +* TTM swapping out such pages. Also important is to prevent TTM from +* ever directly mapping these pages. +* +* Note that enum ttm_bo_type.ttm_bo_type_sg objects will always enable +* this flag. +* +* TTM_TT_FLAG_PRIV_POPULATED: TTM internal only. DO NOT USE. +*/ +#define TTM_TT_FLAG_SWAPPED(1 << 0) +#define TTM_TT_FLAG_ZERO_ALLOC (1 << 1) +#define TTM_TT_FLAG_EXTERNAL (1 << 2) + +#define TTM_TT_FLAG_PRIV_POPULATED (1 << 31) uint32_t page_flags; + /** @num_pages: Number of pages in the page array. */ uint32_t num_pages; + /** @sg: for SG objects via dma-buf. */ struct sg_table *sg; + /** @dma_address: The DMA (bus) addresses of the pages. */ dma_addr_t *dma_address; + /** @swap_storage: Pointer to shmem struct file for swap storage. */ struct file *swap_storage; + /** +* @caching: The current caching state of the pages, see enum +* ttm_caching. +*/ enum ttm_caching caching; }; -- 2.26.3
[PATCH v4 09/14] drm/i915/ttm: add tt shmem backend
For cached objects we can allocate our pages directly in shmem. This should make it possible(in a later patch) to utilise the existing i915-gem shrinker code for such objects. For now this is still disabled. v2(Thomas): - Add optional try_to_writeback hook for objects. Importantly we need to check if the object is even still shrinkable; in between us dropping the shrinker LRU lock and acquiring the object lock it could for example have been moved. Also we need to differentiate between "lazy" shrinking and the immediate writeback mode. Also later we need to handle objects which don't even have mm.pages, so bundling this into put_pages() would require somehow handling that edge case, hence just letting the ttm backend handle everything in try_to_writeback doesn't seem too bad. Signed-off-by: Matthew Auld Cc: Thomas Hellström Cc: Christian König --- drivers/gpu/drm/i915/gem/i915_gem_object.h| 8 + .../gpu/drm/i915/gem/i915_gem_object_types.h | 2 + drivers/gpu/drm/i915/gem/i915_gem_shmem.c | 14 +- drivers/gpu/drm/i915/gem/i915_gem_shrinker.c | 17 +- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 252 -- 5 files changed, 258 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index 48112b9d76df..561d6bd0a5c9 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -618,6 +618,14 @@ int i915_gem_object_wait_migration(struct drm_i915_gem_object *obj, bool i915_gem_object_placement_possible(struct drm_i915_gem_object *obj, enum intel_memory_type type); +struct sg_table *shmem_alloc_st(struct drm_i915_private *i915, + size_t size, struct intel_memory_region *mr, + struct address_space *mapping, + unsigned int max_segment); +void shmem_free_st(struct sg_table *st, struct address_space *mapping, + bool dirty, bool backup); +void __shmem_writeback(size_t size, struct address_space *mapping); + #ifdef CONFIG_MMU_NOTIFIER static inline bool i915_gem_object_is_userptr(struct drm_i915_gem_object *obj) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h index 2471f36aaff3..1b7ba859cf5e 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h @@ -56,6 +56,8 @@ struct drm_i915_gem_object_ops { struct sg_table *pages); void (*truncate)(struct drm_i915_gem_object *obj); void (*writeback)(struct drm_i915_gem_object *obj); + int (*try_to_writeback)(struct drm_i915_gem_object *obj, + bool do_writeback); int (*pread)(struct drm_i915_gem_object *obj, const struct drm_i915_gem_pread *arg); diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c index 36b711ae9e28..19e55cc29a15 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c @@ -25,8 +25,8 @@ static void check_release_pagevec(struct pagevec *pvec) cond_resched(); } -static void shmem_free_st(struct sg_table *st, struct address_space *mapping, - bool dirty, bool backup) +void shmem_free_st(struct sg_table *st, struct address_space *mapping, + bool dirty, bool backup) { struct sgt_iter sgt_iter; struct pagevec pvec; @@ -52,10 +52,10 @@ static void shmem_free_st(struct sg_table *st, struct address_space *mapping, kfree(st); } -static struct sg_table *shmem_alloc_st(struct drm_i915_private *i915, - size_t size, struct intel_memory_region *mr, - struct address_space *mapping, - unsigned int max_segment) +struct sg_table *shmem_alloc_st(struct drm_i915_private *i915, + size_t size, struct intel_memory_region *mr, + struct address_space *mapping, + unsigned int max_segment) { const unsigned long page_count = size / PAGE_SIZE; unsigned long i; @@ -300,7 +300,7 @@ shmem_truncate(struct drm_i915_gem_object *obj) obj->mm.pages = ERR_PTR(-EFAULT); } -static void __shmem_writeback(size_t size, struct address_space *mapping) +void __shmem_writeback(size_t size, struct address_space *mapping) { struct writeback_control wbc = { .sync_mode = WB_SYNC_NONE, diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c index e382b7f2353b..478663dc42b4 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_shr
[PATCH v4 07/14] drm/ttm: add TTM_TT_FLAG_EXTERNAL_MAPPABLE
In commit: commit 667a50db0477d47fdff01c666f5ee1ce26b5264c Author: Thomas Hellstrom Date: Fri Jan 3 11:17:18 2014 +0100 drm/ttm: Refuse to fault (prime-) imported pages we introduced the restriction that imported pages should not be directly mappable through TTM(this also extends to userptr). In the next patch we want to introduce a shmem_tt backend, which should follow all the existing rules with TTM_PAGE_FLAG_EXTERNAL, since it will need to handle swapping itself, but with the above mapping restriction lifted. v2(Christian): - Don't OR together EXTERNAL and EXTERNAL_MAPPABLE in the definition of EXTERNAL_MAPPABLE, just leave it the caller to handle this correctly, otherwise we might encounter subtle issues. Signed-off-by: Matthew Auld Cc: Thomas Hellström Cc: Christian König --- drivers/gpu/drm/ttm/ttm_bo_vm.c | 6 -- drivers/gpu/drm/ttm/ttm_tt.c| 3 +++ include/drm/ttm/ttm_tt.h| 19 --- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index 950f4f132802..33680c94127c 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -163,8 +163,10 @@ vm_fault_t ttm_bo_vm_reserve(struct ttm_buffer_object *bo, * (if at all) by redirecting mmap to the exporter. */ if (bo->ttm && (bo->ttm->page_flags & TTM_TT_FLAG_EXTERNAL)) { - dma_resv_unlock(bo->base.resv); - return VM_FAULT_SIGBUS; + if (!(bo->ttm->page_flags & TTM_TT_FLAG_EXTERNAL_MAPPABLE)) { + dma_resv_unlock(bo->base.resv); + return VM_FAULT_SIGBUS; + } } return 0; diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index 86f31fde6e35..7e83c00a3f48 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c @@ -84,6 +84,9 @@ int ttm_tt_create(struct ttm_buffer_object *bo, bool zero_alloc) if (unlikely(bo->ttm == NULL)) return -ENOMEM; + WARN_ON(bo->ttm->page_flags & TTM_TT_FLAG_EXTERNAL_MAPPABLE && + !(bo->ttm->page_flags & TTM_TT_FLAG_EXTERNAL)); + return 0; } diff --git a/include/drm/ttm/ttm_tt.h b/include/drm/ttm/ttm_tt.h index f3ef568da651..5995b8ee1667 100644 --- a/include/drm/ttm/ttm_tt.h +++ b/include/drm/ttm/ttm_tt.h @@ -66,11 +66,24 @@ struct ttm_tt { * Note that enum ttm_bo_type.ttm_bo_type_sg objects will always enable * this flag. * +* TTM_TT_FLAG_EXTERNAL_MAPPABLE: Same behaviour as +* TTM_TT_FLAG_EXTERNAL, but with the reduced restriction that it is +* still valid to use TTM to map the pages directly. This is useful when +* implementing a ttm_tt backend which still allocates driver owned +* pages underneath(say with shmem). +* +* Note that since this also implies TTM_TT_FLAG_EXTERNAL, the usage +* here should always be: +* +* page_flags = TTM_TT_FLAG_EXTERNAL | +*TTM_TT_FLAG_EXTERNAL_MAPPABLE; +* * TTM_TT_FLAG_PRIV_POPULATED: TTM internal only. DO NOT USE. */ -#define TTM_TT_FLAG_SWAPPED(1 << 0) -#define TTM_TT_FLAG_ZERO_ALLOC (1 << 1) -#define TTM_TT_FLAG_EXTERNAL (1 << 2) +#define TTM_TT_FLAG_SWAPPED(1 << 0) +#define TTM_TT_FLAG_ZERO_ALLOC (1 << 1) +#define TTM_TT_FLAG_EXTERNAL (1 << 2) +#define TTM_TT_FLAG_EXTERNAL_MAPPABLE (1 << 3) #define TTM_TT_FLAG_PRIV_POPULATED (1 << 31) uint32_t page_flags; -- 2.26.3
[PATCH v4 08/14] drm/i915/gem: Break out some shmem backend utils
From: Thomas Hellström Break out some shmem backend utils for future reuse by the TTM backend: shmem_alloc_st(), shmem_free_st() and __shmem_writeback() which we can use to provide a shmem-backed TTM page pool for cached-only TTM buffer objects. Main functional change here is that we now compute the page sizes using the dma segments rather than using the physical page address segments. v2(Reported-by: kernel test robot ) - Make sure we initialise the mapping on the error path in shmem_get_pages() Signed-off-by: Thomas Hellström Reviewed-by: Matthew Auld Signed-off-by: Matthew Auld --- drivers/gpu/drm/i915/gem/i915_gem_shmem.c | 181 +- 1 file changed, 106 insertions(+), 75 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c index 11f072193f3b..36b711ae9e28 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c @@ -25,46 +25,61 @@ static void check_release_pagevec(struct pagevec *pvec) cond_resched(); } -static int shmem_get_pages(struct drm_i915_gem_object *obj) +static void shmem_free_st(struct sg_table *st, struct address_space *mapping, + bool dirty, bool backup) { - struct drm_i915_private *i915 = to_i915(obj->base.dev); - struct intel_memory_region *mem = obj->mm.region; - const unsigned long page_count = obj->base.size / PAGE_SIZE; + struct sgt_iter sgt_iter; + struct pagevec pvec; + struct page *page; + + mapping_clear_unevictable(mapping); + + pagevec_init(&pvec); + for_each_sgt_page(page, sgt_iter, st) { + if (dirty) + set_page_dirty(page); + + if (backup) + mark_page_accessed(page); + + if (!pagevec_add(&pvec, page)) + check_release_pagevec(&pvec); + } + if (pagevec_count(&pvec)) + check_release_pagevec(&pvec); + + sg_free_table(st); + kfree(st); +} + +static struct sg_table *shmem_alloc_st(struct drm_i915_private *i915, + size_t size, struct intel_memory_region *mr, + struct address_space *mapping, + unsigned int max_segment) +{ + const unsigned long page_count = size / PAGE_SIZE; unsigned long i; - struct address_space *mapping; struct sg_table *st; struct scatterlist *sg; - struct sgt_iter sgt_iter; struct page *page; unsigned long last_pfn = 0; /* suppress gcc warning */ - unsigned int max_segment = i915_sg_segment_size(); - unsigned int sg_page_sizes; gfp_t noreclaim; int ret; - /* -* Assert that the object is not currently in any GPU domain. As it -* wasn't in the GTT, there shouldn't be any way it could have been in -* a GPU cache -*/ - GEM_BUG_ON(obj->read_domains & I915_GEM_GPU_DOMAINS); - GEM_BUG_ON(obj->write_domain & I915_GEM_GPU_DOMAINS); - /* * If there's no chance of allocating enough pages for the whole * object, bail early. */ - if (obj->base.size > resource_size(&mem->region)) - return -ENOMEM; + if (size > resource_size(&mr->region)) + return ERR_PTR(-ENOMEM); st = kmalloc(sizeof(*st), GFP_KERNEL); if (!st) - return -ENOMEM; + return ERR_PTR(-ENOMEM); -rebuild_st: if (sg_alloc_table(st, page_count, GFP_KERNEL)) { kfree(st); - return -ENOMEM; + return ERR_PTR(-ENOMEM); } /* @@ -73,14 +88,12 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj) * * Fail silently without starting the shrinker */ - mapping = obj->base.filp->f_mapping; mapping_set_unevictable(mapping); noreclaim = mapping_gfp_constraint(mapping, ~__GFP_RECLAIM); noreclaim |= __GFP_NORETRY | __GFP_NOWARN; sg = st->sgl; st->nents = 0; - sg_page_sizes = 0; for (i = 0; i < page_count; i++) { const unsigned int shrink[] = { I915_SHRINK_BOUND | I915_SHRINK_UNBOUND, @@ -135,10 +148,9 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj) if (!i || sg->length >= max_segment || page_to_pfn(page) != last_pfn + 1) { - if (i) { - sg_page_sizes |= sg->length; + if (i) sg = sg_next(sg); - } + st->nents++; sg_set_page(sg, page, PAGE_SIZE, 0); } else { @@ -149,14 +161,65 @@ static int shmem_get_pages(struct drm_i915_gem_object *
[PATCH v4 11/14] drm/i915/ttm: use cached system pages when evicting lmem
This should let us do an accelerated copy directly to the shmem pages when temporarily moving lmem-only objects, where the i915-gem shrinker can later kick in to swap out the pages, if needed. Signed-off-by: Matthew Auld Cc: Thomas Hellström --- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c index b438ddb52764..f4f7010e1c15 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -125,11 +125,11 @@ static enum ttm_caching i915_ttm_select_tt_caching(const struct drm_i915_gem_object *obj) { /* -* Objects only allowed in system get cached cpu-mappings. -* Other objects get WC mapping for now. Even if in system. +* Objects only allowed in system get cached cpu-mappings, or when +* evicting lmem-only buffers to system for swapping. Other objects get +* WC mapping for now. Even if in system. */ - if (obj->mm.region->type == INTEL_MEMORY_SYSTEM && - obj->mm.n_placements <= 1) + if (obj->mm.n_placements <= 1) return ttm_cached; return ttm_write_combined; -- 2.26.3
[PATCH v4 10/14] drm/i915/ttm: hide shmem objects from TTM LRU
This is probably a NAK. But ideally we need to somehow prevent TTM from seeing shmem objects when doing its LRU swap walk. Since these are EXTERNAL they are ignored anyway, but keeping them in the LRU seems pretty wasteful. Trying to use bo_pin() for this is all kinds of nasty since we need to be able to do the bo_unpin() from the unpopulate hook, but since that can be called from the BO destroy path we will likely go down in flames. An alternative is to maybe just add EXTERNAL objects to some bdev->external LRU in TTM, or just don't add them at all? Signed-off-by: Matthew Auld Cc: Thomas Hellström Cc: Christian König --- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 17 + 1 file changed, 17 insertions(+) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c index 174aebe11264..b438ddb52764 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -800,6 +800,22 @@ static unsigned long i915_ttm_io_mem_pfn(struct ttm_buffer_object *bo, return ((base + sg_dma_address(sg)) >> PAGE_SHIFT) + ofs; } +static void i915_ttm_del_from_lru_notify(struct ttm_buffer_object *bo) +{ + struct i915_ttm_tt *i915_tt = + container_of(bo->ttm, typeof(*i915_tt), ttm); + + /* Idealy we need to prevent TTM from seeing shmem objects when doing +* its LRU swap walk. Since these are EXTERNAL they are ignored anyway, +* but keeping them in the LRU is pretty waseful. Trying to use bo_pin() +* for this is very nasty since we need to be able to do the bo_unpin() +* from the unpopulate hook, but since that can be called from the BO +* destroy path we will go down in flames. +*/ + if (bo->ttm && ttm_tt_is_populated(bo->ttm) && i915_tt->is_shmem) + list_del_init(&bo->lru); +} + static struct ttm_device_funcs i915_ttm_bo_driver = { .ttm_tt_create = i915_ttm_tt_create, .ttm_tt_populate = i915_ttm_tt_populate, @@ -810,6 +826,7 @@ static struct ttm_device_funcs i915_ttm_bo_driver = { .move = i915_ttm_move, .swap_notify = i915_ttm_swap_notify, .delete_mem_notify = i915_ttm_delete_mem_notify, + .del_from_lru_notify = i915_ttm_del_from_lru_notify, .io_mem_reserve = i915_ttm_io_mem_reserve, .io_mem_pfn = i915_ttm_io_mem_pfn, }; -- 2.26.3
[PATCH v4 12/14] drm/i915: try to simplify make_{un}shrinkable
Drop the atomic shrink_pin stuff, and just have make_{un}shrinkable update the shrinker visible lists immediately. This at least simplifies the next patch, and does make the behaviour more obvious. The potential downside is that make_unshrinkable now grabs a global lock even when the object itself is no longer shrinkable(transitioning from purgeable <-> shrinkable doesn't seem to be a thing), for example in the ppGTT insertion paths we should now be careful not to needlessly call make_unshrinkable multiple times. Outside of that there is some fallout in intel_context which relies on nesting calls to shrink_pin. Signed-off-by: Matthew Auld Cc: Thomas Hellström --- drivers/gpu/drm/i915/gem/i915_gem_object.c| 9 .../gpu/drm/i915/gem/i915_gem_object_types.h | 3 +- drivers/gpu/drm/i915/gem/i915_gem_pages.c | 16 +- drivers/gpu/drm/i915/gem/i915_gem_shrinker.c | 52 +-- drivers/gpu/drm/i915/gt/gen6_ppgtt.c | 1 - drivers/gpu/drm/i915/gt/gen8_ppgtt.c | 1 - drivers/gpu/drm/i915/gt/intel_context.c | 9 +--- 7 files changed, 41 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c index 6fb9afb65034..e8265a432fcb 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c @@ -305,15 +305,6 @@ static void i915_gem_free_object(struct drm_gem_object *gem_obj) */ atomic_inc(&i915->mm.free_count); - /* -* This serializes freeing with the shrinker. Since the free -* is delayed, first by RCU then by the workqueue, we want the -* shrinker to be able to free pages of unreferenced objects, -* or else we may oom whilst there are plenty of deferred -* freed objects. -*/ - i915_gem_object_make_unshrinkable(obj); - /* * Since we require blocking on struct_mutex to unbind the freed * object from the GPU before releasing resources back to the diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h index 1b7ba859cf5e..a0069c643e3d 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h @@ -455,7 +455,6 @@ struct drm_i915_gem_object { * instead go through the pin/unpin interfaces. */ atomic_t pages_pin_count; - atomic_t shrink_pin; /** * Priority list of potential placements for this object. @@ -516,7 +515,7 @@ struct drm_i915_gem_object { struct i915_gem_object_page_iter get_dma_page; /** -* Element within i915->mm.unbound_list or i915->mm.bound_list, +* Element within i915->mm.shrink_list or i915->mm.purge_list, * locked by i915->mm.obj_lock. */ struct list_head link; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c index 8eb1c3a6fc9c..f0df1394d7f6 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c @@ -64,28 +64,16 @@ void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, GEM_BUG_ON(i915_gem_object_has_tiling_quirk(obj)); i915_gem_object_set_tiling_quirk(obj); GEM_BUG_ON(!list_empty(&obj->mm.link)); - atomic_inc(&obj->mm.shrink_pin); shrinkable = false; } if (shrinkable) { - struct list_head *list; - unsigned long flags; - assert_object_held(obj); - spin_lock_irqsave(&i915->mm.obj_lock, flags); - - i915->mm.shrink_count++; - i915->mm.shrink_memory += obj->base.size; if (obj->mm.madv != I915_MADV_WILLNEED) - list = &i915->mm.purge_list; + i915_gem_object_make_purgeable(obj); else - list = &i915->mm.shrink_list; - list_add_tail(&obj->mm.link, list); - - atomic_set(&obj->mm.shrink_pin, 0); - spin_unlock_irqrestore(&i915->mm.obj_lock, flags); + i915_gem_object_make_shrinkable(obj); } } diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c index 478663dc42b4..4f5d49ada9e6 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c @@ -460,23 +460,26 @@ void i915_gem_shrinker_taints_mutex(struct drm_i915_private *i915, #define obj_to_i915(obj__) to_i915((obj__)->base.dev) +/** + * i915_gem_object_make_unshrinkable - Hide the object from the shrinker. By + * default all object types that support shrinking(see IS_SHRINKABLE), will also + * make the
[PATCH v4 13/14] drm/i915/ttm: make evicted shmem pages visible to the shrinker
We currently just evict lmem objects to system memory when under memory pressure. For this case we lack the usual object mm.pages, which effectively hides the pages from the i915-gem shrinker, until we actually "attach" the TT to the object, or in the case of lmem-only objects it just gets migrated back to lmem when touched again. For such cases we can make the object visible as soon as we populate the TT with shmem pages, and then hide it again when doing the unpopulate. Signed-off-by: Matthew Auld Cc: Thomas Hellström --- drivers/gpu/drm/i915/gem/i915_gem_object.h | 1 + drivers/gpu/drm/i915/gem/i915_gem_shrinker.c | 29 +++- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 11 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index 561d6bd0a5c9..28b831c78c47 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -540,6 +540,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, void i915_gem_object_make_unshrinkable(struct drm_i915_gem_object *obj); void i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj); +void __i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj); void i915_gem_object_make_purgeable(struct drm_i915_gem_object *obj); static inline bool cpu_write_needs_clflush(struct drm_i915_gem_object *obj) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c index 4f5d49ada9e6..a69d7c207558 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c @@ -487,13 +487,12 @@ void i915_gem_object_make_unshrinkable(struct drm_i915_gem_object *obj) spin_unlock_irqrestore(&i915->mm.obj_lock, flags); } -static void __i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj, - struct list_head *head) +static void ___i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj, + struct list_head *head) { struct drm_i915_private *i915 = obj_to_i915(obj); unsigned long flags; - GEM_BUG_ON(!i915_gem_object_has_pages(obj)); if (!i915_gem_object_is_shrinkable(obj)) return; @@ -512,6 +511,21 @@ static void __i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj, spin_unlock_irqrestore(&i915->mm.obj_lock, flags); } +/** + * __i915_gem_object_make_shrinkable - Move the object to the tail of the + * shrinkable list. Objects on this list might be swapped out. Used with + * WILLNEED objects. + * @obj: The GEM object. + * + * DO NOT USE. This is intended to be called on very special objects that don't + * yet have mm.pages, but are guaranteed to have potentially reclaimable pages + * underneath. + */ +void __i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj) +{ + ___i915_gem_object_make_shrinkable(obj, + &obj_to_i915(obj)->mm.shrink_list); +} /** * i915_gem_object_make_shrinkable - Move the object to the tail of the @@ -523,8 +537,8 @@ static void __i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj, */ void i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj) { - __i915_gem_object_make_shrinkable(obj, - &obj_to_i915(obj)->mm.shrink_list); + GEM_BUG_ON(!i915_gem_object_has_pages(obj)); + __i915_gem_object_make_shrinkable(obj); } /** @@ -538,6 +552,7 @@ void i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj) */ void i915_gem_object_make_purgeable(struct drm_i915_gem_object *obj) { - __i915_gem_object_make_shrinkable(obj, - &obj_to_i915(obj)->mm.purge_list); + GEM_BUG_ON(!i915_gem_object_has_pages(obj)); + ___i915_gem_object_make_shrinkable(obj, + &obj_to_i915(obj)->mm.purge_list); } diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c index f4f7010e1c15..f68481b852ff 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -233,6 +233,15 @@ static int i915_ttm_tt_shmem_populate(struct ttm_device *bdev, if (ttm->page_flags & TTM_TT_FLAG_SWAPPED) ttm->page_flags &= ~TTM_TT_FLAG_SWAPPED; + /* +* Even if we lack mm.pages for this object(which will be the case when +* something is evicted to system memory by TTM), we still want to make +* this object visible to the shrinker, since the underlying ttm_tt +* still has the real shmem pages. When unpopulating the tt(possibly due +* to shrinking) we hide it again from the shrinker. +*/ + __i915_gem_object_make_shrinkable(ob
[PATCH v4 14/14] drm/i915/ttm: enable shmem tt backend
Enable shmem tt backend, and enable shrinking. Signed-off-by: Matthew Auld Cc: Thomas Hellström --- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c index f68481b852ff..33c1c0a50fdf 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -1101,6 +1101,7 @@ static u64 i915_ttm_mmap_offset(struct drm_i915_gem_object *obj) static const struct drm_i915_gem_object_ops i915_gem_ttm_obj_ops = { .name = "i915_gem_object_ttm", + .flags = I915_GEM_OBJECT_IS_SHRINKABLE, .get_pages = i915_ttm_get_pages, .put_pages = i915_ttm_put_pages, -- 2.26.3
[RFC PATCH] component: do not leave master devres group open after bind
In current code, the devres group for aggregate master is left open after call to component_master_add_*(). This leads to problems when the master does further managed allocations on its own. When any participating driver calls component_del(), this leads to immediate release of resources. This came up when investigating a page fault occurring with i915 DRM driver unbind with 5.15-rc1 kernel. The following sequence occurs: i915_pci_remove() -> intel_display_driver_unregister() -> i915_audio_component_cleanup() -> component_del() -> component.c:take_down_master() -> hdac_component_master_unbind() [via master->ops->unbind()] -> devres_release_group(master->parent, NULL) With older kernels this has not caused issues, but with audio driver moving to use managed interfaces for more of its allocations, this no longer works. Devres log shows following to occur: component_master_add_with_match() [ 126.886032] snd_hda_intel :00:1f.3: DEVRES ADD 323ccdc5 devm_component_match_release (24 bytes) [ 126.886045] snd_hda_intel :00:1f.3: DEVRES ADD 865cdb29 grp< (0 bytes) [ 126.886049] snd_hda_intel :00:1f.3: DEVRES ADD 1b480725 grp< (0 bytes) audio driver completes its PCI probe() [ 126.892238] snd_hda_intel :00:1f.3: DEVRES ADD 1b480725 pcim_iomap_release (48 bytes) component_del() called() at DRM/i915 unbind() [ 137.579422] i915 :00:02.0: DEVRES REL ef44c293 grp< (0 bytes) [ 137.579445] snd_hda_intel :00:1f.3: DEVRES REL 865cdb29 grp< (0 bytes) [ 137.579458] snd_hda_intel :00:1f.3: DEVRES REL 1b480725 pcim_iomap_release (48 bytes) So the "devres_release_group(master->parent, NULL)" ends up freeing the pcim_iomap allocation. Upon next runtime resume, the audio driver will cause a page fault as the iomap alloc was released without the driver knowing about it. Fix this issue by using the "struct master" pointer as identifier for the devres group, and by closing the devres group after the master->ops->bind() call is done. This allows devres allocations done by the driver acting as master to be isolated from the binding state of the aggregate driver. This modifies the logic originally introduced in commit 9e1ccb4a7700 ("drivers/base: fix devres handling for master device"). BugLink: https://gitlab.freedesktop.org/drm/intel/-/issues/4136 Signed-off-by: Kai Vehmanen --- drivers/base/component.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) Hi, I'm sending this as RFC as I'm not sure of the implications of not leaving the devres group open might have to other users of the component framework. For audio, the current behaviour seems very problematic. The display codec is usually just one of many audio codecs attached to the controller, and unbind of the display codec (and the aggregate driver created with DRM), should not bring down the whole audio card. However, now all allocations audio driver does after call to component_master_add_with_match(), will be freed when display driver calls component_del(). Closing the devres group at end of component_master_add_*() would seem the cleanest option. Looking for feedback whether this approach is feasible. One alternative would be for the audio driver to close the "last opened" group after its call to component_master_add(), but this seems messy (audio would make assumptions on component.c internals). diff --git a/drivers/base/component.c b/drivers/base/component.c index 5e79299f6c3f..870485cbbb87 100644 --- a/drivers/base/component.c +++ b/drivers/base/component.c @@ -246,7 +246,7 @@ static int try_to_bring_up_master(struct master *master, return 0; } - if (!devres_open_group(master->parent, NULL, GFP_KERNEL)) + if (!devres_open_group(master->parent, master, GFP_KERNEL)) return -ENOMEM; /* Found all components */ @@ -258,6 +258,7 @@ static int try_to_bring_up_master(struct master *master, return ret; } + devres_close_group(master->parent, NULL); master->bound = true; return 1; } @@ -282,7 +283,7 @@ static void take_down_master(struct master *master) { if (master->bound) { master->ops->unbind(master->parent); - devres_release_group(master->parent, NULL); + devres_release_group(master->parent, master); master->bound = false; } } base-commit: 930e99a51fcc8b1254e0a45fbe0cd5a5b8a704a5 -- 2.32.0
Re: [PATCH v4 01/14] drm/ttm: stop calling tt_swapin in vm_access
Am 21.09.21 um 13:01 schrieb Matthew Auld: In commit: commit 09ac4fcb3f255e9225967c75f5893325c116cdbe Author: Felix Kuehling Date: Thu Jul 13 17:01:16 2017 -0400 drm/ttm: Implement vm_operations_struct.access v2 we added the vm_access hook, where we also directly call tt_swapin for some reason. If something is swapped-out then the ttm_tt must also be unpopulated, and since access_kmap should also call tt_populate, if needed, then swapping-in will already be handled there. Sounds like you completely misunderstand what that is good for. This is for debugger attaching to a process and peek/poke into the VMA and completely unrelated to kmap. If anything, calling tt_swapin directly here would likely always fail since the tt->pages won't yet be populated, or worse since the tt->pages array is never actually cleared in unpopulate this might lead to a nasty uaf. That's indeed true, but we just need to unconditionally call ttm_tt_populate() here instead. Regards, Christian. Fixes: 09ac4fcb3f25 ("drm/ttm: Implement vm_operations_struct.access v2") Signed-off-by: Matthew Auld Cc: Thomas Hellström Cc: Christian König --- drivers/gpu/drm/ttm/ttm_bo_vm.c | 5 - 1 file changed, 5 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index f56be5bc0861..5b9b7fd01a69 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -519,11 +519,6 @@ int ttm_bo_vm_access(struct vm_area_struct *vma, unsigned long addr, switch (bo->resource->mem_type) { case TTM_PL_SYSTEM: - if (unlikely(bo->ttm->page_flags & TTM_PAGE_FLAG_SWAPPED)) { - ret = ttm_tt_swapin(bo->ttm); - if (unlikely(ret != 0)) - return ret; - } fallthrough; case TTM_PL_TT: ret = ttm_bo_vm_access_kmap(bo, offset, buf, len, write);
Re: [PATCH v4 03/14] drm/ttm: move ttm_tt_{add,clear}_mapping into amdgpu
Am 21.09.21 um 13:01 schrieb Matthew Auld: Now that setting page->index shouldn't be needed anymore, we are just left with setting page->mapping, and here it looks like amdgpu is the only user, where pointing the page->mapping at the dev_mapping is used to verify that the pages do indeed belong to the device, if userspace later tries to touch them. v2(Christian): - Drop the functions altogether and just inline modifying the page->mapping Signed-off-by: Matthew Auld Cc: Thomas Hellström Cc: Christian König Reviewed-by: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 15 ++- drivers/gpu/drm/ttm/ttm_tt.c| 25 - 2 files changed, 14 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 820fcb24231f..438377a89aa3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -1119,6 +1119,8 @@ static int amdgpu_ttm_tt_populate(struct ttm_device *bdev, { struct amdgpu_device *adev = amdgpu_ttm_adev(bdev); struct amdgpu_ttm_tt *gtt = (void *)ttm; + pgoff_t i; + int ret; /* user pages are bound by amdgpu_ttm_tt_pin_userptr() */ if (gtt->userptr) { @@ -1131,7 +1133,14 @@ static int amdgpu_ttm_tt_populate(struct ttm_device *bdev, if (ttm->page_flags & TTM_PAGE_FLAG_SG) return 0; - return ttm_pool_alloc(&adev->mman.bdev.pool, ttm, ctx); + ret = ttm_pool_alloc(&adev->mman.bdev.pool, ttm, ctx); + if (ret) + return ret; + + for (i = 0; i < ttm->num_pages; ++i) + ttm->pages[i]->mapping = bdev->dev_mapping; + + return 0; } /* @@ -1145,6 +1154,7 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_device *bdev, { struct amdgpu_ttm_tt *gtt = (void *)ttm; struct amdgpu_device *adev; + pgoff_t i; amdgpu_ttm_backend_unbind(bdev, ttm); @@ -1158,6 +1168,9 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_device *bdev, if (ttm->page_flags & TTM_PAGE_FLAG_SG) return; + for (i = 0; i < ttm->num_pages; ++i) + ttm->pages[i]->mapping = NULL; + adev = amdgpu_ttm_adev(bdev); return ttm_pool_free(&adev->mman.bdev.pool, ttm); } diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index 1cc04c224988..980ecb079b2c 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c @@ -289,17 +289,6 @@ int ttm_tt_swapout(struct ttm_device *bdev, struct ttm_tt *ttm, return ret; } -static void ttm_tt_add_mapping(struct ttm_device *bdev, struct ttm_tt *ttm) -{ - pgoff_t i; - - if (ttm->page_flags & TTM_PAGE_FLAG_SG) - return; - - for (i = 0; i < ttm->num_pages; ++i) - ttm->pages[i]->mapping = bdev->dev_mapping; -} - int ttm_tt_populate(struct ttm_device *bdev, struct ttm_tt *ttm, struct ttm_operation_ctx *ctx) { @@ -336,7 +325,6 @@ int ttm_tt_populate(struct ttm_device *bdev, if (ret) goto error; - ttm_tt_add_mapping(bdev, ttm); ttm->page_flags |= TTM_PAGE_FLAG_PRIV_POPULATED; if (unlikely(ttm->page_flags & TTM_PAGE_FLAG_SWAPPED)) { ret = ttm_tt_swapin(ttm); @@ -359,24 +347,11 @@ int ttm_tt_populate(struct ttm_device *bdev, } EXPORT_SYMBOL(ttm_tt_populate); -static void ttm_tt_clear_mapping(struct ttm_tt *ttm) -{ - pgoff_t i; - struct page **page = ttm->pages; - - if (ttm->page_flags & TTM_PAGE_FLAG_SG) - return; - - for (i = 0; i < ttm->num_pages; ++i) - (*page)->mapping = NULL; -} - void ttm_tt_unpopulate(struct ttm_device *bdev, struct ttm_tt *ttm) { if (!ttm_tt_is_populated(ttm)) return; - ttm_tt_clear_mapping(ttm); if (bdev->funcs->ttm_tt_unpopulate) bdev->funcs->ttm_tt_unpopulate(bdev, ttm); else
Re: [PATCH v4 05/14] drm/ttm: s/FLAG_SG/FLAG_EXTERNAL/
Am 21.09.21 um 13:01 schrieb Matthew Auld: It covers more than just ttm_bo_type_sg usage, like with say dma-buf, since one other user is userptr in amdgpu, and in the future we might have some more. Hence EXTERNAL is likely a more suitable name. v2(Christian): - Rename these to TTM_TT_FLAGS_* - Fix up all the holes in the flag values Suggested-by: Christian König Signed-off-by: Matthew Auld Cc: Thomas Hellström Cc: Christian König Acked-by: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 10 +- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 6 +++--- drivers/gpu/drm/nouveau/nouveau_bo.c| 4 ++-- drivers/gpu/drm/radeon/radeon_ttm.c | 8 drivers/gpu/drm/ttm/ttm_bo.c| 4 ++-- drivers/gpu/drm/ttm/ttm_bo_util.c | 4 ++-- drivers/gpu/drm/ttm/ttm_bo_vm.c | 2 +- drivers/gpu/drm/ttm/ttm_pool.c | 2 +- drivers/gpu/drm/ttm/ttm_tt.c| 24 include/drm/ttm/ttm_device.h| 2 +- include/drm/ttm/ttm_tt.h| 18 +- 11 files changed, 42 insertions(+), 42 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 438377a89aa3..0cf94421665f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -894,7 +894,7 @@ static int amdgpu_ttm_backend_bind(struct ttm_device *bdev, DRM_ERROR("failed to pin userptr\n"); return r; } - } else if (ttm->page_flags & TTM_PAGE_FLAG_SG) { + } else if (ttm->page_flags & TTM_TT_FLAG_EXTERNAL) { if (!ttm->sg) { struct dma_buf_attachment *attach; struct sg_table *sgt; @@ -1130,7 +1130,7 @@ static int amdgpu_ttm_tt_populate(struct ttm_device *bdev, return 0; } - if (ttm->page_flags & TTM_PAGE_FLAG_SG) + if (ttm->page_flags & TTM_TT_FLAG_EXTERNAL) return 0; ret = ttm_pool_alloc(&adev->mman.bdev.pool, ttm, ctx); @@ -1165,7 +1165,7 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_device *bdev, return; } - if (ttm->page_flags & TTM_PAGE_FLAG_SG) + if (ttm->page_flags & TTM_TT_FLAG_EXTERNAL) return; for (i = 0; i < ttm->num_pages; ++i) @@ -1198,8 +1198,8 @@ int amdgpu_ttm_tt_set_userptr(struct ttm_buffer_object *bo, return -ENOMEM; } - /* Set TTM_PAGE_FLAG_SG before populate but after create. */ - bo->ttm->page_flags |= TTM_PAGE_FLAG_SG; + /* Set TTM_TT_FLAG_EXTERNAL before populate but after create. */ + bo->ttm->page_flags |= TTM_TT_FLAG_EXTERNAL; gtt = (void *)bo->ttm; gtt->userptr = addr; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c index 2f672f06b169..fd5b925b27c5 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -182,7 +182,7 @@ static struct ttm_tt *i915_ttm_tt_create(struct ttm_buffer_object *bo, if (obj->flags & I915_BO_ALLOC_CPU_CLEAR && man->use_tt) - page_flags |= TTM_PAGE_FLAG_ZERO_ALLOC; + page_flags |= TTM_TT_FLAG_ZERO_ALLOC; ret = ttm_tt_init(&i915_tt->ttm, bo, page_flags, i915_ttm_select_tt_caching(obj)); @@ -546,7 +546,7 @@ static int i915_ttm_move(struct ttm_buffer_object *bo, bool evict, } /* Populate ttm with pages if needed. Typically system memory. */ - if (ttm && (dst_man->use_tt || (ttm->page_flags & TTM_PAGE_FLAG_SWAPPED))) { + if (ttm && (dst_man->use_tt || (ttm->page_flags & TTM_TT_FLAG_SWAPPED))) { ret = ttm_tt_populate(bo->bdev, ttm, ctx); if (ret) return ret; @@ -557,7 +557,7 @@ static int i915_ttm_move(struct ttm_buffer_object *bo, bool evict, return PTR_ERR(dst_st); clear = !cpu_maps_iomem(bo->resource) && (!ttm || !ttm_tt_is_populated(ttm)); - if (!(clear && ttm && !(ttm->page_flags & TTM_PAGE_FLAG_ZERO_ALLOC))) + if (!(clear && ttm && !(ttm->page_flags & TTM_TT_FLAG_ZERO_ALLOC))) __i915_ttm_move(bo, clear, dst_mem, dst_st); ttm_bo_move_sync_cleanup(bo, dst_mem); diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index d3b21d318b42..12b107acb6ee 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -1250,7 +1250,7 @@ nouveau_ttm_tt_populate(struct ttm_device *bdev, struct ttm_tt *ttm_dma = (void *)ttm; struct nouveau_drm *drm; struct device *dev; - bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG); + bool slave = !!(ttm->page_flags & TTM_TT_FLAG_EXTERNAL); if (ttm_tt_is_populated(ttm)) return 0; @@ -1273,
Re: [PATCH v4 06/14] drm/ttm: add some kernel-doc for TTM_TT_FLAG_*
Am 21.09.21 um 13:01 schrieb Matthew Auld: Move it to inline kernel-doc, otherwise we can't add empty lines it seems. Also drop the kernel-doc for pages_list, which doesn't seem to exist. Signed-off-by: Matthew Auld Cc: Thomas Hellström Cc: Christian König One comment below, with that fixed Reviewed-by: Christian König --- include/drm/ttm/ttm_tt.h | 57 ++-- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/include/drm/ttm/ttm_tt.h b/include/drm/ttm/ttm_tt.h index b023cd58ff38..f3ef568da651 100644 --- a/include/drm/ttm/ttm_tt.h +++ b/include/drm/ttm/ttm_tt.h @@ -38,35 +38,54 @@ struct ttm_resource; struct ttm_buffer_object; struct ttm_operation_ctx; -#define TTM_TT_FLAG_SWAPPED (1 << 0) -#define TTM_TT_FLAG_ZERO_ALLOC (1 << 1) -#define TTM_TT_FLAG_EXTERNAL (1 << 2) - -#define TTM_TT_FLAG_PRIV_POPULATED (1 << 31) - /** - * struct ttm_tt - * - * @pages: Array of pages backing the data. - * @page_flags: see TTM_TT_FLAG_* - * @num_pages: Number of pages in the page array. - * @sg: for SG objects via dma-buf - * @dma_address: The DMA (bus) addresses of the pages - * @swap_storage: Pointer to shmem struct file for swap storage. - * @pages_list: used by some page allocation backend - * @caching: The current caching state of the pages, see enum ttm_caching. - * - * This is a structure holding the pages, caching- and aperture binding - * status for a buffer object that isn't backed by fixed (VRAM / AGP) + * struct ttm_tt - This is a structure holding the pages, caching- and aperture + * binding status for a buffer object that isn't backed by fixed (VRAM / AGP) * memory. */ struct ttm_tt { + /** @pages: Array of pages backing the data. */ struct page **pages; + /** +* @page_flags: The page flags. +* +* Supported values: +* +* TTM_TT_FLAG_SWAPPED: Set if the pages have been swapped out. +* Calling ttm_tt_populate() will swap the pages back in, and unset the +* flag. +* +* TTM_TT_FLAG_ZERO_ALLOC: Set if the pages will be zeroed on +* allocation. +* +* TTM_TT_FLAG_EXTERNAL: Set if the underlying pages were allocated +* externally, like with dma-buf or userptr. This effectively disables +* TTM swapping out such pages. Also important is to prevent TTM from +* ever directly mapping these pages. +* +* Note that enum ttm_bo_type.ttm_bo_type_sg objects will always enable +* this flag. +* +* TTM_TT_FLAG_PRIV_POPULATED: TTM internal only. DO NOT USE. The swapped flag should probably not be touched by the drivers either. Better just describe what this is good for. Christian. +*/ +#define TTM_TT_FLAG_SWAPPED(1 << 0) +#define TTM_TT_FLAG_ZERO_ALLOC (1 << 1) +#define TTM_TT_FLAG_EXTERNAL (1 << 2) + +#define TTM_TT_FLAG_PRIV_POPULATED (1 << 31) uint32_t page_flags; + /** @num_pages: Number of pages in the page array. */ uint32_t num_pages; + /** @sg: for SG objects via dma-buf. */ struct sg_table *sg; + /** @dma_address: The DMA (bus) addresses of the pages. */ dma_addr_t *dma_address; + /** @swap_storage: Pointer to shmem struct file for swap storage. */ struct file *swap_storage; + /** +* @caching: The current caching state of the pages, see enum +* ttm_caching. +*/ enum ttm_caching caching; };
Re: [PATCH v4 01/14] drm/ttm: stop calling tt_swapin in vm_access
HI, Christian, On Tue, 2021-09-21 at 13:28 +0200, Christian König wrote: > Am 21.09.21 um 13:01 schrieb Matthew Auld: > > In commit: > > > > commit 09ac4fcb3f255e9225967c75f5893325c116cdbe > > Author: Felix Kuehling > > Date: Thu Jul 13 17:01:16 2017 -0400 > > > > drm/ttm: Implement vm_operations_struct.access v2 > > > > we added the vm_access hook, where we also directly call tt_swapin > > for > > some reason. If something is swapped-out then the ttm_tt must also > > be > > unpopulated, and since access_kmap should also call tt_populate, if > > needed, then swapping-in will already be handled there. > > Sounds like you completely misunderstand what that is good for. > > This is for debugger attaching to a process and peek/poke into the > VMA > and completely unrelated to kmap. I think what Matthew is saying is that there is a fallthrough to TTM_PL_TT which calls ttm_bo_vm_access_kmap which calls ttm_tt_populate(). So from my pow, unless there are other concerns, this is Reviewed-by: Thomas Hellström > > > > > If anything, calling tt_swapin directly here would likely always > > fail > > since the tt->pages won't yet be populated, or worse since the tt- > > >pages > > array is never actually cleared in unpopulate this might lead to a > > nasty > > uaf. > > That's indeed true, but we just need to unconditionally call > ttm_tt_populate() here instead. > > Regards, > Christian. > > > > > Fixes: 09ac4fcb3f25 ("drm/ttm: Implement > > vm_operations_struct.access v2") > > Signed-off-by: Matthew Auld > > Cc: Thomas Hellström > > Cc: Christian König > > --- > > drivers/gpu/drm/ttm/ttm_bo_vm.c | 5 - > > 1 file changed, 5 deletions(-) > > > > diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c > > b/drivers/gpu/drm/ttm/ttm_bo_vm.c > > index f56be5bc0861..5b9b7fd01a69 100644 > > --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c > > +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c > > @@ -519,11 +519,6 @@ int ttm_bo_vm_access(struct vm_area_struct > > *vma, unsigned long addr, > > > > switch (bo->resource->mem_type) { > > case TTM_PL_SYSTEM: > > - if (unlikely(bo->ttm->page_flags & > > TTM_PAGE_FLAG_SWAPPED)) { > > - ret = ttm_tt_swapin(bo->ttm); > > - if (unlikely(ret != 0)) > > - return ret; > > - } > > fallthrough; > > case TTM_PL_TT: > > ret = ttm_bo_vm_access_kmap(bo, offset, buf, len, > > write); >
Re: [PATCH v4 01/14] drm/ttm: stop calling tt_swapin in vm_access
Am 21.09.21 um 13:37 schrieb Thomas Hellström: HI, Christian, On Tue, 2021-09-21 at 13:28 +0200, Christian König wrote: Am 21.09.21 um 13:01 schrieb Matthew Auld: In commit: commit 09ac4fcb3f255e9225967c75f5893325c116cdbe Author: Felix Kuehling Date: Thu Jul 13 17:01:16 2017 -0400 drm/ttm: Implement vm_operations_struct.access v2 we added the vm_access hook, where we also directly call tt_swapin for some reason. If something is swapped-out then the ttm_tt must also be unpopulated, and since access_kmap should also call tt_populate, if needed, then swapping-in will already be handled there. Sounds like you completely misunderstand what that is good for. This is for debugger attaching to a process and peek/poke into the VMA and completely unrelated to kmap. I think what Matthew is saying is that there is a fallthrough to TTM_PL_TT which calls ttm_bo_vm_access_kmap Ah, good point. Now that makes much more sense. which calls ttm_tt_populate(). So from my pow, unless there are other concerns, this is Reviewed-by: Thomas Hellström In that case the patch is Reviewed-by: Christian König as well. When this is gone we can also make ttm_tt_swapin() static since that here is the only user. And BTW replacing the switch/case with a check for use_tt in the resource_manager is probably a good idea as well. Regards, Christian. If anything, calling tt_swapin directly here would likely always fail since the tt->pages won't yet be populated, or worse since the tt- pages array is never actually cleared in unpopulate this might lead to a nasty uaf. That's indeed true, but we just need to unconditionally call ttm_tt_populate() here instead. Regards, Christian. Fixes: 09ac4fcb3f25 ("drm/ttm: Implement vm_operations_struct.access v2") Signed-off-by: Matthew Auld Cc: Thomas Hellström Cc: Christian König --- drivers/gpu/drm/ttm/ttm_bo_vm.c | 5 - 1 file changed, 5 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index f56be5bc0861..5b9b7fd01a69 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -519,11 +519,6 @@ int ttm_bo_vm_access(struct vm_area_struct *vma, unsigned long addr, switch (bo->resource->mem_type) { case TTM_PL_SYSTEM: - if (unlikely(bo->ttm->page_flags & TTM_PAGE_FLAG_SWAPPED)) { - ret = ttm_tt_swapin(bo->ttm); - if (unlikely(ret != 0)) - return ret; - } fallthrough; case TTM_PL_TT: ret = ttm_bo_vm_access_kmap(bo, offset, buf, len, write);
Re: [PATCH] drm/nouveau/fifo/ga102: initialise chid on return from channel creation
On Tue, Sep 21, 2021 at 11:07 AM Ben Skeggs wrote: > > From: Ben Skeggs > > Turns out caller isn't zero-initialised after-all. > > Fixes: 6b457230bfa1 ("drm/nouveau/ga102-: support ttm buffer moves via copy > engine") > Reported-by: Karol Herbst > Signed-off-by: Ben Skeggs > --- > drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c > b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c > index f897bef13acf..c630dbd2911a 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c > +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c > @@ -179,6 +179,9 @@ ga102_chan_new(struct nvkm_device *device, > return -ENODEV; > > chan->ctrl.chan = nvkm_rd32(device, chan->ctrl.runl + 0x004) & > 0xfff0; > + > + args->chid = 0; > + args->inst = 0; > args->token = nvkm_rd32(device, chan->ctrl.runl + 0x008) & 0x; > > ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000, > true, &chan->mthd); > -- > 2.31.1 > Reviewed-by: Karol Herbst
Re: [PATCH v4 10/14] drm/i915/ttm: hide shmem objects from TTM LRU
Am 21.09.21 um 13:01 schrieb Matthew Auld: This is probably a NAK. But ideally we need to somehow prevent TTM from seeing shmem objects when doing its LRU swap walk. Since these are EXTERNAL they are ignored anyway, but keeping them in the LRU seems pretty wasteful. Trying to use bo_pin() for this is all kinds of nasty since we need to be able to do the bo_unpin() from the unpopulate hook, but since that can be called from the BO destroy path we will likely go down in flames. An alternative is to maybe just add EXTERNAL objects to some bdev->external LRU in TTM, or just don't add them at all? Yeah, that goes into the same direction as why I want to push the LRU into the resource for some time. The problem is that the LRU is needed for multiple things. E.g. swapping, GART management, resource constrains, IOMMU teardown etc.. So for now I think that everything should be on the LRU even if it isn't valid to be there for some use case. Regards, Christian. Signed-off-by: Matthew Auld Cc: Thomas Hellström Cc: Christian König --- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 17 + 1 file changed, 17 insertions(+) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c index 174aebe11264..b438ddb52764 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -800,6 +800,22 @@ static unsigned long i915_ttm_io_mem_pfn(struct ttm_buffer_object *bo, return ((base + sg_dma_address(sg)) >> PAGE_SHIFT) + ofs; } +static void i915_ttm_del_from_lru_notify(struct ttm_buffer_object *bo) +{ + struct i915_ttm_tt *i915_tt = + container_of(bo->ttm, typeof(*i915_tt), ttm); + + /* Idealy we need to prevent TTM from seeing shmem objects when doing +* its LRU swap walk. Since these are EXTERNAL they are ignored anyway, +* but keeping them in the LRU is pretty waseful. Trying to use bo_pin() +* for this is very nasty since we need to be able to do the bo_unpin() +* from the unpopulate hook, but since that can be called from the BO +* destroy path we will go down in flames. +*/ + if (bo->ttm && ttm_tt_is_populated(bo->ttm) && i915_tt->is_shmem) + list_del_init(&bo->lru); +} + static struct ttm_device_funcs i915_ttm_bo_driver = { .ttm_tt_create = i915_ttm_tt_create, .ttm_tt_populate = i915_ttm_tt_populate, @@ -810,6 +826,7 @@ static struct ttm_device_funcs i915_ttm_bo_driver = { .move = i915_ttm_move, .swap_notify = i915_ttm_swap_notify, .delete_mem_notify = i915_ttm_delete_mem_notify, + .del_from_lru_notify = i915_ttm_del_from_lru_notify, .io_mem_reserve = i915_ttm_io_mem_reserve, .io_mem_pfn = i915_ttm_io_mem_pfn, };
[PATCH] MAINTAINERS: fix typo in DRM DRIVER FOR SAMSUNG S6D27A1 PANELS
Commit ebd8cbf1fb96 ("drm/panel: s6d27a1: Add driver for Samsung S6D27A1 display panel") introduces a new section DRM DRIVER FOR SAMSUNG S6D27A1 PANELS with a minor typo in one of its file entries. Hence, ./scripts/get_maintainer.pl --self-test=patterns complains: warning: no file matches F: driver/gpu/drm/panel/panel-samsung-s6d27a1.c So, repair the entry and make get_maintainer.pl happy. Signed-off-by: Lukas Bulwahn --- applies cleanly on next-20210920 Linus, please pick this minor quick clean-up patch on drm-misc-next (on top of the commit mentioned above). MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 2b990794ec35..1c486baf9c8d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6045,7 +6045,7 @@ DRM DRIVER FOR SAMSUNG S6D27A1 PANELS M: Markuss Broks S: Maintained F: Documentation/devicetree/bindings/display/panel/samsung,s6d27a1.yaml -F: driver/gpu/drm/panel/panel-samsung-s6d27a1.c +F: drivers/gpu/drm/panel/panel-samsung-s6d27a1.c DRM DRIVER FOR SITRONIX ST7703 PANELS M: Guido Günther -- 2.26.2
Re: [PATCH 1/3] drm/bridge: Add a function to abstract away panels
On Fri, Sep 10, 2021 at 3:10 PM Maxime Ripard wrote: > > Display drivers so far need to have a lot of boilerplate to first > retrieve either the panel or bridge that they are connected to using > drm_of_find_panel_or_bridge(), and then either deal with each with ad-hoc > functions or create a drm panel bridge through drm_panel_bridge_add. > > In order to reduce the boilerplate and hopefully create a path of least > resistance towards using the DRM panel bridge layer, let's create the > function devm_drm_of_get_next to reduce that boilerplate. Hi Maxime, This patch creates a dependency error for me: depmod: ERROR: Cycle detected: drm_kms_helper -> drm -> drm_kms_helper depmod: ERROR: Cycle detected: cec depmod: ERROR: Found 2 modules in dependency cycles! Cheers Patrik > > Signed-off-by: Maxime Ripard > --- > drivers/gpu/drm/drm_bridge.c | 42 > drivers/gpu/drm/drm_of.c | 3 +++ > include/drm/drm_bridge.h | 2 ++ > 3 files changed, 43 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c > index a8ed66751c2d..10ddca4638b0 100644 > --- a/drivers/gpu/drm/drm_bridge.c > +++ b/drivers/gpu/drm/drm_bridge.c > @@ -28,6 +28,7 @@ > #include > #include > #include > +#include > #include > > #include "drm_crtc_internal.h" > @@ -51,10 +52,8 @@ > * > * Display drivers are responsible for linking encoders with the first bridge > * in the chains. This is done by acquiring the appropriate bridge with > - * of_drm_find_bridge() or drm_of_find_panel_or_bridge(), or creating it for > a > - * panel with drm_panel_bridge_add_typed() (or the managed version > - * devm_drm_panel_bridge_add_typed()). Once acquired, the bridge shall be > - * attached to the encoder with a call to drm_bridge_attach(). > + * devm_drm_of_get_bridge(). Once acquired, the bridge shall be attached to > the > + * encoder with a call to drm_bridge_attach(). > * > * Bridges are responsible for linking themselves with the next bridge in the > * chain, if any. This is done the same way as for encoders, with the call to > @@ -1233,6 +1232,41 @@ struct drm_bridge *of_drm_find_bridge(struct > device_node *np) > return NULL; > } > EXPORT_SYMBOL(of_drm_find_bridge); > + > +/** > + * devm_drm_of_get_bridge - Return next bridge in the chain > + * @dev: device to tie the bridge lifetime to > + * @np: device tree node containing encoder output ports > + * @port: port in the device tree node > + * @endpoint: endpoint in the device tree node > + * > + * Given a DT node's port and endpoint number, finds the connected node > + * and returns the associated bridge if any, or creates and returns a > + * drm panel bridge instance if a panel is connected. > + * > + * Returns a pointer to the bridge if successful, or an error pointer > + * otherwise. > + */ > +struct drm_bridge *devm_drm_of_get_bridge(struct device *dev, > + struct device_node *np, > + unsigned int port, > + unsigned int endpoint) > +{ > + struct drm_bridge *bridge; > + struct drm_panel *panel; > + int ret; > + > + ret = drm_of_find_panel_or_bridge(np, port, endpoint, > + &panel, &bridge); > + if (ret) > + return ERR_PTR(ret); > + > + if (panel) > + bridge = devm_drm_panel_bridge_add(dev, panel); > + > + return bridge; > +} > +EXPORT_SYMBOL(devm_drm_of_get_bridge); > #endif > > MODULE_AUTHOR("Ajay Kumar "); > diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c > index 997b8827fed2..37c34146eea8 100644 > --- a/drivers/gpu/drm/drm_of.c > +++ b/drivers/gpu/drm/drm_of.c > @@ -231,6 +231,9 @@ EXPORT_SYMBOL_GPL(drm_of_encoder_active_endpoint); > * return either the associated struct drm_panel or drm_bridge device. Either > * @panel or @bridge must not be NULL. > * > + * This function is deprecated and should not be used in new drivers. Use > + * devm_drm_of_get_bridge() instead. > + * > * Returns zero if successful, or one of the standard error codes if it > fails. > */ > int drm_of_find_panel_or_bridge(const struct device_node *np, > diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h > index 46bdfa48c413..f70c88ca96ef 100644 > --- a/include/drm/drm_bridge.h > +++ b/include/drm/drm_bridge.h > @@ -911,6 +911,8 @@ struct drm_bridge *devm_drm_panel_bridge_add(struct > device *dev, > struct drm_bridge *devm_drm_panel_bridge_add_typed(struct device *dev, >struct drm_panel *panel, >u32 connector_type); > +struct drm_bridge *devm_drm_of_get_bridge(struct device *dev, struct > device_node *node, > + unsigned int port, unsigned int > endpoint); > struct drm_connector *drm_pane
Re: [Intel-gfx] [PATCH] drm/i915/guc/slpc: remove unneeded clflush calls
On Mon, Sep 20, 2021 at 10:47:08PM -0700, Lucas De Marchi wrote: > On Wed, Sep 15, 2021 at 12:29:12PM -0700, John Harrison wrote: > >On 9/15/2021 12:24, Belgaumkar, Vinay wrote: > >>On 9/14/2021 12:51 PM, Lucas De Marchi wrote: > >>>The clflush calls here aren't doing anything since we are not writting > >>>something and flushing the cache lines to be visible to GuC. Here the > >>>intention seems to be to make sure whatever GuC has written is visible > >>>to the CPU before we read them. However a clflush from the CPU side is > >>>the wrong instruction to use. > >Is there a right instruction to use? Either we need to verify that no > > how can there be a right instruction? If the GuC needs to flush, then > the GuC needs to do it, nothing to be done by the CPU. > > Flushing the CPU cache line here is doing nothing to guarantee that what > was written by GuC hit the memory and we are reading it. Not sure why it > was actually added, but since it was added by Vinay and he reviewed this > patch, I'm assuming he also agrees clflush == writeback + invalidate. The invalidate is the important part when the CPU has to read something written by something else that's not cache coherent. Now, I have no idea if the guc has its own (CPU invisible) caches or not. If it does then it will need to trigger a writeback. But regardless, if the guc bypasses the CPU caches the CPU will need to invalidate before it reads anything in case it has stale data sitting in its cache. -- Ville Syrjälä Intel
Re: [Intel-gfx] [PATCH 13/26] drm/i915: use the new iterator in i915_gem_busy_ioctl
On 21/09/2021 10:41, Christian König wrote: Am 20.09.21 um 12:33 schrieb Tvrtko Ursulin: On 20/09/2021 11:13, Christian König wrote: Am 20.09.21 um 10:45 schrieb Tvrtko Ursulin: On 17/09/2021 13:35, Christian König wrote: This makes the function much simpler since the complex retry logic is now handled else where. Signed-off-by: Christian König --- drivers/gpu/drm/i915/gem/i915_gem_busy.c | 32 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_busy.c b/drivers/gpu/drm/i915/gem/i915_gem_busy.c index 6234e17259c1..b1cb7ba688da 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_busy.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_busy.c @@ -82,8 +82,8 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, { struct drm_i915_gem_busy *args = data; struct drm_i915_gem_object *obj; - struct dma_resv_list *list; - unsigned int seq; + struct dma_resv_iter cursor; + struct dma_fence *fence; int err; err = -ENOENT; @@ -109,27 +109,17 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, * to report the overall busyness. This is what the wait-ioctl does. * */ -retry: - seq = raw_read_seqcount(&obj->base.resv->seq); - - /* Translate the exclusive fence to the READ *and* WRITE engine */ - args->busy = busy_check_writer(dma_resv_excl_fence(obj->base.resv)); - - /* Translate shared fences to READ set of engines */ - list = dma_resv_shared_list(obj->base.resv); - if (list) { - unsigned int shared_count = list->shared_count, i; - - for (i = 0; i < shared_count; ++i) { - struct dma_fence *fence = - rcu_dereference(list->shared[i]); - + args->busy = false; + dma_resv_iter_begin(&cursor, obj->base.resv, true); + dma_resv_for_each_fence_unlocked(&cursor, fence) { You did not agree with my suggestion to reset args->busy on restart and so preserve current behaviour? No, I want to keep the restart behavior internally to the dma_resv object and as far as I can see it should not make a difference here. To be clear, on paper difference between old and new implementation is if the restart happens while processing the shared fences. Old implementation unconditionally goes to "args->busy = >>> busy_check_writer(dma_resv_excl_fence(obj->base.resv));" and so overwrites the set of flags returned to userspace. New implementation can merge new read flags to the old set of flags and so return a composition of past and current fences. Maybe it does not matter hugely in this case, depends if userspace typically just restarts until flags are clear. But I am not sure. On the higher level - what do you mean with wanting to keep the restart behaviour internal? Not providing iterators users means of detecting it? I think it has to be provided. Ok I will adjust that for now to get the patch set upstream. But in general when somebody outside of the dma_resv code base depends on the restart behavior then that's a bug inside the design of that code. Thanks, no change in behaviour makes for an easy r-b. :) The callers should only care about what unsignaled fences are inside the dma_resv container and it shouldn't matter if those fences are presented once or multiple times because of a reset.. When this makes a difference we have a bug in the handling and should probably consider taking the dma_resv.lock instead. I agree, which is why I was mentioning earlier how it would be good to completely sort locked from unlocked iterators and avoid situations where unlocked one is called from a path where object is locked. Unfortunately for the display code path I cannot easily help with the audit of call paths. And I think there are at least two patches in your series which need KMS expertise. Regards, Tvrtko
Re: [PATCH v2 0/4] CMDQ refinement of Mediatek DRM driver
Hi, Enric: Enric Balletbo Serra 於 2021年9月21日 週二 下午4:36寫道: > > Hi Chun-Kuang, > > (again without html format, sorry for the noise) > > Missatge de Chun-Kuang Hu del dia dj., 12 > d’ag. 2021 a les 2:13: > > > > Chun-Kuang Hu 於 2021年8月9日 週一 上午7:47寫道: > > > > > > These refinements include using standard mailbox callback interface, > > > timeout detection, and a fixed cmdq_handle. > > > > For this series, applied to mediatek-drm-next [1]. > > > > [1] > > https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux.git/log/?h=mediatek-drm-next > > > > These patches seem to break the display on the Acer Chromebook R 13 > (MT8173) in the current mainline. After running a bisection it pointed > me to the following commit > > commit f4be17cd5b14dd73545b0e014a63ebe9ab5ef837 > Author: Chun-Kuang Hu > Date: Sun Jul 4 15:36:48 2021 +0800 > > drm/mediatek: Remove struct cmdq_client > > Reverting this patch alone is not trivial, so I ended up reverting the > full series, and I can confirm that reverting the full series makes > the display work again. I think you could not just revert "drm/mediatek: Remove struct cmdq_client", you should also revert the patches after it, such as "drm/mediatek: Clear pending flag when cmdq packet is done" "drm/mediatek: Add cmdq_handle in mtk_crtc" "drm/mediatek: Detect CMDQ execution timeout" If "drm/mediatek: Remove struct cmdq_client" is the patch cause display abnormal, I think you could compare code w/ and w/o this patch. Focus on the value accuracy, such as cmdq_cl and cmdq_chan. And focus on the flow accuracy, such as mtk_drm_crtc_update_config() and ddp_cmdq_cb(). If this could not find the problem, I think the latest way is to break this patch into small patches, changes little in each small patches and we could finally find out the problem. Regards, Chun-Kuang. > > Unfortunately, after the merge window, different things broke for this > device, and I didn't finish isolating them, and it is not clear to me > yet whether the logs I'm getting are useful for this specific issue or > not. Basically with this series merged the kernel seems to be stuck, > and the display is not working. Latest message is > > [ 12.329173] mtk-iommu 10205000.iommu: Partial TLB flush timed out, > falling back to full flush > > Without the series, the kernel goes far and display works, however > there are other issues affecting the cros-ec, but I think that's > another issue. > > I'll try to dig a bit more, but, meanwhile, if you have any idea > please let me know. > > Thanks, > Enric > > > > Regards, > > Chun-Kuang. > > > > > > > > Changes in v2: > > > 1. Define mtk_drm_cmdq_pkt_create() and mtk_drm_cmdq_pkt_destroy() > > >when CONFIG_MTK_CMDQ is reachable. > > > > > > Chun-Kuang Hu (4): > > > drm/mediatek: Use mailbox rx_callback instead of cmdq_task_cb > > > drm/mediatek: Remove struct cmdq_client > > > drm/mediatek: Detect CMDQ execution timeout > > > drm/mediatek: Add cmdq_handle in mtk_crtc > > > > > > drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 110 > > > 1 file changed, 91 insertions(+), 19 deletions(-) > > > > > > -- > > > 2.25.1 > > >
Re: [PATCH v2 6/9] vfio/mdev: Add mdev available instance checking to the core
On Mon, Sep 20, 2021 at 08:02:29PM +0200, Cornelia Huck wrote: > On Thu, Sep 09 2021, Jason Gunthorpe wrote: > > > Many of the mdev drivers use a simple counter for keeping track of the > > available instances. Move this code to the core code and store the counter > > in the mdev_type. Implement it using correct locking, fixing mdpy. > > > > Drivers provide a get_available() callback to set the number of available > > instances for their mtypes which is fixed at registration time. The core > > provides a standard sysfs attribute to return the available_instances. > > So, according to the documentation, available_instances is > mandatory. This means that drivers either need to provide get_available > or implement their own version of the attribute. I think we want to > update vfio-mediated-device.rst as well? I added this, and something similar for the device_api patch too, thanks diff --git a/Documentation/driver-api/vfio-mediated-device.rst b/Documentation/driver-api/vfio-mediated-device.rst index 9f26079cacae35..0a130d76b33a48 100644 --- a/Documentation/driver-api/vfio-mediated-device.rst +++ b/Documentation/driver-api/vfio-mediated-device.rst @@ -106,6 +106,7 @@ structure to represent a mediated device's driver:: int (*probe) (struct mdev_device *dev); void (*remove) (struct mdev_device *dev); struct device_driverdriver; +unsigned int (*get_available)(struct mdev_type *mtype); }; A mediated bus driver for mdev should use this structure in the function calls @@ -230,7 +231,8 @@ Directories and files under the sysfs for Each Physical Device * available_instances This attribute should show the number of devices of type that can be - created. + created. Drivers can supply a get_availble() function pointer to have the core + code create and maintain this sysfs automatically. * [device]
Re: [PATCH] drm/nouveau/ga102: Free resources on error in ga102_chan_new()
On 9/20/21 8:07 PM, Karol Herbst wrote: On Mon, Sep 20, 2021 at 8:17 PM Tim Gardner wrote: Coverity complains of a resource leak in ga102_chan_new(): CID 119637 (#7 of 7): Resource leak (RESOURCE_LEAK) 13. leaked_storage: Variable chan going out of scope leaks the storage it points to. 190return ret; Fix this by freeing 'chan' in the error path. yeah, this is actually a false positive. I ran your patch through kasan and got a use-after-free as we deallocate the passed in pointer after calling the function pointer to the new function. One might argue that the programming style isn't the best and we should be explicit about freeing memory though. So the caller of this constructor has to look at the error return code and decide whether the value stored in *pobject can be freed ? I guess if the caller initializes the value at *pobject to be NULL then it can kfree() regardless. Cc: Ben Skeggs Cc: David Airlie Cc: Daniel Vetter Cc: Karol Herbst Cc: dri-devel@lists.freedesktop.org Cc: nouv...@lists.freedesktop.org Cc: linux-ker...@vger.kernel.org Signed-off-by: Tim Gardner --- .../gpu/drm/nouveau/nvkm/engine/fifo/ga102.c | 20 --- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c index f897bef13acf..4dbdfb53e65f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c @@ -175,19 +175,21 @@ ga102_chan_new(struct nvkm_device *device, } } - if (!chan->ctrl.runl) - return -ENODEV; + if (!chan->ctrl.runl) { + ret = -ENODEV; + goto free_chan; + } chan->ctrl.chan = nvkm_rd32(device, chan->ctrl.runl + 0x004) & 0xfff0; args->token = nvkm_rd32(device, chan->ctrl.runl + 0x008) & 0x; ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000, true, &chan->mthd); if (ret) - return ret; + goto free_chan; ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000, true, &chan->inst); if (ret) - return ret; + goto free_chan; nvkm_kmap(chan->inst); nvkm_wo32(chan->inst, 0x010, 0xface); @@ -209,11 +211,11 @@ ga102_chan_new(struct nvkm_device *device, ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000, true, &chan->user); if (ret) - return ret; + goto free_chan; ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000, true, &chan->runl); if (ret) - return ret; + goto free_chan; nvkm_kmap(chan->runl); nvkm_wo32(chan->runl, 0x00, 0x80030001); @@ -228,10 +230,14 @@ ga102_chan_new(struct nvkm_device *device, ret = nvkm_vmm_join(vmm, chan->inst); if (ret) - return ret; + goto free_chan; chan->vmm = nvkm_vmm_ref(vmm); return 0; + +free_chan: + kfree(chan); + return ret; } static const struct nvkm_device_oclass -- 2.33.0 -- --- Tim Gardner Canonical, Inc
Re: [RFC PATCH v3 1/6] drm/doc: Color Management and HDR10 RFC
On Mon, 20 Sep 2021 20:14:50 -0400 Harry Wentland wrote: > On 2021-09-15 10:01, Pekka Paalanen wrote:> On Fri, 30 Jul 2021 16:41:29 -0400 > > Harry Wentland wrote: > > > >> Use the new DRM RFC doc section to capture the RFC previously only > >> described in the cover letter at > >> https://patchwork.freedesktop.org/series/89506/ > >> > >> v3: > >> * Add sections on single-plane and multi-plane HDR > >> * Describe approach to define HW details vs approach to define SW > >> intentions > >> * Link Jeremy Cline's excellent HDR summaries > >> * Outline intention behind overly verbose doc > >> * Describe FP16 use-case > >> * Clean up links > >> > >> v2: create this doc > >> > >> v1: n/a > >> > >> Signed-off-by: Harry Wentland Hi Harry! ... > >> --- > >> Documentation/gpu/rfc/color_intentions.drawio | 1 + > >> Documentation/gpu/rfc/color_intentions.svg| 3 + > >> Documentation/gpu/rfc/colorpipe | 1 + > >> Documentation/gpu/rfc/colorpipe.svg | 3 + > >> Documentation/gpu/rfc/hdr-wide-gamut.rst | 580 ++ > >> Documentation/gpu/rfc/index.rst | 1 + > >> 6 files changed, 589 insertions(+) > >> create mode 100644 Documentation/gpu/rfc/color_intentions.drawio > >> create mode 100644 Documentation/gpu/rfc/color_intentions.svg > >> create mode 100644 Documentation/gpu/rfc/colorpipe > >> create mode 100644 Documentation/gpu/rfc/colorpipe.svg > >> create mode 100644 Documentation/gpu/rfc/hdr-wide-gamut.rst ... > >> + > >> +Here are some examples of real-life objects and their approximate > >> +luminance values: > >> + > >> + > >> +.. _PQ (perceptual quantizer) function: > >> https://en.wikipedia.org/wiki/High-dynamic-range_video#Perceptual_Quantizer > >> + > >> +.. flat-table:: > >> + :header-rows: 1 > >> + > >> + * - Object > >> + - Luminance in nits > >> + > >> + * - Fluorescent light > >> + - 10,000 > >> + > >> + * - Highlights > >> + - 1,000 - sunlight > > > > Did fluorescent and highlights get swapped here? > > > No, though at first glance it can look like that. This is pulled > from an internal doc I didn't write, but I think the intention is > to show that fluorescent lights can be up to 10,000 nits and > highlights are usually 1,000+ nits. > > I'll clarify this in v4. > > A quick google search seems to show that there are even fluorescent > lights with 46,000 nits. I guess these numbers provide a ballpark > view more than anything. Those seem quite extreme fluorescent lights, far beyond what one might find in offices I suppose? I mean, I can totally stare straight at my office fluorescent lights without any discomfort. Highlights OTOH of course depend on which highlights we're talking about, and your 1000 - sunlight range I can totally agree with. If you look at a sea or a lake on a sunny day, the reflections of Sun on the water surface are much much brighter than anything else in nature aside from Sun itself. I happened to see this myself when playing with a camera: the rest of the image can be black while the water highlights still shoot way beyond the captured dynamic range. > >> + > >> + * - White Objects > >> + - 250 - 1,000 > >> + > >> + * - Typical Objects > >> + - 1 - 250 > >> + > >> + * - Shadows > >> + - 0.01 - 1 > >> + > >> + * - Ultra Blacks > >> + - 0 - 0.0005 > >> + > >> + > >> +Transfer functions > >> +-- > >> + > >> +Traditionally we used the terms gamma and de-gamma to describe the > >> +encoding of a pixel's luminance value and the operation to transfer from > >> +a linear luminance space to the non-linear space used to encode the > >> +pixels. Since some newer encodings don't use a gamma curve I suggest > >> +we refer to non-linear encodings using the terms `EOTF, and OETF`_, or > >> +simply as transfer function in general. > > > > Yeah, gamma could mean lots of things. If you have e.g. OETF gamma > > 1/2.2 and EOTF gamma 2.4, the result is OOTF gamma 1.09. > > > > OETF, EOTF and OOTF are not unambiguous either, since there is always > > the question of whose function is it. > > > Yeah, I think both gamma and EO/OE/OO/EETF are all somewhat problematic. We can use them, but we have to explain which functions we are referring to. In particular, if you have a specific EOTF, then the inverse of it should be called EOTF^-1 and not OETF, to follow what I have understood of specs like BT.2100. Personally I'd take things further and talk about encoding and decoding functions when the intent is to translate between pixel values and light-linear color values rather than characterising a piece of equipment. > I tend to think about these more in terms of input and output transfer > functions but then you have the ambiguity about what your input and > output mean. I see the input TF between framebuffer and blender, > and the output TF between blender and display. Indeed, those are good explanations. > You also
Re: [PATCH V2] video: backlight: Drop maximum brightness override for brightness zero
On Sat, 11 Sep 2021, Marek Vasut wrote: > On 7/13/21 9:16 PM, Marek Vasut wrote: > > The note in c2adda27d202f ("video: backlight: Add of_find_backlight helper > > in backlight.c") says that gpio-backlight uses brightness as power state. > > This has been fixed since in ec665b756e6f7 ("backlight: gpio-backlight: > > Correct initial power state handling") and other backlight drivers do not > > require this workaround. Drop the workaround. > > > > This fixes the case where e.g. pwm-backlight can perfectly well be set to > > brightness 0 on boot in DT, which without this patch leads to the display > > brightness to be max instead of off. > > > > Fixes: c2adda27d202f ("video: backlight: Add of_find_backlight helper in > > backlight.c") > > Acked-by: Noralf Trønnes > > Reviewed-by: Daniel Thompson > > Cc: # 5.4+ > > Cc: # 4.19.x: ec665b756e6f7: backlight: > > gpio-backlight: Correct initial power state handling > > Signed-off-by: Marek Vasut > > Cc: Daniel Thompson > > Cc: Meghana Madhyastha > > Cc: Noralf Trønnes > > Cc: Sean Paul > > Cc: Thierry Reding > > --- > > V2: Add AB/RB, CC stable > > --- > > drivers/video/backlight/backlight.c | 6 -- > > 1 file changed, 6 deletions(-) > > > > diff --git a/drivers/video/backlight/backlight.c > > b/drivers/video/backlight/backlight.c > > index 537fe1b376ad7..fc990e576340b 100644 > > --- a/drivers/video/backlight/backlight.c > > +++ b/drivers/video/backlight/backlight.c > > @@ -688,12 +688,6 @@ static struct backlight_device > > *of_find_backlight(struct device *dev) > > of_node_put(np); > > if (!bd) > > return ERR_PTR(-EPROBE_DEFER); > > - /* > > -* Note: gpio_backlight uses brightness as > > -* power state during probe > > -*/ > > - if (!bd->props.brightness) > > - bd->props.brightness = bd->props.max_brightness; > > } > > } > > > > Any news on this ? > > Expanding CC list. Looks like I was left off of the original submission. I can't apply a quoted patch. Please re-submit. -- Lee Jones [李琼斯] Senior Technical Lead - Developer Services Linaro.org │ Open source software for Arm SoCs Follow Linaro: Facebook | Twitter | Blog
[PATCH v2] drm/i915/request: fix early tracepoints
Currently we blow up in trace_dma_fence_init, when calling into get_driver_name or get_timeline_name, since both the engine and context might be NULL(or contain some garbage address) in the case of newly allocated slab objects via the request ctor. Note that we also use SLAB_TYPESAFE_BY_RCU here, which allows requests to be immediately freed, but delay freeing the underlying page by an RCU grace period. With this scheme requests can be re-allocated, at the same time as they are also being read by some lockless RCU lookup mechanism. In the ctor case, which is only called for new slab objects(i.e allocate new page and call the ctor for each object) it's safe to reset the context/engine prior to calling into dma_fence_init, since we can be certain that no one is doing an RCU lookup which might depend on peeking at the engine/context, like in active_engine(), since the object can't yet be externally visible. In the recycled case(which might also be externally visible) the request refcount always transitions from 0->1 after we set the context/engine etc, which should ensure it's valid to dereference the engine for example, when doing an RCU list-walk, so long as we can also increment the refcount first. If the refcount is already zero, then the request is considered complete/released. If it's non-zero, then the request might be in the process of being re-allocated, or potentially still in flight, however after successfully incrementing the refcount, it's possible to carefully inspect the request state, to determine if the request is still what we were looking for. Note that all externally visible requests returned to the cache must have zero refcount. One possible fix then is to move dma_fence_init out from the request ctor. Originally this was how it was done, but it was moved in: commit 855e39e65cfc33a73724f1cc644ffc5754864a20 Author: Chris Wilson Date: Mon Feb 3 09:41:48 2020 + drm/i915: Initialise basic fence before acquiring seqno where it looks like intel_timeline_get_seqno() relied on some of the rq->fence state, but that is no longer the case since: commit 12ca695d2c1ed26b2dcbb528b42813bd0f216cfc Author: Maarten Lankhorst Date: Tue Mar 23 16:49:50 2021 +0100 drm/i915: Do not share hwsp across contexts any more, v8. intel_timeline_get_seqno() could also be cleaned up slightly by dropping the request argument. Moving dma_fence_init back out of the ctor, should ensure we have enough of the request initialised in case of trace_dma_fence_init. Functionally this should be the same, and is effectively what we were already open coding before, except now we also assign the fence->lock and fence->ops, but since these are invariant for recycled requests(which might be externally visible), and will therefore already hold the same value, it shouldn't matter. An alternative fix, since we don't yet have a fully initialised request when in the ctor, is just setting the context/engine as NULL, but this does require adding some extra handling in get_driver_name etc. v2(Daniel): - Try to make the commit message less confusing Fixes: 855e39e65cfc ("drm/i915: Initialise basic fence before acquiring seqno") Signed-off-by: Matthew Auld Cc: Michael Mason Cc: Daniel Vetter Reviewed-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_request.c | 11 ++- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index ce446716d092..79da5eca60af 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -829,8 +829,6 @@ static void __i915_request_ctor(void *arg) i915_sw_fence_init(&rq->submit, submit_notify); i915_sw_fence_init(&rq->semaphore, semaphore_notify); - dma_fence_init(&rq->fence, &i915_fence_ops, &rq->lock, 0, 0); - rq->capture_list = NULL; init_llist_head(&rq->execute_cb); @@ -905,17 +903,12 @@ __i915_request_create(struct intel_context *ce, gfp_t gfp) rq->ring = ce->ring; rq->execution_mask = ce->engine->mask; - kref_init(&rq->fence.refcount); - rq->fence.flags = 0; - rq->fence.error = 0; - INIT_LIST_HEAD(&rq->fence.cb_list); - ret = intel_timeline_get_seqno(tl, rq, &seqno); if (ret) goto err_free; - rq->fence.context = tl->fence_context; - rq->fence.seqno = seqno; + dma_fence_init(&rq->fence, &i915_fence_ops, &rq->lock, + tl->fence_context, seqno); RCU_INIT_POINTER(rq->timeline, tl); rq->hwsp_seqno = tl->hwsp_seqno; -- 2.26.3
Re: [Intel-gfx] [PATCH v2 2/6] drm/i915/uncore: Associate shadow table with uncore
On 10/09/2021 21:10, Matt Roper wrote: Store a reference to a platform's shadow table inside the uncore, the same as we do with the forcewake table. This will allow us to use a single set of functions that operate on the shadow table reference rather than generating lots of nearly-identical functions via macros that differ only in terms of the table that they reference. Signed-off-by: Matt Roper --- drivers/gpu/drm/i915/intel_uncore.c | 40 - drivers/gpu/drm/i915/intel_uncore.h | 7 + 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 8c09af1e9f7a..5fa2bf26a948 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -1026,17 +1026,19 @@ static int mmio_range_cmp(u32 key, const struct i915_range *range) return 0; } -#define __is_X_shadowed(x) \ -static bool is_##x##_shadowed(u32 offset) \ -{ \ - const struct i915_range *regs = x##_shadowed_regs; \ - return BSEARCH(offset, regs, ARRAY_SIZE(x##_shadowed_regs), \ +static bool +is_shadowed(struct intel_uncore *uncore, u32 offset) Fits in one line if you want. +{ + if (drm_WARN_ON(&uncore->i915->drm, !uncore->shadowed_reg_table)) + return false; + + return BSEARCH(offset, + uncore->shadowed_reg_table, + uncore->shadowed_reg_table_entries, mmio_range_cmp); \ } -__is_X_shadowed(gen8) -__is_X_shadowed(gen11) -__is_X_shadowed(gen12) + If you want to tidy. static enum forcewake_domains gen6_reg_write_fw_domains(struct intel_uncore *uncore, i915_reg_t reg) @@ -1047,7 +1049,7 @@ gen6_reg_write_fw_domains(struct intel_uncore *uncore, i915_reg_t reg) #define __gen8_reg_write_fw_domains(uncore, offset) \ ({ \ enum forcewake_domains __fwd; \ - if (NEEDS_FORCE_WAKE(offset) && !is_gen8_shadowed(offset)) \ + if (NEEDS_FORCE_WAKE(offset) && !is_shadowed(uncore, offset)) \ __fwd = FORCEWAKE_RENDER; \ else \ __fwd = 0; \ @@ -1081,7 +1083,7 @@ static const struct intel_forcewake_range __chv_fw_ranges[] = { #define __fwtable_reg_write_fw_domains(uncore, offset) \ ({ \ enum forcewake_domains __fwd = 0; \ - if (NEEDS_FORCE_WAKE((offset)) && !is_gen8_shadowed(offset)) \ + if (NEEDS_FORCE_WAKE((offset)) && !is_shadowed(uncore, offset)) \ __fwd = find_fw_domain(uncore, offset); \ __fwd; \ }) @@ -1090,7 +1092,7 @@ static const struct intel_forcewake_range __chv_fw_ranges[] = { ({ \ enum forcewake_domains __fwd = 0; \ const u32 __offset = (offset); \ - if (!is_gen11_shadowed(__offset)) \ + if (!is_shadowed(uncore, __offset)) \ __fwd = find_fw_domain(uncore, __offset); \ __fwd; \ }) @@ -1099,7 +1101,7 @@ static const struct intel_forcewake_range __chv_fw_ranges[] = { ({ \ enum forcewake_domains __fwd = 0; \ const u32 __offset = (offset); \ - if (!is_gen12_shadowed(__offset)) \ + if (!is_shadowed(uncore, __offset)) \ __fwd = find_fw_domain(uncore, __offset); \ __fwd; \ }) @@ -1705,6 +1707,7 @@ __gen_write(func, 8) \ __gen_write(func, 16) \ __gen_write(func, 32) + Ditto. __gen_reg_write_funcs(gen12_fwtable); __gen_reg_write_funcs(gen11_fwtable); __gen_reg_write_funcs(fwtable); @@ -1969,6 +1972,12 @@ static int intel_uncore_fw_domains_init(struct intel_uncore *uncore) (uncore)->fw_domains_table_entries = ARRAY_SIZE((d)); \ } +#define ASSIGN_SHADOW_TABLE(uncore, d) \ +{ \ + (uncore)->shadowed_reg_table = d; \ + (uncore)->shadowed_reg_table_entries = ARRAY_SIZE((d)); \ +} + static int i915_pmic_bus_access_notifier(struct notifier_block *nb, unsigned long action, void *data) { @@ -2081,30 +2090,37 @@ static int uncore_forcewake_init(struct intel_uncore *uncore) if (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 55)) { ASSIGN_FW_DOMAINS_TABLE(uncore, __dg2_fw_ranges); + ASSIGN_SHADOW_TABLE(uncore, gen12_shadowed_regs); ASSIGN_WRITE_MMIO_VFUNCS(uncore, gen12_fwtable); ASSIGN_READ_MMIO_VFUNCS(uncore, gen11_fwtable); } else if (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 50)) { ASSIGN_FW_DOMAINS_TABLE(uncore, __xehp_fw_ranges); + ASSIGN_SHADOW_TABLE(uncore, gen12_shadowed_regs); ASSIGN_WRITE_MMIO_VFUNCS(uncore, gen12_fwtable); ASSIGN_READ_MMIO_VFUNCS(uncore, gen11_fwtable); } else if (GRAPHICS_VER(i915) >= 12) { ASSIGN_FW_DOMAINS_TABLE(uncore, __gen12_fw_ranges); + ASSIGN_SHADOW_TABLE(uncore, gen12_shadowed_regs); ASSIGN_WRITE_MMIO_VFUNCS(uncore, gen12_fwtable); ASSIGN_READ_MM
Re: [PATCH v2 1/6] drm/i915/uncore: Convert gen6/gen7 read operations to fwtable
On 10/09/2021 21:10, Matt Roper wrote: On gen6-gen8 (except vlv/chv) we don't use a forcewake lookup table; we simply check whether the register offset is < 0x4, and return FORCEWAKE_RENDER if it is. To prepare for upcoming refactoring, let's define a single-entry forcewake table from [0x0, 0x3] and switch these platforms over to use the fwtable reader functions. v2: - Drop __gen6_reg_read_fw_domains which is no longer used. (Tvrtko) Cc: Tvrtko Ursulin Signed-off-by: Matt Roper --- drivers/gpu/drm/i915/intel_uncore.c | 21 - 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index f9767054dbdf..8c09af1e9f7a 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -853,16 +853,6 @@ void assert_forcewakes_active(struct intel_uncore *uncore, /* We give fast paths for the really cool registers */ #define NEEDS_FORCE_WAKE(reg) ((reg) < 0x4) -#define __gen6_reg_read_fw_domains(uncore, offset) \ -({ \ - enum forcewake_domains __fwd; \ - if (NEEDS_FORCE_WAKE(offset)) \ - __fwd = FORCEWAKE_RENDER; \ - else \ - __fwd = 0; \ - __fwd; \ -}) - static int fw_range_cmp(u32 offset, const struct intel_forcewake_range *entry) { if (offset < entry->start) @@ -1064,6 +1054,10 @@ gen6_reg_write_fw_domains(struct intel_uncore *uncore, i915_reg_t reg) __fwd; \ }) +static const struct intel_forcewake_range __gen6_fw_ranges[] = { + GEN_FW_RANGE(0x0, 0x3, FORCEWAKE_RENDER), +}; + /* *Must* be sorted by offset ranges! See intel_fw_table_check(). */ static const struct intel_forcewake_range __chv_fw_ranges[] = { GEN_FW_RANGE(0x2000, 0x3fff, FORCEWAKE_RENDER), @@ -1623,7 +1617,6 @@ __gen_read(func, 64) __gen_reg_read_funcs(gen11_fwtable); __gen_reg_read_funcs(fwtable); -__gen_reg_read_funcs(gen6); #undef __gen_reg_read_funcs #undef GEN6_READ_FOOTER @@ -2111,15 +2104,17 @@ static int uncore_forcewake_init(struct intel_uncore *uncore) ASSIGN_WRITE_MMIO_VFUNCS(uncore, fwtable); ASSIGN_READ_MMIO_VFUNCS(uncore, fwtable); } else if (GRAPHICS_VER(i915) == 8) { + ASSIGN_FW_DOMAINS_TABLE(uncore, __gen6_fw_ranges); ASSIGN_WRITE_MMIO_VFUNCS(uncore, gen8); - ASSIGN_READ_MMIO_VFUNCS(uncore, gen6); + ASSIGN_READ_MMIO_VFUNCS(uncore, fwtable); } else if (IS_VALLEYVIEW(i915)) { ASSIGN_FW_DOMAINS_TABLE(uncore, __vlv_fw_ranges); ASSIGN_WRITE_MMIO_VFUNCS(uncore, gen6); ASSIGN_READ_MMIO_VFUNCS(uncore, fwtable); } else if (IS_GRAPHICS_VER(i915, 6, 7)) { + ASSIGN_FW_DOMAINS_TABLE(uncore, __gen6_fw_ranges); ASSIGN_WRITE_MMIO_VFUNCS(uncore, gen6); - ASSIGN_READ_MMIO_VFUNCS(uncore, gen6); + ASSIGN_READ_MMIO_VFUNCS(uncore, fwtable); } uncore->pmic_bus_access_nb.notifier_call = i915_pmic_bus_access_notifier; Reviewed-by: Tvrtko Ursulin Regards, Tvrtko
[PATCH 0/3] drm/omap: add crtc properties
This patchset adds the following CRTC properties: - background color - transparency keying property - alpha blender on DSS3 Tomi Valkeinen (3): drm/omap: add crtc background property drm/omap: add crtc transparency key property drm/omap: add alpha blender property drivers/gpu/drm/omapdrm/dss/dispc.c | 4 +- drivers/gpu/drm/omapdrm/dss/omapdss.h | 2 +- drivers/gpu/drm/omapdrm/omap_crtc.c | 85 ++- drivers/gpu/drm/omapdrm/omap_drv.c| 30 ++ drivers/gpu/drm/omapdrm/omap_drv.h| 6 ++ 5 files changed, 121 insertions(+), 6 deletions(-) -- 2.25.1
[PATCH 1/3] drm/omap: add crtc background property
From: Tomi Valkeinen Add DRM properties for crtc background color property. Background color is shown on areas where there are no planes. Signed-off-by: Tomi Valkeinen Signed-off-by: Neil Armstrong --- drivers/gpu/drm/omapdrm/omap_crtc.c | 22 +- drivers/gpu/drm/omapdrm/omap_drv.c | 7 +++ drivers/gpu/drm/omapdrm/omap_drv.h | 3 +++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 06a719c104f4..4ba2d3e51b2b 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -24,6 +24,8 @@ struct omap_crtc_state { unsigned int rotation; unsigned int zpos; bool manually_updated; + + u32 default_color; }; #define to_omap_crtc(x) container_of(x, struct omap_crtc, base) @@ -395,13 +397,14 @@ static void omap_crtc_cpr_coefs_from_ctm(const struct drm_color_ctm *ctm, static void omap_crtc_write_crtc_properties(struct drm_crtc *crtc) { + const struct omap_crtc_state *omap_state = to_omap_crtc_state(crtc->state); struct omap_drm_private *priv = crtc->dev->dev_private; struct omap_crtc *omap_crtc = to_omap_crtc(crtc); struct omap_overlay_manager_info info; memset(&info, 0, sizeof(info)); - info.default_color = 0x00; + info.default_color = omap_state->default_color; info.trans_enabled = false; info.partial_alpha_enabled = false; @@ -668,6 +671,7 @@ static int omap_crtc_atomic_set_property(struct drm_crtc *crtc, { struct omap_drm_private *priv = crtc->dev->dev_private; struct drm_plane_state *plane_state; + struct omap_crtc_state *omap_state = to_omap_crtc_state(state); /* * Delegate property set to the primary plane. Get the plane state and @@ -683,6 +687,8 @@ static int omap_crtc_atomic_set_property(struct drm_crtc *crtc, plane_state->rotation = val; else if (property == priv->zorder_prop) plane_state->zpos = val; + else if (property == priv->background_color_prop) + omap_state->default_color = val; else return -EINVAL; @@ -701,6 +707,8 @@ static int omap_crtc_atomic_get_property(struct drm_crtc *crtc, *val = omap_state->rotation; else if (property == priv->zorder_prop) *val = omap_state->zpos; + else if (property == priv->background_color_prop) + *val = omap_state->default_color; else return -EINVAL; @@ -741,6 +749,8 @@ omap_crtc_duplicate_state(struct drm_crtc *crtc) state->rotation = current_state->rotation; state->manually_updated = current_state->manually_updated; + state->default_color = current_state->default_color; + return &state->base; } @@ -778,6 +788,15 @@ static const char *channel_names[] = { [OMAP_DSS_CHANNEL_LCD3] = "lcd3", }; +static void omap_crtc_install_properties(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_mode_object *obj = &crtc->base; + struct omap_drm_private *priv = dev->dev_private; + + drm_object_attach_property(obj, priv->background_color_prop, 0); +} + /* initialize crtc */ struct drm_crtc *omap_crtc_init(struct drm_device *dev, struct omap_drm_pipeline *pipe, @@ -843,6 +862,7 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev, drm_mode_crtc_set_gamma_size(crtc, gamma_lut_size); } + omap_crtc_install_properties(crtc); omap_plane_install_properties(crtc->primary, &crtc->base); return crtc; diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index f86e20578143..48ebd1689601 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -200,6 +200,13 @@ static int omap_modeset_init_properties(struct drm_device *dev) if (!priv->zorder_prop) return -ENOMEM; + /* crtc properties */ + + priv->background_color_prop = + drm_property_create_range(dev, 0, "background", 0, 0xff); + if (!priv->background_color_prop) + return -ENOMEM; + return 0; } diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h index 591d4c273f02..ed69ae78ae89 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.h +++ b/drivers/gpu/drm/omapdrm/omap_drv.h @@ -73,6 +73,9 @@ struct omap_drm_private { /* properties: */ struct drm_property *zorder_prop; + /* crtc properties */ + struct drm_property *background_color_prop; + /* irq handling: */ spinlock_t wait_lock; /* protects the wait_list */ struct list_head wait_list; /* list of omap_irq_wait */ -- 2.25.1
[PATCH 2/3] drm/omap: add crtc transparency key property
From: Tomi Valkeinen Add support for transparency keying. User space must understand how the TCK works and needs to place the planes to correct zpos. The generic zpos normalization in DRM however is going to do normalization and might move the position of the planes which breaks the TCK as planes are no longer in the position where application deliberately placed them. If the TCK is enabled for the crtc then use the zpos configured by the application instead of the normalized positions and at the same time do a sanity check against overlapping zpos. Signed-off-by: Tomi Valkeinen Signed-off-by: Peter Ujfalusi Signed-off-by: Neil Armstrong --- drivers/gpu/drm/omapdrm/omap_crtc.c | 53 - drivers/gpu/drm/omapdrm/omap_drv.c | 18 ++ drivers/gpu/drm/omapdrm/omap_drv.h | 2 ++ 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 4ba2d3e51b2b..d1fbbbaa3da8 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -26,6 +26,8 @@ struct omap_crtc_state { bool manually_updated; u32 default_color; + unsigned int trans_key_mode; + unsigned int trans_key; }; #define to_omap_crtc(x) container_of(x, struct omap_crtc, base) @@ -405,9 +407,25 @@ static void omap_crtc_write_crtc_properties(struct drm_crtc *crtc) memset(&info, 0, sizeof(info)); info.default_color = omap_state->default_color; - info.trans_enabled = false; info.partial_alpha_enabled = false; + info.trans_key = omap_state->trans_key; + + switch (omap_state->trans_key_mode) { + case 0: + default: + info.trans_enabled = false; + break; + case 1: + info.trans_enabled = true; + info.trans_key_type = OMAP_DSS_COLOR_KEY_GFX_DST; + break; + case 2: + info.trans_enabled = true; + info.trans_key_type = OMAP_DSS_COLOR_KEY_VID_SRC; + break; + } + if (crtc->state->ctm) { struct drm_color_ctm *ctm = crtc->state->ctm->data; @@ -584,6 +602,7 @@ static int omap_crtc_atomic_check(struct drm_crtc *crtc, { struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + const struct omap_crtc_state *omap_state = to_omap_crtc_state(crtc_state); struct drm_plane_state *pri_state; if (crtc_state->color_mgmt_changed && crtc_state->degamma_lut) { @@ -594,6 +613,25 @@ static int omap_crtc_atomic_check(struct drm_crtc *crtc, return -EINVAL; } + if (omap_state->trans_key_mode) { + struct drm_plane *plane; + struct drm_plane_state *plane_state; + u32 zpos_mask = 0; + + drm_for_each_plane_mask(plane, crtc->dev, crtc_state->plane_mask) { + plane_state = + drm_atomic_get_plane_state(crtc_state->state, plane); + if (IS_ERR(plane_state)) + return PTR_ERR(plane_state); + + if (zpos_mask & BIT(plane_state->zpos)) + return -EINVAL; + + zpos_mask |= BIT(plane_state->zpos); + plane_state->normalized_zpos = plane_state->zpos; + } + } + pri_state = drm_atomic_get_new_plane_state(state, crtc->primary); if (pri_state) { @@ -689,6 +727,10 @@ static int omap_crtc_atomic_set_property(struct drm_crtc *crtc, plane_state->zpos = val; else if (property == priv->background_color_prop) omap_state->default_color = val; + else if (property == priv->trans_key_mode_prop) + omap_state->trans_key_mode = val; + else if (property == priv->trans_key_prop) + omap_state->trans_key = val; else return -EINVAL; @@ -709,6 +751,10 @@ static int omap_crtc_atomic_get_property(struct drm_crtc *crtc, *val = omap_state->zpos; else if (property == priv->background_color_prop) *val = omap_state->default_color; + else if (property == priv->trans_key_mode_prop) + *val = omap_state->trans_key_mode; + else if (property == priv->trans_key_prop) + *val = omap_state->trans_key; else return -EINVAL; @@ -751,6 +797,9 @@ omap_crtc_duplicate_state(struct drm_crtc *crtc) state->default_color = current_state->default_color; + state->trans_key_mode = current_state->trans_key_mode; + state->trans_key = current_state->trans_key; + return &state->base; } @@ -795,6 +844,8 @@ static void omap_
[PATCH 3/3] drm/omap: add alpha blender property
From: Tomi Valkeinen Add support to enable/disable alpha blender on DSS3. Signed-off-by: Tomi Valkeinen Signed-off-by: Neil Armstrong --- drivers/gpu/drm/omapdrm/dss/dispc.c | 4 ++-- drivers/gpu/drm/omapdrm/dss/omapdss.h | 2 +- drivers/gpu/drm/omapdrm/omap_crtc.c | 10 +- drivers/gpu/drm/omapdrm/omap_drv.c| 5 + drivers/gpu/drm/omapdrm/omap_drv.h| 1 + 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c index 5619420cc2cc..ca05d608e44a 100644 --- a/drivers/gpu/drm/omapdrm/dss/dispc.c +++ b/drivers/gpu/drm/omapdrm/dss/dispc.c @@ -2995,7 +2995,7 @@ void dispc_mgr_setup(struct dispc_device *dispc, info->trans_key); dispc_mgr_enable_trans_key(dispc, channel, info->trans_enabled); dispc_mgr_enable_alpha_fixed_zorder(dispc, channel, - info->partial_alpha_enabled); + info->alpha_blender_enabled); if (dispc_has_feature(dispc, FEAT_CPR)) { dispc_mgr_enable_cpr(dispc, channel, info->cpr_enable); dispc_mgr_set_cpr_coef(dispc, channel, &info->cpr_coefs); @@ -4588,7 +4588,7 @@ static const struct dispc_errata_i734_data { .mgri = { .default_color = 0, .trans_enabled = false, - .partial_alpha_enabled = false, + .alpha_blender_enabled = false, .cpr_enable = false, }, .lcd_conf = { diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h index 040d5a3e33d6..6988459f267c 100644 --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h @@ -175,7 +175,7 @@ struct omap_overlay_manager_info { u32 trans_key; bool trans_enabled; - bool partial_alpha_enabled; + bool alpha_blender_enabled; bool cpr_enable; struct omap_dss_cpr_coefs cpr_coefs; diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index d1fbbbaa3da8..fbcc092399dd 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -28,6 +28,7 @@ struct omap_crtc_state { u32 default_color; unsigned int trans_key_mode; unsigned int trans_key; + bool alpha_blender_enabled; }; #define to_omap_crtc(x) container_of(x, struct omap_crtc, base) @@ -407,7 +408,6 @@ static void omap_crtc_write_crtc_properties(struct drm_crtc *crtc) memset(&info, 0, sizeof(info)); info.default_color = omap_state->default_color; - info.partial_alpha_enabled = false; info.trans_key = omap_state->trans_key; @@ -426,6 +426,8 @@ static void omap_crtc_write_crtc_properties(struct drm_crtc *crtc) break; } + info.alpha_blender_enabled = omap_state->alpha_blender_enabled; + if (crtc->state->ctm) { struct drm_color_ctm *ctm = crtc->state->ctm->data; @@ -731,6 +733,8 @@ static int omap_crtc_atomic_set_property(struct drm_crtc *crtc, omap_state->trans_key_mode = val; else if (property == priv->trans_key_prop) omap_state->trans_key = val; + else if (property == priv->alpha_blender_prop) + omap_state->alpha_blender_enabled = !!val; else return -EINVAL; @@ -755,6 +759,8 @@ static int omap_crtc_atomic_get_property(struct drm_crtc *crtc, *val = omap_state->trans_key_mode; else if (property == priv->trans_key_prop) *val = omap_state->trans_key; + else if (property == priv->alpha_blender_prop) + *val = omap_state->alpha_blender_enabled; else return -EINVAL; @@ -799,6 +805,7 @@ omap_crtc_duplicate_state(struct drm_crtc *crtc) state->trans_key_mode = current_state->trans_key_mode; state->trans_key = current_state->trans_key; + state->alpha_blender_enabled = current_state->alpha_blender_enabled; return &state->base; } @@ -846,6 +853,7 @@ static void omap_crtc_install_properties(struct drm_crtc *crtc) drm_object_attach_property(obj, priv->background_color_prop, 0); drm_object_attach_property(obj, priv->trans_key_mode_prop, 0); drm_object_attach_property(obj, priv->trans_key_prop, 0); + drm_object_attach_property(obj, priv->alpha_blender_prop, 0); } /* initialize crtc */ diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index adf99b60b2e0..92e459c67eff 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -225,6 +225,11 @@ static int omap_modeset_init_properties(struct drm_device *dev) if (!priv->trans_key_prop) return -ENOMEM; + priv->alpha_blender_prop = + drm_property_create_bool(dev, 0, "alpha_blender"); +
Re: [Intel-gfx] [PATCH v2 3/6] drm/i915/uncore: Replace gen8 write functions with general fwtable
On 10/09/2021 21:10, Matt Roper wrote: Now that we have both a standard forcewake table (albeit a single-entry table) and the shadow table stored in the uncore, we can drop the gen8-specific write handlers in favor of the general fwtable version. Signed-off-by: Matt Roper --- drivers/gpu/drm/i915/intel_uncore.c | 13 + 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 5fa2bf26a948..4c6898746d10 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -1046,16 +1046,6 @@ gen6_reg_write_fw_domains(struct intel_uncore *uncore, i915_reg_t reg) return FORCEWAKE_RENDER; } -#define __gen8_reg_write_fw_domains(uncore, offset) \ -({ \ - enum forcewake_domains __fwd; \ - if (NEEDS_FORCE_WAKE(offset) && !is_shadowed(uncore, offset)) \ - __fwd = FORCEWAKE_RENDER; \ - else \ - __fwd = 0; \ - __fwd; \ -}) - static const struct intel_forcewake_range __gen6_fw_ranges[] = { GEN_FW_RANGE(0x0, 0x3, FORCEWAKE_RENDER), }; @@ -1711,7 +1701,6 @@ __gen_write(func, 32) __gen_reg_write_funcs(gen12_fwtable); __gen_reg_write_funcs(gen11_fwtable); __gen_reg_write_funcs(fwtable); -__gen_reg_write_funcs(gen8); #undef __gen_reg_write_funcs #undef GEN6_WRITE_FOOTER @@ -2121,7 +2110,7 @@ static int uncore_forcewake_init(struct intel_uncore *uncore) } else if (GRAPHICS_VER(i915) == 8) { ASSIGN_FW_DOMAINS_TABLE(uncore, __gen6_fw_ranges); ASSIGN_SHADOW_TABLE(uncore, gen8_shadowed_regs); - ASSIGN_WRITE_MMIO_VFUNCS(uncore, gen8); + ASSIGN_WRITE_MMIO_VFUNCS(uncore, fwtable); ASSIGN_READ_MMIO_VFUNCS(uncore, fwtable); } else if (IS_VALLEYVIEW(i915)) { ASSIGN_FW_DOMAINS_TABLE(uncore, __vlv_fw_ranges); Reviewed-by: Tvrtko Ursulin Regards, Tvrtko
Re: [PATCH 0/3] drm/omap: add crtc properties
Hi Neil, On 21/09/2021 17:16, Neil Armstrong wrote: This patchset adds the following CRTC properties: - background color - transparency keying property - alpha blender on DSS3 Tomi Valkeinen (3): drm/omap: add crtc background property drm/omap: add crtc transparency key property drm/omap: add alpha blender property Nack, these don't comply with DRM uAPI rules. That's why I never sent them upstream. https://www.kernel.org/doc/html/latest/gpu/drm-uapi.html#open-source-userspace-requirements Tomi
[PATCH] drm/i915/selftests: exercise shmem_writeback with THP
In commit: commit 1e6decf30af5c5c75445ed6ad4e65a26de578a03 Author: Hugh Dickins Date: Thu Sep 2 14:54:43 2021 -0700 shmem: shmem_writepage() split unlikely i915 THP it looks THP + shmem_writeback was an unexpected combination, and ends up hitting some BUG_ON, but it also looks like that is now fixed. While the IGTs did eventually hit this(although not during pre-merge it seems), it's likely worthwhile adding some explicit coverage for this scenario in the shrink_thp selftest. References: https://gitlab.freedesktop.org/drm/intel/-/issues/4166 Signed-off-by: Matthew Auld Cc: Tvrtko Ursulin --- drivers/gpu/drm/i915/gem/selftests/huge_pages.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c index 0827634c842c..8260a533d43f 100644 --- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c +++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c @@ -1589,7 +1589,8 @@ static int igt_shrink_thp(void *arg) i915_gem_shrink(NULL, i915, -1UL, NULL, I915_SHRINK_BOUND | I915_SHRINK_UNBOUND | - I915_SHRINK_ACTIVE); + I915_SHRINK_ACTIVE | + I915_SHRINK_WRITEBACK); if (should_swap == i915_gem_object_has_pages(obj)) { pr_err("unexpected pages mismatch, should_swap=%s\n", yesno(should_swap)); -- 2.26.3
Re: [PATCH 0/3] drm/omap: add crtc properties
Hi Tomi, On 21/09/2021 16:28, Tomi Valkeinen wrote: > Hi Neil, > > On 21/09/2021 17:16, Neil Armstrong wrote: >> This patchset adds the following CRTC properties: >> - background color >> - transparency keying property >> - alpha blender on DSS3 >> >> Tomi Valkeinen (3): >> drm/omap: add crtc background property >> drm/omap: add crtc transparency key property >> drm/omap: add alpha blender property > > Nack, these don't comply with DRM uAPI rules. That's why I never sent them > upstream. > > https://www.kernel.org/doc/html/latest/gpu/drm-uapi.html#open-source-userspace-requirements Thanks for the reply, I was wondering why ! Neil > > Tomi
[Bug 211277] sometimes crash at s2ram-wake (Ryzen 3500U): amdgpu, drm, commit_tail, amdgpu_dm_atomic_commit_tail
https://bugzilla.kernel.org/show_bug.cgi?id=211277 --- Comment #67 from James Zhu (jam...@amd.com) --- (In reply to youling257 from comment #66) > resume failed record video, > https://drive.google.com/drive/folders/1bWMC4ByGvudC9zBk-9Xgamz- > shir0pqX?usp=sharing Can you try apply this patch: https://lore.kernel.org/all/20210920163922.313113...@linuxfoundation.org/? -- You may reply to this email to add a comment. You are receiving this mail because: You are watching the assignee of the bug.
Re: [PATCH v2 4/6] drm/i915/uncore: Drop gen11/gen12 mmio write handlers
On 10/09/2021 21:10, Matt Roper wrote: Now that the reference to the shadow table is stored within the uncore, we don't need to generate separate fwtable, gen11_fwtable, and gen12_fwtable variants of the register write functions; a single 'fwtable' implementation will work for all of those platforms now. While consolidating the functions, gen11/gen12 pick up a NEEDS_FORCE_WAKE() check that they didn't have before, allowing them to bypass a lot of forcewake/shadow checking for non-GT registers (e.g., display). However since these later platforms also introduce media engines at higher MMIO offsets, the definition of NEEDS_FORCE_WAKE() is extended to also consider register offsets above GEN11_BSD_RING_BASE. v2: - Restore NEEDS_FORCE_WAKE(), but extend it for compatibility with the gen11+ platforms by also passing offsets above GEN11_BSD_RING_BASE. (Chris, Tvrtko) Cc: Tvrtko Ursulin Cc: Chris Wilson Signed-off-by: Matt Roper --- drivers/gpu/drm/i915/intel_uncore.c | 61 ++--- 1 file changed, 21 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 4c6898746d10..bfb2a6337f9d 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -851,7 +851,10 @@ void assert_forcewakes_active(struct intel_uncore *uncore, } /* We give fast paths for the really cool registers */ -#define NEEDS_FORCE_WAKE(reg) ((reg) < 0x4) +#define NEEDS_FORCE_WAKE(reg) ({ \ + u32 __reg = (reg); \ + __reg < 0x4 || __reg >= GEN11_BSD_RING_BASE; \ +}) static int fw_range_cmp(u32 offset, const struct intel_forcewake_range *entry) { @@ -1071,27 +1074,10 @@ static const struct intel_forcewake_range __chv_fw_ranges[] = { }; #define __fwtable_reg_write_fw_domains(uncore, offset) \ -({ \ - enum forcewake_domains __fwd = 0; \ - if (NEEDS_FORCE_WAKE((offset)) && !is_shadowed(uncore, offset)) \ - __fwd = find_fw_domain(uncore, offset); \ - __fwd; \ -}) - -#define __gen11_fwtable_reg_write_fw_domains(uncore, offset) \ ({ \ enum forcewake_domains __fwd = 0; \ const u32 __offset = (offset); \ - if (!is_shadowed(uncore, __offset)) \ - __fwd = find_fw_domain(uncore, __offset); \ - __fwd; \ -}) - -#define __gen12_fwtable_reg_write_fw_domains(uncore, offset) \ -({ \ - enum forcewake_domains __fwd = 0; \ - const u32 __offset = (offset); \ - if (!is_shadowed(uncore, __offset)) \ + if (NEEDS_FORCE_WAKE((__offset)) && !is_shadowed(uncore, __offset)) \ __fwd = find_fw_domain(uncore, __offset); \ __fwd; \ }) @@ -1675,34 +1661,29 @@ __gen6_write(8) __gen6_write(16) __gen6_write(32) -#define __gen_write(func, x) \ +#define __gen_fwtable_write(x) \ static void \ -func##_write##x(struct intel_uncore *uncore, i915_reg_t reg, u##x val, bool trace) { \ +fwtable_write##x(struct intel_uncore *uncore, i915_reg_t reg, u##x val, bool trace) { \ enum forcewake_domains fw_engine; \ GEN6_WRITE_HEADER; \ - fw_engine = __##func##_reg_write_fw_domains(uncore, offset); \ + fw_engine = __fwtable_reg_write_fw_domains(uncore, offset); \ if (fw_engine) \ __force_wake_auto(uncore, fw_engine); \ __raw_uncore_write##x(uncore, reg, val); \ GEN6_WRITE_FOOTER; \ } -#define __gen_reg_write_funcs(func) \ -static enum forcewake_domains \ -func##_reg_write_fw_domains(struct intel_uncore *uncore, i915_reg_t reg) { \ - return __##func##_reg_write_fw_domains(uncore, i915_mmio_reg_offset(reg)); \ -} \ -\ -__gen_write(func, 8) \ -__gen_write(func, 16) \ -__gen_write(func, 32) - +static enum forcewake_domains +fwtable_reg_write_fw_domains(struct intel_uncore *uncore, i915_reg_t reg) +{ + return __fwtable_reg_write_fw_domains(uncore, i915_mmio_reg_offset(reg)); +} -__gen_reg_write_funcs(gen12_fwtable); -__gen_reg_write_funcs(gen11_fwtable); -__gen_reg_write_funcs(fwtable); +__gen_fwtable_write(8) +__gen_fwtable_write(16) +__gen_fwtable_write(32) -#undef __gen_reg_write_funcs +#undef __gen_fwtable_write #undef GEN6_WRITE_FOOTER #undef GEN6_WRITE_HEADER @@ -2080,22 +2061,22 @@ static int uncore_forcewake_init(struct intel_uncore *uncore) if (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 55)) { ASSIGN_FW_DOMAINS_TABLE(uncore, __dg2_fw_ranges); ASSIGN_SHADOW_TABLE(uncore, gen12_shadowed_regs); - ASSIGN_WRITE_MMIO_VFUNCS(uncore, gen12_fwtable); + ASSIGN_WRITE_MMIO_VFUNCS(uncore, fwtable); ASSIGN_READ_MMIO_VFUNCS(uncore, gen11_fwtable); } else if (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 50)) { ASSIGN_FW_DOMAINS_TABLE(uncore, __xehp_fw_ranges); ASSIGN_SHADOW_TABLE(uncore, gen12_shadowed_regs); - ASSIGN_WRITE_MMIO_VFUNCS(uncore, gen12_fwtable); +
Re: [PATCH v2 5/6] drm/i915/uncore: Drop gen11 mmio read handlers
On 10/09/2021 21:10, Matt Roper wrote: Consolidate down to just a single 'fwtable' implementation. For reads we don't need to worry about shadow tables. Also, the NEEDS_FORCE_WAKE() check we previously had in the fwtable implementation can be dropped --- if a register is outside that range on one of the old platforms, then it won't belong to any forcewake range and 0 will be returned anyway. v2: - Restore NEEDS_FORCE_WAKE() check. (Chris, Tvrtko) I started liking rewording the commit message when the revision log starts contradicting it, but it is just a suggestion. Cc: Chris Wilson Cc: Tvrtko Ursulin Signed-off-by: Matt Roper --- drivers/gpu/drm/i915/intel_uncore.c | 40 - 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index bfb2a6337f9d..10f124297e7c 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -935,9 +935,6 @@ static const struct intel_forcewake_range __vlv_fw_ranges[] = { __fwd; \ }) -#define __gen11_fwtable_reg_read_fw_domains(uncore, offset) \ - find_fw_domain(uncore, offset) - /* *Must* be sorted by offset! See intel_shadow_table_check(). */ static const struct i915_range gen8_shadowed_regs[] = { { .start = 0x2030, .end = 0x2030 }, @@ -1570,33 +1567,30 @@ static inline void __force_wake_auto(struct intel_uncore *uncore, ___force_wake_auto(uncore, fw_domains); } -#define __gen_read(func, x) \ +#define __gen_fwtable_read(x) \ static u##x \ -func##_read##x(struct intel_uncore *uncore, i915_reg_t reg, bool trace) { \ +fwtable_read##x(struct intel_uncore *uncore, i915_reg_t reg, bool trace) \ +{ \ enum forcewake_domains fw_engine; \ GEN6_READ_HEADER(x); \ - fw_engine = __##func##_reg_read_fw_domains(uncore, offset); \ + fw_engine = __fwtable_reg_read_fw_domains(uncore, offset); \ if (fw_engine) \ __force_wake_auto(uncore, fw_engine); \ val = __raw_uncore_read##x(uncore, reg); \ GEN6_READ_FOOTER; \ } -#define __gen_reg_read_funcs(func) \ -static enum forcewake_domains \ -func##_reg_read_fw_domains(struct intel_uncore *uncore, i915_reg_t reg) { \ - return __##func##_reg_read_fw_domains(uncore, i915_mmio_reg_offset(reg)); \ -} \ -\ -__gen_read(func, 8) \ -__gen_read(func, 16) \ -__gen_read(func, 32) \ -__gen_read(func, 64) +static enum forcewake_domains +fwtable_reg_read_fw_domains(struct intel_uncore *uncore, i915_reg_t reg) { + return __fwtable_reg_read_fw_domains(uncore, i915_mmio_reg_offset(reg)); +} -__gen_reg_read_funcs(gen11_fwtable); -__gen_reg_read_funcs(fwtable); +__gen_fwtable_read(8) +__gen_fwtable_read(16) +__gen_fwtable_read(32) +__gen_fwtable_read(64) -#undef __gen_reg_read_funcs +#undef __gen_fwtable_read #undef GEN6_READ_FOOTER #undef GEN6_READ_HEADER @@ -2062,22 +2056,22 @@ static int uncore_forcewake_init(struct intel_uncore *uncore) ASSIGN_FW_DOMAINS_TABLE(uncore, __dg2_fw_ranges); ASSIGN_SHADOW_TABLE(uncore, gen12_shadowed_regs); ASSIGN_WRITE_MMIO_VFUNCS(uncore, fwtable); - ASSIGN_READ_MMIO_VFUNCS(uncore, gen11_fwtable); + ASSIGN_READ_MMIO_VFUNCS(uncore, fwtable); } else if (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 50)) { ASSIGN_FW_DOMAINS_TABLE(uncore, __xehp_fw_ranges); ASSIGN_SHADOW_TABLE(uncore, gen12_shadowed_regs); ASSIGN_WRITE_MMIO_VFUNCS(uncore, fwtable); - ASSIGN_READ_MMIO_VFUNCS(uncore, gen11_fwtable); + ASSIGN_READ_MMIO_VFUNCS(uncore, fwtable); } else if (GRAPHICS_VER(i915) >= 12) { ASSIGN_FW_DOMAINS_TABLE(uncore, __gen12_fw_ranges); ASSIGN_SHADOW_TABLE(uncore, gen12_shadowed_regs); ASSIGN_WRITE_MMIO_VFUNCS(uncore, fwtable); - ASSIGN_READ_MMIO_VFUNCS(uncore, gen11_fwtable); + ASSIGN_READ_MMIO_VFUNCS(uncore, fwtable); } else if (GRAPHICS_VER(i915) == 11) { ASSIGN_FW_DOMAINS_TABLE(uncore, __gen11_fw_ranges); ASSIGN_SHADOW_TABLE(uncore, gen11_shadowed_regs); ASSIGN_WRITE_MMIO_VFUNCS(uncore, fwtable); - ASSIGN_READ_MMIO_VFUNCS(uncore, gen11_fwtable); + ASSIGN_READ_MMIO_VFUNCS(uncore, fwtable); } else if (IS_GRAPHICS_VER(i915, 9, 10)) { ASSIGN_FW_DOMAINS_TABLE(uncore, __gen9_fw_ranges); ASSIGN_SHADOW_TABLE(uncore, gen8_shadowed_regs); Reviewed-by: Tvrtko Ursulin Regards, Tvrtko
Re: [Intel-gfx] [PATCH 19/27] drm/i915: Fix bug in user proto-context creation that leaked contexts
On 20/09/2021 23:57, John Harrison wrote: On 8/20/2021 15:44, Matthew Brost wrote: Set number of engines before attempting to create contexts so the function free_engines can clean up properly. Fixes: d4433c7600f7 ("drm/i915/gem: Use the proto-context to handle create parameters (v5)") Signed-off-by: Matthew Brost Cc: --- drivers/gpu/drm/i915/gem/i915_gem_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c index dbaeb924a437..bcaaf514876b 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c @@ -944,6 +944,7 @@ static struct i915_gem_engines *user_engines(struct i915_gem_context *ctx, unsigned int n; e = alloc_engines(num_engines); This can return null when out of memory. There needs to be an early exit check before dereferencing a null pointer. Not sure if that is a worse bug or not than leaking memory! Either way, it would be good to fix that too. Pull out from the series and send a fix standalone ASAP? Also suggest adding author and reviewer to cc for typically quicker turnaround time. Regards, Tvrtko John. + e->num_engines = num_engines; for (n = 0; n < num_engines; n++) { struct intel_context *ce; int ret; @@ -977,7 +978,6 @@ static struct i915_gem_engines *user_engines(struct i915_gem_context *ctx, goto free_engines; } } - e->num_engines = num_engines; return e;
Re: [PATCH v2] backlight: propagate errors from get_brightness()
On 2021-09-07T14:47+0200, Thomas Weißschuh wrote: > backlight.h documents "struct backlight_ops->get_brightness()" to return > a negative errno on failure. > So far these errors have not been handled in the backlight core. > This leads to negative values being exposed through sysfs although only > positive values are documented to be reported. > [..] Friendly ping.
Re: [PATCH v2] backlight: propagate errors from get_brightness()
On Tue, 21 Sep 2021, Thomas Weißschuh wrote: > On 2021-09-07T14:47+0200, Thomas Weißschuh wrote: > > backlight.h documents "struct backlight_ops->get_brightness()" to return > > a negative errno on failure. > > So far these errors have not been handled in the backlight core. > > This leads to negative values being exposed through sysfs although only > > positive values are documented to be reported. > > > [..] > > Friendly ping. Don't do that. If you think the submission has been forgotten about (it hasn't), then please submit a [RESEND]. As it happens, this is on my TOREVEW list. I just need to get around to it post-vacation. -- Lee Jones [李琼斯] Senior Technical Lead - Developer Services Linaro.org │ Open source software for Arm SoCs Follow Linaro: Facebook | Twitter | Blog
Re: [PATCH v2] drm/rockchip: cdn-dp-core: Fix cdn_dp_resume unused warning
On Tue, 21 Sep 2021 02:12:17 PDT (-0700), he...@sntech.de wrote: On Fri, 10 Sep 2021 20:43:18 -0700, Palmer Dabbelt wrote: cdn_dp_resume is only used under PM_SLEEP, and now that it's static an unused function warning is triggered undner !PM_SLEEP. This marks the function as possibly unused, to avoid triggering compiler warnings. Applied, thanks! [1/1] drm/rockchip: cdn-dp-core: Fix cdn_dp_resume unused warning commit: f7c57a4566115657c16fd6603b6ef8a21bae5194 I'm not quite sure where that lives, but is it applied on top of something or is it merged from the tag? Like I said a bit below this in the original patch, this has started to break the build for me and I'd like to pull it in as soon as possible.
[RFC PATCH] drm/print: Add deprecation notes to DRM_...() functions
It's hard for someone (like me) who's not following closely to know what the suggested best practices are for error printing in DRM drivers. Add some hints to the header file. In general, my understanding is that: * When possible we should be using a `struct drm_device` for logging and recent patches have tried to make it more possible to access a relevant `struct drm_device` in more places. * For most cases when we don't have a `struct drm_device`, we no longer bother with DRM-specific wrappers on the dev_...() functions or pr_...() functions and just encourage drivers to use the normal functions. * For debug-level functions where we might want filtering based on a category we'll still have DRM-specific wrappers, but we'll only support passing a `struct drm_device`, not a `struct device`. Presumably most of the cases where we want the filtering are messages that happen while the system is in a normal running state (AKA not during probe time) and we should have a `struct drm_device` then. If we absolutely can't get a `struct drm_device` then these functions begrudgingly accept NULL for the `struct drm_device` and hopefully the awkwardness of having to manually pass NULL will keep people from doing this unless absolutely necessary. Signed-off-by: Douglas Anderson --- include/drm/drm_print.h | 30 ++ 1 file changed, 30 insertions(+) diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h index 15a089a87c22..22fabdeed297 100644 --- a/include/drm/drm_print.h +++ b/include/drm/drm_print.h @@ -340,6 +340,8 @@ void drm_dev_dbg(const struct device *dev, enum drm_debug_category category, /** * DRM_DEV_ERROR() - Error output. * + * NOTE: this is deprecated in favor of drm_err() or dev_err(). + * * @dev: device pointer * @fmt: printf() like format string. */ @@ -349,6 +351,9 @@ void drm_dev_dbg(const struct device *dev, enum drm_debug_category category, /** * DRM_DEV_ERROR_RATELIMITED() - Rate limited error output. * + * NOTE: this is deprecated in favor of drm_err_ratelimited() or + * dev_err_ratelimited(). + * * @dev: device pointer * @fmt: printf() like format string. * @@ -364,9 +369,11 @@ void drm_dev_dbg(const struct device *dev, enum drm_debug_category category, DRM_DEV_ERROR(dev, fmt, ##__VA_ARGS__); \ }) +/* NOTE: this is deprecated in favor of drm_info() or dev_info(). */ #define DRM_DEV_INFO(dev, fmt, ...)\ drm_dev_printk(dev, KERN_INFO, fmt, ##__VA_ARGS__) +/* NOTE: this is deprecated in favor of drm_info_once() or dev_info_once(). */ #define DRM_DEV_INFO_ONCE(dev, fmt, ...) \ ({ \ static bool __print_once __read_mostly; \ @@ -379,6 +386,8 @@ void drm_dev_dbg(const struct device *dev, enum drm_debug_category category, /** * DRM_DEV_DEBUG() - Debug output for generic drm code * + * NOTE: this is deprecated in favor of drm_dbg_core(). + * * @dev: device pointer * @fmt: printf() like format string. */ @@ -387,6 +396,8 @@ void drm_dev_dbg(const struct device *dev, enum drm_debug_category category, /** * DRM_DEV_DEBUG_DRIVER() - Debug output for vendor specific part of the driver * + * NOTE: this is deprecated in favor of drm_dbg() or dev_dbg(). + * * @dev: device pointer * @fmt: printf() like format string. */ @@ -395,6 +406,8 @@ void drm_dev_dbg(const struct device *dev, enum drm_debug_category category, /** * DRM_DEV_DEBUG_KMS() - Debug output for modesetting code * + * NOTE: this is deprecated in favor of drm_dbg_kms(). + * * @dev: device pointer * @fmt: printf() like format string. */ @@ -480,47 +493,63 @@ void __drm_err(const char *format, ...); #define _DRM_PRINTK(once, level, fmt, ...) \ printk##once(KERN_##level "[" DRM_NAME "] " fmt, ##__VA_ARGS__) +/* NOTE: this is deprecated in favor of pr_info(). */ #define DRM_INFO(fmt, ...) \ _DRM_PRINTK(, INFO, fmt, ##__VA_ARGS__) +/* NOTE: this is deprecated in favor of pr_notice(). */ #define DRM_NOTE(fmt, ...) \ _DRM_PRINTK(, NOTICE, fmt, ##__VA_ARGS__) +/* NOTE: this is deprecated in favor of pr_warn(). */ #define DRM_WARN(fmt, ...) \ _DRM_PRINTK(, WARNING, fmt, ##__VA_ARGS__) +/* NOTE: this is deprecated in favor of pr_info_once(). */ #define DRM_INFO_ONCE(fmt, ...) \ _DRM_PRINTK(_once, INFO, fmt, ##__VA_ARGS__) +/* NOTE: this is deprecated in favor of pr_notice_once(). */ #define DRM_NOTE_ONCE(fmt, ...) \ _DRM_PRINTK(_once, NOTICE, fmt, ##__VA_ARGS__) +/* NOTE: this is deprecated in favor of pr_warn_once(). */ #defin
RE: [PATCH 2/2] Add drm buddy manager support to amdgpu driver
[AMD Public Use] Hi Christian, Please find my comments. Thanks, Arun -Original Message- From: Koenig, Christian Sent: Tuesday, September 21, 2021 2:34 PM To: Paneer Selvam, Arunpravin ; dri-devel@lists.freedesktop.org; intel-...@lists.freedesktop.org; amd-...@lists.freedesktop.org; matthew.a...@intel.com; dan...@ffwll.ch; Deucher, Alexander Subject: Re: [PATCH 2/2] Add drm buddy manager support to amdgpu driver Am 20.09.21 um 21:21 schrieb Arunpravin: > Replace drm_mm with drm buddy manager for VRAM memory management > > Signed-off-by: Arunpravin > --- > .../gpu/drm/amd/amdgpu/amdgpu_res_cursor.h| 78 +-- > drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h | 3 +- > drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 216 ++ > 3 files changed, 189 insertions(+), 108 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h > index acfa207cf970..ba24052e9062 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h > @@ -30,12 +30,25 @@ > #include > #include > > +struct amdgpu_vram_mgr_node { > + struct ttm_range_mgr_node tnode; NAK, don't base this on ttm_range_mgr_node. Instead use ttm_resource. And please name the member base instead. Arun - ok > + struct list_head blocks; > +}; > + > +static inline struct amdgpu_vram_mgr_node * > +to_amdgpu_vram_mgr_node(struct ttm_resource *res) { > + return container_of(container_of(res, struct ttm_range_mgr_node, base), > + struct amdgpu_vram_mgr_node, tnode); } > + Maybe stuff that in a separate amdgpu_vram_mgr.h file together with all the other defines for the vram manager. Arun - I thought about it, will create a new header file for vram manager > /* state back for walking over vram_mgr and gtt_mgr allocations */ > struct amdgpu_res_cursor { > uint64_tstart; > uint64_tsize; > uint64_tremaining; > - struct drm_mm_node *node; > + void*node; > + uint32_tmem_type; > }; > > /** > @@ -52,8 +65,6 @@ static inline void amdgpu_res_first(struct ttm_resource > *res, > uint64_t start, uint64_t size, > struct amdgpu_res_cursor *cur) > { > - struct drm_mm_node *node; > - > if (!res || res->mem_type == TTM_PL_SYSTEM) { > cur->start = start; > cur->size = size; > @@ -65,14 +76,39 @@ static inline void amdgpu_res_first(struct > ttm_resource *res, > > BUG_ON(start + size > res->num_pages << PAGE_SHIFT); > > - node = to_ttm_range_mgr_node(res)->mm_nodes; > - while (start >= node->size << PAGE_SHIFT) > - start -= node++->size << PAGE_SHIFT; > + cur->mem_type = res->mem_type; > + > + if (cur->mem_type == TTM_PL_VRAM) { Rather use a switch/case here. Arun - ok > + struct drm_buddy_block *block; > + struct list_head *head, *next; > + > + head = &to_amdgpu_vram_mgr_node(res)->blocks; > + > + block = list_first_entry_or_null(head, struct drm_buddy_block, > link); > + while (start >= block->size << PAGE_SHIFT) { > + start -= block->size << PAGE_SHIFT; > + > + next = block->link.next; > + if (next != head) > + block = list_entry(next, struct > drm_buddy_block, link); > + } > > - cur->start = (node->start << PAGE_SHIFT) + start; > - cur->size = min((node->size << PAGE_SHIFT) - start, size); > - cur->remaining = size; > - cur->node = node; > + cur->start = (block->start << PAGE_SHIFT) + start; > + cur->size = min((block->size << PAGE_SHIFT) - start, size); > + cur->remaining = size; > + cur->node = block; > + } else if (cur->mem_type == TTM_PL_TT) { > + struct drm_mm_node *node; > + > + node = to_ttm_range_mgr_node(res)->mm_nodes; > + while (start >= node->size << PAGE_SHIFT) > + start -= node++->size << PAGE_SHIFT; > + > + cur->start = (node->start << PAGE_SHIFT) + start; > + cur->size = min((node->size << PAGE_SHIFT) - start, size); > + cur->remaining = size; > + cur->node = node; With a default handling for other placement types. Arun - ok > + } > } > > /** > @@ -85,8 +121,6 @@ static inline void amdgpu_res_first(struct ttm_resource > *res, >*/ > static inline void amdgpu_res_next(struct amdgpu_res_cursor *cur, uint64_t > size) > { > - struct drm_mm_node *node = cur->node; > - > BUG_ON(size > cur->remaining); > > cur->remaining -= size; > @@ -99,9 +133,23 @@ static inline void amdgpu_res_next(struct > amdgpu_res_cursor *cur
[PATCH v11 08/16] arm64: dts: mt8195: add display node for vdosys0
Add display node for vdosys0. Signed-off-by: jason-jh.lin --- This patch is based on [1][2][3] [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]arm64: dts: mt8195: add gce node - https://patchwork.kernel.org/project/linux-mediatek/patch/20210831070903.8672-4-jason-jh@mediatek.com/ --- arch/arm64/boot/dts/mediatek/mt8195.dtsi | 111 +++ 1 file changed, 111 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi index 35b6022d6fdc..e136761345db 100644 --- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi @@ -1115,9 +1115,120 @@ #clock-cells = <1>; }; + ovl0: disp_ovl@1c00 { + compatible = "mediatek,mt8195-disp-ovl", +"mediatek,mt8192-disp-ovl"; + reg = <0 0x1c00 0 0x1000>; + interrupts = ; + power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>; + clocks = <&vdosys0 CLK_VDO0_DISP_OVL0>; + iommus = <&iommu_vdo M4U_PORT_L0_DISP_OVL0_RDMA0>; + mediatek,gce-client-reg = +<&gce0 SUBSYS_1c00 0x 0x1000>; + }; + + rdma0: disp_rdma@1c002000 { + compatible = "mediatek,mt8195-disp-rdma"; + reg = <0 0x1c002000 0 0x1000>; + interrupts = ; + power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>; + clocks = <&vdosys0 CLK_VDO0_DISP_RDMA0>; + iommus = <&iommu_vdo M4U_PORT_L0_DISP_RDMA0>; + mediatek,gce-client-reg = +<&gce0 SUBSYS_1c00 0x2000 0x1000>; + }; + + color0: disp_color@1c003000 { + compatible = "mediatek,mt8195-disp-color", +"mediatek,mt8173-disp-color"; + reg = <0 0x1c003000 0 0x1000>; + interrupts = ; + power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>; + clocks = <&vdosys0 CLK_VDO0_DISP_COLOR0>; + mediatek,gce-client-reg = +<&gce0 SUBSYS_1c00 0x3000 0x1000>; + }; + + ccorr0: disp_ccorr@1c004000 { + compatible = "mediatek,mt8195-disp-ccorr", +"mediatek,mt8192-disp-ccorr"; + reg = <0 0x1c004000 0 0x1000>; + interrupts = ; + power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>; + clocks = <&vdosys0 CLK_VDO0_DISP_CCORR0>; + mediatek,gce-client-reg = +<&gce0 SUBSYS_1c00 0x4000 0x1000>; + }; + + aal0: disp_aal@1c005000 { + compatible = "mediatek,mt8195-disp-aal", +"mediatek,mt8173-disp-aal"; + reg = <0 0x1c005000 0 0x1000>; + interrupts = ; + power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>; + clocks = <&vdosys0 CLK_VDO0_DISP_AAL0>; + mediatek,gce-client-reg = +<&gce0 SUBSYS_1c00 0x5000 0x1000>; + }; + + gamma0: disp_gamma@1c006000 { + compatible = "mediatek,mt8195-disp-gamma", +"mediatek,mt8173-disp-gamma"; + reg = <0 0x1c006000 0 0x1000>; + interrupts = ; + power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>; + clocks = <&vdosys0 CLK_VDO0_DISP_GAMMA0>; + mediatek,gce-client-reg = +<&gce0 SUBSYS_1c00 0x6000 0x1000>; + }; + + dither0: disp_dither@1c007000 { + compatible = "mediatek,mt8195-disp-dither", +"mediatek,mt8183-disp-dither"; + reg = <0 0x1c007000 0 0x1000>; + interrupts = ; + power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>; + clocks = <&vdosys0 CLK_VDO0_DISP_DITHER0>; + mediatek,gce-client-reg = +<&gce0 SUBSYS_1c00 0x7000 0x1000>; + }; + +
[PATCH v11 01/16] dt-bindings: arm: mediatek: mmsys: add power and gce properties
Power: 1. Add description for power-domains property. GCE: 1. Add description for mboxes property. 2. Add description for mediatek,gce-client-reg property. Signed-off-by: jason-jh.lin --- .../bindings/arm/mediatek/mediatek,mmsys.yaml | 30 ++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml index f9ffa5b703a5..b78219c83c40 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml @@ -40,6 +40,30 @@ properties: reg: 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. + + mboxes: +description: + Using mailbox to communicate with GCE, it should have this + property and list of phandle, mailbox specifiers. See + Documentation/devicetree/bindings/mailbox/mtk-gce.txt for details. +$ref: /schemas/types.yaml#/definitions/phandle-array + + mediatek,gce-client-reg: +description: + The register of client driver can be configured by gce with 4 arguments + defined in this property, such as phandle of gce, subsys id, + register offset and size. + Each subsys id is mapping to a base address of display function blocks + register which is defined in the gce header + include/dt-bindings/gce/-gce.h. +$ref: /schemas/types.yaml#/definitions/phandle-array +maxItems: 1 + "#clock-cells": const: 1 @@ -54,6 +78,10 @@ examples: - | mmsys: syscon@1400 { compatible = "mediatek,mt8173-mmsys", "syscon"; -reg = <0x1400 0x1000>; +reg = <0 0x1400 0 0x1000>; +power-domains = <&spm MT8173_POWER_DOMAIN_MM>; #clock-cells = <1>; +mboxes = <&gce 0 CMDQ_THR_PRIO_HIGHEST>, + <&gce 1 CMDQ_THR_PRIO_HIGHEST>; +mediatek,gce-client-reg = <&gce SUBSYS_1400 0 0x1000>; }; -- 2.18.0
[PATCH v11 05/16] dt-bindings: display: mediatek: merge: add additional prop for mt8195
add MERGE additional properties description for mt8195: 1. async clock 2. fifo setting enable 3. reset controller Signed-off-by: jason-jh.lin --- .../display/mediatek/mediatek,merge.yaml | 31 +++ 1 file changed, 31 insertions(+) diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml index 75beeb207ceb..542dd7137d3b 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml @@ -38,6 +38,19 @@ properties: clocks: items: - description: MERGE Clock + - description: MERGE Async Clock + Controlling the synchronous process between MERGE and other display + function blocks cross clock domain. + + mediatek,merge-fifo-en: +description: + The setting of merge fifo is mainly provided for the display latency + buffer to ensure that the back-end panel display data will not be + underrun, a little more data is needed in the fifo. + According to the merge fifo settings, when the water level is detected + to be insufficient, it will trigger RDMA sending ultra and preulra + command to SMI to speed up the data rate. +type: boolean mediatek,gce-client-reg: description: @@ -50,6 +63,11 @@ properties: $ref: /schemas/types.yaml#/definitions/phandle-array maxItems: 1 + resets: +description: reset controller + See Documentation/devicetree/bindings/reset/reset.txt for details. +maxItems: 1 + required: - compatible - reg @@ -67,3 +85,16 @@ examples: power-domains = <&spm MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_MERGE>; }; + +merge5: disp_vpp_merge5@1c11 { +compatible = "mediatek,mt8195-disp-merge"; +reg = <0 0x1c11 0 0x1000>; +interrupts = ; +clocks = <&vdosys1 CLK_VDO1_VPP_MERGE4>, + <&vdosys1 CLK_VDO1_MERGE4_DL_ASYNC>; +clock-names = "merge","merge_async"; +power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; +mediatek,gce-client-reg = <&gce1 SUBSYS_1c11 0x 0x1000>; +mediatek,merge-fifo-en = <1>; +resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE4_DL_ASYNC>; +}; -- 2.18.0
[PATCH v11 14/16] drm/mediatek: add DSC support for mediatek-drm
DSC is designed for real-time systems with real-time compression, transmission, decompression and display. The DSC standard is a specification of the algorithms used for compressing and decompressing image display streams, including the specification of the syntax and semantics of the compressed video bit stream. Signed-off-by: jason-jh.lin --- rebase on series [1] [1] drm/mediatek: add support for mediatek SOC MT8192 - https://patchwork.kernel.org/project/linux-mediatek/list/?series=529489 --- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 47 + drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 1 + 2 files changed, 48 insertions(+) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c index 23c03e550658..ce6c90b9edef 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c @@ -40,6 +40,12 @@ #define DITHER_LSB_ERR_SHIFT_G(x) (((x) & 0x7) << 12) #define DITHER_ADD_LSHIFT_G(x) (((x) & 0x7) << 4) +#define DISP_REG_DSC_CON 0x +#define DSC_EN BIT(0) +#define DSC_DUAL_INOUT BIT(2) +#define DSC_BYPASS BIT(4) +#define DSC_UFOE_SEL BIT(16) + #define DISP_REG_OD_EN 0x #define DISP_REG_OD_CFG0x0020 #define OD_RELAYMODE BIT(0) @@ -181,6 +187,36 @@ static void mtk_dither_set(struct device *dev, unsigned int bpc, DISP_DITHERING, cmdq_pkt); } +static void mtk_dsc_config(struct device *dev, unsigned int w, + unsigned int h, unsigned int vrefresh, + unsigned int bpc, struct cmdq_pkt *cmdq_pkt) +{ + struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev); + + /* dsc bypass mode */ + mtk_ddp_write_mask(cmdq_pkt, DSC_BYPASS, &priv->cmdq_reg, priv->regs, + DISP_REG_DSC_CON, DSC_BYPASS); + mtk_ddp_write_mask(cmdq_pkt, DSC_UFOE_SEL, &priv->cmdq_reg, priv->regs, + DISP_REG_DSC_CON, DSC_UFOE_SEL); + mtk_ddp_write_mask(cmdq_pkt, DSC_DUAL_INOUT, &priv->cmdq_reg, priv->regs, + DISP_REG_DSC_CON, DSC_DUAL_INOUT); +} + +static void mtk_dsc_start(struct device *dev) +{ + struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev); + + /* write with mask to reserve the value set in mtk_dsc_config */ + mtk_ddp_write_mask(NULL, DSC_EN, &priv->cmdq_reg, priv->regs, DISP_REG_DSC_CON, DSC_EN); +} + +static void mtk_dsc_stop(struct device *dev) +{ + struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev); + + writel_relaxed(0x0, priv->regs + DISP_REG_DSC_CON); +} + static void mtk_od_config(struct device *dev, unsigned int w, unsigned int h, unsigned int vrefresh, unsigned int bpc, struct cmdq_pkt *cmdq_pkt) @@ -270,6 +306,14 @@ static const struct mtk_ddp_comp_funcs ddp_dpi = { .stop = mtk_dpi_stop, }; +static const struct mtk_ddp_comp_funcs ddp_dsc = { + .clk_enable = mtk_ddp_clk_enable, + .clk_disable = mtk_ddp_clk_disable, + .config = mtk_dsc_config, + .start = mtk_dsc_start, + .stop = mtk_dsc_stop, +}; + static const struct mtk_ddp_comp_funcs ddp_dsi = { .start = mtk_dsi_ddp_start, .stop = mtk_dsi_ddp_stop, @@ -339,6 +383,7 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = { [MTK_DISP_CCORR] = "ccorr", [MTK_DISP_COLOR] = "color", [MTK_DISP_DITHER] = "dither", + [MTK_DISP_DSC] = "dsc", [MTK_DISP_GAMMA] = "gamma", [MTK_DISP_MUTEX] = "mutex", [MTK_DISP_OD] = "od", @@ -369,6 +414,8 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = { [DDP_COMPONENT_DITHER] = { MTK_DISP_DITHER,0, &ddp_dither }, [DDP_COMPONENT_DPI0]= { MTK_DPI,0, &ddp_dpi }, [DDP_COMPONENT_DPI1]= { MTK_DPI,1, &ddp_dpi }, + [DDP_COMPONENT_DSC0]= { MTK_DISP_DSC, 0, &ddp_dsc }, + [DDP_COMPONENT_DSC1]= { MTK_DISP_DSC, 1, &ddp_dsc }, [DDP_COMPONENT_DSI0]= { MTK_DSI,0, &ddp_dsi }, [DDP_COMPONENT_DSI1]= { MTK_DSI,1, &ddp_dsi }, [DDP_COMPONENT_DSI2]= { MTK_DSI,2, &ddp_dsi }, diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h index 4c6a98662305..5e6ff12f16ad 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h @@ -23,6 +23,7 @@ enum mtk_ddp_comp_type { MTK_DISP_CCORR, MTK_DISP_COLOR, MTK_DISP_DITHER, + MTK_DISP_DSC, MTK_DISP_G
[PATCH v11 03/16] dt-bindings: display: mediatek: disp: split each block to individual yaml
1. Remove mediatek,dislpay.txt 2. Split each display function block to individual yaml file. Signed-off-by: jason-jh.lin --- .../display/mediatek/mediatek,aal.yaml| 79 +++ .../display/mediatek/mediatek,ccorr.yaml | 74 ++ .../display/mediatek/mediatek,color.yaml | 88 +++ .../display/mediatek/mediatek,disp.txt| 219 -- .../display/mediatek/mediatek,dither.yaml | 78 +++ .../display/mediatek/mediatek,gamma.yaml | 79 +++ .../display/mediatek/mediatek,merge.yaml | 69 ++ .../display/mediatek/mediatek,mutex.yaml | 82 +++ .../display/mediatek/mediatek,od.yaml | 53 + .../display/mediatek/mediatek,ovl-2l.yaml | 91 .../display/mediatek/mediatek,ovl.yaml| 101 .../display/mediatek/mediatek,postmask.yaml | 72 ++ .../display/mediatek/mediatek,rdma.yaml | 118 ++ .../display/mediatek/mediatek,split.yaml | 58 + .../display/mediatek/mediatek,ufoe.yaml | 61 + .../display/mediatek/mediatek,wdma.yaml | 89 +++ 16 files changed, 1192 insertions(+), 219 deletions(-) create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml delete mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,postmask.yaml create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml new file mode 100644 index ..92a350ab9722 --- /dev/null +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml @@ -0,0 +1,79 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/mediatek/mediatek,aal.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Mediatek display adaptive ambient light processor + +maintainers: + - Chun-Kuang Hu + - Philipp Zabel + +description: | + Mediatek display adaptive ambient light processor, namely AAL, + is responsible for backlight power saving and sunlight visibility improving. + AAL 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,mt8173-disp-aal + - items: + - enum: + - mediatek,mt2712-disp-aal + - mediatek,mt8183-disp-aal + - mediatek,mt8192-disp-aal + - enum: + - mediatek,mt8173-disp-aal + + 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: AAL Clock + + mediatek,gce-client-reg: +description: + The register of client driver can be configured by gce with 4 arguments + defined in this property, such as phandle of gce, subsys id, + register offset and size. + Each subsys id is mapping to a base address of display function blocks + register which is defined in the gce header + include/dt-bindings/gce/-gce.h. +$ref: /schemas/types.yaml#/definitions/phandle-array +maxItems: 1 + +required: + - compatible + - reg + - interrupts + - power-domains + - clocks + +additionalProperties: false + +examples: + - | + +aal@14015000 { +compatible = "mediatek,mt8173-disp-aal"; +
[PATCH v11 00/16] Add Mediatek Soc DRM (vdosys0) support for mt8195
Change in v11: - rebase on kernel-5.15-rc1 - change mbox label to gce0 for dts node of vdosys0 - change ovl compatibale to mt8192 to set smi_id_en=true in driver data - move common module from display folder to common folder, such as AAL, COCLOR, CCORR and MUTEX Change in v10: - rebase on "drm/mediatek: add support for mediatek SOC MT8192" series https://patchwork.kernel.org/project/linux-mediatek/list/?series=529489 - rebase on "soc: mediatek: mmsys: add mt8192 mmsys support" series https://patchwork.kernel.org/project/linux-mediatek/list/?series=524857 - fix some typo and "mediatek" start with capital in every dt-bindings - move mutex yaml from dfisplay folder to soc folder - separate merge additional propoerties to an individual dt-bindings patch Change in v9: - separate power and gce properties of mmsys into another dt-binding patch - rebase on "Separate aal module" series https://patchwork.kernel.org/project/linux-mediatek/list/?series=516463 - keep mtk_ddp_clk_enable/disable in the same place - change mtk_dsc_start config register to mtk_drm_ddp_write_mask - remove the 0 setting of merge fifo config function - add CCORR driver data for mt8195 Change in v8: - add DP_INTF0 mux into mmsys routing table - add DP_INTF0 mutex mod and enum into add/remove comp function - remove bypass DSC enum in mtk_ddp_comp_init Change in v7: - add dt=binding of mmsys and disp path into this series - separate th modidfication of alphabetic order, remove unused define and rename the define of register offset to individual patch - add comment for MERGE ultra and preultra setting Change in v6: - adjust alphabetic order for mediatek-drm - move the patch that add mt8195 support for mediatek-drm as the lastest patch - add MERGE define for const varriable Change in v5: - add power-domain property into vdosys0 and vdosys1 dts node. - add MT8195 prifix and remove unused VDO1 define in mt8195-mmsys.h Change in v4: - extract dt-binding patches to another patch series https://patchwork.kernel.org/project/linux-mediatek/list/?series=519597 - squash DSC module into mtk_drm_ddp_comp.c - add coment and simplify MERGE config function Change in v3: - change mmsys and display dt-bindings document from txt to yaml - add MERGE additional description in display dt-bindings document - fix mboxes-cells number of vdosys0 node in dts - drop mutex eof convert define - remove pm_runtime apis in DSC and MERGE - change DSC and MERGE enum to alphabetic order Change in v2: - add DSC yaml file - add mt8195 drm driver porting parts in to one patch - remove useless define, variable, structure member and function - simplify DSC and MERGE file and switch threre order jason-jh.lin (16): dt-bindings: arm: mediatek: mmsys: add power and gce properties dt-bindings: arm: mediatek: mmsys: add mt8195 SoC binding dt-bindings: display: mediatek: disp: split each block to individual yaml dt-bindings: display: mediatek: dsc: add yaml for mt8195 SoC binding dt-bindings: display: mediatek: merge: add additional prop for mt8195 dt-bindings: display: mediatek: add mt8195 SoC binding for vdosys0 dt-bindings: arm: mediatek: move common module from display folder arm64: dts: mt8195: add display node for vdosys0 soc: mediatek: add mtk-mmsys support for mt8195 vdosys0 soc: mediatek: add mtk-mutex support for mt8195 vdosys0 drm/mediatek: remove unused define in mtk_drm_ddp_comp.c drm/mediatek: rename the define of register offset drm/mediatek: adjust to the alphabetic order for mediatek-drm drm/mediatek: add DSC support for mediatek-drm drm/mediatek: add MERGE support for mediatek-drm drm/mediatek: add mediatek-drm of vdosys0 support for mt8195 .../bindings/arm/mediatek/mediatek,aal.yaml | 79 ++ .../bindings/arm/mediatek/mediatek,ccorr.yaml | 78 ++ .../bindings/arm/mediatek/mediatek,color.yaml | 88 +++ .../bindings/arm/mediatek/mediatek,mmsys.yaml | 32 ++- .../bindings/arm/mediatek/mediatek,mutex.yaml | 81 ++ .../bindings/arm/mediatek/mediatek,wdma.yaml | 88 +++ .../display/mediatek/mediatek,disp.txt| 219 .../display/mediatek/mediatek,dither.yaml | 79 ++ .../display/mediatek/mediatek,dsc.yaml| 71 ++ .../display/mediatek/mediatek,gamma.yaml | 80 ++ .../display/mediatek/mediatek,merge.yaml | 102 .../display/mediatek/mediatek,od.yaml | 53 .../display/mediatek/mediatek,ovl-2l.yaml | 91 +++ .../display/mediatek/mediatek,ovl.yaml| 106 .../display/mediatek/mediatek,postmask.yaml | 72 ++ .../display/mediatek/mediatek,rdma.yaml | 120 + .../display/mediatek/mediatek,split.yaml | 58 + .../display/mediatek/mediatek,ufoe.yaml | 61 + arch/arm64/boot/dts/mediatek/mt8195.dtsi | 111 drivers/gpu/drm/mediatek/Makefile | 1 + drivers/gpu/drm/mediatek/mtk_disp_drv.h | 8 + drivers/gpu/drm/mediatek/mtk_dis
[PATCH v11 13/16] drm/mediatek: adjust to the alphabetic order for mediatek-drm
Adjust to the alphabetic order for the define, function, struct and array in mediatek-drm driver Signed-off-by: jason-jh.lin --- rebase on series [1] [1] drm/mediatek: add support for mediatek SOC MT8192 - https://patchwork.kernel.org/project/linux-mediatek/list/?series=529489 --- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 126 ++-- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 24 ++-- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 120 +-- 3 files changed, 134 insertions(+), 136 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c index b46bc0f5d1a5..23c03e550658 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c @@ -20,26 +20,30 @@ #include "mtk_drm_ddp_comp.h" #include "mtk_drm_crtc.h" -#define DISP_REG_OD_EN 0x -#define DISP_REG_OD_CFG0x0020 -#define DISP_REG_OD_SIZE 0x0030 -#define DISP_REG_DITHER_5 0x0114 -#define DISP_REG_DITHER_7 0x011c -#define DISP_REG_DITHER_15 0x013c -#define DISP_REG_DITHER_16 0x0140 - -#define DISP_REG_UFO_START 0x #define DISP_REG_DITHER_EN 0x #define DITHER_EN BIT(0) #define DISP_REG_DITHER_CFG0x0020 #define DITHER_RELAY_MODE BIT(0) #define DITHER_ENGINE_EN BIT(1) +#define DISP_DITHERING BIT(2) #define DISP_REG_DITHER_SIZE 0x0030 +#define DISP_REG_DITHER_5 0x0114 +#define DISP_REG_DITHER_7 0x011c +#define DISP_REG_DITHER_15 0x013c +#define DITHER_LSB_ERR_SHIFT_R(x) (((x) & 0x7) << 28) +#define DITHER_ADD_LSHIFT_R(x) (((x) & 0x7) << 20) +#define DITHER_NEW_BIT_MODEBIT(0) +#define DISP_REG_DITHER_16 0x0140 +#define DITHER_LSB_ERR_SHIFT_B(x) (((x) & 0x7) << 28) +#define DITHER_ADD_LSHIFT_B(x) (((x) & 0x7) << 20) +#define DITHER_LSB_ERR_SHIFT_G(x) (((x) & 0x7) << 12) +#define DITHER_ADD_LSHIFT_G(x) (((x) & 0x7) << 4) +#define DISP_REG_OD_EN 0x +#define DISP_REG_OD_CFG0x0020 #define OD_RELAYMODE BIT(0) - -#define UFO_BYPASS BIT(2) +#define DISP_REG_OD_SIZE 0x0030 #define DISP_REG_POSTMASK_EN 0x #define POSTMASK_ENBIT(0) @@ -47,14 +51,8 @@ #define POSTMASK_RELAY_MODEBIT(0) #define DISP_REG_POSTMASK_SIZE 0x0030 -#define DISP_DITHERING BIT(2) -#define DITHER_LSB_ERR_SHIFT_R(x) (((x) & 0x7) << 28) -#define DITHER_ADD_LSHIFT_R(x) (((x) & 0x7) << 20) -#define DITHER_NEW_BIT_MODEBIT(0) -#define DITHER_LSB_ERR_SHIFT_B(x) (((x) & 0x7) << 28) -#define DITHER_ADD_LSHIFT_B(x) (((x) & 0x7) << 20) -#define DITHER_LSB_ERR_SHIFT_G(x) (((x) & 0x7) << 12) -#define DITHER_ADD_LSHIFT_G(x) (((x) & 0x7) << 4) +#define DISP_REG_UFO_START 0x +#define UFO_BYPASS BIT(2) struct mtk_ddp_comp_dev { struct clk *clk; @@ -147,8 +145,35 @@ void mtk_dither_set_common(void __iomem *regs, struct cmdq_client_reg *cmdq_reg, } } +static void mtk_dither_config(struct device *dev, unsigned int w, + unsigned int h, unsigned int vrefresh, + unsigned int bpc, struct cmdq_pkt *cmdq_pkt) +{ + struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev); + + mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs, DISP_REG_DITHER_SIZE); + mtk_ddp_write(cmdq_pkt, DITHER_RELAY_MODE, &priv->cmdq_reg, priv->regs, + DISP_REG_DITHER_CFG); + mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, DISP_REG_DITHER_CFG, + DITHER_ENGINE_EN, cmdq_pkt); +} + +static void mtk_dither_start(struct device *dev) +{ + struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev); + + writel(DITHER_EN, priv->regs + DISP_REG_DITHER_EN); +} + +static void mtk_dither_stop(struct device *dev) +{ + struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev); + + writel_relaxed(0x0, priv->regs + DISP_REG_DITHER_EN); +} + static void mtk_dither_set(struct device *dev, unsigned int bpc, - unsigned int cfg, struct cmdq_pkt *cmdq_pkt) + unsigned int cfg, struct cmdq_pkt *cmdq_pkt) { struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev); @@
[PATCH v11 11/16] drm/mediatek: remove unused define in mtk_drm_ddp_comp.c
Remove the unsed define in mtk_drm_ddp_comp.c Signed-off-by: jason-jh.lin Reviewed-by: Chun-Kuang Hu --- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 10 -- 1 file changed, 10 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c index f3db96a1b24d..839ffae3019c 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c @@ -21,8 +21,6 @@ #include "mtk_drm_crtc.h" #define DISP_OD_EN 0x -#define DISP_OD_INTEN 0x0008 -#define DISP_OD_INTSTA 0x000c #define DISP_OD_CFG0x0020 #define DISP_OD_SIZE 0x0030 #define DISP_DITHER_5 0x0114 @@ -39,8 +37,6 @@ #define DITHER_ENGINE_EN BIT(1) #define DISP_DITHER_SIZE 0x0030 -#define LUT_10BIT_MASK 0x03ff - #define OD_RELAYMODE BIT(0) #define UFO_BYPASS BIT(2) @@ -53,18 +49,12 @@ #define DISP_DITHERING BIT(2) #define DITHER_LSB_ERR_SHIFT_R(x) (((x) & 0x7) << 28) -#define DITHER_OVFLW_BIT_R(x) (((x) & 0x7) << 24) #define DITHER_ADD_LSHIFT_R(x) (((x) & 0x7) << 20) -#define DITHER_ADD_RSHIFT_R(x) (((x) & 0x7) << 16) #define DITHER_NEW_BIT_MODEBIT(0) #define DITHER_LSB_ERR_SHIFT_B(x) (((x) & 0x7) << 28) -#define DITHER_OVFLW_BIT_B(x) (((x) & 0x7) << 24) #define DITHER_ADD_LSHIFT_B(x) (((x) & 0x7) << 20) -#define DITHER_ADD_RSHIFT_B(x) (((x) & 0x7) << 16) #define DITHER_LSB_ERR_SHIFT_G(x) (((x) & 0x7) << 12) -#define DITHER_OVFLW_BIT_G(x) (((x) & 0x7) << 8) #define DITHER_ADD_LSHIFT_G(x) (((x) & 0x7) << 4) -#define DITHER_ADD_RSHIFT_G(x) (((x) & 0x7) << 0) struct mtk_ddp_comp_dev { struct clk *clk; -- 2.18.0
[PATCH v11 09/16] soc: mediatek: add mtk-mmsys support for mt8195 vdosys0
Add mt8195 vdosys0 clock driver name and routing table to the driver data of mtk-mmsys. Signed-off-by: jason-jh.lin --- This patch is base on [1] [1] soc: mediatek: mmsys: add mt8192 mmsys support - https://patchwork.kernel.org/project/linux-mediatek/list/?series=524857 The vdosys1 impelmentation patch [2] [2] soc: mediatek: add mtk-mmsys support for mt8195 vdosys1 - https://patchwork.kernel.org/project/linux-mediatek/patch/20210906071539.12953-7-nancy@mediatek.com/ --- drivers/soc/mediatek/mt8195-mmsys.h| 114 + drivers/soc/mediatek/mtk-mmsys.c | 11 +++ include/linux/soc/mediatek/mtk-mmsys.h | 9 ++ 3 files changed, 134 insertions(+) create mode 100644 drivers/soc/mediatek/mt8195-mmsys.h diff --git a/drivers/soc/mediatek/mt8195-mmsys.h b/drivers/soc/mediatek/mt8195-mmsys.h new file mode 100644 index ..0c97a5f016c1 --- /dev/null +++ b/drivers/soc/mediatek/mt8195-mmsys.h @@ -0,0 +1,114 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_MEDIATEK_MT8195_MMSYS_H +#define __SOC_MEDIATEK_MT8195_MMSYS_H + +#define MT8195_VDO0_OVL_MOUT_EN0xf14 +#define MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0BIT(0) +#define MT8195_MOUT_DISP_OVL0_TO_DISP_WDMA0BIT(1) +#define MT8195_MOUT_DISP_OVL0_TO_DISP_OVL1 BIT(2) +#define MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1BIT(4) +#define MT8195_MOUT_DISP_OVL1_TO_DISP_WDMA1BIT(5) +#define MT8195_MOUT_DISP_OVL1_TO_DISP_OVL0 BIT(6) + +#define MT8195_VDO0_SEL_IN 0xf34 +#define MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT (0 << 0) +#define MT8195_SEL_IN_VPP_MERGE_FROM_DISP_DITHER1 (1 << 0) +#define MT8195_SEL_IN_VPP_MERGE_FROM_VDO1_VIRTUAL0 (2 << 0) +#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0 (0 << 4) +#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_VPP_MERGE (1 << 4) +#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_DISP_DITHER1 (0 << 5) +#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_VPP_MERGE (1 << 5) +#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_VPP_MERGE (0 << 8) +#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_DSC_WRAP1_OUT (1 << 8) +#define MT8195_SEL_IN_SINB_VIRTUAL0_FROM_DSC_WRAP0_OUT (0 << 9) +#define MT8195_SEL_IN_DP_INTF0_FROM_DSC_WRAP1_OUT (0 << 12) +#define MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE (1 << 12) +#define MT8195_SEL_IN_DP_INTF0_FROM_VDO1_VIRTUAL0 (2 << 12) +#define MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT (0 << 16) +#define MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0 (1 << 16) +#define MT8195_SEL_IN_DSI1_FROM_DSC_WRAP1_OUT (0 << 17) +#define MT8195_SEL_IN_DSI1_FROM_VPP_MERGE (1 << 17) +#define MT8195_SEL_IN_DISP_WDMA1_FROM_DISP_OVL1(0 << 20) +#define MT8195_SEL_IN_DISP_WDMA1_FROM_VPP_MERGE(1 << 20) +#define MT8195_SEL_IN_DSC_WRAP1_OUT_FROM_DSC_WRAP1_IN (0 << 21) +#define MT8195_SEL_IN_DSC_WRAP1_OUT_FROM_DISP_DITHER1 (1 << 21) +#define MT8195_SEL_IN_DISP_WDMA0_FROM_DISP_OVL0(0 << 22) +#define MT8195_SEL_IN_DISP_WDMA0_FROM_VPP_MERGE(1 << 22) + +#define MT8195_VDO0_SEL_OUT0xf38 +#define MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN (0 << 0) +#define MT8195_SOUT_DISP_DITHER0_TO_DSI0 (1 << 0) +#define MT8195_SOUT_DISP_DITHER1_TO_DSC_WRAP1_IN (0 << 1) +#define MT8195_SOUT_DISP_DITHER1_TO_VPP_MERGE (1 << 1) +#define MT8195_SOUT_DISP_DITHER1_TO_DSC_WRAP1_OUT (2 << 1) +#define MT8195_SOUT_VDO1_VIRTUAL0_TO_VPP_MERGE (0 << 4) +#define MT8195_SOUT_VDO1_VIRTUAL0_TO_DP_INTF0 (1 << 4) +#define MT8195_SOUT_VPP_MERGE_TO_DSI1 (0 << 8) +#define MT8195_SOUT_VPP_MERGE_TO_DP_INTF0 (1 << 8) +#define MT8195_SOUT_VPP_MERGE_TO_SINA_VIRTUAL0 (2 << 8) +#define MT8195_SOUT_VPP_MERGE_TO_DISP_WDMA1(3 << 8) +#define MT8195_SOUT_VPP_MERGE_TO_DSC_WRAP0_IN (4 << 8) +#define MT8195_SOUT_VPP_MERGE_TO_DSC_WRAP1_IN (0 << 11) +#define MT8195_SOUT_VPP_MERGE_TO_DISP_WDMA0(1 << 11) +#define MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0 (0 << 12) +#define MT8195_SOUT_DSC_WRAP0_OUT_TO_SINB_VIRTUAL0 (1 << 12) +#define MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE (2 << 12) +#define MT8195_SOUT_DSC_WRAP1_OUT_TO_DSI1 (0 << 16) +#define MT8195_SOUT_DSC_WRAP1_OUT_TO_DP_INTF0 (1 << 16) +#define MT8195_SOUT_DSC_WRAP1_OUT_TO_SINA_VIRTUAL0 (2 << 16) +#define MT8195_SOUT_DSC_WRAP1_OUT_TO_VPP_MERGE (
[PATCH v11 12/16] drm/mediatek: rename the define of register offset
Add DISP_REG prefix for the define of register offset to make the difference from the define of register value. Signed-off-by: jason-jh.lin --- rebase on series [1] [1] drm/mediatek: add support for mediatek SOC MT8192 - https://patchwork.kernel.org/project/linux-mediatek/list/?series=529489 --- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 61 +++-- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c index 839ffae3019c..b46bc0f5d1a5 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c @@ -20,32 +20,32 @@ #include "mtk_drm_ddp_comp.h" #include "mtk_drm_crtc.h" -#define DISP_OD_EN 0x -#define DISP_OD_CFG0x0020 -#define DISP_OD_SIZE 0x0030 -#define DISP_DITHER_5 0x0114 -#define DISP_DITHER_7 0x011c -#define DISP_DITHER_15 0x013c -#define DISP_DITHER_16 0x0140 +#define DISP_REG_OD_EN 0x +#define DISP_REG_OD_CFG0x0020 +#define DISP_REG_OD_SIZE 0x0030 +#define DISP_REG_DITHER_5 0x0114 +#define DISP_REG_DITHER_7 0x011c +#define DISP_REG_DITHER_15 0x013c +#define DISP_REG_DITHER_16 0x0140 #define DISP_REG_UFO_START 0x -#define DISP_DITHER_EN 0x +#define DISP_REG_DITHER_EN 0x #define DITHER_EN BIT(0) -#define DISP_DITHER_CFG0x0020 +#define DISP_REG_DITHER_CFG0x0020 #define DITHER_RELAY_MODE BIT(0) #define DITHER_ENGINE_EN BIT(1) -#define DISP_DITHER_SIZE 0x0030 +#define DISP_REG_DITHER_SIZE 0x0030 #define OD_RELAYMODE BIT(0) #define UFO_BYPASS BIT(2) -#define DISP_POSTMASK_EN 0x +#define DISP_REG_POSTMASK_EN 0x #define POSTMASK_ENBIT(0) -#define DISP_POSTMASK_CFG 0x0020 +#define DISP_REG_POSTMASK_CFG 0x0020 #define POSTMASK_RELAY_MODEBIT(0) -#define DISP_POSTMASK_SIZE 0x0030 +#define DISP_REG_POSTMASK_SIZE 0x0030 #define DISP_DITHERING BIT(2) #define DITHER_LSB_ERR_SHIFT_R(x) (((x) & 0x7) << 28) @@ -130,19 +130,19 @@ void mtk_dither_set_common(void __iomem *regs, struct cmdq_client_reg *cmdq_reg, return; if (bpc >= MTK_MIN_BPC) { - mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_DITHER_5); - mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_DITHER_7); + mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_REG_DITHER_5); + mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_REG_DITHER_7); mtk_ddp_write(cmdq_pkt, DITHER_LSB_ERR_SHIFT_R(MTK_MAX_BPC - bpc) | DITHER_ADD_LSHIFT_R(MTK_MAX_BPC - bpc) | DITHER_NEW_BIT_MODE, - cmdq_reg, regs, DISP_DITHER_15); + cmdq_reg, regs, DISP_REG_DITHER_15); mtk_ddp_write(cmdq_pkt, DITHER_LSB_ERR_SHIFT_B(MTK_MAX_BPC - bpc) | DITHER_ADD_LSHIFT_B(MTK_MAX_BPC - bpc) | DITHER_LSB_ERR_SHIFT_G(MTK_MAX_BPC - bpc) | DITHER_ADD_LSHIFT_G(MTK_MAX_BPC - bpc), - cmdq_reg, regs, DISP_DITHER_16); + cmdq_reg, regs, DISP_REG_DITHER_16); mtk_ddp_write(cmdq_pkt, dither_en, cmdq_reg, regs, cfg); } } @@ -162,16 +162,16 @@ static void mtk_od_config(struct device *dev, unsigned int w, { struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev); - mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_OD_SIZE); - mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, &priv->cmdq_reg, priv->regs, DISP_OD_CFG); - mtk_dither_set(dev, bpc, DISP_OD_CFG, cmdq_pkt); + mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_REG_OD_SIZE); + mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, &priv->cmdq_reg, priv->regs, DISP_REG_OD_CFG); + mtk_dither_set(dev, bpc, DISP_REG_OD_CFG, cmdq_pkt); } static void mtk_od_start(struct device *dev) { struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev); - writel(1, priv->regs + DISP_OD_EN); + writel(1, priv->regs + DISP_REG_OD_EN);
[PATCH v11 02/16] dt-bindings: arm: mediatek: mmsys: add mt8195 SoC binding
There are 2 mmsys, namely vdosys0 and vdosys1 in mt8195. Each of them is bound to a display pipeline, so add their definition in mtk-mmsys documentation with 2 compatibles. Signed-off-by: jason-jh.lin --- .../devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml| 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml index b78219c83c40..679437ee2590 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml @@ -31,6 +31,8 @@ properties: - mediatek,mt8183-mmsys - mediatek,mt8192-mmsys - mediatek,mt8365-mmsys + - mediatek,mt8195-vdosys0 + - mediatek,mt8195-vdosys1 - const: syscon - items: - const: mediatek,mt7623-mmsys -- 2.18.0
[PATCH v11 06/16] dt-bindings: display: mediatek: add mt8195 SoC binding for vdosys0
Add mt8195 SoC binding to AAL, CCORR, COLOR, DITHER, GAMMA, MERGE, MUTEX, OVL and RDMA yaml schema for vdosys0. Signed-off-by: jason-jh.lin --- .../devicetree/bindings/display/mediatek/mediatek,aal.yaml | 1 + .../devicetree/bindings/display/mediatek/mediatek,ccorr.yaml | 5 + .../devicetree/bindings/display/mediatek/mediatek,color.yaml | 1 + .../bindings/display/mediatek/mediatek,dither.yaml | 1 + .../devicetree/bindings/display/mediatek/mediatek,gamma.yaml | 1 + .../devicetree/bindings/display/mediatek/mediatek,merge.yaml | 2 ++ .../devicetree/bindings/display/mediatek/mediatek,mutex.yaml | 5 +++-- .../devicetree/bindings/display/mediatek/mediatek,ovl.yaml | 5 + .../devicetree/bindings/display/mediatek/mediatek,rdma.yaml | 2 ++ 9 files changed, 21 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml index 92a350ab9722..311bbf05a967 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml @@ -28,6 +28,7 @@ properties: - mediatek,mt2712-disp-aal - mediatek,mt8183-disp-aal - mediatek,mt8192-disp-aal + - mediatek,mt8195-disp-aal - enum: - mediatek,mt8173-disp-aal diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml index 7840e12d4caf..60752ce45d49 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml @@ -25,6 +25,11 @@ properties: - const: mediatek,mt8183-disp-ccorr - items: - const: mediatek,mt8192-disp-ccorr + - items: + - enum: + - mediatek,mt8195-disp-ccorr + - enum: + - mediatek,mt8192-disp-ccorr reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml index 7a249ba8584c..f6636869909c 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml @@ -38,6 +38,7 @@ properties: - enum: - mediatek,mt8183-disp-color - mediatek,mt8192-disp-color + - mediatek,mt8195-disp-color - enum: - mediatek,mt8173-disp-color reg: diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml index 316374315962..d4fa75bb19a3 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml @@ -27,6 +27,7 @@ properties: - items: - enum: - mediatek,mt8192-disp-dither + - mediatek,mt8195-disp-dither - enum: - mediatek,mt8183-disp-dither diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml index 1c53ce20a71e..8ce612b016ab 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml @@ -28,6 +28,7 @@ properties: - items: - enum: - mediatek,mt8192-disp-gamma + - mediatek,mt8195-disp-gamma - enum: - mediatek,mt8183-disp-gamma diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml index 542dd7137d3b..6007e00679a8 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml @@ -23,6 +23,8 @@ properties: oneOf: - items: - const: mediatek,mt8173-disp-merge + - items: + - const: mediatek,mt8195-disp-merge reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml index 90f11e12a55e..6eca525eced0 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml @@ -4,7 +4,7 @@ $id: http://devicetree.org/schemas/display/mediatek/mediatek,mutex.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Mediatek display mutex +title: Mediatek mutex maintainers: - Chun-Kuang Hu @@ -36,7 +36,
Re: [PATCH v3 4/9] drm/scheduler: Add fence deadline support
On Wed, Sep 8, 2021 at 10:45 AM Daniel Vetter wrote: > > On Fri, Sep 03, 2021 at 11:47:55AM -0700, Rob Clark wrote: > > From: Rob Clark > > > > As the finished fence is the one that is exposed to userspace, and > > therefore the one that other operations, like atomic update, would > > block on, we need to propagate the deadline from from the finished > > fence to the actual hw fence. > > > > v2: Split into drm_sched_fence_set_parent() (ckoenig) > > > > Signed-off-by: Rob Clark > > --- > > drivers/gpu/drm/scheduler/sched_fence.c | 34 + > > drivers/gpu/drm/scheduler/sched_main.c | 2 +- > > include/drm/gpu_scheduler.h | 8 ++ > > 3 files changed, 43 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/gpu/drm/scheduler/sched_fence.c > > b/drivers/gpu/drm/scheduler/sched_fence.c > > index bcea035cf4c6..4fc41a71d1c7 100644 > > --- a/drivers/gpu/drm/scheduler/sched_fence.c > > +++ b/drivers/gpu/drm/scheduler/sched_fence.c > > @@ -128,6 +128,30 @@ static void drm_sched_fence_release_finished(struct > > dma_fence *f) > > dma_fence_put(&fence->scheduled); > > } > > > > +static void drm_sched_fence_set_deadline_finished(struct dma_fence *f, > > + ktime_t deadline) > > +{ > > + struct drm_sched_fence *fence = to_drm_sched_fence(f); > > + unsigned long flags; > > + > > + spin_lock_irqsave(&fence->lock, flags); > > + > > + /* If we already have an earlier deadline, keep it: */ > > + if (test_bit(DMA_FENCE_FLAG_HAS_DEADLINE_BIT, &f->flags) && > > + ktime_before(fence->deadline, deadline)) { > > + spin_unlock_irqrestore(&fence->lock, flags); > > + return; > > + } > > + > > + fence->deadline = deadline; > > + set_bit(DMA_FENCE_FLAG_HAS_DEADLINE_BIT, &f->flags); > > + > > + spin_unlock_irqrestore(&fence->lock, flags); > > + > > + if (fence->parent) > > + dma_fence_set_deadline(fence->parent, deadline); > > +} > > + > > static const struct dma_fence_ops drm_sched_fence_ops_scheduled = { > > .get_driver_name = drm_sched_fence_get_driver_name, > > .get_timeline_name = drm_sched_fence_get_timeline_name, > > @@ -138,6 +162,7 @@ static const struct dma_fence_ops > > drm_sched_fence_ops_finished = { > > .get_driver_name = drm_sched_fence_get_driver_name, > > .get_timeline_name = drm_sched_fence_get_timeline_name, > > .release = drm_sched_fence_release_finished, > > + .set_deadline = drm_sched_fence_set_deadline_finished, > > }; > > > > struct drm_sched_fence *to_drm_sched_fence(struct dma_fence *f) > > @@ -152,6 +177,15 @@ struct drm_sched_fence *to_drm_sched_fence(struct > > dma_fence *f) > > } > > EXPORT_SYMBOL(to_drm_sched_fence); > > > > +void drm_sched_fence_set_parent(struct drm_sched_fence *s_fence, > > + struct dma_fence *fence) > > +{ > > + s_fence->parent = dma_fence_get(fence); > > + if (test_bit(DMA_FENCE_FLAG_HAS_DEADLINE_BIT, > > + &s_fence->finished.flags)) > > Don't you need the spinlock here too to avoid races? test_bit is very > unordered, so guarantees nothing. Spinlock would need to be both around > ->parent = and the test_bit. > > Entirely aside, but there's discussions going on to preallocate the hw > fence somehow. If we do that we could make the deadline forwarding > lockless here. Having a spinlock just to set the parent is a bit annoying > ... > > Alternative is that you do this locklessly with barriers and a _lot_ of > comments. Would be good to benchmark whether the overhead matters though > first. So, my thinking is that very few (well no) guarantees are made to the fence implementor that their ->set_deadline() is not called multiple times, from multiple threads, etc. And no guarantee that a later deadline is set after an earlier deadline has been set. It is all up to the set_deadline() implementation to deal with these cases. So that means we just need the appropriate barrier-fu to ensure another thread calling drm_sched_fence_set_deadline_finished() sees fence->parent set before the test_bit. It could mean that the backend implementation sees the same deadline set twice, but that is fine. BR, -R > -Daniel > > > + dma_fence_set_deadline(fence, s_fence->deadline); > > +} > > + > > struct drm_sched_fence *drm_sched_fence_alloc(struct drm_sched_entity > > *entity, > > void *owner) > > { > > diff --git a/drivers/gpu/drm/scheduler/sched_main.c > > b/drivers/gpu/drm/scheduler/sched_main.c > > index 595e47ff7d06..27bf0ac0625f 100644 > > --- a/drivers/gpu/drm/scheduler/sched_main.c > > +++ b/drivers/gpu/drm/scheduler/sched_main.c > > @@ -978,7 +978,7 @@ static int drm_sched_main(void *param) > > drm_sched_fence_scheduled(s_fence); > > > > if (!IS_ERR_OR_NULL(fence)) { > > - s_fence->parent = dma_fence_get(fence);
[PATCH v11 07/16] dt-bindings: arm: mediatek: move common module from display folder
AAL, COLOR, CCORR, MUTEX, WDMA could be used by other modules, such as MDP, so move their binding document into the common folder. Signed-off-by: jason-jh.lin --- .../{display => arm}/mediatek/mediatek,aal.yaml | 9 - .../{display => arm}/mediatek/mediatek,ccorr.yaml| 9 - .../{display => arm}/mediatek/mediatek,color.yaml| 11 +-- .../{display => arm}/mediatek/mediatek,mutex.yaml| 12 +--- .../{display => arm}/mediatek/mediatek,wdma.yaml | 9 - 5 files changed, 22 insertions(+), 28 deletions(-) rename Documentation/devicetree/bindings/{display => arm}/mediatek/mediatek,aal.yaml (88%) rename Documentation/devicetree/bindings/{display => arm}/mediatek/mediatek,ccorr.yaml (87%) rename Documentation/devicetree/bindings/{display => arm}/mediatek/mediatek,color.yaml (86%) rename Documentation/devicetree/bindings/{display => arm}/mediatek/mediatek,mutex.yaml (85%) rename Documentation/devicetree/bindings/{display => arm}/mediatek/mediatek,wdma.yaml (90%) diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,aal.yaml similarity index 88% rename from Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml rename to Documentation/devicetree/bindings/arm/mediatek/mediatek,aal.yaml index 311bbf05a967..ab6eb9b550a4 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,aal.yaml @@ -1,17 +1,16 @@ # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2 --- -$id: http://devicetree.org/schemas/display/mediatek/mediatek,aal.yaml# +$id: http://devicetree.org/schemas/arm/mediatek/mediatek,aal.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Mediatek display adaptive ambient light processor +title: MediaTek adaptive ambient light processor maintainers: - - Chun-Kuang Hu - - Philipp Zabel + - Matthias Brugger description: | - Mediatek display adaptive ambient light processor, namely AAL, + MediaTek adaptive ambient light processor, namely AAL, is responsible for backlight power saving and sunlight visibility improving. AAL device node must be siblings to the central MMSYS_CONFIG node. For a description of the MMSYS_CONFIG binding, see diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ccorr.yaml similarity index 87% rename from Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml rename to Documentation/devicetree/bindings/arm/mediatek/mediatek,ccorr.yaml index 60752ce45d49..de86e9ae35f3 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ccorr.yaml @@ -1,17 +1,16 @@ # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2 --- -$id: http://devicetree.org/schemas/display/mediatek/mediatek,ccorr.yaml# +$id: http://devicetree.org/schemas/arm/mediatek/mediatek,ccorr.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Mediatek display color correction +title: MediaTek color correction maintainers: - - Chun-Kuang Hu - - Philipp Zabel + - Matthias Brugger description: | - Mediatek display color correction, namely CCORR, reproduces correct color + MediaTek color correction, namely CCORR, reproduces correct color on panels with different color gamut. CCORR device node must be siblings to the central MMSYS_CONFIG node. For a description of the MMSYS_CONFIG binding, see diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,color.yaml similarity index 86% rename from Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml rename to Documentation/devicetree/bindings/arm/mediatek/mediatek,color.yaml index f6636869909c..73be301b50d2 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,color.yaml @@ -1,18 +1,17 @@ # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2 --- -$id: http://devicetree.org/schemas/display/mediatek/mediatek,color.yaml# +$id: http://devicetree.org/schemas/arm/mediatek/mediatek,color.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Mediatek display color processor +title: MediaTek color processor maintainers: - - Chun-Kuang Hu - - Philipp Zabel + - Matthias Brugger description: | - Mediatek display color processor, namely COLOR, provides hue, luma and - saturation adjustments to get better picture quality and to have one panel + MediaTek color processor, namely COLOR, provides hue, luma and saturation + adjustments to get better picture quality and to have one panel resemble the other in
[PATCH v11 15/16] drm/mediatek: add MERGE support for mediatek-drm
Add MERGE engine file: MERGE module is used to merge two slice-per-line inputs into one side-by-side output. Signed-off-by: jason-jh.lin --- rebase on series [1] [1] drm/mediatek: add support for mediatek SOC MT8192 - https://patchwork.kernel.org/project/linux-mediatek/list/?series=529489 --- drivers/gpu/drm/mediatek/Makefile | 1 + drivers/gpu/drm/mediatek/mtk_disp_drv.h | 8 + drivers/gpu/drm/mediatek/mtk_disp_merge.c | 239 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 16 ++ drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 1 + drivers/gpu/drm/mediatek/mtk_drm_drv.c | 4 +- drivers/gpu/drm/mediatek/mtk_drm_drv.h | 1 + 7 files changed, 269 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_merge.c diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile index 29098d7c8307..a38e88e82d12 100644 --- a/drivers/gpu/drm/mediatek/Makefile +++ b/drivers/gpu/drm/mediatek/Makefile @@ -4,6 +4,7 @@ mediatek-drm-y := mtk_disp_aal.o \ mtk_disp_ccorr.o \ mtk_disp_color.o \ mtk_disp_gamma.o \ + mtk_disp_merge.o \ mtk_disp_ovl.o \ mtk_disp_rdma.o \ mtk_drm_crtc.o \ diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h index 86c3068894b1..a33b13fe2b6e 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h @@ -55,6 +55,14 @@ void mtk_gamma_set_common(void __iomem *regs, struct drm_crtc_state *state); void mtk_gamma_start(struct device *dev); void mtk_gamma_stop(struct device *dev); +int mtk_merge_clk_enable(struct device *dev); +void mtk_merge_clk_disable(struct device *dev); +void mtk_merge_config(struct device *dev, unsigned int width, + unsigned int height, unsigned int vrefresh, + unsigned int bpc, struct cmdq_pkt *cmdq_pkt); +void mtk_merge_start(struct device *dev); +void mtk_merge_stop(struct device *dev); + void mtk_ovl_bgclr_in_on(struct device *dev); void mtk_ovl_bgclr_in_off(struct device *dev); void mtk_ovl_bypass_shadow(struct device *dev); diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c new file mode 100644 index ..b05e1df79c3d --- /dev/null +++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c @@ -0,0 +1,239 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include + +#include "mtk_drm_ddp_comp.h" +#include "mtk_drm_drv.h" +#include "mtk_disp_drv.h" + +#define DISP_REG_MERGE_CTRL0x000 +#define MERGE_EN 1 +#define DISP_REG_MERGE_CFG_0 0x010 +#define DISP_REG_MERGE_CFG_4 0x020 +#define DISP_REG_MERGE_CFG_10 0x038 +/* no swap */ +#define SWAP_MODE 0 +#define FLD_SWAP_MODE GENMASK(4, 0) +#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 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_36 0x0a0 +#define ULTRA_EN BIT(0) +#define PREULTRA_ENBIT(4) +#define DISP_REG_MERGE_CFG_37 0x0a4 +/* 0: Off, 1: SRAM0, 2: SRAM1, 3: SRAM0 + SRAM1 */ +#define BUFFER_MODE3 +#define FLD_BUFFER_MODEGENMASK(1, 0) +/* + * For the ultra and preultra settings, 6us ~ 9us is experience value + * and the maximum frequency of mmsys clock is 594MHz. + */ +#define DISP_REG_MERGE_CFG_40 0x0b0 +/* 6 us, 594M pixel/sec */ +#define ULTRA_TH_LOW (6 * 594) +/* 8 us, 594M pixel/sec */ +#define ULTRA_TH_HIGH (8 * 594) +#define FLD_ULTRA_TH_LOW GENMASK(15, 0) +#define FLD_ULTRA_TH_HIGH GENMASK(31, 16) +#define DISP_REG_MERGE_CFG_41 0x0b4 +/* 8 us, 594M pixel/sec */ +#define PREULTRA_TH_LOW(8 * 594) +/* 9 us, 594M pixel/sec */ +#define PREULTRA_TH_HIGH (9 * 594) +#define FLD_PREULTRA_TH_LOWGENMASK(15, 0) +#define FLD_PREULTRA_TH_HIGH GENMASK(31, 16) + +struct mtk_disp_merge { + void __iomem *regs; + struct clk *clk; + struct clk *async_clk; + struct cmdq_client_reg cmdq_reg; + boolfifo_en; +}; + +void mtk_merge_start(struct device *dev) +{ + struct mtk_disp_merge *priv = dev_get_drvdata(dev); + + writel(MERGE_EN, priv->regs + DISP_REG_MERGE_CTRL); +} + +void mtk_merge_stop(
[PATCH v11 10/16] soc: mediatek: add mtk-mutex support for mt8195 vdosys0
Add mtk-mutex support for mt8195 vdosys0. Signed-off-by: jason-jh.lin --- This patch is base on [1] [1] soc: mediatek: add mtk mutex support for MT8192 - https://patchwork.kernel.org/project/linux-mediatek/patch/1628647802-5127-5-git-send-email-yongqiang@mediatek.com/ --- drivers/soc/mediatek/mtk-mutex.c | 95 +++- 1 file changed, 92 insertions(+), 3 deletions(-) diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c index 2ca55bb5a8be..36502b27fe20 100644 --- a/drivers/soc/mediatek/mtk-mutex.c +++ b/drivers/soc/mediatek/mtk-mutex.c @@ -17,6 +17,9 @@ #define MT8183_MUTEX0_MOD0 0x30 #define MT8183_MUTEX0_SOF0 0x2c +#define MT8195_DISP_MUTEX0_MOD00x30 +#define MT8195_DISP_MUTEX0_SOF 0x2c + #define DISP_REG_MUTEX_EN(n) (0x20 + 0x20 * (n)) #define DISP_REG_MUTEX(n) (0x24 + 0x20 * (n)) #define DISP_REG_MUTEX_RST(n) (0x28 + 0x20 * (n)) @@ -79,6 +82,36 @@ #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 @@ -115,9 +148,21 @@ #define MT8167_MUTEX_SOF_DPI1 3 #define MT8183_MUTEX_SOF_DSI0 1 #define MT8183_MUTEX_SOF_DPI0 2 +#define MT8195_MUTEX_SOF_DSI0 1 +#define MT8195_MUTEX_SOF_DSI1 2 +#define MT8195_MUTEX_SOF_DP_INTF0 3 +#define MT8195_MUTEX_SOF_DP_INTF1 4 +#define MT8195_MUTEX_SOF_DPI0 6 /* for HDMI_TX */ +#define MT8195_MUTEX_SOF_DPI1 5 /* for digital video out */ #define MT8183_MUTEX_EOF_DSI0 (MT8183_MUTEX_SOF_DSI0 << 6) #define MT8183_MUTEX_EOF_DPI0 (MT8183_MUTEX_SOF_DPI0 << 6) +#define MT8195_MUTEX_EOF_DSI0 (MT8195_MUTEX_SOF_DSI0 << 7) +#define MT8195_MUTEX_EOF_DSI1 (MT8195_MUTEX_SOF_DSI1 << 7) +#define MT8195_MUTEX_EOF_DP_INTF0 (MT8195_MUTEX_SOF_DP_INTF0 << 7) +#define MT8195_MUTEX_EOF_DP_INTF1 (MT8195_MUTEX_SOF_DP_INTF1 << 7) +#define MT8195_MUTEX_EOF_DPI0 (MT8195_MUTEX_SOF_DPI0 << 7) +#define MT8195_MUTEX_EOF_DPI1 (MT8195_MUTEX_SOF_DPI1 << 7) struct mtk_mutex { int id; @@ -132,6 +177,9 @@ enum mtk_mutex_sof_id { MUTEX_SOF_DPI1, MUTEX_SOF_DSI2, MUTEX_SOF_DSI3, + MUTEX_SOF_DP_INTF0, + MUTEX_SOF_DP_INTF1, + DDP_MUTEX_SOF_MAX, }; struct mtk_mutex_data { @@ -240,7 +288,23 @@ static const unsigned int mt8192_mutex_mod[DDP_COMPONENT_ID_MAX] = { [DDP_COMPONENT_RDMA4] = MT8192_MUTEX_MOD_DISP_RDMA4, }; -static const unsigned int mt2712_mutex_sof[MUTEX_SOF_DSI3 + 1] = { +static const unsigned int mt8195_mutex_mod[DDP_COMPONENT_ID_MAX] = { + [DDP_COMPONENT_OVL0] = MT8195_MUTEX_MOD_DISP_OVL0, + [DDP_COMPONENT_WDMA0] = MT8195_MUTEX_MOD_DISP_WDMA0, + [DDP_COMPONENT_RDMA0] = MT8195_MUTEX_MOD_DISP_RDMA0, + [DDP_COMPONENT_COLOR0] = MT8195_MUTEX_MOD_DISP_COLOR0, + [DDP_COMPONENT_CCORR] = MT8195_MUTEX_MOD_DISP_CCORR0, + [DDP_COMPONENT_AAL0] = MT8195_MUTEX_MOD_DISP_AAL0, + [DDP_COMPONENT_GAMMA] = MT8195_MUTEX_MOD_DISP_GAMMA0, + [DDP_COMPONENT_DITHER] = MT8195_MUTEX_MOD_DISP_DITHER
[PATCH v11 16/16] drm/mediatek: add mediatek-drm of vdosys0 support for mt8195
Add driver data of mt8195 vdosys0 to mediatek-drm and the sub driver. Signed-off-by: jason-jh.lin --- rebase on series [1] [1] drm/mediatek: add support for mediatek SOC MT8192 - https://patchwork.kernel.org/project/linux-mediatek/list/?series=529489 --- drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 6 + drivers/gpu/drm/mediatek/mtk_drm_drv.c | 28 2 files changed, 34 insertions(+) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c index d41a3970b944..77c952bdc88c 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c @@ -357,6 +357,10 @@ static const struct mtk_disp_rdma_data mt8192_rdma_driver_data = { .fifo_size = 5 * SZ_1K, }; +static const struct mtk_disp_rdma_data mt8195_rdma_driver_data = { + .fifo_size = 1920, +}; + static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = { { .compatible = "mediatek,mt2701-disp-rdma", .data = &mt2701_rdma_driver_data}, @@ -366,6 +370,8 @@ static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = { .data = &mt8183_rdma_driver_data}, { .compatible = "mediatek,mt8192-disp-rdma", .data = &mt8192_rdma_driver_data}, + { .compatible = "mediatek,mt8195-disp-rdma", + .data = &mt8195_rdma_driver_data}, {}, }; MODULE_DEVICE_TABLE(of, mtk_disp_rdma_driver_dt_match); diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index 2f33fe8ad46b..274a5bb10851 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -177,6 +177,19 @@ static const enum mtk_ddp_comp_id mt8192_mtk_ddp_ext[] = { DDP_COMPONENT_DPI0, }; +static const enum mtk_ddp_comp_id mt8195_mtk_ddp_main[] = { + DDP_COMPONENT_OVL0, + DDP_COMPONENT_RDMA0, + DDP_COMPONENT_COLOR0, + DDP_COMPONENT_CCORR, + DDP_COMPONENT_AAL0, + DDP_COMPONENT_GAMMA, + DDP_COMPONENT_DITHER, + DDP_COMPONENT_DSC0, + DDP_COMPONENT_MERGE0, + DDP_COMPONENT_DP_INTF0, +}; + 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), @@ -228,6 +241,11 @@ static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = { .ext_len = ARRAY_SIZE(mt8192_mtk_ddp_ext), }; +static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = { + .main_path = mt8195_mtk_ddp_main, + .main_len = ARRAY_SIZE(mt8195_mtk_ddp_main), +}; + static int mtk_drm_kms_init(struct drm_device *drm) { struct mtk_drm_private *private = drm->dev_private; @@ -447,12 +465,16 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = { .data = (void *)MTK_DISP_DITHER }, { .compatible = "mediatek,mt8183-disp-dither", .data = (void *)MTK_DISP_DITHER }, + { .compatible = "mediatek,mt8195-disp-dsc", + .data = (void *)MTK_DISP_DSC }, { .compatible = "mediatek,mt8167-disp-gamma", .data = (void *)MTK_DISP_GAMMA, }, { .compatible = "mediatek,mt8173-disp-gamma", .data = (void *)MTK_DISP_GAMMA, }, { .compatible = "mediatek,mt8183-disp-gamma", .data = (void *)MTK_DISP_GAMMA, }, + { .compatible = "mediatek,mt8195-disp-merge", + .data = (void *)MTK_DISP_MERGE }, { .compatible = "mediatek,mt2701-disp-mutex", .data = (void *)MTK_DISP_MUTEX }, { .compatible = "mediatek,mt2712-disp-mutex", @@ -465,6 +487,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = { .data = (void *)MTK_DISP_MUTEX }, { .compatible = "mediatek,mt8192-disp-mutex", .data = (void *)MTK_DISP_MUTEX }, + { .compatible = "mediatek,mt8195-disp-mutex", + .data = (void *)MTK_DISP_MUTEX }, { .compatible = "mediatek,mt8173-disp-od", .data = (void *)MTK_DISP_OD }, { .compatible = "mediatek,mt2701-disp-ovl", @@ -499,6 +523,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = { .data = (void *)MTK_DISP_RDMA }, { .compatible = "mediatek,mt8192-disp-rdma", .data = (void *)MTK_DISP_RDMA }, + { .compatible = "mediatek,mt8195-disp-rdma", + .data = (void *)MTK_DISP_RDMA }, { .compatible = "mediatek,mt8173-disp-ufoe", .data = (void *)MTK_DISP_UFOE }, { .compatible = "mediatek,mt8173-disp-wdma", @@ -535,6 +561,8 @@ static const struct of_device_id mtk_drm_of_ids[] = { .data = &mt8183_mmsys_driver_data}, { .compatible = "mediatek,mt8192-mmsys", .data = &mt8192_mmsys_driver_data}, + {.compatible = "mediatek,mt8195-vdosys0", + .data = &mt8195_vdosys0_driver_data}, { } }; MODULE_DEVICE_TABLE(of, mtk_drm_of_ids); -- 2.18.0
[PATCH v11 04/16] dt-bindings: display: mediatek: dsc: add yaml for mt8195 SoC binding
1. Add mediatek,dsc.yaml to describe DSC module in details. 2. Add mt8195 SoC binding to mediatek,dsc.yaml. Signed-off-by: jason-jh.lin --- .../display/mediatek/mediatek,dsc.yaml| 71 +++ 1 file changed, 71 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml new file mode 100644 index ..1ec083eff824 --- /dev/null +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml @@ -0,0 +1,71 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/mediatek/mediatek,dsc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: mediatek display DSC controller + +maintainers: + - Chun-Kuang Hu + - Philipp Zabel + +description: | + The DSC standard is a specification of the algorithms used for + compressing and decompressing image display streams, including + the specification of the syntax and semantics of the compressed + video bit stream. DSC is designed for real-time systems with + real-time compression, transmission, decompression and Display. + +properties: + compatible: +oneOf: + - items: + - const: mediatek,mt8195-disp-dsc + + reg: +maxItems: 1 + + interrupts: +maxItems: 1 + + clocks: +items: + - description: DSC Wrapper Clock + + 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. + + mediatek,gce-client-reg: +description: + The register of client driver can be configured by gce with 4 arguments + defined in this property, such as phandle of gce, subsys id, + register offset and size. + Each subsys id is mapping to a base address of display function blocks + register which is defined in the gce header + include/dt-bindings/gce/-gce.h. +$ref: /schemas/types.yaml#/definitions/phandle-array +maxItems: 1 + +required: + - compatible + - reg + - interrupts + - power-domains + - clocks + +additionalProperties: false + +examples: + - | + +dsc0: disp_dsc_wrap@1c009000 { +compatible = "mediatek,mt8195-disp-dsc"; +reg = <0 0x1c009000 0 0x1000>; +interrupts = ; +power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>; +clocks = <&vdosys0 CLK_VDO0_DSC_WRAP0>; +mediatek,gce-client-reg = <&gce1 SUBSYS_1c00 0x9000 0x1000>; +}; -- 2.18.0
Re: [RESEND] [PATCH v2 1/2] dt-bindings: display: bridge: Add binding for R-Car MIPI DSI/CSI-2 TX
Hi Laurent, On Wed, Jul 28, 2021 at 6:26 PM Laurent Pinchart wrote: > The R-Car MIPI DSI/CSI-2 TX is embedded in the Renesas R-Car V3U SoC. It > can operate in either DSI or CSI-2 mode, with up to four data lanes. > > Signed-off-by: Laurent Pinchart > Reviewed-by: Kieran Bingham Thanks for your patch! > --- /dev/null > +++ > b/Documentation/devicetree/bindings/display/bridge/renesas,dsi-csi2-tx.yaml > @@ -0,0 +1,118 @@ > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/display/bridge/renesas,dsi-csi2-tx.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: Renesas R-Car MIPI DSI/CSI-2 Encoder > + > +maintainers: > + - Laurent Pinchart > + > +description: | > + This binding describes the MIPI DSI/CSI-2 encoder embedded in the Renesas > + R-Car V3U SoC. The encoder can operate in either DSI or CSI-2 mode, with up > + to four data lanes. > + > +properties: > + compatible: > +enum: > + - renesas,r8a779a0-dsi-csi2-tx# for V3U > + > + reg: > +maxItems: 1 > + > + clocks: > +items: > + - description: Functional clock > + - description: DSI (and CSI-2) functional clock > + - description: PLL reference clock > + > + clock-names: > +items: > + - const: fck > + - const: dsi > + - const: pll No interrupts? The hardware manual says there are 9 interrupts. 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 v5 2/2] drm/bridge: parade-ps8640: Add support for AUX channel
Hi, On Sat, Sep 18, 2021 at 10:21 AM Philip Chen wrote: > > +static ssize_t ps8640_aux_transfer(struct drm_dp_aux *aux, > + struct drm_dp_aux_msg *msg) > +{ > + struct ps8640 *ps_bridge = aux_to_ps8640(aux); > + struct regmap *map = ps_bridge->regmap[PAGE0_DP_CNTL]; > + struct device *dev = &ps_bridge->page[PAGE0_DP_CNTL]->dev; > + > + unsigned int len = msg->size; nit: usually no blank lines in the variable definition section. > + base = PAGE0_SWAUX_ADDR_7_0; > + addr_len[PAGE0_SWAUX_ADDR_7_0 - base] = msg->address; > + addr_len[PAGE0_SWAUX_ADDR_15_8 - base] = msg->address >> 8; > + addr_len[PAGE0_SWAUX_ADDR_23_16 - base] = (msg->address >> 16) & > + SWAUX_ADDR_19_16_MASK; > + addr_len[PAGE0_SWAUX_ADDR_23_16 - base] |= (msg->request << 4) & > + SWAUX_CMD_MASK; optional nit: Probably you could get rid of the mask for the request. After all, you're storing it to a thing that's a byte (so bits above bit 7 will implicitly be masked) and you're left shifting by 4 (so bits 0-3 will implicitly be masked) so this just makes it uglier. ;-) optional nit: In theory you could also get rid of the SWAUX_ADDR_19_16_MASK and if you really wanted to you could error check that the address wasn't bigger than 20-bits since giving an error for an invalid address would actually be better than silently masking it anyway... > + if (len && (request == DP_AUX_NATIVE_READ || > + request == DP_AUX_I2C_READ)) { > + /* Read from the internal FIFO buffer */ > + for (i = 0; i < len; i++) { > + ret = regmap_read(map, PAGE0_SWAUX_RDATA, > + (unsigned int *)(buf + i)); The cast to "unsigned int *" looks wrong to me. You can't just cast like this for a number of reasons. Go back to reading into a local variable and copy the byte into your buffer. Other than the regmap_read() this looks fine to me. If you send a v6 with that fixed I'll plan to wait a day or two and then apply it with Sam's tags. -Doug
[PATCH] drm/msm/dsi: do not install irq handler before power up the host
The DSI host might be left in some state by the bootloader. If this state generates an IRQ, it might hang the system by holding the interrupt line before the driver sets up the DSI host to the known state. Move the request/free_irq calls into msm_dsi_host_power_on/_off calls, so that we can be sure that the interrupt is delivered when the host is in the known state. Fixes: a689554ba6ed ("drm/msm: Initial add DSI connector support") Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dsi/dsi_host.c | 21 - 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index e269df285136..cd842347a6b1 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -1951,15 +1951,6 @@ int msm_dsi_host_modeset_init(struct mipi_dsi_host *host, return ret; } - ret = devm_request_irq(&pdev->dev, msm_host->irq, - dsi_host_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, - "dsi_isr", msm_host); - if (ret < 0) { - DRM_DEV_ERROR(&pdev->dev, "failed to request IRQ%u: %d\n", - msm_host->irq, ret); - return ret; - } - msm_host->dev = dev; ret = cfg_hnd->ops->tx_buf_alloc(msm_host, SZ_4K); if (ret) { @@ -2413,6 +2404,16 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host, if (msm_host->disp_en_gpio) gpiod_set_value(msm_host->disp_en_gpio, 1); + ret = devm_request_irq(&msm_host->pdev->dev, msm_host->irq, + dsi_host_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + "dsi_isr", msm_host); + if (ret < 0) { + DRM_DEV_ERROR(&msm_host->pdev->dev, "failed to request IRQ%u: %d\n", + msm_host->irq, ret); + return ret; + } + + msm_host->power_on = true; mutex_unlock(&msm_host->dev_mutex); @@ -2439,6 +2440,8 @@ int msm_dsi_host_power_off(struct mipi_dsi_host *host) goto unlock_ret; } + devm_free_irq(&msm_host->pdev->dev, msm_host->irq, msm_host); + dsi_ctrl_config(msm_host, false, NULL, NULL); if (msm_host->disp_en_gpio) -- 2.30.2
Re: [PATCH v3 4/9] drm/scheduler: Add fence deadline support
On Tue, Sep 21, 2021 at 8:57 AM Rob Clark wrote: > > On Wed, Sep 8, 2021 at 10:45 AM Daniel Vetter wrote: > > > > On Fri, Sep 03, 2021 at 11:47:55AM -0700, Rob Clark wrote: > > > From: Rob Clark > > > > > > As the finished fence is the one that is exposed to userspace, and > > > therefore the one that other operations, like atomic update, would > > > block on, we need to propagate the deadline from from the finished > > > fence to the actual hw fence. > > > > > > v2: Split into drm_sched_fence_set_parent() (ckoenig) > > > > > > Signed-off-by: Rob Clark > > > --- > > > drivers/gpu/drm/scheduler/sched_fence.c | 34 + > > > drivers/gpu/drm/scheduler/sched_main.c | 2 +- > > > include/drm/gpu_scheduler.h | 8 ++ > > > 3 files changed, 43 insertions(+), 1 deletion(-) > > > > > > diff --git a/drivers/gpu/drm/scheduler/sched_fence.c > > > b/drivers/gpu/drm/scheduler/sched_fence.c > > > index bcea035cf4c6..4fc41a71d1c7 100644 > > > --- a/drivers/gpu/drm/scheduler/sched_fence.c > > > +++ b/drivers/gpu/drm/scheduler/sched_fence.c > > > @@ -128,6 +128,30 @@ static void drm_sched_fence_release_finished(struct > > > dma_fence *f) > > > dma_fence_put(&fence->scheduled); > > > } > > > > > > +static void drm_sched_fence_set_deadline_finished(struct dma_fence *f, > > > + ktime_t deadline) > > > +{ > > > + struct drm_sched_fence *fence = to_drm_sched_fence(f); > > > + unsigned long flags; > > > + > > > + spin_lock_irqsave(&fence->lock, flags); > > > + > > > + /* If we already have an earlier deadline, keep it: */ > > > + if (test_bit(DMA_FENCE_FLAG_HAS_DEADLINE_BIT, &f->flags) && > > > + ktime_before(fence->deadline, deadline)) { > > > + spin_unlock_irqrestore(&fence->lock, flags); > > > + return; > > > + } > > > + > > > + fence->deadline = deadline; > > > + set_bit(DMA_FENCE_FLAG_HAS_DEADLINE_BIT, &f->flags); > > > + > > > + spin_unlock_irqrestore(&fence->lock, flags); > > > + > > > + if (fence->parent) > > > + dma_fence_set_deadline(fence->parent, deadline); > > > +} > > > + > > > static const struct dma_fence_ops drm_sched_fence_ops_scheduled = { > > > .get_driver_name = drm_sched_fence_get_driver_name, > > > .get_timeline_name = drm_sched_fence_get_timeline_name, > > > @@ -138,6 +162,7 @@ static const struct dma_fence_ops > > > drm_sched_fence_ops_finished = { > > > .get_driver_name = drm_sched_fence_get_driver_name, > > > .get_timeline_name = drm_sched_fence_get_timeline_name, > > > .release = drm_sched_fence_release_finished, > > > + .set_deadline = drm_sched_fence_set_deadline_finished, > > > }; > > > > > > struct drm_sched_fence *to_drm_sched_fence(struct dma_fence *f) > > > @@ -152,6 +177,15 @@ struct drm_sched_fence *to_drm_sched_fence(struct > > > dma_fence *f) > > > } > > > EXPORT_SYMBOL(to_drm_sched_fence); > > > > > > +void drm_sched_fence_set_parent(struct drm_sched_fence *s_fence, > > > + struct dma_fence *fence) > > > +{ > > > + s_fence->parent = dma_fence_get(fence); > > > + if (test_bit(DMA_FENCE_FLAG_HAS_DEADLINE_BIT, > > > + &s_fence->finished.flags)) > > > > Don't you need the spinlock here too to avoid races? test_bit is very > > unordered, so guarantees nothing. Spinlock would need to be both around > > ->parent = and the test_bit. > > > > Entirely aside, but there's discussions going on to preallocate the hw > > fence somehow. If we do that we could make the deadline forwarding > > lockless here. Having a spinlock just to set the parent is a bit annoying > > ... > > > > Alternative is that you do this locklessly with barriers and a _lot_ of > > comments. Would be good to benchmark whether the overhead matters though > > first. > > So, my thinking is that very few (well no) guarantees are made to the > fence implementor that their ->set_deadline() is not called multiple > times, from multiple threads, etc. And no guarantee that a later > deadline is set after an earlier deadline has been set. It is all up > to the set_deadline() implementation to deal with these cases. > > So that means we just need the appropriate barrier-fu to ensure > another thread calling drm_sched_fence_set_deadline_finished() sees > fence->parent set before the test_bit. It could mean that the backend > implementation sees the same deadline set twice, but that is fine. > something like: - diff --git a/drivers/gpu/drm/scheduler/sched_fence.c b/drivers/gpu/drm/scheduler/sched_fence.c index 4fc41a71d1c7..7f2af6d1777c 100644 --- a/drivers/gpu/drm/scheduler/sched_fence.c +++ b/drivers/gpu/drm/scheduler/sched_fence.c @@ -132,6 +132,7 @@ static void drm_sched_fence_set_deadline_finished(struct dma_fence *f, ktime_t deadline) { struct drm_sched_fence *fence = to_drm_sched_fence(f); + struct dma_fence *parent; unsigned long flags; spin_loc
[PATCH] drm/msm/dsi/phy: fix clock names in 28nm_8960 phy
The commit 9f91f22aafcd ("drm/msm/dsi: remove duplicate fields from dsi_pll_Nnm instances") mistakenly changed registered clock names. While the platform is in progress of migration to using clock properties in the dts rather than the global clock names, we should provide backwards compatibility. Thus restore registerd global clock names. Fixes: 9f91f22aafcd ("drm/msm/dsi: remove duplicate fields from dsi_pll_Nnm instances") Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c index aaa37456f4ee..71ed4aa0dc67 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c @@ -428,7 +428,7 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov bytediv->reg = pll_28nm->phy->pll_base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9; snprintf(parent_name, 32, "dsi%dvco_clk", pll_28nm->phy->id); - snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->phy->id); + snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->phy->id + 1); bytediv_init.name = clk_name; bytediv_init.ops = &clk_bytediv_ops; @@ -442,7 +442,7 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov return ret; provided_clocks[DSI_BYTE_PLL_CLK] = &bytediv->hw; - snprintf(clk_name, 32, "dsi%dpll", pll_28nm->phy->id); + snprintf(clk_name, 32, "dsi%dpll", pll_28nm->phy->id + 1); /* DIV3 */ hw = devm_clk_hw_register_divider(dev, clk_name, parent_name, 0, pll_28nm->phy->pll_base + -- 2.30.2