Re: [git pull] drm fixes for 5.17-rc8/final
On Fri, 11 Mar 2022 at 17:51, Thorsten Leemhuis wrote: > > On 11.03.22 06:15, Dave Airlie wrote: > > > > As expected at this stage its pretty quiet, one sun4i mixer fix and > > one i915 display flicker fix. > > > > Thanks, > > Dave. > > > > drm-fixes-2022-03-11: > > drm fixes for v5.17-rc8/final > > > > i915: > > - psr fix screen flicker > > > > sun4i: > > - mixer format fix. > > The following changes since commit ffb217a13a2eaf6d5bd974fc83036a53ca69f1e2: > > [...] > > Out of curiosity: I might be missing something, but why wasn't the > (afaics simple) fix for a build problem caused by 9d6366e743f3 ("drm: > fb_helper: improve CONFIG_FB dependency") (merged for v5.16-rc1) not > among these fixes? I mean this one: > https://lore.kernel.org/lkml/20220203093922.20754-1-tzimmerm...@suse.de/ > > It's sitting in next for a few days already: > https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?h=master&id=eea89dff4c39a106f98d1cb5e4d626f8c63908b9 > > I already asked a few days ago why this fix was not on track for merging > in this cycle, but I didn't get an answer: > https://lore.kernel.org/lkml/782a683e-c625-8e68-899b-ce56939af...@leemhuis.info/ > > Fun fact: It seems the problem and at a rough fix were already kinda > known mid November when 9d6366e743f3 was still in next: > https://lore.kernel.org/all/2027062704.14671-1-rdun...@infradead.org/ > > Then the issue was reported again two times in February: > https://lore.kernel.org/dri-devel/CA+G9fYvN0NyaVkRQmA1O6rX7H8PPaZrUAD7=rdy33qy9ruu...@mail.gmail.com/ > https://lore.kernel.org/lkml/YhofdlzadzRmy7tj@debian/ > > And the fix is relative simple, that's why I wonder why merging is > delayed. What am I missing? My radar just missed it, though someone else should have realised it was necessary on fixes earlier, it also had incorrect Fixes: tagging, so I fixed that and sent it to Linus, Thanks, Dave.
[git pull] drm fixes for 5.17-rc8 (kconfig fix)
Hi Linus, Thorsten pointed out this had fallen down the cracks and was in -next only, I've picked it out, fixed up it's Fixes: line. Thanks, Dave. drm-fixes-2022-03-12: drm kconfig fix for 5.17-rc8 - fix regression in Kconfig. The following changes since commit 30eb13a26014ca640b5eb57b6d010114084d5c92: Merge tag 'drm-intel-fixes-2022-03-10' of git://anongit.freedesktop.org/drm/drm-intel into drm-fixes (2022-03-11 13:26:19 +1000) are available in the Git repository at: git://anongit.freedesktop.org/drm/drm tags/drm-fixes-2022-03-12 for you to fetch changes up to 3755d35ee1d2454b20b8a1e20d790e56201678a4: drm/panel: Select DRM_DP_HELPER for DRM_PANEL_EDP (2022-03-12 17:41:30 +1000) drm kconfig fix for 5.17-rc8 - fix regression in Kconfig. Thomas Zimmermann (1): drm/panel: Select DRM_DP_HELPER for DRM_PANEL_EDP drivers/gpu/drm/panel/Kconfig | 1 + 1 file changed, 1 insertion(+)
Re: [Intel-gfx] [PATCH] drm/i915/uapi: Add DRM_I915_QUERY_GEOMETRY_SUBSLICES
On Thu, Mar 10, 2022 at 12:26:12PM +, Tvrtko Ursulin wrote: > > On 10/03/2022 05:18, Matt Atwood wrote: > > Newer platforms have DSS that aren't necessarily available for both > > geometry and compute, two queries will need to exist. This introduces > > the first, when passing a valid engine class and engine instance in the > > flags returns a topology describing geometry. > > > > v2: fix white space errors > > > > Cc: Ashutosh Dixit > > Cc: Matt Roper > > Cc: Joonas Lahtinen > > UMD (mesa): https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14143 > > Signed-off-by: Matt Atwood > > --- > > drivers/gpu/drm/i915/i915_query.c | 68 ++- > > include/uapi/drm/i915_drm.h | 24 +++ > > 2 files changed, 65 insertions(+), 27 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/i915_query.c > > b/drivers/gpu/drm/i915/i915_query.c > > index 2dfbc22857a3..e4f35da28642 100644 > > --- a/drivers/gpu/drm/i915/i915_query.c > > +++ b/drivers/gpu/drm/i915/i915_query.c > > @@ -9,6 +9,7 @@ > > #include "i915_drv.h" > > #include "i915_perf.h" > > #include "i915_query.h" > > +#include "gt/intel_engine_user.h" > > #include > > static int copy_query_item(void *query_hdr, size_t query_sz, > > @@ -28,36 +29,30 @@ static int copy_query_item(void *query_hdr, size_t > > query_sz, > > return 0; > > } > > -static int query_topology_info(struct drm_i915_private *dev_priv, > > - struct drm_i915_query_item *query_item) > > +static int fill_topology_info(const struct sseu_dev_info *sseu, > > + struct drm_i915_query_item *query_item, > > + const u8 *subslice_mask) > > { > > - const struct sseu_dev_info *sseu = &to_gt(dev_priv)->info.sseu; > > struct drm_i915_query_topology_info topo; > > u32 slice_length, subslice_length, eu_length, total_length; > > int ret; > > - if (query_item->flags != 0) > > - return -EINVAL; > > + BUILD_BUG_ON(sizeof(u8) != sizeof(sseu->slice_mask)); > > if (sseu->max_slices == 0) > > return -ENODEV; > > - BUILD_BUG_ON(sizeof(u8) != sizeof(sseu->slice_mask)); > > - > > slice_length = sizeof(sseu->slice_mask); > > subslice_length = sseu->max_slices * sseu->ss_stride; > > eu_length = sseu->max_slices * sseu->max_subslices * sseu->eu_stride; > > total_length = sizeof(topo) + slice_length + subslice_length + > >eu_length; > > - ret = copy_query_item(&topo, sizeof(topo), total_length, > > - query_item); > > + ret = copy_query_item(&topo, sizeof(topo), total_length, query_item); > > + > > if (ret != 0) > > return ret; > > - if (topo.flags != 0) > > - return -EINVAL; > > - > > memset(&topo, 0, sizeof(topo)); > > topo.max_slices = sseu->max_slices; > > topo.max_subslices = sseu->max_subslices; > > @@ -69,27 +64,61 @@ static int query_topology_info(struct drm_i915_private > > *dev_priv, > > topo.eu_stride = sseu->eu_stride; > > if (copy_to_user(u64_to_user_ptr(query_item->data_ptr), > > - &topo, sizeof(topo))) > > +&topo, sizeof(topo))) > > return -EFAULT; > > if (copy_to_user(u64_to_user_ptr(query_item->data_ptr + sizeof(topo)), > > - &sseu->slice_mask, slice_length)) > > +&sseu->slice_mask, slice_length)) > > return -EFAULT; > > if (copy_to_user(u64_to_user_ptr(query_item->data_ptr + > > - sizeof(topo) + slice_length), > > - sseu->subslice_mask, subslice_length)) > > +sizeof(topo) + slice_length), > > +subslice_mask, subslice_length)) > > return -EFAULT; > > if (copy_to_user(u64_to_user_ptr(query_item->data_ptr + > > - sizeof(topo) + > > - slice_length + subslice_length), > > - sseu->eu_mask, eu_length)) > > +sizeof(topo) + > > +slice_length + subslice_length), > > +sseu->eu_mask, eu_length)) > > return -EFAULT; > > return total_length; > > } > > +static int query_topology_info(struct drm_i915_private *dev_priv, > > + struct drm_i915_query_item *query_item) > > +{ > > + const struct sseu_dev_info *sseu = &to_gt(dev_priv)->info.sseu; > > + > > + if (query_item->flags != 0) > > + return -EINVAL; > > + > > + return fill_topology_info(sseu, query_item, sseu->subslice_mask); > > +} > > + > > +static int query_geometry_subslices(struct drm_i915_private *i915, > > + struct drm_i915_query_item *query_item) > > +{ > > + const struct sseu_dev_info *sseu; > > + struct intel_engine_cs *engine; > > + u8 engine_
Re: [PATCH v4 4/4] dt-bindings: display/panel: Add Leadtek ltk035c5444t
On Fri, 11 Mar 2022 18:02:40 +0100, Christophe Branchereau wrote: > Add binding for the leadtek ltk035c5444t, which is a 640x480 > mipi-dbi over spi / 24-bit RGB panel based on the newvision > NV03052C chipset. > > It is found in the Anbernic RG350M mips handheld. > > Signed-off-by: Christophe Branchereau > --- > .../display/panel/leadtek,ltk035c5444t.yaml | 59 +++ > 1 file changed, 59 insertions(+) > create mode 100644 > Documentation/devicetree/bindings/display/panel/leadtek,ltk035c5444t.yaml > Reviewed-by: Rob Herring
Re: [PATCH v7 00/12] clk: Improve clock range handling
Quoting Maxime Ripard (2022-02-25 06:35:22) > Hi, > > This is a follow-up of the discussion here: > https://lore.kernel.org/linux-clk/20210319150355.xzw7ikwdaga2dwhv@gilmour/ > > and here: > https://lore.kernel.org/all/20210914093515.260031-1-max...@cerno.tech/ > > While the initial proposal implemented a new API to temporarily raise and > lower > clock rates based on consumer workloads, Stephen suggested an > alternative approach implemented here. > > The main issue that needed to be addressed in our case was that in a > situation where we would have multiple calls to clk_set_rate_range, we > would end up with a clock at the maximum of the minimums being set. This > would be expected, but the issue was that if one of the users was to > relax or drop its requirements, the rate would be left unchanged, even > though the ideal rate would have changed. > > So something like > > clk_set_rate(user1_clk, 1000); > clk_set_min_rate(user1_clk, 2000); > clk_set_min_rate(user2_clk, 3000); > clk_set_min_rate(user2_clk, 1000); > > Would leave the clock running at 3000Hz, while the minimum would now be > 2000Hz. > > This was mostly due to the fact that the core only triggers a rate > change in clk_set_rate_range() if the current rate is outside of the > boundaries, but not if it's within the new boundaries. > > That series changes that and will trigger a rate change on every call, > with the former rate being tried again. This way, providers have a > chance to follow whatever policy they see fit for a given clock each > time the boundaries change. > > This series also implements some kunit tests, first to test a few rate > related functions in the CCF, and then extends it to make sure that > behaviour has some test coverage. > > Let me know what you think Thanks. I'm going to apply this to clk-next but not the last two drm patches. That is OK?
Re: [PATCH v4 00/24] DEPT(Dependency Tracker)
On Fri, Mar 04, 2022 at 04:06:19PM +0900, Byungchul Park wrote: > Hi Linus and folks, > > I've been developing a tool for detecting deadlock possibilities by > tracking wait/event rather than lock(?) acquisition order to try to > cover all synchonization machanisms. It's done on v5.17-rc1 tag. > > https://github.com/lgebyungchulpark/linux-dept/commits/dept1.14_on_v5.17-rc1 > Small feedback unrelated to thread: I'm not sure "Need to expand the ring buffer" is something to call WARN(). Is this stack trace useful for something? Hello Byungchul. These are two warnings of DEPT on system. Both cases look similar. In what case DEPT says (unknown)? I'm not sure we can properly debug this. === DEPT: Circular dependency has been detected. 5.17.0-rc1+ #3 Tainted: GW --- summary --- *** AA DEADLOCK *** context A [S] (unknown)(&vfork:0) [W] wait_for_completion_killable(&vfork:0) [E] complete(&vfork:0) [S]: start of the event context [W]: the wait blocked [E]: the event not reachable --- context A's detail --- context A [S] (unknown)(&vfork:0) [W] wait_for_completion_killable(&vfork:0) [E] complete(&vfork:0) [S] (unknown)(&vfork:0): (N/A) [W] wait_for_completion_killable(&vfork:0): [] kernel_clone+0x25c/0x2b8 stacktrace: dept_wait+0x74/0x88 wait_for_completion_killable+0x60/0xa0 kernel_clone+0x25c/0x2b8 __do_sys_clone+0x5c/0x74 __arm64_sys_clone+0x18/0x20 invoke_syscall.constprop.0+0x78/0xc4 do_el0_svc+0x98/0xd0 el0_svc+0x44/0xe4 el0t_64_sync_handler+0xb0/0x12c el0t_64_sync+0x158/0x15c [E] complete(&vfork:0): [] mm_release+0x7c/0x90 stacktrace: dept_event+0xe0/0x100 complete+0x48/0x98 mm_release+0x7c/0x90 exit_mm_release+0xc/0x14 do_exit+0x1b4/0x81c do_group_exit+0x30/0x9c __wake_up_parent+0x0/0x24 invoke_syscall.constprop.0+0x78/0xc4 do_el0_svc+0x98/0xd0 el0_svc+0x44/0xe4 el0t_64_sync_handler+0xb0/0x12c el0t_64_sync+0x158/0x15c --- information that might be helpful --- CPU: 6 PID: 229 Comm: start-stop-daem Tainted: GW 5.17.0-rc1+ #3 Hardware name: linux,dummy-virt (DT) Call trace: dump_backtrace.part.0+0x9c/0xc4 show_stack+0x14/0x28 dump_stack_lvl+0x9c/0xcc dump_stack+0x14/0x2c print_circle+0x2d4/0x438 cb_check_dl+0x44/0x70 bfs+0x60/0x168 add_dep+0x88/0x11c do_event.constprop.0+0x19c/0x2c0 dept_event+0xe0/0x100 complete+0x48/0x98 mm_release+0x7c/0x90 exit_mm_release+0xc/0x14 do_exit+0x1b4/0x81c do_group_exit+0x30/0x9c __wake_up_parent+0x0/0x24 invoke_syscall.constprop.0+0x78/0xc4 do_el0_svc+0x98/0xd0 el0_svc+0x44/0xe4 el0t_64_sync_handler+0xb0/0x12c el0t_64_sync+0x158/0x15c === DEPT: Circular dependency has been detected. 5.17.0-rc1+ #3 Tainted: GW --- summary --- *** AA DEADLOCK *** context A [S] (unknown)(&try_completion:0) [W] wait_for_completion_timeout(&try_completion:0) [E] complete(&try_completion:0) [S]: start of the event context [W]: the wait blocked [E]: the event not reachable --- context A's detail --- context A [S] (unknown)(&try_completion:0) [W] wait_for_completion_timeout(&try_completion:0) [E] complete(&try_completion:0) [S] (unknown)(&try_completion:0): (N/A) [W] wait_for_completion_timeout(&try_completion:0): [] kunit_try_catch_run+0xb4/0x160 stacktrace: dept_wait+0x74/0x88 wait_for_completion_timeout+0x64/0xa0 kunit_try_catch_run+0xb4/0x160 kunit_test_try_catch_successful_try_no_catch+0x3c/0x98 kunit_try_run_case+0x9c/0xa0 kunit_generic_run_threadfn_adapter+0x1c/0x28 kthread+0xd4/0xe4 ret_from_fork+0x10/0x20 [E] complete(&try_completion:0): [] kthread_complete_and_exit+0x18/0x20 stacktrace: dept_event+0xe0/0x100 complete+0x48/0x98 kthread_complete_and_exit+0x18/0x20 kunit_try_catch_throw+0x0/0x1c kthread+0xd4/0xe4 ret_from_fork+0x10/0x20 --- information that might be helpful --- CPU: 15 PID: 132 Comm: kunit_try_catch Tainted: GW 5.17.0-rc1+ #3 Hardware name: linux,dummy-virt (DT) Call trace: dump_backtrace.part.0+0x9c/0xc4 show_stack+0x14/0x28 dump_stack_lvl+0x9c/0xcc dump_stack+0x14/0x2c print_circle+0x2d4/0x438 cb_check_dl+0x44/0x70 bfs+0x60/0x168 add_dep+0
Re: [PATCH 2/5] dyndbg: add class_id field and query support
On Fri, Mar 11, 2022 at 12:06 PM Jason Baron wrote: > > > > On 3/10/22 23:47, Jim Cromie wrote: > > DRM defines/uses 10 enum drm_debug_category's to create exclusive > > classes of debug messages. To support this directly in dynamic-debug, > > add the following: > > > > - struct _ddebug.class_id:4 - 4 bits is enough > > - define _DPRINTK_SITE_UNCLASSED 15 - see below > > > > and the query support: > > - struct _ddebug_query.class_id > > - ddebug_parse_query - looks for "class" keyword, then calls.. > > - parse_class - accepts uint: 0-15, sets query.class_id and marker > > - vpr_info_dq - displays new field > > - ddebug_proc_show- append column with "cls:%d" if !UNCLASSED > > > > With the patch, one can enable current/unclassed callsites by: > > > > #> echo drm class 15 +p > /proc/dynamic_debug/control > > > > To me, this is hard to read, what the heck is '15'? I have to go look it > up in the control file and it's not descriptive. I think that using > classes/categories makes sense but I'm wondering if it can be a bit more > user friendly? Perhaps, we can pass an array of strings that is indexed > by the class id to each pr_debug() site that wants to use class. So > something like: > Im not at all averse to nice names, but as something added on. 1st, the interface to make friendlier is DRM's echo 0x04 > /sys/module/drm/parameters/debug # which category ? parm: debug:Enable debug output, where each bit enables a debug category. Bit 0 (0x01) will enable CORE messages (drm core code) Bit 1 (0x02) will enable DRIVER messages (drm controller code) Bit 2 (0x04) will enable KMS messages (modesetting code) echo DRM_UT_DRIVER,DRM_UT_KMS > /sys/module/drm/parameters/debug # now its pretty clear If that works, its cuz DEFINE_DYNAMIC_DEBUG_CLASSBITS() plucks class symbols out of its __VA_ARGS__, and #stringifes them. So that macro could then build the 1-per-module static constant string array and (only) the callbacks would be able to use it. from there, it shouldnt be hard to ref that from the module's ddebug_table, so parse_query could validate class args against the module given (or fail if none given) Speaking strictly, theres a gap: echo module * class DRM_UT_KMS +p > control is nonsense for * other than drm + drivers, but its fair/safe to just disallow wildcards on modname for this purpose. it does however imply that module foo must exist for FOO_CAT_1 to be usable. thats not currently the case: bash-5.1# echo module foo +p > /proc/dynamic_debug/control [ 15.403749] dyndbg: read 14 bytes from userspace [ 15.405413] dyndbg: query 0: "module foo +p" mod:* [ 15.406486] dyndbg: split into words: "module" "foo" "+p" [ 15.407070] dyndbg: op='+' [ 15.407388] dyndbg: flags=0x1 [ 15.407809] dyndbg: *flagsp=0x1 *maskp=0x [ 15.408300] dyndbg: parsed: func="" file="" module="foo" format="" lineno=0-0 class=15 [ 15.409151] dyndbg: no matches for query [ 15.409591] dyndbg: no-match: func="" file="" module="foo" format="" lineno=0-0 class=15 [ 15.410524] dyndbg: processed 1 queries, with 0 matches, 0 errs bash-5.1# ISTM we can keep that "0 errs" response for that case, but still reject this: echo module foo class FOO_NOT_HERE +p > /proc/dynamic_debug/control > enum levels { > LOW, > MEDIUM, > HIGH > }; I want to steer clear of "level" anything, since 2>1 implies non independence of the categories > > static const char * const level_to_strings[] = { > [LOW] = "low", > [MEDIUM] = "medium", > [HIGH] = "high", > }; > > And then you'd have a wrapper macros in your driver: > > #define module_foo_pr_debug_class(level, fmt, args...) > pr_debug_class(level, level_to_strings, fmt, args); > > Such that call sites look like: > > module_foo_pr_debug_class(LOW, fmt, args...); > That macro, minus the "module_foo_" prefix, could go into dynamic_debug.h I didnt do that, for 2 reasons: DRM didnt need it - it had an enum var, and a set of macros to encapsulate the categories. - the "prototype" looks like this might be ok: define LOW "low" pr_debug_class(LOW, "mumble about something %p %p\n", foo, bar) ok thats a stretch, but... Basically, I didnt want to deal with creating a new interface. KIS > Such that you're not always passing the strings array around. Now, this > does mean another pointer for struct _ddebug and most wouldn't have it. > Maybe we could just add another linker section for these so as to save > space. >From a space consideration, adding DRM users means adding thousands of callsites ~2k for i915, ~4k for amdgpu Also increasing per/callsite memory seems counterproductive. see DEFINE_DYNAMIC_DEBUG_CLASSBITS for the way forward. > > parse_class() accepts 0 .. _DPRINTK_SITE_UNCLASSED, which allows the > >> control interface to explicitly manipulate unclassed callsites. > > > > After parsing keywords, ddebug_parse_query() sets .class_id=15, iff it > > wasnt explicitly se
[PATCH v8 00/13] Add GuC Error Capture Support
This series: 1. Enables support of GuC to report error-state-capture using a list of MMIO registers the driver registers and GuC will dump, log and notify right before a GuC triggered engine-reset event. 2. Updates the ADS blob creation to register said lists of global, engine class and engine instance registers with GuC. 3. Defines tables of register lists that are global or engine class or engine instance in scope. 4. Updates usage and buffer-state data for the regions of the shared GuC log-buffer to accomdate both the existing relay logging of general debug logs along with the new error state capture usage. 5. Using a pool of preallocated memory, provide ability to extract and format the GuC reported register-capture data into chunks consistent with existing i915 error- state collection flows and structures. 6. Connects the i915_gpu_coredump reporting function to the GuC error capture module to print all GuC error state capture dumps that is reported. This is the 8th rev of this series with the first 3 revs labelled as RFC. Prior receipts of rvb's: - Patch #2, #3, #4, #5, #10, #11, #12, #13 have received R-v-b's from Umesh Nerlige Ramappa - Patch #6, #7, #8, #9 has received an R-v-b from Matthew Brost . NOTE: some of these came in on the trybot series. https://patchwork.freedesktop.org/series/100831/ Changes from prior revs: v8: - Fix a bug found by CI in rev7: Create a cached ADS capture list for null-header like the other lists. - Fixed a bug on the ggtt offset calculation in the ADS population loop. Thanks to Matt Brost. - Change the storage uses for initial allocation and caching of the ADS register lists so we only store a regular pointer instead of file handle. - Multiple improvements on code styling, variable names, comments and code reduction from Umesh suggestions across multiple patches. v7: - Rebased on lastest drm_tip that has the ADS now using shmem based ads_blob_write utilities. Stress test was performed with this patch included to fix a legacy bug: https://patchwork.freedesktop.org/series/100768/ v6: - In patch #1, ADS reg-list population, we now alloc regular memory to create the lists and cache them for simpler and faster use by GuC ADS module at init, suspend-resume and reset cycles. This was in response to review comments from Lucas De Marchi that also wanted to ensure the GuC ADS module owns the final copying into the ADS phyical memory. - Thanks to Jani Nikula for pointing out that patch #2 and #3 should ensure static tables as constant and dynamic lists should be allocated and cached but attached to the GT level for the case of multiple cards with different fusings for steered registers. These are addressed now along with multiple code style fixups (thanks to review comment from Umesh) and splitting the steered register list generation as a seperate patch. - The extraction functionality, Patch #10 and #11 (was patch #7), has fixed all of Umesh's review comments related to the code styling. Additionally, it was discovered during stress tests that the extraction function could be called by the ct processing thread at the same time as the start of a GT reset event. Thus, a redesign was done whereby the linked list of processed capture-output-nodes are allocated up front and reused throughout the driver's life to ensure no memory locks are taken during extraction. - For patch #6 (now 7, 8 and 9), updates to intel_guc_log was split into smaller chunks and the log_state structure was returned back to inside of the intel_guc_log struct as opposed to the intel_guc struct in prior rev. This is in response to review comments by Matt Brost. - #Patch 13 (previously #10) is mostly identical but addresses all of the code styling comments reviews from Umesh. v5: - Added Gen9->Gen11 register list for CI coverage that included Gen9 with GuC submission. - Redesigned the extraction of the GuC error-capture dumps by grouping them into complete per-engine-reset nodes. Complete here means each node includes the global, engine-class and engine-instance register lists in a single structure. - Extraction is decoupled from the print-out. We now do the extraction immediately when receiving the G2H for error-capture notification. A link list of nodes is maintained with a FIFO based threshold while awaiting retrieval from i915_gpu_coredump's capture_engine function. - Added new plumbing through the i915_gpu_coredump allocation and
Re: [v6 1/5] drm/edid: seek for available CEA block from specific EDID block index
On Fri, Mar 11, 2022 at 09:22:14AM +0800, Lee Shawn C wrote: > drm_find_cea_extension() always look for a top level CEA block. Pass > ext_index from caller then this function to search next available > CEA ext block from a specific EDID block pointer. > > v2: save proper extension block index if CTA data information > was found in DispalyID block. > > Cc: Jani Nikula > Cc: Ville Syrjala > Cc: Ankit Nautiyal > Cc: intel-gfx > Signed-off-by: Lee Shawn C > --- > drivers/gpu/drm/drm_edid.c | 43 +++--- > 1 file changed, 21 insertions(+), 22 deletions(-) > > diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c > index 561f53831e29..e267d31d5c87 100644 > --- a/drivers/gpu/drm/drm_edid.c > +++ b/drivers/gpu/drm/drm_edid.c > @@ -3353,16 +3353,14 @@ const u8 *drm_find_edid_extension(const struct edid > *edid, > return edid_ext; > } > > -static const u8 *drm_find_cea_extension(const struct edid *edid) > +static const u8 *drm_find_cea_extension(const struct edid *edid, int > *ext_index) > { > const struct displayid_block *block; > struct displayid_iter iter; > const u8 *cea; > - int ext_index = 0; > > - /* Look for a top level CEA extension block */ > - /* FIXME: make callers iterate through multiple CEA ext blocks? */ > - cea = drm_find_edid_extension(edid, CEA_EXT, &ext_index); > + /* Look for a CEA extension block from ext_index */ > + cea = drm_find_edid_extension(edid, CEA_EXT, ext_index); > if (cea) > return cea; > > @@ -3370,6 +3368,7 @@ static const u8 *drm_find_cea_extension(const struct > edid *edid) > displayid_iter_edid_begin(edid, &iter); > displayid_iter_for_each(block, &iter) { > if (block->tag == DATA_BLOCK_CTA) { > + *ext_index = iter.ext_index; This could still end up in an infinite loop in patch 2 in the case that there is no CEA_EXT block in the edid, but there is a CEA block in the DisplayId block. Repeating my review comment from elsewhere, consider the case: - If there are no cea extension blocks in the EDID, drm_find_edid_extension returns NULL - drm_find_cea_extension will then return the first DisplayId block with tag DATA_BLOCK_CTA If the version of the cea data from DisplayId block is less than 3, the loop will restart and call drm_find_cea_extension the same way, returning the same DisplayID block every time. Setting *ext_index inside the display_iter_for_each block doesn't change this, since we're not checking it. But I don't think we want to use the same *ext_index both to pass into drm_find_edid_extension and for tracking the next DisplayId block to check. This might end up in similar infinite loops or skipping DisplayId blocks. Maybe you'll need to pass in two indexes to drm_find_cea_extension, one which is passed to drm_find_edid_extension, and the other to keep track of the next DisplayId block to check. > cea = (const u8 *)block; > break; > } > @@ -3643,10 +3642,10 @@ add_alternate_cea_modes(struct drm_connector > *connector, struct edid *edid) > struct drm_device *dev = connector->dev; > struct drm_display_mode *mode, *tmp; > LIST_HEAD(list); > - int modes = 0; > + int modes = 0, ext_index = 0; > > /* Don't add CEA modes if the CEA extension block is missing */ > - if (!drm_find_cea_extension(edid)) > + if (!drm_find_cea_extension(edid, &ext_index)) > return 0; > > /* > @@ -4321,11 +4320,11 @@ static void drm_parse_y420cmdb_bitmap(struct > drm_connector *connector, > static int > add_cea_modes(struct drm_connector *connector, struct edid *edid) > { > - const u8 *cea = drm_find_cea_extension(edid); > - const u8 *db, *hdmi = NULL, *video = NULL; > + const u8 *cea, *db, *hdmi = NULL, *video = NULL; > u8 dbl, hdmi_len, video_len = 0; > - int modes = 0; > + int modes = 0, ext_index = 0; > > + cea = drm_find_cea_extension(edid, &ext_index); > if (cea && cea_revision(cea) >= 3) { > int i, start, end; > > @@ -4562,7 +4561,7 @@ static void drm_edid_to_eld(struct drm_connector > *connector, struct edid *edid) > uint8_t *eld = connector->eld; > const u8 *cea; > const u8 *db; > - int total_sad_count = 0; > + int total_sad_count = 0, ext_index = 0; > int mnl; > int dbl; > > @@ -4571,7 +4570,7 @@ static void drm_edid_to_eld(struct drm_connector > *connector, struct edid *edid) > if (!edid) > return; > > - cea = drm_find_cea_extension(edid); > + cea = drm_find_cea_extension(edid, &ext_index); > if (!cea) { > DRM_DEBUG_KMS("ELD: no CEA Extension found\n"); > return; > @@ -4655,11 +4654,11 @@ static void drm_edid_to_eld(struct drm_connector > *connector, struct edid *edid) > */ > int drm_edid_to_sad(struct edid *edid, st
Re: [Intel-gfx] [PATCH 1/2] drm/i915/sseu: Don't overallocate subslice storage
On Fri, Mar 11, 2022 at 11:01:01PM +0200, Ville Syrjälä wrote: > On Fri, Mar 11, 2022 at 12:52:33PM -0800, Lucas De Marchi wrote: > > On Fri, Mar 11, 2022 at 12:43:40PM -0800, Matt Roper wrote: > > >On Fri, Mar 11, 2022 at 12:38:17PM -0800, Matt Roper wrote: > > >> On Fri, Mar 11, 2022 at 11:00:09AM -0800, Lucas De Marchi wrote: > > >> > On Thu, Mar 10, 2022 at 10:15:42PM -0800, Matt Roper wrote: > > >> > > Xe_HP removed "slice" as a first-class unit in the hardware design. > > >> > > Instead we now have a single pool of subslices (which are now > > >> > > referred > > >> > > to as "DSS") that different hardware units have different ways of > > >> > > grouping ("compute slices," "geometry slices," etc.). For the > > >> > > purposes > > >> > > of topology representation, we treat Xe_HP-based platforms as having > > >> > > a > > >> > > single slice that contains all of the platform's DSS. There's no > > >> > > need > > >> > > to allocate storage space for (max legacy slices * max dss); let's > > >> > > update some of our macros to minimize the storage requirement for > > >> > > sseu > > >> > > topology. We'll also document some of the constants to make it a > > >> > > little > > >> > > bit more clear what they represent. > > >> > > > > >> > > Signed-off-by: Matt Roper > > >> > > --- > > >> > > drivers/gpu/drm/i915/gt/intel_engine_types.h | 2 +- > > >> > > drivers/gpu/drm/i915/gt/intel_sseu.h | 47 > > >> > > +++- > > >> > > 2 files changed, 36 insertions(+), 13 deletions(-) > > >> > > > > >> > > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h > > >> > > b/drivers/gpu/drm/i915/gt/intel_engine_types.h > > >> > > index 4fbf45a74ec0..f9e246004bc0 100644 > > >> > > --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h > > >> > > +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h > > >> > > @@ -645,7 +645,7 @@ intel_engine_has_relative_mmio(const struct > > >> > > intel_engine_cs * const engine) > > >> > > > > >> > > #define for_each_instdone_gslice_dss_xehp(dev_priv_, sseu_, iter_, > > >> > > gslice_, dss_) \ > > >> > > for ((iter_) = 0, (gslice_) = 0, (dss_) = 0; \ > > >> > > - (iter_) < GEN_MAX_SUBSLICES; \ > > >> > > + (iter_) < GEN_SS_MASK_SIZE; \ > > >> > > (iter_)++, (gslice_) = (iter_) / GEN_DSS_PER_GSLICE, \ > > >> > > (dss_) = (iter_) % GEN_DSS_PER_GSLICE) \ > > >> > > for_each_if(intel_sseu_has_subslice((sseu_), 0, > > >> > > (iter_))) > > >> > > diff --git a/drivers/gpu/drm/i915/gt/intel_sseu.h > > >> > > b/drivers/gpu/drm/i915/gt/intel_sseu.h > > >> > > index 8a79cd8eaab4..4f59eadbb61a 100644 > > >> > > --- a/drivers/gpu/drm/i915/gt/intel_sseu.h > > >> > > +++ b/drivers/gpu/drm/i915/gt/intel_sseu.h > > >> > > @@ -15,26 +15,49 @@ struct drm_i915_private; > > >> > > struct intel_gt; > > >> > > struct drm_printer; > > >> > > > > >> > > -#define GEN_MAX_SLICES (3) /* SKL upper bound */ > > >> > > -#define GEN_MAX_SUBSLICES (32) /* XEHPSDV upper bound */ > > >> > > -#define GEN_SSEU_STRIDE(max_entries) DIV_ROUND_UP(max_entries, > > >> > > BITS_PER_BYTE) > > >> > > -#define GEN_MAX_SUBSLICE_STRIDE GEN_SSEU_STRIDE(GEN_MAX_SUBSLICES) > > >> > > -#define GEN_MAX_EUS (16) /* TGL upper bound */ > > >> > > -#define GEN_MAX_EU_STRIDE GEN_SSEU_STRIDE(GEN_MAX_EUS) > > >> > > +/* > > >> > > + * Maximum number of legacy slices. Legacy slices no longer exist > > >> > > starting on > > >> > > + * Xe_HP ("gslices," "cslices," etc. on Xe_HP and beyond are a > > >> > > different > > >> > > + * concept and are not expressed through fusing). > > >> > > + */ > > >> > > +#define GEN_MAX_LEGACY_SLICES 3 > > >> > > + > > >> > > +/* > > >> > > + * Maximum number of subslices that can exist within a legacy > > >> > > slice. This is > > >> > > + * only relevant to pre-Xe_HP platforms (Xe_HP and beyond use the > > >> > > GEN_MAX_DSS > > >> > > + * value below). > > >> > > + */ > > >> > > +#define GEN_MAX_LEGACY_SUBSLICES6 > > >> > > > >> > instead of calling the old legacy, maybe just add the XEHP_ prefix to > > >> > the new ones? > > >> > > >> Maybe a "HSW_" prefix on the old ones would be better? People still use > > >> the termm 'subslice' in casual discussion when talking about DSS, so I > > >> want to somehow distinguish that what we're talking about here is a > > >> different, older design than we have on modern platforms. > > > > > >Hmm, or maybe just "GEN_MAX_SUBSLICES_PER_LEGACY_SLICE" to tie it into > > >the slice definition above? > > > > I'm not too fond of calling it "legacy" when everywhere else in the driver > > we just use the platform as prefix/suffix. Some may see legacy as > > < ver 12, others as 12.50, etc. > > Everything will become legacy at some point. This kind of naming > scheme falls apart when the next shiny new thing comes around > and we end up with multiple different leagacies. Are we going > to have ANCIENT_LEGACY, RECENT_LEGACY, NOT_YET_LEGACY etc? We
Re: [PATCH V3 05/13] drm: bridge: icn6211: Add DSI lane count DT property parsing
On 3/11/22 21:38, Jagan Teki wrote: Hi Marek, Small correction in the previous comment. On Sat, Mar 12, 2022 at 2:05 AM Jagan Teki wrote: Hi Marek, On Sat, Mar 12, 2022 at 1:32 AM Marek Vasut wrote: On 3/11/22 17:29, Maxime Ripard wrote: On Fri, Mar 11, 2022 at 11:36:58AM +0100, Marek Vasut wrote: On 3/10/22 15:18, Maxime Ripard wrote: On Thu, Mar 10, 2022 at 01:47:13PM +0100, Marek Vasut wrote: On 3/10/22 11:53, Maxime Ripard wrote: On Tue, Mar 08, 2022 at 10:41:05PM +0100, Marek Vasut wrote: On 3/8/22 17:21, Maxime Ripard wrote: On Tue, Mar 08, 2022 at 03:47:22PM +0100, Marek Vasut wrote: On 3/8/22 14:49, Maxime Ripard wrote: On Tue, Mar 08, 2022 at 02:27:40PM +0100, Marek Vasut wrote: On 3/8/22 13:51, Maxime Ripard wrote: On Tue, Mar 08, 2022 at 11:29:59AM +0100, Marek Vasut wrote: On 3/8/22 11:07, Jagan Teki wrote: On Tue, Mar 8, 2022 at 3:19 PM Marek Vasut wrote: On 3/8/22 09:03, Jagan Teki wrote: Hi, [...] @@ -314,7 +321,9 @@ static const struct drm_bridge_funcs chipone_bridge_funcs = { static int chipone_parse_dt(struct chipone *icn) { struct device *dev = icn->dev; + struct device_node *endpoint; struct drm_panel *panel; + int dsi_lanes; int ret; icn->vdd1 = devm_regulator_get_optional(dev, "vdd1"); @@ -350,15 +359,42 @@ static int chipone_parse_dt(struct chipone *icn) return PTR_ERR(icn->enable_gpio); } + endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, 0); + dsi_lanes = of_property_count_u32_elems(endpoint, "data-lanes"); + icn->host_node = of_graph_get_remote_port_parent(endpoint); + of_node_put(endpoint); + + if (!icn->host_node) + return -ENODEV; The non-ports-based OF graph returns a -19 example on the Allwinner Display pipeline in R16 [1]. We need to have a helper to return host_node for non-ports as I have done it for drm_of_find_bridge. [1] https://patchwork.amarulasolutions.com/patch/1805/ The link points to a patch marked "DO NOT MERGE", maybe that patch is missing the DSI host port@0 OF graph link ? Both port@0 and port@1 are required, see: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/display/bridge/chipone,icn6211.yaml#n53 What is "non-ports-based OF graph" ? I don't see drm_of_find_bridge() in linux-next , what is that ? port@0 is optional as some of the DSI host OF-graph represent the bridge or panel as child nodes instead of ports. (i think dt-binding has to fix it to make port@0 optional) The current upstream DT binding document says: required: - port@0 - port@1 So port@0 is mandatory. In the binding, sure, but fundamentally the DT excerpt Jagan provided is correct. If the bridge supports DCS, there's no reason to use the OF graph in the first place: the bridge node will be a child node of the MIPI-DSI controller (and there's no obligation to use the OF-graph for a MIPI-DSI controller). I believe port@0 should be made optional (or downright removed if MIPI-DCS in the only control bus). That's out of scope of this series anyway, so Jagan can implement patches for that mode if needed. Not really? You can't count on the port@0 being there generally speaking, so you can't count on data-lanes being there either, which exactly what you're doing in this patch. I can because the upstream DT bindings currently say port@0 must be present, see above. If that requirement should be relaxed, sure, but that's a separate series. And another upstream DT bindings say that you don't need them at all. Which "another upstream DT bindings" do you refer to ? https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt Yes, there's a conflict. Yes, it's unfortunate. But the generic DSI binding is far more relevant than a single bridge driver. That seems to be the wrong way around, how can generic subsystem-wide binding take precedence over specific driver binding ? This is the binding of the bus. You're part of that bus. You're a child node of that bus, but nothing ever mandates that your parent node uses the same convention. And some don't. And since your bridge can be connected to pretty much any DSI controller, you have to use the lowest common denominator, not make up some new constraints that not all controller will be able to comply with. It seems to me the ICN6211 DT bindings currently further constraint the generic DSI bus bindings, and that seems OK to me. Let me reiterate this again -- if someone wants to relax the requirements currently imposed by the ICN6211 DT bindings, fine, but that can be done in a separate patchset AND that needs DT bindings update. Furthermore, there are no users of this ICN6211 bridge in upstream DTs, so there is currently no bridge which wou
[PATCH v4 11/13] drm: bridge: icn6211: Add I2C configuration support
The ICN6211 chip starts in I2C configuration mode after cold boot. Implement support for configuring the chip via I2C in addition to the current DSI LP command mode configuration support. The later seems to be available only on chips which have additional MCU on the panel/bridge board which preconfigures the ICN6211, while the I2C configuration mode added by this patch does not require any such MCU. Signed-off-by: Marek Vasut Cc: Jagan Teki Cc: Maxime Ripard Cc: Robert Foss Cc: Sam Ravnborg Cc: Thomas Zimmermann To: dri-devel@lists.freedesktop.org --- V2: - Drop the abridge variable - Rename chipone_dsi_setup to chipone_dsi_host_attach and call it from chipone_i2c_probe() V3: Add AB from Maxime V4: - Update on top of small change in drm: bridge: icn6211: Add generic DSI-to-DPI PLL configuration - Look up host_node locally in chipone_dsi_host_attach() - Drop AB from Maxime --- drivers/gpu/drm/bridge/chipone-icn6211.c | 174 --- 1 file changed, 153 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c b/drivers/gpu/drm/bridge/chipone-icn6211.c index 144bed4c83083..44fdb9c9bd448 100644 --- a/drivers/gpu/drm/bridge/chipone-icn6211.c +++ b/drivers/gpu/drm/bridge/chipone-icn6211.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -133,6 +134,7 @@ struct chipone { struct device *dev; + struct i2c_client *client; struct drm_bridge bridge; struct drm_display_mode mode; struct drm_bridge *panel_bridge; @@ -142,6 +144,7 @@ struct chipone { struct regulator *vdd2; struct regulator *vdd3; int dsi_lanes; + bool interface_i2c; }; static inline struct chipone *bridge_to_chipone(struct drm_bridge *bridge) @@ -152,9 +155,10 @@ static inline struct chipone *bridge_to_chipone(struct drm_bridge *bridge) static inline int chipone_dsi_write(struct chipone *icn, const void *seq, size_t len) { - struct mipi_dsi_device *dsi = to_mipi_dsi_device(icn->dev); - - return mipi_dsi_generic_write(dsi, seq, len); + if (icn->interface_i2c) + i2c_smbus_write_byte_data(icn->client, reg, val); + else + mipi_dsi_generic_write(icn->dsi, (u8[]){reg, val}, 2); } #define ICN6211_DSI(icn, seq...) \ @@ -259,7 +263,10 @@ static void chipone_atomic_enable(struct drm_bridge *bridge, bridge_state = drm_atomic_get_new_bridge_state(state, bridge); bus_flags = bridge_state->output_bus_cfg.flags; - ICN6211_DSI(icn, MIPI_CFG_PW, MIPI_CFG_PW_CONFIG_DSI); + if (icn->interface_i2c) + ICN6211_DSI(icn, MIPI_CFG_PW, MIPI_CFG_PW_CONFIG_I2C); + else + ICN6211_DSI(icn, MIPI_CFG_PW, MIPI_CFG_PW_CONFIG_DSI); ICN6211_DSI(icn, HACTIVE_LI, mode->hdisplay & 0xff); @@ -380,6 +387,67 @@ static void chipone_mode_set(struct drm_bridge *bridge, struct chipone *icn = bridge_to_chipone(bridge); drm_mode_copy(&icn->mode, adjusted_mode); +}; + +static int chipone_dsi_attach(struct chipone *icn) +{ + struct mipi_dsi_device *dsi = icn->dsi; + int ret; + + dsi->lanes = icn->dsi_lanes; + dsi->format = MIPI_DSI_FMT_RGB888; + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | + MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_NO_EOT_PACKET; + + ret = mipi_dsi_attach(dsi); + if (ret < 0) + dev_err(icn->dev, "failed to attach dsi\n"); + + return ret; +} + +static int chipone_dsi_host_attach(struct chipone *icn) +{ + struct device *dev = icn->dev; + struct device_node *host_node; + struct device_node *endpoint; + struct mipi_dsi_device *dsi; + struct mipi_dsi_host *host; + int ret = 0; + + const struct mipi_dsi_device_info info = { + .type = "chipone", + .channel = 0, + .node = NULL, + }; + + endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, 0); + host_node = of_graph_get_remote_port_parent(endpoint); + of_node_put(endpoint); + + if (!host_node) + return -EINVAL; + + host = of_find_mipi_dsi_host_by_node(host_node); + of_node_put(host_node); + if (!host) { + dev_err(dev, "failed to find dsi host\n"); + return -EPROBE_DEFER; + } + + dsi = mipi_dsi_device_register_full(host, &info); + if (IS_ERR(dsi)) { + return dev_err_probe(dev, PTR_ERR(dsi), +"failed to create dsi device\n"); + } + + icn->dsi = dsi; + + ret = chipone_dsi_attach(icn); + if (ret < 0) + mipi_dsi_device_unregister(dsi); + + return ret; } static int chipone_attach(struct drm_bridge *bridge, enum drm_bridge_attach_flags flags) @@ -487,9 +55
[PATCH v4 12/13] drm: bridge: icn6211: Rework ICN6211_DSI to chipone_writeb()
Rename and inline macro ICN6211_DSI() into function chipone_writeb() to keep all function names lower-case. No functional change. Acked-by: Maxime Ripard Signed-off-by: Marek Vasut Cc: Jagan Teki Cc: Maxime Ripard Cc: Robert Foss Cc: Sam Ravnborg Cc: Thomas Zimmermann To: dri-devel@lists.freedesktop.org --- V2: Rebase on next-20220214 V3: Add AB from Maxime V4: No change --- drivers/gpu/drm/bridge/chipone-icn6211.c | 63 +++- 1 file changed, 28 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c b/drivers/gpu/drm/bridge/chipone-icn6211.c index 44fdb9c9bd448..178390040a11b 100644 --- a/drivers/gpu/drm/bridge/chipone-icn6211.c +++ b/drivers/gpu/drm/bridge/chipone-icn6211.c @@ -152,8 +152,7 @@ static inline struct chipone *bridge_to_chipone(struct drm_bridge *bridge) return container_of(bridge, struct chipone, bridge); } -static inline int chipone_dsi_write(struct chipone *icn, const void *seq, - size_t len) +static void chipone_writeb(struct chipone *icn, u8 reg, u8 val) { if (icn->interface_i2c) i2c_smbus_write_byte_data(icn->client, reg, val); @@ -161,12 +160,6 @@ static inline int chipone_dsi_write(struct chipone *icn, const void *seq, mipi_dsi_generic_write(icn->dsi, (u8[]){reg, val}, 2); } -#define ICN6211_DSI(icn, seq...) \ - { \ - const u8 d[] = { seq }; \ - chipone_dsi_write(icn, d, ARRAY_SIZE(d)); \ - } - static void chipone_configure_pll(struct chipone *icn, const struct drm_display_mode *mode) { @@ -241,11 +234,11 @@ static void chipone_configure_pll(struct chipone *icn, (fin * best_m) / BIT(best_p + best_s + 2)); /* Clock source selection fixed to MIPI DSI clock lane */ - ICN6211_DSI(icn, PLL_CTRL(6), PLL_CTRL_6_MIPI_CLK); - ICN6211_DSI(icn, PLL_REF_DIV, + chipone_writeb(icn, PLL_CTRL(6), PLL_CTRL_6_MIPI_CLK); + chipone_writeb(icn, PLL_REF_DIV, (best_p ? PLL_REF_DIV_Pe : 0) | /* Prefer /2 pre-divider */ PLL_REF_DIV_P(best_p) | PLL_REF_DIV_S(best_s)); - ICN6211_DSI(icn, PLL_INT(0), best_m); + chipone_writeb(icn, PLL_INT(0), best_m); } static void chipone_atomic_enable(struct drm_bridge *bridge, @@ -264,19 +257,19 @@ static void chipone_atomic_enable(struct drm_bridge *bridge, bus_flags = bridge_state->output_bus_cfg.flags; if (icn->interface_i2c) - ICN6211_DSI(icn, MIPI_CFG_PW, MIPI_CFG_PW_CONFIG_I2C); + chipone_writeb(icn, MIPI_CFG_PW, MIPI_CFG_PW_CONFIG_I2C); else - ICN6211_DSI(icn, MIPI_CFG_PW, MIPI_CFG_PW_CONFIG_DSI); + chipone_writeb(icn, MIPI_CFG_PW, MIPI_CFG_PW_CONFIG_DSI); - ICN6211_DSI(icn, HACTIVE_LI, mode->hdisplay & 0xff); + chipone_writeb(icn, HACTIVE_LI, mode->hdisplay & 0xff); - ICN6211_DSI(icn, VACTIVE_LI, mode->vdisplay & 0xff); + chipone_writeb(icn, VACTIVE_LI, mode->vdisplay & 0xff); /* * lsb nibble: 2nd nibble of hdisplay * msb nibble: 2nd nibble of vdisplay */ - ICN6211_DSI(icn, VACTIVE_HACTIVE_HI, + chipone_writeb(icn, VACTIVE_HACTIVE_HI, ((mode->hdisplay >> 8) & 0xf) | (((mode->vdisplay >> 8) & 0xf) << 4)); @@ -284,49 +277,49 @@ static void chipone_atomic_enable(struct drm_bridge *bridge, hsync = mode->hsync_end - mode->hsync_start; hbp = mode->htotal - mode->hsync_end; - ICN6211_DSI(icn, HFP_LI, hfp & 0xff); - ICN6211_DSI(icn, HSYNC_LI, hsync & 0xff); - ICN6211_DSI(icn, HBP_LI, hbp & 0xff); + chipone_writeb(icn, HFP_LI, hfp & 0xff); + chipone_writeb(icn, HSYNC_LI, hsync & 0xff); + chipone_writeb(icn, HBP_LI, hbp & 0xff); /* Top two bits of Horizontal Front porch/Sync/Back porch */ - ICN6211_DSI(icn, HFP_HSW_HBP_HI, + chipone_writeb(icn, HFP_HSW_HBP_HI, HFP_HSW_HBP_HI_HFP(hfp) | HFP_HSW_HBP_HI_HS(hsync) | HFP_HSW_HBP_HI_HBP(hbp)); - ICN6211_DSI(icn, VFP, mode->vsync_start - mode->vdisplay); + chipone_writeb(icn, VFP, mode->vsync_start - mode->vdisplay); - ICN6211_DSI(icn, VSYNC, mode->vsync_end - mode->vsync_start); + chipone_writeb(icn, VSYNC, mode->vsync_end - mode->vsync_start); - ICN6211_DSI(icn, VBP, mode->vtotal - mode->vsync_end); + chipone_writeb(icn, VBP, mode->vtotal - mode->vsync_end); /* dsi specific sequence */ - ICN6211_DSI(icn, SYNC_EVENT_DLY, 0x80); - ICN6211_DSI(icn, HFP_MIN, hfp & 0xff); + chipone_writeb(icn, SYNC_EVENT_DLY, 0x80); + chipone_writeb(icn, HFP_MIN, hfp & 0xff); /* DSI data lane count
[PATCH v4 10/13] drm: bridge: icn6211: Implement atomic_get_input_bus_fmts
Implement .atomic_get_input_bus_fmts callback, which sets up the input (DSI-end) format, and that format can then be used in pipeline format negotiation between the DSI-end of this bridge and the other component closer to the scanout engine. Acked-by: Maxime Ripard Signed-off-by: Marek Vasut Cc: Jagan Teki Cc: Maxime Ripard Cc: Robert Foss Cc: Sam Ravnborg Cc: Thomas Zimmermann To: dri-devel@lists.freedesktop.org --- V2: Rebase on next-20220214 V3: Add AB from Maxime V4: No change --- drivers/gpu/drm/bridge/chipone-icn6211.c | 27 1 file changed, 27 insertions(+) diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c b/drivers/gpu/drm/bridge/chipone-icn6211.c index 9fbe9343db235..144bed4c83083 100644 --- a/drivers/gpu/drm/bridge/chipone-icn6211.c +++ b/drivers/gpu/drm/bridge/chipone-icn6211.c @@ -389,6 +389,32 @@ static int chipone_attach(struct drm_bridge *bridge, enum drm_bridge_attach_flag return drm_bridge_attach(bridge->encoder, icn->panel_bridge, bridge, flags); } +#define MAX_INPUT_SEL_FORMATS 1 + +static u32 * +chipone_atomic_get_input_bus_fmts(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + u32 output_fmt, + unsigned int *num_input_fmts) +{ + u32 *input_fmts; + + *num_input_fmts = 0; + + input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, sizeof(*input_fmts), +GFP_KERNEL); + if (!input_fmts) + return NULL; + + /* This is the DSI-end bus format */ + input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24; + *num_input_fmts = 1; + + return input_fmts; +} + static const struct drm_bridge_funcs chipone_bridge_funcs = { .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, @@ -398,6 +424,7 @@ static const struct drm_bridge_funcs chipone_bridge_funcs = { .atomic_post_disable= chipone_atomic_post_disable, .mode_set = chipone_mode_set, .attach = chipone_attach, + .atomic_get_input_bus_fmts = chipone_atomic_get_input_bus_fmts, }; static int chipone_parse_dt(struct chipone *icn) -- 2.34.1
[PATCH v4 09/13] drm: bridge: icn6211: Set SYS_CTRL_1 to value used in examples
Both example code [1], [2] as well as one provided by custom panel vendor set register SYS_CTRL_1 to 0x88. What exactly does the value mean is unknown due to unavailable datasheet. Align this register value with example code. [1] https://github.com/rockchip-linux/kernel/blob/develop-4.19/drivers/gpu/drm/bridge/icn6211.c [2] https://github.com/tdjastrzebski/ICN6211-Configurator Acked-by: Maxime Ripard Signed-off-by: Marek Vasut Cc: Jagan Teki Cc: Maxime Ripard Cc: Robert Foss Cc: Sam Ravnborg Cc: Thomas Zimmermann To: dri-devel@lists.freedesktop.org --- V2: Rebase on next-20220214 V3: Add AB from Maxime V4: No change --- drivers/gpu/drm/bridge/chipone-icn6211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c b/drivers/gpu/drm/bridge/chipone-icn6211.c index 11c5a1553e7e0..9fbe9343db235 100644 --- a/drivers/gpu/drm/bridge/chipone-icn6211.c +++ b/drivers/gpu/drm/bridge/chipone-icn6211.c @@ -314,7 +314,7 @@ static void chipone_atomic_enable(struct drm_bridge *bridge, chipone_configure_pll(icn, mode); ICN6211_DSI(icn, SYS_CTRL(0), 0x40); - ICN6211_DSI(icn, SYS_CTRL(1), 0x98); + ICN6211_DSI(icn, SYS_CTRL(1), 0x88); /* icn6211 specific sequence */ ICN6211_DSI(icn, MIPI_FORCE_0, 0x20); -- 2.34.1
[PATCH v4 13/13] drm: bridge: icn6211: Read and validate chip IDs before configuration
Read out the Vendor/Chip/Version ID registers from the chip before performing any configuration, and validate that the registers have correct values. This is mostly a simple test whether DSI register access does work, since that tends to be broken on various bridges. Acked-by: Maxime Ripard Signed-off-by: Marek Vasut Cc: Jagan Teki Cc: Maxime Ripard Cc: Robert Foss Cc: Sam Ravnborg Cc: Thomas Zimmermann To: dri-devel@lists.freedesktop.org --- V2: Rebase on next-20220214 V3: Add AB from Maxime V4: No change --- drivers/gpu/drm/bridge/chipone-icn6211.c | 24 +++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c b/drivers/gpu/drm/bridge/chipone-icn6211.c index 178390040a11b..ff744bd4d22bc 100644 --- a/drivers/gpu/drm/bridge/chipone-icn6211.c +++ b/drivers/gpu/drm/bridge/chipone-icn6211.c @@ -152,6 +152,14 @@ static inline struct chipone *bridge_to_chipone(struct drm_bridge *bridge) return container_of(bridge, struct chipone, bridge); } +static void chipone_readb(struct chipone *icn, u8 reg, u8 *val) +{ + if (icn->interface_i2c) + *val = i2c_smbus_read_byte_data(icn->client, reg); + else + mipi_dsi_generic_read(icn->dsi, (u8[]){reg, 1}, 2, val, 1); +} + static void chipone_writeb(struct chipone *icn, u8 reg, u8 val) { if (icn->interface_i2c) @@ -250,7 +258,21 @@ static void chipone_atomic_enable(struct drm_bridge *bridge, const struct drm_bridge_state *bridge_state; u16 hfp, hbp, hsync; u32 bus_flags; - u8 pol; + u8 pol, id[4]; + + chipone_readb(icn, VENDOR_ID, id); + chipone_readb(icn, DEVICE_ID_H, id + 1); + chipone_readb(icn, DEVICE_ID_L, id + 2); + chipone_readb(icn, VERSION_ID, id + 3); + + dev_dbg(icn->dev, + "Chip IDs: Vendor=0x%02x Device=0x%02x:0x%02x Version=0x%02x\n", + id[0], id[1], id[2], id[3]); + + if (id[0] != 0xc1 || id[1] != 0x62 || id[2] != 0x11) { + dev_dbg(icn->dev, "Invalid Chip IDs, aborting configuration\n"); + return; + } /* Get the DPI flags from the bridge state. */ bridge_state = drm_atomic_get_new_bridge_state(state, bridge); -- 2.34.1
[PATCH v4 08/13] drm: bridge: icn6211: Disable DPI color swap
The chip is capable of swapping DPI RGB channels. The driver currently does not implement support for this functionality. Write the MIPI_PN_SWAP register to 0 to assure the color swap is disabled. Acked-by: Maxime Ripard Signed-off-by: Marek Vasut Cc: Jagan Teki Cc: Maxime Ripard Cc: Robert Foss Cc: Sam Ravnborg Cc: Thomas Zimmermann To: dri-devel@lists.freedesktop.org --- V2: Rebase on next-20220214 V3: Add AB from Maxime V4: No change --- drivers/gpu/drm/bridge/chipone-icn6211.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c b/drivers/gpu/drm/bridge/chipone-icn6211.c index b3212f3387615..11c5a1553e7e0 100644 --- a/drivers/gpu/drm/bridge/chipone-icn6211.c +++ b/drivers/gpu/drm/bridge/chipone-icn6211.c @@ -302,6 +302,7 @@ static void chipone_atomic_enable(struct drm_bridge *bridge, ICN6211_DSI(icn, MIPI_PD_CK_LANE, 0xa0); ICN6211_DSI(icn, PLL_CTRL(12), 0xff); + ICN6211_DSI(icn, MIPI_PN_SWAP, 0x00); /* DPI HS/VS/DE polarity */ pol = ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? BIST_POL_HSYNC_POL : 0) | -- 2.34.1
[PATCH v4 06/13] drm: bridge: icn6211: Add generic DSI-to-DPI PLL configuration
The chip contains fractional PLL, however the driver currently hard-codes one specific PLL setting. Implement generic PLL parameter calculation code, so any DPI panel with arbitrary pixel clock can be attached to this bridge. The datasheet for this bridge is not available, the PLL behavior has been inferred from [1] and [2] and by analyzing the DPI pixel clock with scope. The PLL limits might be wrong, but at least the calculated values match all the example code available. This is better than one hard-coded pixel clock value anyway. [1] https://github.com/rockchip-linux/kernel/blob/develop-4.19/drivers/gpu/drm/bridge/icn6211.c [2] https://github.com/tdjastrzebski/ICN6211-Configurator Acked-by: Maxime Ripard Signed-off-by: Marek Vasut Cc: Jagan Teki Cc: Maxime Ripard Cc: Robert Foss Cc: Sam Ravnborg Cc: Thomas Zimmermann To: dri-devel@lists.freedesktop.org --- V2: Rebase on next-20220214 V3: Add AB from Maxime V4: - Cache mipi_dsi_device pointer in struct chipone {}, this is moved here from drm: "bridge: icn6211: Add I2C configuration support" --- drivers/gpu/drm/bridge/chipone-icn6211.c | 89 +++- 1 file changed, 86 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c b/drivers/gpu/drm/bridge/chipone-icn6211.c index fc99dae185dbc..c838d25c96ce2 100644 --- a/drivers/gpu/drm/bridge/chipone-icn6211.c +++ b/drivers/gpu/drm/bridge/chipone-icn6211.c @@ -136,6 +136,7 @@ struct chipone { struct drm_bridge bridge; struct drm_display_mode mode; struct drm_bridge *panel_bridge; + struct mipi_dsi_device *dsi; struct gpio_desc *enable_gpio; struct regulator *vdd1; struct regulator *vdd2; @@ -162,6 +163,87 @@ static inline int chipone_dsi_write(struct chipone *icn, const void *seq, chipone_dsi_write(icn, d, ARRAY_SIZE(d)); \ } +static void chipone_configure_pll(struct chipone *icn, + const struct drm_display_mode *mode) +{ + unsigned int best_p = 0, best_m = 0, best_s = 0; + unsigned int delta, min_delta = 0x; + unsigned int freq_p, freq_s, freq_out; + unsigned int p_min, p_max; + unsigned int p, m, s; + unsigned int fin; + + /* +* DSI clock lane frequency (input into PLL) is calculated as: +* DSI_CLK = mode clock * bpp / dsi_data_lanes / 2 +* the 2 is there because the bus is DDR. +* +* DPI pixel clock frequency (output from PLL) is mode clock. +* +* The chip contains fractional PLL which works as follows: +* DPI_CLK = ((DSI_CLK / P) * M) / S +* P is pre-divider, register PLL_REF_DIV[3:0] is 2^(n+1) divider +* register PLL_REF_DIV[4] is extra 1:2 divider +* M is integer multiplier, register PLL_INT(0) is multiplier +* S is post-divider, register PLL_REF_DIV[7:5] is 2^(n+1) divider +* +* It seems the PLL input clock after applying P pre-divider have +* to be lower than 20 MHz. +*/ + fin = mode->clock * mipi_dsi_pixel_format_to_bpp(icn->dsi->format) / + icn->dsi_lanes / 2; /* in kHz */ + + /* Minimum value of P predivider for PLL input in 5..20 MHz */ + p_min = ffs(fin / 2); + p_max = (fls(fin / 5000) - 1) & 0x1f; + + for (p = p_min; p < p_max; p++) { /* PLL_REF_DIV[4,3:0] */ + freq_p = fin / BIT(p + 1); + if (freq_p == 0)/* Divider too high */ + break; + + for (s = 0; s < 0x7; s++) { /* PLL_REF_DIV[7:5] */ + freq_s = freq_p / BIT(s + 1); + if (freq_s == 0)/* Divider too high */ + break; + + m = mode->clock / freq_s; + + /* Multiplier is 8 bit */ + if (m > 0xff) + continue; + + /* Limit PLL VCO frequency to 1 GHz */ + freq_out = (fin * m) / BIT(p + 1); + if (freq_out > 100) + continue; + + /* Apply post-divider */ + freq_out /= BIT(s + 1); + + delta = abs(mode->clock - freq_out); + if (delta < min_delta) { + best_p = p; + best_m = m; + best_s = s; + min_delta = delta; + } + } + } + + dev_dbg(icn->dev, + "PLL: P[3:0]=2^%d P[4]=2*%d M=%d S[7:5]=2^%d delta=%d => DSI f_in=%d kHz ; DPI f_out=%ld kHz\n", + best_p, !!best_p, best_m, best_s + 1, min_delta, fin, + (fin * best_m) / BIT(best_p + best_s + 2)); + + /* Clock source selection fixed
[PATCH v4 03/13] drm: bridge: icn6211: Fix HFP_HSW_HBP_HI and HFP_MIN handling
The HFP_HSW_HBP_HI register must be programmed with 2 LSbits of each Horizontal Front Porch/Sync/Back Porch. Currently the driver programs this register to 0, which breaks displays with either value above 255. The HFP_MIN register must be set to the same value as HFP_LI, otherwise there is visible image distortion, usually in the form of missing lines at the bottom of the panel. Fix this by correctly programming the HFP_HSW_HBP_HI and HFP_MIN registers. Acked-by: Maxime Ripard Fixes: ce517f18944e3 ("drm: bridge: Add Chipone ICN6211 MIPI-DSI to RGB bridge") Signed-off-by: Marek Vasut Cc: Jagan Teki Cc: Maxime Ripard Cc: Robert Foss Cc: Sam Ravnborg Cc: Thomas Zimmermann To: dri-devel@lists.freedesktop.org --- V2: Rebase on next-20220214 V3: Add AB from Maxime V4: No change --- drivers/gpu/drm/bridge/chipone-icn6211.c | 23 --- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c b/drivers/gpu/drm/bridge/chipone-icn6211.c index 376e0f80da5ca..c871a90c0b8f4 100644 --- a/drivers/gpu/drm/bridge/chipone-icn6211.c +++ b/drivers/gpu/drm/bridge/chipone-icn6211.c @@ -35,6 +35,9 @@ #define HSYNC_LI 0x24 #define HBP_LI 0x25 #define HFP_HSW_HBP_HI 0x26 +#define HFP_HSW_HBP_HI_HFP(n) (((n) & 0x300) >> 4) +#define HFP_HSW_HBP_HI_HS(n) (((n) & 0x300) >> 6) +#define HFP_HSW_HBP_HI_HBP(n) (((n) & 0x300) >> 8) #define VFP0x27 #define VSYNC 0x28 #define VBP0x29 @@ -163,6 +166,7 @@ static void chipone_atomic_enable(struct drm_bridge *bridge, { struct chipone *icn = bridge_to_chipone(bridge); struct drm_display_mode *mode = &icn->mode; + u16 hfp, hbp, hsync; ICN6211_DSI(icn, MIPI_CFG_PW, MIPI_CFG_PW_CONFIG_DSI); @@ -178,13 +182,18 @@ static void chipone_atomic_enable(struct drm_bridge *bridge, ((mode->hdisplay >> 8) & 0xf) | (((mode->vdisplay >> 8) & 0xf) << 4)); - ICN6211_DSI(icn, HFP_LI, mode->hsync_start - mode->hdisplay); + hfp = mode->hsync_start - mode->hdisplay; + hsync = mode->hsync_end - mode->hsync_start; + hbp = mode->htotal - mode->hsync_end; - ICN6211_DSI(icn, HSYNC_LI, mode->hsync_end - mode->hsync_start); - - ICN6211_DSI(icn, HBP_LI, mode->htotal - mode->hsync_end); - - ICN6211_DSI(icn, HFP_HSW_HBP_HI, 0x00); + ICN6211_DSI(icn, HFP_LI, hfp & 0xff); + ICN6211_DSI(icn, HSYNC_LI, hsync & 0xff); + ICN6211_DSI(icn, HBP_LI, hbp & 0xff); + /* Top two bits of Horizontal Front porch/Sync/Back porch */ + ICN6211_DSI(icn, HFP_HSW_HBP_HI, + HFP_HSW_HBP_HI_HFP(hfp) | + HFP_HSW_HBP_HI_HS(hsync) | + HFP_HSW_HBP_HI_HBP(hbp)); ICN6211_DSI(icn, VFP, mode->vsync_start - mode->vdisplay); @@ -194,7 +203,7 @@ static void chipone_atomic_enable(struct drm_bridge *bridge, /* dsi specific sequence */ ICN6211_DSI(icn, SYNC_EVENT_DLY, 0x80); - ICN6211_DSI(icn, HFP_MIN, 0x28); + ICN6211_DSI(icn, HFP_MIN, hfp & 0xff); ICN6211_DSI(icn, MIPI_PD_CK_LANE, 0xa0); ICN6211_DSI(icn, PLL_CTRL(12), 0xff); ICN6211_DSI(icn, BIST_POL, BIST_POL_DE_POL); -- 2.34.1
[PATCH v4 04/13] drm: bridge: icn6211: Add HS/VS/DE polarity handling
The driver currently hard-codes HS/VS polarity to active-low and DE to active-high, which is not correct for a lot of supported DPI panels. Add the missing mode flag handling for HS/VS/DE polarity. Acked-by: Maxime Ripard Signed-off-by: Marek Vasut Cc: Jagan Teki Cc: Maxime Ripard Cc: Robert Foss Cc: Sam Ravnborg Cc: Thomas Zimmermann To: dri-devel@lists.freedesktop.org --- V2: Rebase on next-20220214 V3: No change V4: Add AB from Maxime --- drivers/gpu/drm/bridge/chipone-icn6211.c | 16 +++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c b/drivers/gpu/drm/bridge/chipone-icn6211.c index c871a90c0b8f4..30db8d1783cef 100644 --- a/drivers/gpu/drm/bridge/chipone-icn6211.c +++ b/drivers/gpu/drm/bridge/chipone-icn6211.c @@ -165,8 +165,16 @@ static void chipone_atomic_enable(struct drm_bridge *bridge, struct drm_bridge_state *old_bridge_state) { struct chipone *icn = bridge_to_chipone(bridge); + struct drm_atomic_state *state = old_bridge_state->base.state; struct drm_display_mode *mode = &icn->mode; + const struct drm_bridge_state *bridge_state; u16 hfp, hbp, hsync; + u32 bus_flags; + u8 pol; + + /* Get the DPI flags from the bridge state. */ + bridge_state = drm_atomic_get_new_bridge_state(state, bridge); + bus_flags = bridge_state->output_bus_cfg.flags; ICN6211_DSI(icn, MIPI_CFG_PW, MIPI_CFG_PW_CONFIG_DSI); @@ -206,7 +214,13 @@ static void chipone_atomic_enable(struct drm_bridge *bridge, ICN6211_DSI(icn, HFP_MIN, hfp & 0xff); ICN6211_DSI(icn, MIPI_PD_CK_LANE, 0xa0); ICN6211_DSI(icn, PLL_CTRL(12), 0xff); - ICN6211_DSI(icn, BIST_POL, BIST_POL_DE_POL); + + /* DPI HS/VS/DE polarity */ + pol = ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? BIST_POL_HSYNC_POL : 0) | + ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? BIST_POL_VSYNC_POL : 0) | + ((bus_flags & DRM_BUS_FLAG_DE_HIGH) ? BIST_POL_DE_POL : 0); + ICN6211_DSI(icn, BIST_POL, pol); + ICN6211_DSI(icn, PLL_CTRL(6), PLL_CTRL_6_MIPI_CLK); ICN6211_DSI(icn, PLL_REF_DIV, 0x71); ICN6211_DSI(icn, PLL_INT(0), 0x2b); -- 2.34.1
[PATCH v4 07/13] drm: bridge: icn6211: Use DSI burst mode without EoT and with LP command mode
The DSI burst mode is more energy efficient than the DSI sync pulse mode, make use of the burst mode since the chip supports it as well. Disable the generation of EoT packet, the chip ignores it, so no point in emitting it. Enable transmission of data in LP mode, otherwise register read via DSI does not work with this chip. Acked-by: Maxime Ripard Signed-off-by: Marek Vasut Cc: Jagan Teki Cc: Maxime Ripard Cc: Robert Foss Cc: Sam Ravnborg Cc: Thomas Zimmermann To: dri-devel@lists.freedesktop.org --- V2: Rebase on next-20220214 V3: Add AB from Maxime V4: No change --- drivers/gpu/drm/bridge/chipone-icn6211.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c b/drivers/gpu/drm/bridge/chipone-icn6211.c index c838d25c96ce2..b3212f3387615 100644 --- a/drivers/gpu/drm/bridge/chipone-icn6211.c +++ b/drivers/gpu/drm/bridge/chipone-icn6211.c @@ -485,7 +485,8 @@ static int chipone_probe(struct mipi_dsi_device *dsi) dsi->lanes = icn->dsi_lanes; dsi->format = MIPI_DSI_FMT_RGB888; - dsi->mode_flags = MIPI_DSI_MODE_VIDEO_SYNC_PULSE; + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | + MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_NO_EOT_PACKET; ret = mipi_dsi_attach(dsi); if (ret < 0) { -- 2.34.1
[PATCH v4 02/13] drm: bridge: icn6211: Fix register layout
The chip register layout has nothing to do with MIPI DCS, the registers incorrectly marked as MIPI DCS in the driver are regular chip registers often with completely different function. Fill in the actual register names and bits from [1] and [2] and add the entire register layout, since the documentation for this chip is hard to come by. [1] https://github.com/rockchip-linux/kernel/blob/develop-4.19/drivers/gpu/drm/bridge/icn6211.c [2] https://github.com/tdjastrzebski/ICN6211-Configurator Acked-by: Maxime Ripard Fixes: ce517f18944e3 ("drm: bridge: Add Chipone ICN6211 MIPI-DSI to RGB bridge") Signed-off-by: Marek Vasut Cc: Jagan Teki Cc: Maxime Ripard Cc: Robert Foss Cc: Sam Ravnborg Cc: Thomas Zimmermann To: dri-devel@lists.freedesktop.org --- V2: Rebase on next-20220214 V3: Add AB from Maxime V4: No change --- drivers/gpu/drm/bridge/chipone-icn6211.c | 134 --- 1 file changed, 117 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c b/drivers/gpu/drm/bridge/chipone-icn6211.c index d9b7f48b99fbf..376e0f80da5ca 100644 --- a/drivers/gpu/drm/bridge/chipone-icn6211.c +++ b/drivers/gpu/drm/bridge/chipone-icn6211.c @@ -15,8 +15,19 @@ #include #include -#include - +#define VENDOR_ID 0x00 +#define DEVICE_ID_H0x01 +#define DEVICE_ID_L0x02 +#define VERSION_ID 0x03 +#define FIRMWARE_VERSION 0x08 +#define CONFIG_FINISH 0x09 +#define PD_CTRL(n) (0x0a + ((n) & 0x3)) /* 0..3 */ +#define RST_CTRL(n)(0x0e + ((n) & 0x1)) /* 0..1 */ +#define SYS_CTRL(n)(0x10 + ((n) & 0x7)) /* 0..4 */ +#define RGB_DRV(n) (0x18 + ((n) & 0x3)) /* 0..3 */ +#define RGB_DLY(n) (0x1c + ((n) & 0x1)) /* 0..1 */ +#define RGB_TEST_CTRL 0x1e +#define ATE_PLL_EN 0x1f #define HACTIVE_LI 0x20 #define VACTIVE_LI 0x21 #define VACTIVE_HACTIVE_HI 0x22 @@ -27,6 +38,95 @@ #define VFP0x27 #define VSYNC 0x28 #define VBP0x29 +#define BIST_POL 0x2a +#define BIST_POL_BIST_MODE(n) (((n) & 0xf) << 4) +#define BIST_POL_BIST_GEN BIT(3) +#define BIST_POL_HSYNC_POL BIT(2) +#define BIST_POL_VSYNC_POL BIT(1) +#define BIST_POL_DE_POLBIT(0) +#define BIST_RED 0x2b +#define BIST_GREEN 0x2c +#define BIST_BLUE 0x2d +#define BIST_CHESS_X 0x2e +#define BIST_CHESS_Y 0x2f +#define BIST_CHESS_XY_H0x30 +#define BIST_FRAME_TIME_L 0x31 +#define BIST_FRAME_TIME_H 0x32 +#define FIFO_MAX_ADDR_LOW 0x33 +#define SYNC_EVENT_DLY 0x34 +#define HSW_MIN0x35 +#define HFP_MIN0x36 +#define LOGIC_RST_NUM 0x37 +#define OSC_CTRL(n)(0x48 + ((n) & 0x7)) /* 0..5 */ +#define BG_CTRL0x4e +#define LDO_PLL0x4f +#define PLL_CTRL(n)(0x50 + ((n) & 0xf)) /* 0..15 */ +#define PLL_CTRL_6_EXTERNAL0x90 +#define PLL_CTRL_6_MIPI_CLK0x92 +#define PLL_CTRL_6_INTERNAL0x93 +#define PLL_REM(n) (0x60 + ((n) & 0x3)) /* 0..2 */ +#define PLL_DIV(n) (0x63 + ((n) & 0x3)) /* 0..2 */ +#define PLL_FRAC(n)(0x66 + ((n) & 0x3)) /* 0..2 */ +#define PLL_INT(n) (0x69 + ((n) & 0x1)) /* 0..1 */ +#define PLL_REF_DIV0x6b +#define PLL_REF_DIV_P(n) ((n) & 0xf) +#define PLL_REF_DIV_Pe BIT(4) +#define PLL_REF_DIV_S(n) (((n) & 0x7) << 5) +#define PLL_SSC_P(n) (0x6c + ((n) & 0x3)) /* 0..2 */ +#define PLL_SSC_STEP(n)(0x6f + ((n) & 0x3)) /* 0..2 */ +#define PLL_SSC_OFFSET(n) (0x72 + ((n) & 0x3)) /* 0..3 */ +#define GPIO_OEN 0x79 +#define MIPI_CFG_PW0x7a +#define MIPI_CFG_PW_CONFIG_DSI 0xc1 +#define MIPI_CFG_PW_CONFIG_I2C 0x3e +#define GPIO_SEL(n)(0x7b + ((n) & 0x1)) /* 0..1 */ +#define IRQ_SEL0x7d +#define DBG_SEL0x7e +#define DBG_SIGNAL 0x7f +#define MIPI_ERR_VECTOR_L 0x80 +#define MIPI_ERR_VECTOR_H 0x81 +#define MIPI_ERR_VECTOR_EN_L 0x82 +#define MIPI_ERR_VECTOR_EN_H 0x83 +#define MIPI_MAX_SIZE_L0x84 +#define MIPI_MAX_SIZE_H0x85 +#define DSI_CTRL 0x86 +#define DSI_CTRL_UNKNOWN 0x28 +#define DSI_CTRL_DSI_LANES(n) ((n) & 0x3) +#define MIPI_PN_SWAP 0x87 +#define MIPI_PN_SWAP_CLK BIT(4) +#define MIPI_PN_SWAP_D(n) BIT((n) & 0x3) +#define MIPI_SOT_SYNC_BIT_(n) (0x88 + ((n) & 0x1)) /* 0..1 */ +#define MIPI_ULPS_CTRL 0x8a +#define MIPI_CLK_CHK_VAR 0x8e +#define MIPI_CLK_CHK_INI 0x8f +#define MIPI_T_TERM_EN 0x90 +#define MIPI
[PATCH v4 05/13] drm: bridge: icn6211: Add DSI lane count DT property parsing
The driver currently hard-codes DSI lane count to two, however the chip is capable of operating in 1..4 DSI lanes mode. Parse 'data-lanes' DT property and program the result into DSI_CTRL register. Signed-off-by: Marek Vasut Cc: Jagan Teki Cc: Maxime Ripard Cc: Robert Foss Cc: Sam Ravnborg Cc: Thomas Zimmermann To: dri-devel@lists.freedesktop.org --- V2: Rebase on next-20220214 V3: Default to 4 data lanes unless specified otherwise V4: Move host_node caching to i2c addition patch --- drivers/gpu/drm/bridge/chipone-icn6211.c | 23 ++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c b/drivers/gpu/drm/bridge/chipone-icn6211.c index 30db8d1783cef..fc99dae185dbc 100644 --- a/drivers/gpu/drm/bridge/chipone-icn6211.c +++ b/drivers/gpu/drm/bridge/chipone-icn6211.c @@ -140,6 +140,7 @@ struct chipone { struct regulator *vdd1; struct regulator *vdd2; struct regulator *vdd3; + int dsi_lanes; }; static inline struct chipone *bridge_to_chipone(struct drm_bridge *bridge) @@ -212,6 +213,11 @@ static void chipone_atomic_enable(struct drm_bridge *bridge, /* dsi specific sequence */ ICN6211_DSI(icn, SYNC_EVENT_DLY, 0x80); ICN6211_DSI(icn, HFP_MIN, hfp & 0xff); + + /* DSI data lane count */ + ICN6211_DSI(icn, DSI_CTRL, + DSI_CTRL_UNKNOWN | DSI_CTRL_DSI_LANES(icn->dsi_lanes - 1)); + ICN6211_DSI(icn, MIPI_PD_CK_LANE, 0xa0); ICN6211_DSI(icn, PLL_CTRL(12), 0xff); @@ -314,6 +320,8 @@ static const struct drm_bridge_funcs chipone_bridge_funcs = { static int chipone_parse_dt(struct chipone *icn) { struct device *dev = icn->dev; + struct device_node *endpoint; + int dsi_lanes; int ret; icn->vdd1 = devm_regulator_get_optional(dev, "vdd1"); @@ -349,6 +357,19 @@ static int chipone_parse_dt(struct chipone *icn) return PTR_ERR(icn->enable_gpio); } + endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, 0); + dsi_lanes = of_property_count_u32_elems(endpoint, "data-lanes"); + of_node_put(endpoint); + + /* +* If the 'data-lanes' property does not exist in DT or is invalid, +* default to previously hard-coded behavior, which was 4 data lanes. +*/ + if (dsi_lanes >= 1 && dsi_lanes <= 4) + icn->dsi_lanes = dsi_lanes; + else + icn->dsi_lanes = 4; + icn->panel_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0); if (IS_ERR(icn->panel_bridge)) return PTR_ERR(icn->panel_bridge); @@ -379,7 +400,7 @@ static int chipone_probe(struct mipi_dsi_device *dsi) drm_bridge_add(&icn->bridge); - dsi->lanes = 4; + dsi->lanes = icn->dsi_lanes; dsi->format = MIPI_DSI_FMT_RGB888; dsi->mode_flags = MIPI_DSI_MODE_VIDEO_SYNC_PULSE; -- 2.34.1
[PATCH v4 01/13] dt-bindings: display: bridge: icn6211: Document DSI data-lanes property
It is necessary to specify the number of connected/used DSI data lanes when using the DSI input port of this bridge. Document the 'data-lanes' property of the DSI input port. Acked-by: Maxime Ripard Reviewed-by: Rob Herring Signed-off-by: Marek Vasut Cc: Jagan Teki Cc: Maxime Ripard Cc: Rob Herring Cc: Robert Foss Cc: Sam Ravnborg Cc: Thomas Zimmermann Cc: devicet...@vger.kernel.org To: dri-devel@lists.freedesktop.org --- V3: New patch V4: Add RB from Rob, AB from Maxime --- .../display/bridge/chipone,icn6211.yaml| 18 +- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/display/bridge/chipone,icn6211.yaml b/Documentation/devicetree/bindings/display/bridge/chipone,icn6211.yaml index 62c3bd4cb28d8..f8cac721a7330 100644 --- a/Documentation/devicetree/bindings/display/bridge/chipone,icn6211.yaml +++ b/Documentation/devicetree/bindings/display/bridge/chipone,icn6211.yaml @@ -41,10 +41,26 @@ properties: properties: port@0: -$ref: /schemas/graph.yaml#/properties/port +$ref: /schemas/graph.yaml#/$defs/port-base +unevaluatedProperties: false description: Video port for MIPI DSI input +properties: + endpoint: +$ref: /schemas/media/video-interfaces.yaml# +unevaluatedProperties: false + +properties: + data-lanes: +description: array of physical DSI data lane indexes. +minItems: 1 +items: + - const: 1 + - const: 2 + - const: 3 + - const: 4 + port@1: $ref: /schemas/graph.yaml#/properties/port description: -- 2.34.1
[PATCH v4 00/13] drm: bridge: icn6211: Fix hard-coded panel settings and add I2C support
This series fixes multiple problems with the ICN6211 driver and adds support for configuration of the chip via I2C bus. First, in the current state, the ICN6211 driver hard-codes DPI timing and clock settings specific to some unknown panel. The settings provided by panel driver are ignored. Using any other panel than the one for which this driver is currently hard-coded can lead to permanent damage of the panel (per display supplier warning, and it sure did in my case. The damage looks like multiple rows of dead pixels at the bottom of the panel, and this is not going away even after long power off time). Much of this series thus fixes incorrect register layout, DPI timing programming, clock generation by adding actual PLL configuration code. This series also adds lane count decoding instead of using hard-coded value, and fills in a couple of registers with likely correct default values. Second, this series adds support for I2C configuration of the ICN6211. The device can be configured either via DSI command mode or via I2C, the register layout is the same in both cases. Since the datasheet for this device is very hard to come by, a lot of information has been salvaged from [1] and [2]. [1] https://github.com/rockchip-linux/kernel/blob/develop-4.19/drivers/gpu/drm/bridge/icn6211.c [2] https://github.com/tdjastrzebski/ICN6211-Configurator Cc: Jagan Teki Cc: Maxime Ripard Cc: Robert Foss Cc: Sam Ravnborg Cc: Thomas Zimmermann To: dri-devel@lists.freedesktop.org Marek Vasut (13): dt-bindings: display: bridge: icn6211: Document DSI data-lanes property drm: bridge: icn6211: Fix register layout drm: bridge: icn6211: Fix HFP_HSW_HBP_HI and HFP_MIN handling drm: bridge: icn6211: Add HS/VS/DE polarity handling drm: bridge: icn6211: Add DSI lane count DT property parsing drm: bridge: icn6211: Add generic DSI-to-DPI PLL configuration drm: bridge: icn6211: Use DSI burst mode without EoT and with LP command mode drm: bridge: icn6211: Disable DPI color swap drm: bridge: icn6211: Set SYS_CTRL_1 to value used in examples drm: bridge: icn6211: Implement atomic_get_input_bus_fmts drm: bridge: icn6211: Add I2C configuration support drm: bridge: icn6211: Rework ICN6211_DSI to chipone_writeb() drm: bridge: icn6211: Read and validate chip IDs before configuration .../display/bridge/chipone,icn6211.yaml | 18 +- drivers/gpu/drm/bridge/chipone-icn6211.c | 507 -- 2 files changed, 472 insertions(+), 53 deletions(-) -- 2.34.1
Re: [Intel-gfx] [PATCH 1/2] drm/i915/sseu: Don't overallocate subslice storage
On Fri, Mar 11, 2022 at 12:52:33PM -0800, Lucas De Marchi wrote: > On Fri, Mar 11, 2022 at 12:43:40PM -0800, Matt Roper wrote: > >On Fri, Mar 11, 2022 at 12:38:17PM -0800, Matt Roper wrote: > >> On Fri, Mar 11, 2022 at 11:00:09AM -0800, Lucas De Marchi wrote: > >> > On Thu, Mar 10, 2022 at 10:15:42PM -0800, Matt Roper wrote: > >> > > Xe_HP removed "slice" as a first-class unit in the hardware design. > >> > > Instead we now have a single pool of subslices (which are now referred > >> > > to as "DSS") that different hardware units have different ways of > >> > > grouping ("compute slices," "geometry slices," etc.). For the purposes > >> > > of topology representation, we treat Xe_HP-based platforms as having a > >> > > single slice that contains all of the platform's DSS. There's no need > >> > > to allocate storage space for (max legacy slices * max dss); let's > >> > > update some of our macros to minimize the storage requirement for sseu > >> > > topology. We'll also document some of the constants to make it a > >> > > little > >> > > bit more clear what they represent. > >> > > > >> > > Signed-off-by: Matt Roper > >> > > --- > >> > > drivers/gpu/drm/i915/gt/intel_engine_types.h | 2 +- > >> > > drivers/gpu/drm/i915/gt/intel_sseu.h | 47 +++- > >> > > 2 files changed, 36 insertions(+), 13 deletions(-) > >> > > > >> > > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h > >> > > b/drivers/gpu/drm/i915/gt/intel_engine_types.h > >> > > index 4fbf45a74ec0..f9e246004bc0 100644 > >> > > --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h > >> > > +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h > >> > > @@ -645,7 +645,7 @@ intel_engine_has_relative_mmio(const struct > >> > > intel_engine_cs * const engine) > >> > > > >> > > #define for_each_instdone_gslice_dss_xehp(dev_priv_, sseu_, iter_, > >> > > gslice_, dss_) \ > >> > >for ((iter_) = 0, (gslice_) = 0, (dss_) = 0; \ > >> > > - (iter_) < GEN_MAX_SUBSLICES; \ > >> > > + (iter_) < GEN_SS_MASK_SIZE; \ > >> > > (iter_)++, (gslice_) = (iter_) / GEN_DSS_PER_GSLICE, \ > >> > > (dss_) = (iter_) % GEN_DSS_PER_GSLICE) \ > >> > >for_each_if(intel_sseu_has_subslice((sseu_), 0, > >> > > (iter_))) > >> > > diff --git a/drivers/gpu/drm/i915/gt/intel_sseu.h > >> > > b/drivers/gpu/drm/i915/gt/intel_sseu.h > >> > > index 8a79cd8eaab4..4f59eadbb61a 100644 > >> > > --- a/drivers/gpu/drm/i915/gt/intel_sseu.h > >> > > +++ b/drivers/gpu/drm/i915/gt/intel_sseu.h > >> > > @@ -15,26 +15,49 @@ struct drm_i915_private; > >> > > struct intel_gt; > >> > > struct drm_printer; > >> > > > >> > > -#define GEN_MAX_SLICES(3) /* SKL upper bound */ > >> > > -#define GEN_MAX_SUBSLICES (32) /* XEHPSDV upper bound */ > >> > > -#define GEN_SSEU_STRIDE(max_entries) DIV_ROUND_UP(max_entries, > >> > > BITS_PER_BYTE) > >> > > -#define GEN_MAX_SUBSLICE_STRIDE GEN_SSEU_STRIDE(GEN_MAX_SUBSLICES) > >> > > -#define GEN_MAX_EUS (16) /* TGL upper bound */ > >> > > -#define GEN_MAX_EU_STRIDE GEN_SSEU_STRIDE(GEN_MAX_EUS) > >> > > +/* > >> > > + * Maximum number of legacy slices. Legacy slices no longer exist > >> > > starting on > >> > > + * Xe_HP ("gslices," "cslices," etc. on Xe_HP and beyond are a > >> > > different > >> > > + * concept and are not expressed through fusing). > >> > > + */ > >> > > +#define GEN_MAX_LEGACY_SLICES 3 > >> > > + > >> > > +/* > >> > > + * Maximum number of subslices that can exist within a legacy slice. > >> > > This is > >> > > + * only relevant to pre-Xe_HP platforms (Xe_HP and beyond use the > >> > > GEN_MAX_DSS > >> > > + * value below). > >> > > + */ > >> > > +#define GEN_MAX_LEGACY_SUBSLICES 6 > >> > > >> > instead of calling the old legacy, maybe just add the XEHP_ prefix to > >> > the new ones? > >> > >> Maybe a "HSW_" prefix on the old ones would be better? People still use > >> the termm 'subslice' in casual discussion when talking about DSS, so I > >> want to somehow distinguish that what we're talking about here is a > >> different, older design than we have on modern platforms. > > > >Hmm, or maybe just "GEN_MAX_SUBSLICES_PER_LEGACY_SLICE" to tie it into > >the slice definition above? > > I'm not too fond of calling it "legacy" when everywhere else in the driver > we just use the platform as prefix/suffix. Some may see legacy as > < ver 12, others as 12.50, etc. Everything will become legacy at some point. This kind of naming scheme falls apart when the next shiny new thing comes around and we end up with multiple different leagacies. Are we going to have ANCIENT_LEGACY, RECENT_LEGACY, NOT_YET_LEGACY etc? -- Ville Syrjälä Intel
Re: [Intel-gfx] [PATCH 1/2] drm/i915/sseu: Don't overallocate subslice storage
On Fri, Mar 11, 2022 at 12:43:40PM -0800, Matt Roper wrote: On Fri, Mar 11, 2022 at 12:38:17PM -0800, Matt Roper wrote: On Fri, Mar 11, 2022 at 11:00:09AM -0800, Lucas De Marchi wrote: > On Thu, Mar 10, 2022 at 10:15:42PM -0800, Matt Roper wrote: > > Xe_HP removed "slice" as a first-class unit in the hardware design. > > Instead we now have a single pool of subslices (which are now referred > > to as "DSS") that different hardware units have different ways of > > grouping ("compute slices," "geometry slices," etc.). For the purposes > > of topology representation, we treat Xe_HP-based platforms as having a > > single slice that contains all of the platform's DSS. There's no need > > to allocate storage space for (max legacy slices * max dss); let's > > update some of our macros to minimize the storage requirement for sseu > > topology. We'll also document some of the constants to make it a little > > bit more clear what they represent. > > > > Signed-off-by: Matt Roper > > --- > > drivers/gpu/drm/i915/gt/intel_engine_types.h | 2 +- > > drivers/gpu/drm/i915/gt/intel_sseu.h | 47 +++- > > 2 files changed, 36 insertions(+), 13 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h b/drivers/gpu/drm/i915/gt/intel_engine_types.h > > index 4fbf45a74ec0..f9e246004bc0 100644 > > --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h > > +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h > > @@ -645,7 +645,7 @@ intel_engine_has_relative_mmio(const struct intel_engine_cs * const engine) > > > > #define for_each_instdone_gslice_dss_xehp(dev_priv_, sseu_, iter_, gslice_, dss_) \ > > for ((iter_) = 0, (gslice_) = 0, (dss_) = 0; \ > > - (iter_) < GEN_MAX_SUBSLICES; \ > > + (iter_) < GEN_SS_MASK_SIZE; \ > >(iter_)++, (gslice_) = (iter_) / GEN_DSS_PER_GSLICE, \ > >(dss_) = (iter_) % GEN_DSS_PER_GSLICE) \ > > for_each_if(intel_sseu_has_subslice((sseu_), 0, (iter_))) > > diff --git a/drivers/gpu/drm/i915/gt/intel_sseu.h b/drivers/gpu/drm/i915/gt/intel_sseu.h > > index 8a79cd8eaab4..4f59eadbb61a 100644 > > --- a/drivers/gpu/drm/i915/gt/intel_sseu.h > > +++ b/drivers/gpu/drm/i915/gt/intel_sseu.h > > @@ -15,26 +15,49 @@ struct drm_i915_private; > > struct intel_gt; > > struct drm_printer; > > > > -#define GEN_MAX_SLICES (3) /* SKL upper bound */ > > -#define GEN_MAX_SUBSLICES(32) /* XEHPSDV upper bound */ > > -#define GEN_SSEU_STRIDE(max_entries) DIV_ROUND_UP(max_entries, BITS_PER_BYTE) > > -#define GEN_MAX_SUBSLICE_STRIDE GEN_SSEU_STRIDE(GEN_MAX_SUBSLICES) > > -#define GEN_MAX_EUS (16) /* TGL upper bound */ > > -#define GEN_MAX_EU_STRIDE GEN_SSEU_STRIDE(GEN_MAX_EUS) > > +/* > > + * Maximum number of legacy slices. Legacy slices no longer exist starting on > > + * Xe_HP ("gslices," "cslices," etc. on Xe_HP and beyond are a different > > + * concept and are not expressed through fusing). > > + */ > > +#define GEN_MAX_LEGACY_SLICES3 > > + > > +/* > > + * Maximum number of subslices that can exist within a legacy slice. This is > > + * only relevant to pre-Xe_HP platforms (Xe_HP and beyond use the GEN_MAX_DSS > > + * value below). > > + */ > > +#define GEN_MAX_LEGACY_SUBSLICES 6 > > instead of calling the old legacy, maybe just add the XEHP_ prefix to > the new ones? Maybe a "HSW_" prefix on the old ones would be better? People still use the termm 'subslice' in casual discussion when talking about DSS, so I want to somehow distinguish that what we're talking about here is a different, older design than we have on modern platforms. Hmm, or maybe just "GEN_MAX_SUBSLICES_PER_LEGACY_SLICE" to tie it into the slice definition above? I'm not too fond of calling it "legacy" when everywhere else in the driver we just use the platform as prefix/suffix. Some may see legacy as < ver 12, others as 12.50, etc. Well... but I will leave that up to you if you are convinced one is better than the other. thanks Lucas De Marchi
Re: [Intel-gfx] [PATCH 1/2] drm/i915/sseu: Don't overallocate subslice storage
On Fri, Mar 11, 2022 at 12:38:17PM -0800, Matt Roper wrote: > On Fri, Mar 11, 2022 at 11:00:09AM -0800, Lucas De Marchi wrote: > > On Thu, Mar 10, 2022 at 10:15:42PM -0800, Matt Roper wrote: > > > Xe_HP removed "slice" as a first-class unit in the hardware design. > > > Instead we now have a single pool of subslices (which are now referred > > > to as "DSS") that different hardware units have different ways of > > > grouping ("compute slices," "geometry slices," etc.). For the purposes > > > of topology representation, we treat Xe_HP-based platforms as having a > > > single slice that contains all of the platform's DSS. There's no need > > > to allocate storage space for (max legacy slices * max dss); let's > > > update some of our macros to minimize the storage requirement for sseu > > > topology. We'll also document some of the constants to make it a little > > > bit more clear what they represent. > > > > > > Signed-off-by: Matt Roper > > > --- > > > drivers/gpu/drm/i915/gt/intel_engine_types.h | 2 +- > > > drivers/gpu/drm/i915/gt/intel_sseu.h | 47 +++- > > > 2 files changed, 36 insertions(+), 13 deletions(-) > > > > > > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h > > > b/drivers/gpu/drm/i915/gt/intel_engine_types.h > > > index 4fbf45a74ec0..f9e246004bc0 100644 > > > --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h > > > +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h > > > @@ -645,7 +645,7 @@ intel_engine_has_relative_mmio(const struct > > > intel_engine_cs * const engine) > > > > > > #define for_each_instdone_gslice_dss_xehp(dev_priv_, sseu_, iter_, > > > gslice_, dss_) \ > > > for ((iter_) = 0, (gslice_) = 0, (dss_) = 0; \ > > > - (iter_) < GEN_MAX_SUBSLICES; \ > > > + (iter_) < GEN_SS_MASK_SIZE; \ > > >(iter_)++, (gslice_) = (iter_) / GEN_DSS_PER_GSLICE, \ > > >(dss_) = (iter_) % GEN_DSS_PER_GSLICE) \ > > > for_each_if(intel_sseu_has_subslice((sseu_), 0, (iter_))) > > > diff --git a/drivers/gpu/drm/i915/gt/intel_sseu.h > > > b/drivers/gpu/drm/i915/gt/intel_sseu.h > > > index 8a79cd8eaab4..4f59eadbb61a 100644 > > > --- a/drivers/gpu/drm/i915/gt/intel_sseu.h > > > +++ b/drivers/gpu/drm/i915/gt/intel_sseu.h > > > @@ -15,26 +15,49 @@ struct drm_i915_private; > > > struct intel_gt; > > > struct drm_printer; > > > > > > -#define GEN_MAX_SLICES (3) /* SKL upper bound */ > > > -#define GEN_MAX_SUBSLICES(32) /* XEHPSDV upper bound */ > > > -#define GEN_SSEU_STRIDE(max_entries) DIV_ROUND_UP(max_entries, > > > BITS_PER_BYTE) > > > -#define GEN_MAX_SUBSLICE_STRIDE GEN_SSEU_STRIDE(GEN_MAX_SUBSLICES) > > > -#define GEN_MAX_EUS (16) /* TGL upper bound */ > > > -#define GEN_MAX_EU_STRIDE GEN_SSEU_STRIDE(GEN_MAX_EUS) > > > +/* > > > + * Maximum number of legacy slices. Legacy slices no longer exist > > > starting on > > > + * Xe_HP ("gslices," "cslices," etc. on Xe_HP and beyond are a different > > > + * concept and are not expressed through fusing). > > > + */ > > > +#define GEN_MAX_LEGACY_SLICES3 > > > + > > > +/* > > > + * Maximum number of subslices that can exist within a legacy slice. > > > This is > > > + * only relevant to pre-Xe_HP platforms (Xe_HP and beyond use the > > > GEN_MAX_DSS > > > + * value below). > > > + */ > > > +#define GEN_MAX_LEGACY_SUBSLICES 6 > > > > instead of calling the old legacy, maybe just add the XEHP_ prefix to > > the new ones? > > Maybe a "HSW_" prefix on the old ones would be better? People still use > the termm 'subslice' in casual discussion when talking about DSS, so I > want to somehow distinguish that what we're talking about here is a > different, older design than we have on modern platforms. Hmm, or maybe just "GEN_MAX_SUBSLICES_PER_LEGACY_SLICE" to tie it into the slice definition above? Matt > > > Matt > > > > > > + > > > +/* Maximum number of DSS on newer platforms (Xe_HP and beyond). */ > > > +#define GEN_MAX_DSS 32 > > > + > > > +/* Maximum number of EUs that can exist within a subslice or DSS. */ > > > +#define GEN_MAX_EUS_PER_SS 16 > > > + > > > +#define MAX(a, b)((a) > (b) ? (a) : (b)) > > > > what's worse, include kernel.h in another header file or redefine MAX > > everywhere? Re-defining it in headers we risk situations in which the > > include order may create warnings about defining it in multiple places. > > > > > > > + > > > +/* The maximum number of bits needed to express each subslice/DSS > > > independently */ > > > +#define GEN_SS_MASK_SIZE MAX(GEN_MAX_DSS, \ > > > + GEN_MAX_LEGACY_SLICES * > > > GEN_MAX_LEGACY_SUBSLICES) > > > + > > > +#define GEN_SSEU_STRIDE(max_entries) DIV_ROUND_UP(max_entries, > > > BITS_PER_BYTE) > > > +#define GEN_MAX_SUBSLICE_STRIDE > > > GEN_SSEU_STRIDE(GEN_SS_MASK_SIZE) > > > +#define GEN_MAX_EU_STRIDE > > > GEN_SSEU_STRIDE(GEN_MAX_EUS_PER
Re: [PATCH V3 05/13] drm: bridge: icn6211: Add DSI lane count DT property parsing
Hi Marek, Small correction in the previous comment. On Sat, Mar 12, 2022 at 2:05 AM Jagan Teki wrote: > > Hi Marek, > > On Sat, Mar 12, 2022 at 1:32 AM Marek Vasut wrote: > > > > On 3/11/22 17:29, Maxime Ripard wrote: > > > On Fri, Mar 11, 2022 at 11:36:58AM +0100, Marek Vasut wrote: > > >> On 3/10/22 15:18, Maxime Ripard wrote: > > >>> On Thu, Mar 10, 2022 at 01:47:13PM +0100, Marek Vasut wrote: > > On 3/10/22 11:53, Maxime Ripard wrote: > > > On Tue, Mar 08, 2022 at 10:41:05PM +0100, Marek Vasut wrote: > > >> On 3/8/22 17:21, Maxime Ripard wrote: > > >>> On Tue, Mar 08, 2022 at 03:47:22PM +0100, Marek Vasut wrote: > > On 3/8/22 14:49, Maxime Ripard wrote: > > > On Tue, Mar 08, 2022 at 02:27:40PM +0100, Marek Vasut wrote: > > >> On 3/8/22 13:51, Maxime Ripard wrote: > > >>> On Tue, Mar 08, 2022 at 11:29:59AM +0100, Marek Vasut wrote: > > On 3/8/22 11:07, Jagan Teki wrote: > > > On Tue, Mar 8, 2022 at 3:19 PM Marek Vasut > > > wrote: > > >> > > >> On 3/8/22 09:03, Jagan Teki wrote: > > >> > > >> Hi, > > >> > > >> [...] > > >> > > @@ -314,7 +321,9 @@ static const struct drm_bridge_funcs > > chipone_bridge_funcs = { > > static int chipone_parse_dt(struct chipone *icn) > > { > > struct device *dev = icn->dev; > > + struct device_node *endpoint; > > struct drm_panel *panel; > > + int dsi_lanes; > > int ret; > > > > icn->vdd1 = > > devm_regulator_get_optional(dev, "vdd1"); > > @@ -350,15 +359,42 @@ static int chipone_parse_dt(struct > > chipone *icn) > > return PTR_ERR(icn->enable_gpio); > > } > > > > + endpoint = > > of_graph_get_endpoint_by_regs(dev->of_node, 0, 0); > > + dsi_lanes = of_property_count_u32_elems(endpoint, > > "data-lanes"); > > + icn->host_node = > > of_graph_get_remote_port_parent(endpoint); > > + of_node_put(endpoint); > > + > > + if (!icn->host_node) > > + return -ENODEV; > > >>> > > >>> The non-ports-based OF graph returns a -19 example on the > > >>> Allwinner > > >>> Display pipeline in R16 [1]. > > >>> > > >>> We need to have a helper to return host_node for non-ports > > >>> as I have > > >>> done it for drm_of_find_bridge. > > >>> > > >>> [1] https://patchwork.amarulasolutions.com/patch/1805/ > > >> > > >> The link points to a patch marked "DO NOT MERGE", maybe that > > >> patch is > > >> missing the DSI host port@0 OF graph link ? Both port@0 and > > >> port@1 are > > >> required, see: > > >> > > >> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/display/bridge/chipone,icn6211.yaml#n53 > > >> > > >> What is "non-ports-based OF graph" ? > > >> > > >> I don't see drm_of_find_bridge() in linux-next , what is > > >> that ? > > > > > > port@0 is optional as some of the DSI host OF-graph represent > > > the > > > bridge or panel as child nodes instead of ports. (i think > > > dt-binding > > > has to fix it to make port@0 optional) > > > > The current upstream DT binding document says: > > > > required: > > - port@0 > > - port@1 > > > > So port@0 is mandatory. > > >>> > > >>> In the binding, sure, but fundamentally the DT excerpt Jagan > > >>> provided is > > >>> correct. If the bridge supports DCS, there's no reason to use > > >>> the OF > > >>> graph in the first place: the bridge node will be a child node > > >>> of the > > >>> MIPI-DSI controller (and there's no obligation to use the > > >>> OF-graph for a > > >>> MIPI-DSI controller). > > >>> > > >>> I believe port@0 should be made optional (or downright removed > > >>> if > > >>> MIPI-DCS in the only control bus). > > >> > > >> That's out of scope of this seri
Re: [Intel-gfx] [PATCH 1/2] drm/i915/sseu: Don't overallocate subslice storage
On Fri, Mar 11, 2022 at 11:00:09AM -0800, Lucas De Marchi wrote: > On Thu, Mar 10, 2022 at 10:15:42PM -0800, Matt Roper wrote: > > Xe_HP removed "slice" as a first-class unit in the hardware design. > > Instead we now have a single pool of subslices (which are now referred > > to as "DSS") that different hardware units have different ways of > > grouping ("compute slices," "geometry slices," etc.). For the purposes > > of topology representation, we treat Xe_HP-based platforms as having a > > single slice that contains all of the platform's DSS. There's no need > > to allocate storage space for (max legacy slices * max dss); let's > > update some of our macros to minimize the storage requirement for sseu > > topology. We'll also document some of the constants to make it a little > > bit more clear what they represent. > > > > Signed-off-by: Matt Roper > > --- > > drivers/gpu/drm/i915/gt/intel_engine_types.h | 2 +- > > drivers/gpu/drm/i915/gt/intel_sseu.h | 47 +++- > > 2 files changed, 36 insertions(+), 13 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h > > b/drivers/gpu/drm/i915/gt/intel_engine_types.h > > index 4fbf45a74ec0..f9e246004bc0 100644 > > --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h > > +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h > > @@ -645,7 +645,7 @@ intel_engine_has_relative_mmio(const struct > > intel_engine_cs * const engine) > > > > #define for_each_instdone_gslice_dss_xehp(dev_priv_, sseu_, iter_, gslice_, > > dss_) \ > > for ((iter_) = 0, (gslice_) = 0, (dss_) = 0; \ > > -(iter_) < GEN_MAX_SUBSLICES; \ > > +(iter_) < GEN_SS_MASK_SIZE; \ > > (iter_)++, (gslice_) = (iter_) / GEN_DSS_PER_GSLICE, \ > > (dss_) = (iter_) % GEN_DSS_PER_GSLICE) \ > > for_each_if(intel_sseu_has_subslice((sseu_), 0, (iter_))) > > diff --git a/drivers/gpu/drm/i915/gt/intel_sseu.h > > b/drivers/gpu/drm/i915/gt/intel_sseu.h > > index 8a79cd8eaab4..4f59eadbb61a 100644 > > --- a/drivers/gpu/drm/i915/gt/intel_sseu.h > > +++ b/drivers/gpu/drm/i915/gt/intel_sseu.h > > @@ -15,26 +15,49 @@ struct drm_i915_private; > > struct intel_gt; > > struct drm_printer; > > > > -#define GEN_MAX_SLICES (3) /* SKL upper bound */ > > -#define GEN_MAX_SUBSLICES (32) /* XEHPSDV upper bound */ > > -#define GEN_SSEU_STRIDE(max_entries) DIV_ROUND_UP(max_entries, > > BITS_PER_BYTE) > > -#define GEN_MAX_SUBSLICE_STRIDE GEN_SSEU_STRIDE(GEN_MAX_SUBSLICES) > > -#define GEN_MAX_EUS(16) /* TGL upper bound */ > > -#define GEN_MAX_EU_STRIDE GEN_SSEU_STRIDE(GEN_MAX_EUS) > > +/* > > + * Maximum number of legacy slices. Legacy slices no longer exist > > starting on > > + * Xe_HP ("gslices," "cslices," etc. on Xe_HP and beyond are a different > > + * concept and are not expressed through fusing). > > + */ > > +#define GEN_MAX_LEGACY_SLICES 3 > > + > > +/* > > + * Maximum number of subslices that can exist within a legacy slice. This > > is > > + * only relevant to pre-Xe_HP platforms (Xe_HP and beyond use the > > GEN_MAX_DSS > > + * value below). > > + */ > > +#define GEN_MAX_LEGACY_SUBSLICES 6 > > instead of calling the old legacy, maybe just add the XEHP_ prefix to > the new ones? Maybe a "HSW_" prefix on the old ones would be better? People still use the termm 'subslice' in casual discussion when talking about DSS, so I want to somehow distinguish that what we're talking about here is a different, older design than we have on modern platforms. Matt > > > + > > +/* Maximum number of DSS on newer platforms (Xe_HP and beyond). */ > > +#define GEN_MAX_DSS32 > > + > > +/* Maximum number of EUs that can exist within a subslice or DSS. */ > > +#define GEN_MAX_EUS_PER_SS 16 > > + > > +#define MAX(a, b) ((a) > (b) ? (a) : (b)) > > what's worse, include kernel.h in another header file or redefine MAX > everywhere? Re-defining it in headers we risk situations in which the > include order may create warnings about defining it in multiple places. > > > > + > > +/* The maximum number of bits needed to express each subslice/DSS > > independently */ > > +#define GEN_SS_MASK_SIZE MAX(GEN_MAX_DSS, \ > > + GEN_MAX_LEGACY_SLICES * > > GEN_MAX_LEGACY_SUBSLICES) > > + > > +#define GEN_SSEU_STRIDE(max_entries) DIV_ROUND_UP(max_entries, > > BITS_PER_BYTE) > > +#define GEN_MAX_SUBSLICE_STRIDE > > GEN_SSEU_STRIDE(GEN_SS_MASK_SIZE) > > +#define GEN_MAX_EU_STRIDE GEN_SSEU_STRIDE(GEN_MAX_EUS_PER_SS) > > > > #define GEN_DSS_PER_GSLICE 4 > > #define GEN_DSS_PER_CSLICE 8 > > #define GEN_DSS_PER_MSLICE 8 > > > > -#define GEN_MAX_GSLICES(GEN_MAX_SUBSLICES / GEN_DSS_PER_GSLICE) > > -#define GEN_MAX_CSLICES(GEN_MAX_SUBSLICES / GEN_DSS_PER_CSLICE) > > +#define GEN_MAX_GSLICES(GEN_MAX_DSS / GEN_DSS_PER_GSLICE) > > +#define GEN_MAX_CSLICE
Re: [PATCH V3 05/13] drm: bridge: icn6211: Add DSI lane count DT property parsing
Hi Marek, On Sat, Mar 12, 2022 at 1:32 AM Marek Vasut wrote: > > On 3/11/22 17:29, Maxime Ripard wrote: > > On Fri, Mar 11, 2022 at 11:36:58AM +0100, Marek Vasut wrote: > >> On 3/10/22 15:18, Maxime Ripard wrote: > >>> On Thu, Mar 10, 2022 at 01:47:13PM +0100, Marek Vasut wrote: > On 3/10/22 11:53, Maxime Ripard wrote: > > On Tue, Mar 08, 2022 at 10:41:05PM +0100, Marek Vasut wrote: > >> On 3/8/22 17:21, Maxime Ripard wrote: > >>> On Tue, Mar 08, 2022 at 03:47:22PM +0100, Marek Vasut wrote: > On 3/8/22 14:49, Maxime Ripard wrote: > > On Tue, Mar 08, 2022 at 02:27:40PM +0100, Marek Vasut wrote: > >> On 3/8/22 13:51, Maxime Ripard wrote: > >>> On Tue, Mar 08, 2022 at 11:29:59AM +0100, Marek Vasut wrote: > On 3/8/22 11:07, Jagan Teki wrote: > > On Tue, Mar 8, 2022 at 3:19 PM Marek Vasut > > wrote: > >> > >> On 3/8/22 09:03, Jagan Teki wrote: > >> > >> Hi, > >> > >> [...] > >> > @@ -314,7 +321,9 @@ static const struct drm_bridge_funcs > chipone_bridge_funcs = { > static int chipone_parse_dt(struct chipone *icn) > { > struct device *dev = icn->dev; > + struct device_node *endpoint; > struct drm_panel *panel; > + int dsi_lanes; > int ret; > > icn->vdd1 = devm_regulator_get_optional(dev, > "vdd1"); > @@ -350,15 +359,42 @@ static int chipone_parse_dt(struct > chipone *icn) > return PTR_ERR(icn->enable_gpio); > } > > + endpoint = > of_graph_get_endpoint_by_regs(dev->of_node, 0, 0); > + dsi_lanes = of_property_count_u32_elems(endpoint, > "data-lanes"); > + icn->host_node = > of_graph_get_remote_port_parent(endpoint); > + of_node_put(endpoint); > + > + if (!icn->host_node) > + return -ENODEV; > >>> > >>> The non-ports-based OF graph returns a -19 example on the > >>> Allwinner > >>> Display pipeline in R16 [1]. > >>> > >>> We need to have a helper to return host_node for non-ports as > >>> I have > >>> done it for drm_of_find_bridge. > >>> > >>> [1] https://patchwork.amarulasolutions.com/patch/1805/ > >> > >> The link points to a patch marked "DO NOT MERGE", maybe that > >> patch is > >> missing the DSI host port@0 OF graph link ? Both port@0 and > >> port@1 are > >> required, see: > >> > >> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/display/bridge/chipone,icn6211.yaml#n53 > >> > >> What is "non-ports-based OF graph" ? > >> > >> I don't see drm_of_find_bridge() in linux-next , what is that ? > > > > port@0 is optional as some of the DSI host OF-graph represent > > the > > bridge or panel as child nodes instead of ports. (i think > > dt-binding > > has to fix it to make port@0 optional) > > The current upstream DT binding document says: > > required: > - port@0 > - port@1 > > So port@0 is mandatory. > >>> > >>> In the binding, sure, but fundamentally the DT excerpt Jagan > >>> provided is > >>> correct. If the bridge supports DCS, there's no reason to use the > >>> OF > >>> graph in the first place: the bridge node will be a child node of > >>> the > >>> MIPI-DSI controller (and there's no obligation to use the > >>> OF-graph for a > >>> MIPI-DSI controller). > >>> > >>> I believe port@0 should be made optional (or downright removed if > >>> MIPI-DCS in the only control bus). > >> > >> That's out of scope of this series anyway, so Jagan can implement > >> patches > >> for that mode if needed. > > > > Not really? You can't count on the port@0 being there generally > > speaking, so you can't count on data-lanes being there either, which > > exactly what you're doing in this patch. > > I can because
Re: [PATCH V3 05/13] drm: bridge: icn6211: Add DSI lane count DT property parsing
On 3/11/22 17:29, Maxime Ripard wrote: On Fri, Mar 11, 2022 at 11:36:58AM +0100, Marek Vasut wrote: On 3/10/22 15:18, Maxime Ripard wrote: On Thu, Mar 10, 2022 at 01:47:13PM +0100, Marek Vasut wrote: On 3/10/22 11:53, Maxime Ripard wrote: On Tue, Mar 08, 2022 at 10:41:05PM +0100, Marek Vasut wrote: On 3/8/22 17:21, Maxime Ripard wrote: On Tue, Mar 08, 2022 at 03:47:22PM +0100, Marek Vasut wrote: On 3/8/22 14:49, Maxime Ripard wrote: On Tue, Mar 08, 2022 at 02:27:40PM +0100, Marek Vasut wrote: On 3/8/22 13:51, Maxime Ripard wrote: On Tue, Mar 08, 2022 at 11:29:59AM +0100, Marek Vasut wrote: On 3/8/22 11:07, Jagan Teki wrote: On Tue, Mar 8, 2022 at 3:19 PM Marek Vasut wrote: On 3/8/22 09:03, Jagan Teki wrote: Hi, [...] @@ -314,7 +321,9 @@ static const struct drm_bridge_funcs chipone_bridge_funcs = { static int chipone_parse_dt(struct chipone *icn) { struct device *dev = icn->dev; + struct device_node *endpoint; struct drm_panel *panel; + int dsi_lanes; int ret; icn->vdd1 = devm_regulator_get_optional(dev, "vdd1"); @@ -350,15 +359,42 @@ static int chipone_parse_dt(struct chipone *icn) return PTR_ERR(icn->enable_gpio); } + endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, 0); + dsi_lanes = of_property_count_u32_elems(endpoint, "data-lanes"); + icn->host_node = of_graph_get_remote_port_parent(endpoint); + of_node_put(endpoint); + + if (!icn->host_node) + return -ENODEV; The non-ports-based OF graph returns a -19 example on the Allwinner Display pipeline in R16 [1]. We need to have a helper to return host_node for non-ports as I have done it for drm_of_find_bridge. [1] https://patchwork.amarulasolutions.com/patch/1805/ The link points to a patch marked "DO NOT MERGE", maybe that patch is missing the DSI host port@0 OF graph link ? Both port@0 and port@1 are required, see: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/display/bridge/chipone,icn6211.yaml#n53 What is "non-ports-based OF graph" ? I don't see drm_of_find_bridge() in linux-next , what is that ? port@0 is optional as some of the DSI host OF-graph represent the bridge or panel as child nodes instead of ports. (i think dt-binding has to fix it to make port@0 optional) The current upstream DT binding document says: required: - port@0 - port@1 So port@0 is mandatory. In the binding, sure, but fundamentally the DT excerpt Jagan provided is correct. If the bridge supports DCS, there's no reason to use the OF graph in the first place: the bridge node will be a child node of the MIPI-DSI controller (and there's no obligation to use the OF-graph for a MIPI-DSI controller). I believe port@0 should be made optional (or downright removed if MIPI-DCS in the only control bus). That's out of scope of this series anyway, so Jagan can implement patches for that mode if needed. Not really? You can't count on the port@0 being there generally speaking, so you can't count on data-lanes being there either, which exactly what you're doing in this patch. I can because the upstream DT bindings currently say port@0 must be present, see above. If that requirement should be relaxed, sure, but that's a separate series. And another upstream DT bindings say that you don't need them at all. Which "another upstream DT bindings" do you refer to ? https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt Yes, there's a conflict. Yes, it's unfortunate. But the generic DSI binding is far more relevant than a single bridge driver. That seems to be the wrong way around, how can generic subsystem-wide binding take precedence over specific driver binding ? This is the binding of the bus. You're part of that bus. You're a child node of that bus, but nothing ever mandates that your parent node uses the same convention. And some don't. And since your bridge can be connected to pretty much any DSI controller, you have to use the lowest common denominator, not make up some new constraints that not all controller will be able to comply with. It seems to me the ICN6211 DT bindings currently further constraint the generic DSI bus bindings, and that seems OK to me. Let me reiterate this again -- if someone wants to relax the requirements currently imposed by the ICN6211 DT bindings, fine, but that can be done in a separate patchset AND that needs DT bindings update. Furthermore, there are no users of this ICN6211 bridge in upstream DTs, so there is currently no bridge which would operate without OF graph using this driver. And let me reiterate this again: something that used to work for a user doesn't anymore when your series is applied. This is a textbook regression. I suggested a way forwa
Re: [Intel-gfx] [PATCH 2/2] drm/i915/xehp: Update topology dumps for Xe_HP
On Thu, Mar 10, 2022 at 10:15:43PM -0800, Matt Roper wrote: When running on Xe_HP or beyond, let's use an updated format for describing topology in our error state dumps and debugfs to give a more accurate view of the hardware: - Just report DSS directly without the legacy "slice0" output that's no longer meaningful. - Indicate whether each DSS is accessible for geometry and/or compute. - Rename "rcs_topology" to "sseu_topology" since the information reported is common to both RCS and CCS engines now. Signed-off-by: Matt Roper --- drivers/gpu/drm/i915/gt/intel_sseu.c | 48 +--- drivers/gpu/drm/i915/gt/intel_sseu.h | 3 +- drivers/gpu/drm/i915/gt/intel_sseu_debugfs.c | 8 ++-- drivers/gpu/drm/i915/i915_gpu_error.c| 2 +- 4 files changed, 48 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_sseu.c b/drivers/gpu/drm/i915/gt/intel_sseu.c index 614915ffbd37..4d28458ab768 100644 --- a/drivers/gpu/drm/i915/gt/intel_sseu.c +++ b/drivers/gpu/drm/i915/gt/intel_sseu.c @@ -10,6 +10,8 @@ #include "intel_gt_regs.h" #include "intel_sseu.h" +#include "linux/string_helpers.h" + void intel_sseu_set_info(struct sseu_dev_info *sseu, u8 max_slices, u8 max_subslices, u8 max_eus_per_subslice) { @@ -54,6 +56,11 @@ u32 intel_sseu_get_subslices(const struct sseu_dev_info *sseu, u8 slice) return _intel_sseu_get_subslices(sseu, sseu->subslice_mask, slice); this func with a single underscore is the one inconsistent with the rest of the file. Just rename it while touching this part of the code? } +u32 intel_sseu_get_geometry_subslices(const struct sseu_dev_info *sseu) since it's only local to this compilation unit, make it static and remove the intel_ prefix? +{ + return _intel_sseu_get_subslices(sseu, sseu->geometry_subslice_mask, 0); +} + u32 intel_sseu_get_compute_subslices(const struct sseu_dev_info *sseu) { return _intel_sseu_get_subslices(sseu, sseu->compute_subslice_mask, 0); @@ -720,16 +727,11 @@ void intel_sseu_dump(const struct sseu_dev_info *sseu, struct drm_printer *p) str_yes_no(sseu->has_eu_pg)); } -void intel_sseu_print_topology(const struct sseu_dev_info *sseu, - struct drm_printer *p) +static void intel_sseu_print_legacy_topology(const struct sseu_dev_info *sseu, removing the intel_ prefix would make it consistent with the rest of the file too +struct drm_printer *p) { int s, ss; - if (sseu->max_slices == 0) { - drm_printf(p, "Unavailable\n"); - return; - } - for (s = 0; s < sseu->max_slices; s++) { drm_printf(p, "slice%d: %u subslice(s) (0x%08x):\n", s, intel_sseu_subslices_per_slice(sseu, s), @@ -744,6 +746,38 @@ void intel_sseu_print_topology(const struct sseu_dev_info *sseu, } } +static void intel_sseu_print_xehp_topology(const struct sseu_dev_info *sseu, + struct drm_printer *p) ditto +{ + u32 g_dss_mask = intel_sseu_get_geometry_subslices(sseu); + u32 c_dss_mask = intel_sseu_get_compute_subslices(sseu); + int dss; + + for (dss = 0; dss < sseu->max_subslices; dss++) { + u16 enabled_eus = sseu_get_eus(sseu, 0, dss); + + drm_printf(p, "DSS%02d: G:%3s C:%3s, %2u EUs (0x%04hx)\n", dss, + str_yes_no(g_dss_mask & BIT(dss)), + str_yes_no(c_dss_mask & BIT(dss)), + hweight16(enabled_eus), enabled_eus); + } +} + + +void intel_sseu_print_topology(struct drm_i915_private *i915, + const struct sseu_dev_info *sseu, + struct drm_printer *p) +{ + if (sseu->max_slices == 0) { + drm_printf(p, "Unavailable\n"); + return; either make this an early return, or remove the return other than coding style nits metioned above, Reviewed-by: Lucas De Marchi Lucas De Marchi
[RFC PATCH] drm/i915/xehp: intel_sseu_get_geometry_subslices() can be static
drivers/gpu/drm/i915/gt/intel_sseu.c:59:5: warning: symbol 'intel_sseu_get_geometry_subslices' was not declared. Should it be static? Reported-by: kernel test robot Signed-off-by: kernel test robot --- drivers/gpu/drm/i915/gt/intel_sseu.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gt/intel_sseu.c b/drivers/gpu/drm/i915/gt/intel_sseu.c index 4d28458ab768d..99e31dcf3db06 100644 --- a/drivers/gpu/drm/i915/gt/intel_sseu.c +++ b/drivers/gpu/drm/i915/gt/intel_sseu.c @@ -56,7 +56,7 @@ u32 intel_sseu_get_subslices(const struct sseu_dev_info *sseu, u8 slice) return _intel_sseu_get_subslices(sseu, sseu->subslice_mask, slice); } -u32 intel_sseu_get_geometry_subslices(const struct sseu_dev_info *sseu) +static u32 intel_sseu_get_geometry_subslices(const struct sseu_dev_info *sseu) { return _intel_sseu_get_subslices(sseu, sseu->geometry_subslice_mask, 0); }
Re: [Intel-gfx] [PATCH 2/2] drm/i915/xehp: Update topology dumps for Xe_HP
Hi Matt, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on drm-tip/drm-tip] [also build test WARNING on drm-exynos/exynos-drm-next drm/drm-next next-20220310] [cannot apply to drm-intel/for-linux-next tegra-drm/drm/tegra/for-next airlied/drm-next v5.17-rc7] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Matt-Roper/drm-i915-sseu-Don-t-overallocate-subslice-storage/20220311-141705 base: git://anongit.freedesktop.org/drm/drm-tip drm-tip config: x86_64-rhel-8.3-kselftests (https://download.01.org/0day-ci/archive/20220312/202203120322.okxcdfs7-...@intel.com/config) compiler: gcc-9 (Ubuntu 9.4.0-1ubuntu1~20.04) 9.4.0 reproduce: # apt-get install sparse # sparse version: v0.6.4-dirty # https://github.com/0day-ci/linux/commit/38985b2e6acdbe67dedb5de8a8aeef917b746453 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Matt-Roper/drm-i915-sseu-Don-t-overallocate-subslice-storage/20220311-141705 git checkout 38985b2e6acdbe67dedb5de8a8aeef917b746453 # save the config file to linux build tree mkdir build_dir make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=x86_64 SHELL=/bin/bash drivers/gpu/drm/i915/ If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot sparse warnings: (new ones prefixed by >>) >> drivers/gpu/drm/i915/gt/intel_sseu.c:59:5: sparse: sparse: symbol >> 'intel_sseu_get_geometry_subslices' was not declared. Should it be static? Please review and possibly fold the followup patch. --- 0-DAY CI Kernel Test Service https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org
Re: [PATCH 2/5] dyndbg: add class_id field and query support
On 3/10/22 23:47, Jim Cromie wrote: > DRM defines/uses 10 enum drm_debug_category's to create exclusive > classes of debug messages. To support this directly in dynamic-debug, > add the following: > > - struct _ddebug.class_id:4 - 4 bits is enough > - define _DPRINTK_SITE_UNCLASSED 15 - see below > > and the query support: > - struct _ddebug_query.class_id > - ddebug_parse_query - looks for "class" keyword, then calls.. > - parse_class - accepts uint: 0-15, sets query.class_id and marker > - vpr_info_dq - displays new field > - ddebug_proc_show- append column with "cls:%d" if !UNCLASSED > > With the patch, one can enable current/unclassed callsites by: > > #> echo drm class 15 +p > /proc/dynamic_debug/control > To me, this is hard to read, what the heck is '15'? I have to go look it up in the control file and it's not descriptive. I think that using classes/categories makes sense but I'm wondering if it can be a bit more user friendly? Perhaps, we can pass an array of strings that is indexed by the class id to each pr_debug() site that wants to use class. So something like: enum levels { LOW, MEDIUM, HIGH }; static const char * const level_to_strings[] = { [LOW] = "low", [MEDIUM] = "medium", [HIGH] = "high", }; And then you'd have a wrapper macros in your driver: #define module_foo_pr_debug_class(level, fmt, args...) pr_debug_class(level, level_to_strings, fmt, args); Such that call sites look like: module_foo_pr_debug_class(LOW, fmt, args...); Such that you're not always passing the strings array around. Now, this does mean another pointer for struct _ddebug and most wouldn't have it. Maybe we could just add another linker section for these so as to save space. > parse_class() accepts 0 .. _DPRINTK_SITE_UNCLASSED, which allows the >> control interface to explicitly manipulate unclassed callsites. > > After parsing keywords, ddebug_parse_query() sets .class_id=15, iff it > wasnt explicitly set. This allows future classed/categorized > callsites to be untouched by legacy (class unaware) queries. > > DEFINE_DYNAMIC_DEBUG_METADATA gets _CLS(cls,) suffix and arg, and > initializes the new .class_id=cls field. The old name gets the default. > > Then, these _CLS(cls,...) modifications are repeated up through the > stack of *dynamic_func_call* macros that use the METADATA initializer, > so as to actually supply the category into it. > > NOTES: > > _DPRINTK_SITE_UNCLASSED: this symbol is used to initialize all > existing/unclassed pr-debug callsites. Normally, the default would be > zero, but DRM_UT_CORE "uses" that value, in the sense that 0 is > exposed as a bit position in drm.debug. Using 15 allows identity > mapping from category to class, avoiding fiddly offsets. > > Default .class_id = 15 means that ``echo +p > control`` no longer > toggles ALL the callsites, only the unclassed ones. This was only > useful for static-branch toggle load testing anyway. > I think that # echo +p > control should continue to work as is, why should the introduction of classes change that ? > RFC: > > The new _CLS macro flavor gets a warning from DRM/dri-devel's CI, > but not from checkpatch (on this subject). > > a8f6c71f283e dyndbg: add class_id field and query support > -:141: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'id' - possible > side-effects? > +#define __dynamic_func_call_cls(id, cls, fmt, func, ...) do {\ > + DEFINE_DYNAMIC_DEBUG_METADATA_CLS(id, cls, fmt);\ > + if (DYNAMIC_DEBUG_BRANCH(id)) \ > + func(&id, ##__VA_ARGS__); \ > } while (0) > > I couldn't fix it with a ``typeof(id) _id = id`` construct. I haven't > seen the warning myself, on the _CLS extended macro, nor the original. > > CC: Rasmus Villemoes > Signed-off-by: Jim Cromie > --- > .../admin-guide/dynamic-debug-howto.rst | 7 +++ > include/linux/dynamic_debug.h | 54 ++- > lib/dynamic_debug.c | 48 ++--- > 3 files changed, 88 insertions(+), 21 deletions(-) > > diff --git a/Documentation/admin-guide/dynamic-debug-howto.rst > b/Documentation/admin-guide/dynamic-debug-howto.rst > index a89cfa083155..8ef8d7dcd140 100644 > --- a/Documentation/admin-guide/dynamic-debug-howto.rst > +++ b/Documentation/admin-guide/dynamic-debug-howto.rst > @@ -35,6 +35,7 @@ Dynamic debug has even more useful features: > - line number (including ranges of line numbers) > - module name > - format string > + - class number:0-15 > > * Provides a debugfs control file: ``/dynamic_debug/control`` > which can be read to display the complete list of known debug > @@ -143,6 +144,7 @@ against. Possible keywords are::: >'module' string | >'format' string | >'line' line-range > + 'class' integer:[0-15] > >line-range ::= linen
Re: [Intel-gfx] [PATCH 1/2] drm/i915/sseu: Don't overallocate subslice storage
On Thu, Mar 10, 2022 at 10:15:42PM -0800, Matt Roper wrote: Xe_HP removed "slice" as a first-class unit in the hardware design. Instead we now have a single pool of subslices (which are now referred to as "DSS") that different hardware units have different ways of grouping ("compute slices," "geometry slices," etc.). For the purposes of topology representation, we treat Xe_HP-based platforms as having a single slice that contains all of the platform's DSS. There's no need to allocate storage space for (max legacy slices * max dss); let's update some of our macros to minimize the storage requirement for sseu topology. We'll also document some of the constants to make it a little bit more clear what they represent. Signed-off-by: Matt Roper --- drivers/gpu/drm/i915/gt/intel_engine_types.h | 2 +- drivers/gpu/drm/i915/gt/intel_sseu.h | 47 +++- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h b/drivers/gpu/drm/i915/gt/intel_engine_types.h index 4fbf45a74ec0..f9e246004bc0 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h @@ -645,7 +645,7 @@ intel_engine_has_relative_mmio(const struct intel_engine_cs * const engine) #define for_each_instdone_gslice_dss_xehp(dev_priv_, sseu_, iter_, gslice_, dss_) \ for ((iter_) = 0, (gslice_) = 0, (dss_) = 0; \ -(iter_) < GEN_MAX_SUBSLICES; \ +(iter_) < GEN_SS_MASK_SIZE; \ (iter_)++, (gslice_) = (iter_) / GEN_DSS_PER_GSLICE, \ (dss_) = (iter_) % GEN_DSS_PER_GSLICE) \ for_each_if(intel_sseu_has_subslice((sseu_), 0, (iter_))) diff --git a/drivers/gpu/drm/i915/gt/intel_sseu.h b/drivers/gpu/drm/i915/gt/intel_sseu.h index 8a79cd8eaab4..4f59eadbb61a 100644 --- a/drivers/gpu/drm/i915/gt/intel_sseu.h +++ b/drivers/gpu/drm/i915/gt/intel_sseu.h @@ -15,26 +15,49 @@ struct drm_i915_private; struct intel_gt; struct drm_printer; -#define GEN_MAX_SLICES (3) /* SKL upper bound */ -#define GEN_MAX_SUBSLICES (32) /* XEHPSDV upper bound */ -#define GEN_SSEU_STRIDE(max_entries) DIV_ROUND_UP(max_entries, BITS_PER_BYTE) -#define GEN_MAX_SUBSLICE_STRIDE GEN_SSEU_STRIDE(GEN_MAX_SUBSLICES) -#define GEN_MAX_EUS(16) /* TGL upper bound */ -#define GEN_MAX_EU_STRIDE GEN_SSEU_STRIDE(GEN_MAX_EUS) +/* + * Maximum number of legacy slices. Legacy slices no longer exist starting on + * Xe_HP ("gslices," "cslices," etc. on Xe_HP and beyond are a different + * concept and are not expressed through fusing). + */ +#define GEN_MAX_LEGACY_SLICES 3 + +/* + * Maximum number of subslices that can exist within a legacy slice. This is + * only relevant to pre-Xe_HP platforms (Xe_HP and beyond use the GEN_MAX_DSS + * value below). + */ +#define GEN_MAX_LEGACY_SUBSLICES 6 instead of calling the old legacy, maybe just add the XEHP_ prefix to the new ones? + +/* Maximum number of DSS on newer platforms (Xe_HP and beyond). */ +#define GEN_MAX_DSS32 + +/* Maximum number of EUs that can exist within a subslice or DSS. */ +#define GEN_MAX_EUS_PER_SS 16 + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) what's worse, include kernel.h in another header file or redefine MAX everywhere? Re-defining it in headers we risk situations in which the include order may create warnings about defining it in multiple places. + +/* The maximum number of bits needed to express each subslice/DSS independently */ +#define GEN_SS_MASK_SIZE MAX(GEN_MAX_DSS, \ + GEN_MAX_LEGACY_SLICES * GEN_MAX_LEGACY_SUBSLICES) + +#define GEN_SSEU_STRIDE(max_entries) DIV_ROUND_UP(max_entries, BITS_PER_BYTE) +#define GEN_MAX_SUBSLICE_STRIDE GEN_SSEU_STRIDE(GEN_SS_MASK_SIZE) +#define GEN_MAX_EU_STRIDE GEN_SSEU_STRIDE(GEN_MAX_EUS_PER_SS) #define GEN_DSS_PER_GSLICE 4 #define GEN_DSS_PER_CSLICE 8 #define GEN_DSS_PER_MSLICE 8 -#define GEN_MAX_GSLICES(GEN_MAX_SUBSLICES / GEN_DSS_PER_GSLICE) -#define GEN_MAX_CSLICES(GEN_MAX_SUBSLICES / GEN_DSS_PER_CSLICE) +#define GEN_MAX_GSLICES(GEN_MAX_DSS / GEN_DSS_PER_GSLICE) +#define GEN_MAX_CSLICES(GEN_MAX_DSS / GEN_DSS_PER_CSLICE) struct sseu_dev_info { u8 slice_mask; - u8 subslice_mask[GEN_MAX_SLICES * GEN_MAX_SUBSLICE_STRIDE]; - u8 geometry_subslice_mask[GEN_MAX_SLICES * GEN_MAX_SUBSLICE_STRIDE]; - u8 compute_subslice_mask[GEN_MAX_SLICES * GEN_MAX_SUBSLICE_STRIDE]; - u8 eu_mask[GEN_MAX_SLICES * GEN_MAX_SUBSLICES * GEN_MAX_EU_STRIDE]; + u8 subslice_mask[GEN_SS_MASK_SIZE]; + u8 geometry_subslice_mask[GEN_SS_MASK_SIZE]; + u8 compute_subslice_mask[GEN_SS_MASK_SIZE]; + u8 eu_mask[GEN_SS_MASK_SIZE * GEN_MAX_EU_STRIDE]; Aside the minor things above, everything look correct. Reviewed-by: Lucas
Re: [PATCH 2/2] dma-buf/sync-file: fix warning about fence containers
Hi "Christian, I love your patch! Yet something to improve: [auto build test ERROR on linus/master] [also build test ERROR on v5.17-rc7 next-20220310] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Christian-K-nig/dma-buf-add-dma_fence_unwrap/20220311-190352 base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 79b00034e9dcd2b065c1665c8b42f62b6b80a9be config: x86_64-randconfig-m001 (https://download.01.org/0day-ci/archive/20220312/202203120217.bfa438j9-...@intel.com/config) compiler: gcc-9 (Ubuntu 9.4.0-1ubuntu1~20.04) 9.4.0 reproduce (this is a W=1 build): # https://github.com/0day-ci/linux/commit/ca3584ac05c4a450e69b1c6bcb0672b5ab026c7c git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Christian-K-nig/dma-buf-add-dma_fence_unwrap/20220311-190352 git checkout ca3584ac05c4a450e69b1c6bcb0672b5ab026c7c # save the config file to linux build tree mkdir build_dir make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All errors (new ones prefixed by >>): In file included from drivers/dma-buf/sync_file.c:8: include/linux/dma-fence-unwrap.h: In function 'dma_fence_unwrap_array': >> include/linux/dma-fence-unwrap.h:44:18: error: implicit declaration of >> function 'dma_fence_chain_contained'; did you mean 'dma_fence_chain_init'? >> [-Werror=implicit-function-declaration] 44 | cursor->array = dma_fence_chain_contained(cursor->chain); | ^ | dma_fence_chain_init include/linux/dma-fence-unwrap.h:44:16: warning: assignment to 'struct dma_fence *' from 'int' makes pointer from integer without a cast [-Wint-conversion] 44 | cursor->array = dma_fence_chain_contained(cursor->chain); |^ >> include/linux/dma-fence-unwrap.h:46:9: error: implicit declaration of >> function 'dma_fence_array_first'; did you mean 'dma_fence_array_create'? >> [-Werror=implicit-function-declaration] 46 | return dma_fence_array_first(cursor->array); | ^ | dma_fence_array_create include/linux/dma-fence-unwrap.h:46:9: warning: returning 'int' from a function with return type 'struct dma_fence *' makes pointer from integer without a cast [-Wint-conversion] 46 | return dma_fence_array_first(cursor->array); | ^~~~ include/linux/dma-fence-unwrap.h: In function 'dma_fence_unwrap_next': >> include/linux/dma-fence-unwrap.h:77:8: error: implicit declaration of >> function 'dma_fence_array_next'; did you mean 'dma_fence_unwrap_next'? >> [-Werror=implicit-function-declaration] 77 | tmp = dma_fence_array_next(cursor->array, cursor->index); |^~~~ |dma_fence_unwrap_next include/linux/dma-fence-unwrap.h:77:6: warning: assignment to 'struct dma_fence *' from 'int' makes pointer from integer without a cast [-Wint-conversion] 77 | tmp = dma_fence_array_next(cursor->array, cursor->index); | ^ cc1: some warnings being treated as errors vim +44 include/linux/dma-fence-unwrap.h 088aa14c0f5cad Christian König 2022-03-11 33 088aa14c0f5cad Christian König 2022-03-11 34 /** 088aa14c0f5cad Christian König 2022-03-11 35 * dma_fence_unwrap_array - helper to unwrap dma_fence_arrays 088aa14c0f5cad Christian König 2022-03-11 36 * @cursor: cursor to initialize 088aa14c0f5cad Christian König 2022-03-11 37 * 088aa14c0f5cad Christian König 2022-03-11 38 * Helper function to unwrap dma_fence_array containers, don't touch directly. 088aa14c0f5cad Christian König 2022-03-11 39 * Use dma_fence_unwrap_first/next instead. 088aa14c0f5cad Christian König 2022-03-11 40 */ 088aa14c0f5cad Christian König 2022-03-11 41 static inline struct dma_fence * 088aa14c0f5cad Christian König 2022-03-11 42 dma_fence_unwrap_array(struct dma_fence_unwrap * cursor) 088aa14c0f5cad Christian König 2022-03-11 43 { 088aa14c0f5cad Christian König 2022-03-11 @44 cursor->array = dma_fence_chain_contained(cursor->chain); 088aa14c0f5cad Christian König 2022-03-11 45 cursor->index = 0; 088aa14c0f5cad Christian König 2022-03-11 @46 return dma_fence_array_first(cursor->array); 088aa14c0f5cad Christian König 2022-03-11 47 } 088aa14c0f5cad Christian König 2022-03-11 48 08
Re: [PATCH 1/5] dyndbg: fix static_branch manipulation
On 3/10/22 23:47, Jim Cromie wrote: > In > https://urldefense.com/v3/__https://lore.kernel.org/lkml/20211209150910.ga23...@axis.com/__;!!GjvTz_vk!HGKKoni4RVdEBgv_V0zPSNSX428bpf02zkCy2WbeQkBdVtp1QJqGX-lJYlRDGg$ > > > Vincent's patch commented on, and worked around, a bug toggling > static_branch's, when a 2nd PRINTK-ish flag was added. The bug > results in a premature static_branch_disable when the 1st of 2 flags > was disabled. > > The cited commit computed newflags, but then in the JUMP_LABEL block, > failed to use that result, instead using just one of the terms in it. > Using newflags instead made the code work properly. > > This is Vincents test-case, reduced. It needs the 2nd flag to work > properly, but it's explanatory here. > > pt_test() { > echo 5 > /sys/module/dynamic_debug/verbose > > site="module tcp" # just one callsite > echo " $site =_ " > /proc/dynamic_debug/control # clear it > > # A B ~A ~B > for flg in +T +p "-T #broke here" -p; do > echo " $site $flg " > /proc/dynamic_debug/control > done; > > # A B ~B ~A > for flg in +T +p "-p #broke here" -T; do > echo " $site $flg " > /proc/dynamic_debug/control > done > } > pt_test > > Fixes: 84da83a6ffc0 dyndbg: combine flags & mask into a struct, simplify with > it > CC: vincent.whitchu...@axis.com > Signed-off-by: Jim Cromie > > -- > .drop @stable, no exposed bug. > --- > lib/dynamic_debug.c | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > > diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c > index dd7f56af9aed..a56c1286ffa4 100644 > --- a/lib/dynamic_debug.c > +++ b/lib/dynamic_debug.c > @@ -211,10 +211,11 @@ static int ddebug_change(const struct ddebug_query > *query, > continue; > #ifdef CONFIG_JUMP_LABEL > if (dp->flags & _DPRINTK_FLAGS_PRINT) { > - if (!(modifiers->flags & _DPRINTK_FLAGS_PRINT)) > + if (!(newflags & _DPRINTK_FLAGS_PRINT)) > > static_branch_disable(&dp->key.dd_key_true); > - } else if (modifiers->flags & _DPRINTK_FLAGS_PRINT) > + } else if (newflags & _DPRINTK_FLAGS_PRINT) { > static_branch_enable(&dp->key.dd_key_true); > + } > #endif > dp->flags = newflags; > v4pr_info("changed %s:%d [%s]%s =%s\n", Hi Jim, If iiuc this is currently a bug but could be if we add a second 'print' bit such as for printing to the tracing logs. That said I agree that using 'newflags' here makes the code more straightforward/readable. So this one is fine with me. Acked-by: Jason Baron Thanks, -Jason
Re: [PATCH] drm/i915/guc: Use iosys_map interface to update lrc_desc
On Tue, Mar 08, 2022 at 10:17:42PM +0530, Balasubramani Vivekanandan wrote: This patch is continuation of the effort to move all pointers in i915, which at any point may be pointing to device memory or system memory, to iosys_map interface. More details about the need of this change is explained in the patch series which initiated this task https://patchwork.freedesktop.org/series/99711/ This patch converts all access to the lrc_desc through iosys_map interfaces. Cc: Lucas De Marchi Cc: John Harrison Cc: Matthew Brost Cc: Umesh Nerlige Ramappa Signed-off-by: Balasubramani Vivekanandan --- drivers/gpu/drm/i915/gt/uc/intel_guc.h| 2 +- .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 68 --- 2 files changed, 43 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h index e439e6c1ac8b..cbbc24dbaf0f 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h @@ -168,7 +168,7 @@ struct intel_guc { /** @lrc_desc_pool: object allocated to hold the GuC LRC descriptor pool */ struct i915_vma *lrc_desc_pool; /** @lrc_desc_pool_vaddr: contents of the GuC LRC descriptor pool */ - void *lrc_desc_pool_vaddr; + struct iosys_map lrc_desc_pool_vaddr; s/_vaddr/_map/ for consistency with intel_guc_ads /** * @context_lookup: used to resolve intel_context from guc_id, if a diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c index 9ec03234d2c2..84b17ded886a 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -467,13 +467,14 @@ static u32 *get_wq_pointer(struct guc_process_desc *desc, return &__get_parent_scratch(ce)->wq[ce->parallel.guc.wqi_tail / sizeof(u32)]; } -static struct guc_lrc_desc *__get_lrc_desc(struct intel_guc *guc, u32 index) +static void __write_lrc_desc(struct intel_guc *guc, u32 index, +struct guc_lrc_desc *desc) { - struct guc_lrc_desc *base = guc->lrc_desc_pool_vaddr; + unsigned int size = sizeof(struct guc_lrc_desc); GEM_BUG_ON(index >= GUC_MAX_CONTEXT_ID); - return &base[index]; + iosys_map_memcpy_to(&guc->lrc_desc_pool_vaddr, index * size, desc, size); you are not using size anywhere else, so it would be preferred to keep the size calculation inside this call. iosys_map_memcpy_to(&guc->lrc_desc_pool_vaddr, index * size, desc, sizeof(*desc)); which also avoids accidentally using the wrong struct if we ever change the type of what we are copying. } static inline struct intel_context *__get_context(struct intel_guc *guc, u32 id) @@ -489,20 +490,28 @@ static int guc_lrc_desc_pool_create(struct intel_guc *guc) { u32 size; int ret; + void *addr; vaddr for consistency size = PAGE_ALIGN(sizeof(struct guc_lrc_desc) * GUC_MAX_CONTEXT_ID); ret = intel_guc_allocate_and_map_vma(guc, size, &guc->lrc_desc_pool, -(void **)&guc->lrc_desc_pool_vaddr); +&addr); + if (ret) return ret; + if (i915_gem_object_is_lmem(guc->lrc_desc_pool->obj)) + iosys_map_set_vaddr_iomem(&guc->lrc_desc_pool_vaddr, + (void __iomem *)addr); + else + iosys_map_set_vaddr(&guc->lrc_desc_pool_vaddr, addr); + return 0; } static void guc_lrc_desc_pool_destroy(struct intel_guc *guc) { - guc->lrc_desc_pool_vaddr = NULL; + iosys_map_clear(&guc->lrc_desc_pool_vaddr); i915_vma_unpin_and_release(&guc->lrc_desc_pool, I915_VMA_RELEASE_MAP); } @@ -513,9 +522,11 @@ static inline bool guc_submission_initialized(struct intel_guc *guc) static inline void _reset_lrc_desc(struct intel_guc *guc, u32 id) { - struct guc_lrc_desc *desc = __get_lrc_desc(guc, id); + unsigned int size = sizeof(struct guc_lrc_desc); - memset(desc, 0, sizeof(*desc)); + GEM_BUG_ON(id >= GUC_MAX_CONTEXT_ID); + + iosys_map_memset(&guc->lrc_desc_pool_vaddr, id * size, 0, size); ditto. And maybe move it be close to __write_lrc_desc. I don't really understand the difference here with 1 underscore vs the 2. Maybe as a follow up just reconcile them? The rest I left to another reply to focus on what may be the only real issue I see in this patch and to get feedback from other people. thanks Lucas De Marchi
Re: [PATCH] drm/i915/guc: Use iosys_map interface to update lrc_desc
On Tue, Mar 08, 2022 at 10:17:42PM +0530, Balasubramani Vivekanandan wrote: This patch is continuation of the effort to move all pointers in i915, which at any point may be pointing to device memory or system memory, to iosys_map interface. More details about the need of this change is explained in the patch series which initiated this task https://patchwork.freedesktop.org/series/99711/ This patch converts all access to the lrc_desc through iosys_map interfaces. Cc: Lucas De Marchi Cc: John Harrison Cc: Matthew Brost Cc: Umesh Nerlige Ramappa Signed-off-by: Balasubramani Vivekanandan --- ... diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h @@ -2245,13 +2256,13 @@ static void prepare_context_registration_info(struct intel_context *ce) GEM_BUG_ON(i915_gem_object_is_lmem(guc->ct.vma->obj) != i915_gem_object_is_lmem(ce->ring->vma->obj)); - desc = __get_lrc_desc(guc, ctx_id); - desc->engine_class = engine_class_to_guc_class(engine->class); - desc->engine_submit_mask = engine->logical_mask; - desc->hw_context_desc = ce->lrc.lrca; - desc->priority = ce->guc_state.prio; - desc->context_flags = CONTEXT_REGISTRATION_FLAG_KMD; - guc_context_policy_init(engine, desc); + memset(&desc, 0, sizeof(desc)); previously we would re-use whatever was left in guc->lrc_desc_pool_vaddr. Here we are changing it to always zero everything and set the fields we are interested in. As I'm not too familiar with this part and I see us traversing child guc_process_desc which may point to the same id, it doesn't _feel_ safe. Did you check if this is not zero'ing what it shouldn't? Matt Brost / John / Daniele, could you clarify? thanks Lucas De Marchi
[PATCH] drm/edid: Update comments for drm_find_edid_extension
In (40d9b043a89e drm/connector: store tile information from displayid (v3)) this function was changed to find EDID extensions by id, but the comments still are specific to the CEA extension. Signed-off-by: Drew Davenport --- drivers/gpu/drm/drm_edid.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 561f53831e29..1afe73fbf3e0 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -3326,7 +3326,7 @@ add_detailed_modes(struct drm_connector *connector, struct edid *edid, #define EDID_CEA_VCDB_QS (1 << 6) /* - * Search EDID for CEA extension block. + * Search EDID for the extension block with id @ext_id. */ const u8 *drm_find_edid_extension(const struct edid *edid, int ext_id, int *ext_index) @@ -3338,7 +3338,7 @@ const u8 *drm_find_edid_extension(const struct edid *edid, if (edid == NULL || edid->extensions == 0) return NULL; - /* Find CEA extension */ + /* Find extension that matches @ext_id */ for (i = *ext_index; i < edid->extensions; i++) { edid_ext = (const u8 *)edid + EDID_LENGTH * (i + 1); if (edid_ext[0] == ext_id) -- 2.35.1.723.g4982287a31-goog
Re: [PATCH 1/6] drm: allow real encoder to be passed for drm_writeback_connector
On Fri, 11 Mar 2022 at 20:09, Abhinav Kumar wrote: > > Hi Dmitry and Laurent > > On 3/11/2022 12:05 AM, Laurent Pinchart wrote: > > On Fri, Mar 11, 2022 at 10:46:13AM +0300, Dmitry Baryshkov wrote: > >> On Fri, 11 Mar 2022 at 04:50, Abhinav Kumar > >> wrote: > >>> > >>> For some vendor driver implementations, display hardware can > >>> be shared between the encoder used for writeback and the physical > >>> display. > >>> > >>> In addition resources such as clocks and interrupts can > >>> also be shared between writeback and the real encoder. > >>> > >>> To accommodate such vendor drivers and hardware, allow > >>> real encoder to be passed for drm_writeback_connector. > >>> > >>> Co-developed-by: Kandpal Suraj > >>> Signed-off-by: Abhinav Kumar > >>> --- > >>> drivers/gpu/drm/drm_writeback.c | 8 > >>> include/drm/drm_writeback.h | 13 +++-- > >>> 2 files changed, 15 insertions(+), 6 deletions(-) > >>> > >>> diff --git a/drivers/gpu/drm/drm_writeback.c > >>> b/drivers/gpu/drm/drm_writeback.c > >>> index dccf4504..4dad687 100644 > >>> --- a/drivers/gpu/drm/drm_writeback.c > >>> +++ b/drivers/gpu/drm/drm_writeback.c > >>> @@ -189,8 +189,8 @@ int drm_writeback_connector_init(struct drm_device > >>> *dev, > >>> if (IS_ERR(blob)) > >>> return PTR_ERR(blob); > >>> > >>> - drm_encoder_helper_add(&wb_connector->encoder, enc_helper_funcs); > >>> - ret = drm_encoder_init(dev, &wb_connector->encoder, > >>> + drm_encoder_helper_add(wb_connector->encoder, enc_helper_funcs); > >>> + ret = drm_encoder_init(dev, wb_connector->encoder, > >>> &drm_writeback_encoder_funcs, > >>> DRM_MODE_ENCODER_VIRTUAL, NULL); > >> > >> If the encoder is provided by a separate driver, it might use a > >> different set of encoder funcs. > > > > More than that, if the encoder is provided externally but doesn't have > > custom operations, I don't really see the point of having an external > > encoder in the first place. > > > > Has this series been tested with a driver that needs to provide an > > encoder, to make sure it fits the purpose ? > > > > Yes, I have tested this with the MSM driver which provides an encoder > and yes it absolutely fits the purpose. > > > >> I'd suggest checking whether the wb_connector->encoder is NULL here. > >> If it is, allocate one using drmm_kzalloc and init it. > >> If it is not NULL, assume that it has been initialized already, so > >> skip the drm_encoder_init() and just call the drm_encoder_helper_add() > > You are both right. We can skip the drm_encoder_init for drivers which > have already provided an encoder. > > The only issue I was facing with that is some of the drivers for example > the below one, access the "wb_conn->encoder.possible_crtcs" before the > call to drm_writeback_connector_init(). Yes. please do. > > 198 int rcar_du_writeback_init(struct rcar_du_device *rcdu, > 199struct rcar_du_crtc *rcrtc) > 200 { > 201 struct drm_writeback_connector *wb_conn = &rcrtc->writeback; > 202 > 203 wb_conn->encoder.possible_crtcs = 1 << drm_crtc_index(&rcrtc->crtc); > 204 drm_connector_helper_add(&wb_conn->base, > 205 &rcar_du_wb_conn_helper_funcs); > 206 > 207 return drm_writeback_connector_init(&rcdu->ddev, wb_conn, > 208 &rcar_du_wb_conn_funcs, > 209 &rcar_du_wb_enc_helper_funcs, > 210 writeback_formats, > 211 ARRAY_SIZE(writeback_formats)); > > If we allocate the encoder within drm_writeback_connector_init(), do you > suggest I modify the drivers to move the usage of possible_crtcs after > the drm_writeback_connector_init() call to avoid NULL ptr crash? > > > >> > >>> if (ret) > >>> @@ -204,7 +204,7 @@ int drm_writeback_connector_init(struct drm_device > >>> *dev, > >>> goto connector_fail; > >>> > >>> ret = drm_connector_attach_encoder(connector, > >>> - &wb_connector->encoder); > >>> + wb_connector->encoder); > >>> if (ret) > >>> goto attach_fail; > >>> > >>> @@ -233,7 +233,7 @@ int drm_writeback_connector_init(struct drm_device > >>> *dev, > >>> attach_fail: > >>> drm_connector_cleanup(connector); > >>> connector_fail: > >>> - drm_encoder_cleanup(&wb_connector->encoder); > >>> + drm_encoder_cleanup(wb_connector->encoder); > >>> fail: > >>> drm_property_blob_put(blob); > >>> return ret; > >>> diff --git a/include/drm/drm_writeback.h b/include/drm/drm_writeback.h > >>> index 9697d27..0ba266e 100644 > >>> --- a/include/drm/drm_writeback.h > >>> +++ b/include/drm/drm_writeback.h > >>> @@ -25,13 +25,22 @@ struct drm_writeback_connector { > >>
Re: [PATCH 2/2] dma-buf/sync-file: fix warning about fence containers
Hi "Christian, I love your patch! Perhaps something to improve: [auto build test WARNING on linus/master] [also build test WARNING on v5.17-rc7 next-20220310] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Christian-K-nig/dma-buf-add-dma_fence_unwrap/20220311-190352 base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 79b00034e9dcd2b065c1665c8b42f62b6b80a9be config: arm64-randconfig-r014-20220310 (https://download.01.org/0day-ci/archive/20220312/202203120115.qe4gabiv-...@intel.com/config) compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project 276ca87382b8f16a65bddac700202924228982f6) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install arm64 cross compiling tool for clang build # apt-get install binutils-aarch64-linux-gnu # https://github.com/0day-ci/linux/commit/ca3584ac05c4a450e69b1c6bcb0672b5ab026c7c git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Christian-K-nig/dma-buf-add-dma_fence_unwrap/20220311-190352 git checkout ca3584ac05c4a450e69b1c6bcb0672b5ab026c7c # save the config file to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm64 SHELL=/bin/bash drivers/dma-buf/ If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): In file included from drivers/dma-buf/sync_file.c:8: include/linux/dma-fence-unwrap.h:44:18: error: implicit declaration of function 'dma_fence_chain_contained' [-Werror,-Wimplicit-function-declaration] cursor->array = dma_fence_chain_contained(cursor->chain); ^ include/linux/dma-fence-unwrap.h:44:18: note: did you mean 'dma_fence_chain_init'? include/linux/dma-fence-chain.h:108:6: note: 'dma_fence_chain_init' declared here void dma_fence_chain_init(struct dma_fence_chain *chain, ^ In file included from drivers/dma-buf/sync_file.c:8: >> include/linux/dma-fence-unwrap.h:44:16: warning: incompatible integer to >> pointer conversion assigning to 'struct dma_fence *' from 'int' >> [-Wint-conversion] cursor->array = dma_fence_chain_contained(cursor->chain); ^ include/linux/dma-fence-unwrap.h:46:9: error: implicit declaration of function 'dma_fence_array_first' [-Werror,-Wimplicit-function-declaration] return dma_fence_array_first(cursor->array); ^ include/linux/dma-fence-unwrap.h:46:9: note: did you mean 'dma_fence_array_create'? include/linux/dma-fence-array.h:77:25: note: 'dma_fence_array_create' declared here struct dma_fence_array *dma_fence_array_create(int num_fences, ^ In file included from drivers/dma-buf/sync_file.c:8: >> include/linux/dma-fence-unwrap.h:46:9: warning: incompatible integer to >> pointer conversion returning 'int' from a function with result type 'struct >> dma_fence *' [-Wint-conversion] return dma_fence_array_first(cursor->array); ^~~~ include/linux/dma-fence-unwrap.h:77:8: error: implicit declaration of function 'dma_fence_array_next' [-Werror,-Wimplicit-function-declaration] tmp = dma_fence_array_next(cursor->array, cursor->index); ^ include/linux/dma-fence-unwrap.h:77:6: warning: incompatible integer to pointer conversion assigning to 'struct dma_fence *' from 'int' [-Wint-conversion] tmp = dma_fence_array_next(cursor->array, cursor->index); ^ ~~ 3 warnings and 3 errors generated. vim +44 include/linux/dma-fence-unwrap.h 088aa14c0f5cad Christian König 2022-03-11 33 088aa14c0f5cad Christian König 2022-03-11 34 /** 088aa14c0f5cad Christian König 2022-03-11 35 * dma_fence_unwrap_array - helper to unwrap dma_fence_arrays 088aa14c0f5cad Christian König 2022-03-11 36 * @cursor: cursor to initialize 088aa14c0f5cad Christian König 2022-03-11 37 * 088aa14c0f5cad Christian König 2022-03-11 38 * Helper function to unwrap dma_fence_array containers, don't touch directly. 088aa14c0f5cad Christian König 2022-03-11 39 * Use dma_fence_unwrap_first/next instead. 088aa14c0f5cad Christian König 2022-03-11 40 */ 088aa14c
Re: [PATCH 5/6] drm/rcar_du: use drm_encoder pointer for drm_writeback_connector
Hi Laurent On 3/10/2022 11:28 PM, Laurent Pinchart wrote: Hi Abhinav Thank you for the patch. On Thu, Mar 10, 2022 at 05:49:59PM -0800, Abhinav Kumar wrote: Make changes to rcar_du driver to start using drm_encoder pointer for drm_writeback_connector. Co-developed-by: Kandpal Suraj Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/rcar-du/rcar_du_writeback.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_writeback.c b/drivers/gpu/drm/rcar-du/rcar_du_writeback.c index c79d125..03930ad 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_writeback.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_writeback.c @@ -200,7 +200,8 @@ int rcar_du_writeback_init(struct rcar_du_device *rcdu, { struct drm_writeback_connector *wb_conn = &rcrtc->writeback; - wb_conn->encoder.possible_crtcs = 1 << drm_crtc_index(&rcrtc->crtc); + wb_conn->encoder = kzalloc(sizeof(struct drm_encoder), GFP_KERNEL); Where is this freed ? You are right, this isnt. Looking more into this, it seems like moving the allocation of encoder to drm_writeback.c for cases which dont pass a real encoder is much better so that I will not have to add alloc() / free() code for all the vendor driver changes which is what I originally thought in my RFC but changed my mind because of below. + wb_conn->encoder->possible_crtcs = 1 << drm_crtc_index(&rcrtc->crtc); Do you think we can just move usage of wb_conn->encoder->possible_crtcs just right after drm_writeback_connector_init() so that it wont crash? 198 int rcar_du_writeback_init(struct rcar_du_device *rcdu, 199struct rcar_du_crtc *rcrtc) 200 { 201 struct drm_writeback_connector *wb_conn = &rcrtc->writeback; 202 203 wb_conn->encoder.possible_crtcs = 1 << drm_crtc_index(&rcrtc->crtc); 204 drm_connector_helper_add(&wb_conn->base, 205 &rcar_du_wb_conn_helper_funcs); 206 207 return drm_writeback_connector_init(&rcdu->ddev, wb_conn, 208 &rcar_du_wb_conn_funcs, 209 &rcar_du_wb_enc_helper_funcs, 210 writeback_formats, 211 ARRAY_SIZE(writeback_formats)); 212 } drm_connector_helper_add(&wb_conn->base, &rcar_du_wb_conn_helper_funcs);
Re: [PATCH 1/2] dma-buf: add dma_fence_unwrap
Hi "Christian, I love your patch! Perhaps something to improve: [auto build test WARNING on linus/master] [also build test WARNING on v5.17-rc7 next-20220310] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Christian-K-nig/dma-buf-add-dma_fence_unwrap/20220311-190352 base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 79b00034e9dcd2b065c1665c8b42f62b6b80a9be config: hexagon-randconfig-r045-20220310 (https://download.01.org/0day-ci/archive/20220312/202203120114.jpyqmshc-...@intel.com/config) compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project 276ca87382b8f16a65bddac700202924228982f6) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/088aa14c0f5cad378854823fa661ee145dd2c01b git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Christian-K-nig/dma-buf-add-dma_fence_unwrap/20220311-190352 git checkout 088aa14c0f5cad378854823fa661ee145dd2c01b # save the config file to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=hexagon SHELL=/bin/bash drivers/dma-buf/ If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): In file included from drivers/dma-buf/st-dma-fence-unwrap.c:7: include/linux/dma-fence-unwrap.h:44:18: error: implicit declaration of function 'dma_fence_chain_contained' [-Werror,-Wimplicit-function-declaration] cursor->array = dma_fence_chain_contained(cursor->chain); ^ include/linux/dma-fence-unwrap.h:44:18: note: did you mean 'dma_fence_chain_init'? include/linux/dma-fence-chain.h:108:6: note: 'dma_fence_chain_init' declared here void dma_fence_chain_init(struct dma_fence_chain *chain, ^ In file included from drivers/dma-buf/st-dma-fence-unwrap.c:7: >> include/linux/dma-fence-unwrap.h:44:16: warning: incompatible integer to >> pointer conversion assigning to 'struct dma_fence *' from 'int' >> [-Wint-conversion] cursor->array = dma_fence_chain_contained(cursor->chain); ^ include/linux/dma-fence-unwrap.h:46:9: error: implicit declaration of function 'dma_fence_array_first' [-Werror,-Wimplicit-function-declaration] return dma_fence_array_first(cursor->array); ^ include/linux/dma-fence-unwrap.h:46:9: note: did you mean 'dma_fence_array_create'? include/linux/dma-fence-array.h:77:25: note: 'dma_fence_array_create' declared here struct dma_fence_array *dma_fence_array_create(int num_fences, ^ In file included from drivers/dma-buf/st-dma-fence-unwrap.c:7: >> include/linux/dma-fence-unwrap.h:46:9: warning: incompatible integer to >> pointer conversion returning 'int' from a function with result type 'struct >> dma_fence *' [-Wint-conversion] return dma_fence_array_first(cursor->array); ^~~~ include/linux/dma-fence-unwrap.h:77:8: error: implicit declaration of function 'dma_fence_array_next' [-Werror,-Wimplicit-function-declaration] tmp = dma_fence_array_next(cursor->array, cursor->index); ^ include/linux/dma-fence-unwrap.h:77:6: warning: incompatible integer to pointer conversion assigning to 'struct dma_fence *' from 'int' [-Wint-conversion] tmp = dma_fence_array_next(cursor->array, cursor->index); ^ ~~ >> drivers/dma-buf/st-dma-fence-unwrap.c:133:6: warning: variable 'err' set but >> not used [-Wunused-but-set-variable] int err = 0; ^ drivers/dma-buf/st-dma-fence-unwrap.c:175:6: warning: variable 'err' set but not used [-Wunused-but-set-variable] int err = 0; ^ drivers/dma-buf/st-dma-fence-unwrap.c:217:6: warning: variable 'err' set but not used [-Wunused-but-set-variable] int err = 0; ^ 6 warnings and 3 errors generated. vim +44 include/linux/dma-fence-unwrap.h 33 34 /** 35 * dma_fence_unwrap_array - helper to unwrap dma_fence_arrays 36 * @cursor: cursor to initialize 37 * 38 * Helper function to unwrap d
Re: [PATCH 1/6] drm: allow real encoder to be passed for drm_writeback_connector
Hi Dmitry and Laurent On 3/11/2022 12:05 AM, Laurent Pinchart wrote: On Fri, Mar 11, 2022 at 10:46:13AM +0300, Dmitry Baryshkov wrote: On Fri, 11 Mar 2022 at 04:50, Abhinav Kumar wrote: For some vendor driver implementations, display hardware can be shared between the encoder used for writeback and the physical display. In addition resources such as clocks and interrupts can also be shared between writeback and the real encoder. To accommodate such vendor drivers and hardware, allow real encoder to be passed for drm_writeback_connector. Co-developed-by: Kandpal Suraj Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/drm_writeback.c | 8 include/drm/drm_writeback.h | 13 +++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/drm_writeback.c b/drivers/gpu/drm/drm_writeback.c index dccf4504..4dad687 100644 --- a/drivers/gpu/drm/drm_writeback.c +++ b/drivers/gpu/drm/drm_writeback.c @@ -189,8 +189,8 @@ int drm_writeback_connector_init(struct drm_device *dev, if (IS_ERR(blob)) return PTR_ERR(blob); - drm_encoder_helper_add(&wb_connector->encoder, enc_helper_funcs); - ret = drm_encoder_init(dev, &wb_connector->encoder, + drm_encoder_helper_add(wb_connector->encoder, enc_helper_funcs); + ret = drm_encoder_init(dev, wb_connector->encoder, &drm_writeback_encoder_funcs, DRM_MODE_ENCODER_VIRTUAL, NULL); If the encoder is provided by a separate driver, it might use a different set of encoder funcs. More than that, if the encoder is provided externally but doesn't have custom operations, I don't really see the point of having an external encoder in the first place. Has this series been tested with a driver that needs to provide an encoder, to make sure it fits the purpose ? Yes, I have tested this with the MSM driver which provides an encoder and yes it absolutely fits the purpose. I'd suggest checking whether the wb_connector->encoder is NULL here. If it is, allocate one using drmm_kzalloc and init it. If it is not NULL, assume that it has been initialized already, so skip the drm_encoder_init() and just call the drm_encoder_helper_add() You are both right. We can skip the drm_encoder_init for drivers which have already provided an encoder. The only issue I was facing with that is some of the drivers for example the below one, access the "wb_conn->encoder.possible_crtcs" before the call to drm_writeback_connector_init(). 198 int rcar_du_writeback_init(struct rcar_du_device *rcdu, 199struct rcar_du_crtc *rcrtc) 200 { 201 struct drm_writeback_connector *wb_conn = &rcrtc->writeback; 202 203 wb_conn->encoder.possible_crtcs = 1 << drm_crtc_index(&rcrtc->crtc); 204 drm_connector_helper_add(&wb_conn->base, 205 &rcar_du_wb_conn_helper_funcs); 206 207 return drm_writeback_connector_init(&rcdu->ddev, wb_conn, 208 &rcar_du_wb_conn_funcs, 209 &rcar_du_wb_enc_helper_funcs, 210 writeback_formats, 211 ARRAY_SIZE(writeback_formats)); If we allocate the encoder within drm_writeback_connector_init(), do you suggest I modify the drivers to move the usage of possible_crtcs after the drm_writeback_connector_init() call to avoid NULL ptr crash? if (ret) @@ -204,7 +204,7 @@ int drm_writeback_connector_init(struct drm_device *dev, goto connector_fail; ret = drm_connector_attach_encoder(connector, - &wb_connector->encoder); + wb_connector->encoder); if (ret) goto attach_fail; @@ -233,7 +233,7 @@ int drm_writeback_connector_init(struct drm_device *dev, attach_fail: drm_connector_cleanup(connector); connector_fail: - drm_encoder_cleanup(&wb_connector->encoder); + drm_encoder_cleanup(wb_connector->encoder); fail: drm_property_blob_put(blob); return ret; diff --git a/include/drm/drm_writeback.h b/include/drm/drm_writeback.h index 9697d27..0ba266e 100644 --- a/include/drm/drm_writeback.h +++ b/include/drm/drm_writeback.h @@ -25,13 +25,22 @@ struct drm_writeback_connector { struct drm_connector base; /** -* @encoder: Internal encoder used by the connector to fulfill +* @encoder: handle to drm_encoder used by the connector to fulfill * the DRM framework requirements. The users of the * @drm_writeback_connector control the behaviour of the @encoder * by passing the @enc_funcs parameter to drm_writeback_connector_init() * function. +* +* For some vendor drivers, the hardware resources are shared between +* writeback encoder a
Re: [PATCH v1 1/3] mm: split vm_normal_pages for LRU and non-LRU handling
On 2022-03-11 04:16, David Hildenbrand wrote: On 10.03.22 18:26, Alex Sierra wrote: DEVICE_COHERENT pages introduce a subtle distinction in the way "normal" pages can be used by various callers throughout the kernel. They behave like normal pages for purposes of mapping in CPU page tables, and for COW. But they do not support LRU lists, NUMA migration or THP. Therefore we split vm_normal_page into two functions vm_normal_any_page and vm_normal_lru_page. The latter will only return pages that can be put on an LRU list and that support NUMA migration, KSM and THP. We also introduced a FOLL_LRU flag that adds the same behaviour to follow_page and related APIs, to allow callers to specify that they expect to put pages on an LRU list. I still don't see the need for s/vm_normal_page/vm_normal_any_page/. And as this patch is dominated by that change, I'd suggest (again) to just drop it as I don't see any value of that renaming. No specifier implies any. OK. If nobody objects, we can adopts that naming convention. The general idea of this change LGTM. I wonder how this interacts with the actual DEVICE_COHERENT coherent series. Is this a preparation? Should it be part of the DEVICE_COHERENT series? Yes, it should be part of that series. Alex developed it on top of the series for now. But I think eventually it would need to be spliced into it. Patch1 would need to go somewhere before the other DEVICE_COHERENT patches (with minor modifications). Patch 2 could be squashed into "tools: add hmm gup test for long term pinned device pages" or go next to it. Patch 3 doesn't have a direct dependency on device-coherent pages. It only mentions them in comments. IOW, should this patch start with "With DEVICE_COHERENT, we'll soon have vm_normal_pages() return device-managed anonymous pages that are not LRU pages. Although they behave like normal pages for purposes of mapping in CPU page, and for COW, they do not support LRU lists, NUMA migration or THP. [...]" Yes, that makes sense. Regards, Felix But then, I'm confused by patch 2 and 3, because it feels more like we'd already have DEVICE_COHERENT then ("hmm_is_coherent_type").
[PATCH v2 3/7] drm: mxsfb: Wrap FIFO reset and comments into mxsfb_reset_block()
Wrap FIFO reset and comments into mxsfb_reset_block(), this is a clean up. No functional change. Signed-off-by: Marek Vasut Cc: Alexander Stein Cc: Laurent Pinchart Cc: Lucas Stach Cc: Peng Fan Cc: Robby Cai Cc: Sam Ravnborg Cc: Stefan Agner --- V2: No change --- drivers/gpu/drm/mxsfb/mxsfb_kms.c | 36 +-- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/mxsfb/mxsfb_kms.c b/drivers/gpu/drm/mxsfb/mxsfb_kms.c index 657b6afbbf1f9..015b289d93a3c 100644 --- a/drivers/gpu/drm/mxsfb/mxsfb_kms.c +++ b/drivers/gpu/drm/mxsfb/mxsfb_kms.c @@ -183,6 +183,12 @@ static int mxsfb_reset_block(struct mxsfb_drm_private *mxsfb) { int ret; + /* +* It seems, you can't re-program the controller if it is still +* running. This may lead to shifted pictures (FIFO issue?), so +* first stop the controller and drain its FIFOs. +*/ + ret = clear_poll_bit(mxsfb->base + LCDC_CTRL, CTRL_SFTRST); if (ret) return ret; @@ -193,7 +199,20 @@ static int mxsfb_reset_block(struct mxsfb_drm_private *mxsfb) if (ret) return ret; - return clear_poll_bit(mxsfb->base + LCDC_CTRL, CTRL_CLKGATE); + ret = clear_poll_bit(mxsfb->base + LCDC_CTRL, CTRL_CLKGATE); + if (ret) + return ret; + + /* Clear the FIFOs */ + writel(CTRL1_FIFO_CLEAR, mxsfb->base + LCDC_CTRL1 + REG_SET); + readl(mxsfb->base + LCDC_CTRL1); + writel(CTRL1_FIFO_CLEAR, mxsfb->base + LCDC_CTRL1 + REG_CLR); + readl(mxsfb->base + LCDC_CTRL1); + + if (mxsfb->devdata->has_overlay) + writel(0, mxsfb->base + LCDC_AS_CTRL); + + return 0; } static dma_addr_t mxsfb_get_fb_paddr(struct drm_plane *plane) @@ -220,26 +239,11 @@ static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb, u32 vdctrl0, vsync_pulse_len, hsync_pulse_len; int err; - /* -* It seems, you can't re-program the controller if it is still -* running. This may lead to shifted pictures (FIFO issue?), so -* first stop the controller and drain its FIFOs. -*/ - /* Mandatory eLCDIF reset as per the Reference Manual */ err = mxsfb_reset_block(mxsfb); if (err) return; - /* Clear the FIFOs */ - writel(CTRL1_FIFO_CLEAR, mxsfb->base + LCDC_CTRL1 + REG_SET); - readl(mxsfb->base + LCDC_CTRL1); - writel(CTRL1_FIFO_CLEAR, mxsfb->base + LCDC_CTRL1 + REG_CLR); - readl(mxsfb->base + LCDC_CTRL1); - - if (mxsfb->devdata->has_overlay) - writel(0, mxsfb->base + LCDC_AS_CTRL); - mxsfb_set_formats(mxsfb, bus_format); if (mxsfb->bridge && mxsfb->bridge->timings) -- 2.34.1
[PATCH v2 5/7] drm: mxsfb: Factor out mxsfb_set_mode()
Pull mode registers programming from mxsfb_enable_controller() into dedicated function mxsfb_set_mode(). This is a clean up. No functional change. Signed-off-by: Marek Vasut Cc: Alexander Stein Cc: Laurent Pinchart Cc: Lucas Stach Cc: Peng Fan Cc: Robby Cai Cc: Sam Ravnborg Cc: Stefan Agner --- V2: No change --- drivers/gpu/drm/mxsfb/mxsfb_kms.c | 96 +-- 1 file changed, 52 insertions(+), 44 deletions(-) diff --git a/drivers/gpu/drm/mxsfb/mxsfb_kms.c b/drivers/gpu/drm/mxsfb/mxsfb_kms.c index 7b0abd0472aae..14f5cc590a51b 100644 --- a/drivers/gpu/drm/mxsfb/mxsfb_kms.c +++ b/drivers/gpu/drm/mxsfb/mxsfb_kms.c @@ -111,6 +111,57 @@ static void mxsfb_set_formats(struct mxsfb_drm_private *mxsfb, writel(ctrl, mxsfb->base + LCDC_CTRL); } +static void mxsfb_set_mode(struct mxsfb_drm_private *mxsfb, u32 bus_flags) +{ + struct drm_display_mode *m = &mxsfb->crtc.state->adjusted_mode; + u32 vdctrl0, vsync_pulse_len, hsync_pulse_len; + + writel(TRANSFER_COUNT_SET_VCOUNT(m->crtc_vdisplay) | + TRANSFER_COUNT_SET_HCOUNT(m->crtc_hdisplay), + mxsfb->base + mxsfb->devdata->transfer_count); + + vsync_pulse_len = m->crtc_vsync_end - m->crtc_vsync_start; + + vdctrl0 = VDCTRL0_ENABLE_PRESENT | /* Always in DOTCLOCK mode */ + VDCTRL0_VSYNC_PERIOD_UNIT | + VDCTRL0_VSYNC_PULSE_WIDTH_UNIT | + VDCTRL0_SET_VSYNC_PULSE_WIDTH(vsync_pulse_len); + if (m->flags & DRM_MODE_FLAG_PHSYNC) + vdctrl0 |= VDCTRL0_HSYNC_ACT_HIGH; + if (m->flags & DRM_MODE_FLAG_PVSYNC) + vdctrl0 |= VDCTRL0_VSYNC_ACT_HIGH; + /* Make sure Data Enable is high active by default */ + if (!(bus_flags & DRM_BUS_FLAG_DE_LOW)) + vdctrl0 |= VDCTRL0_ENABLE_ACT_HIGH; + /* +* DRM_BUS_FLAG_PIXDATA_DRIVE_ defines are controller centric, +* controllers VDCTRL0_DOTCLK is display centric. +* Drive on positive edge -> display samples on falling edge +* DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE -> VDCTRL0_DOTCLK_ACT_FALLING +*/ + if (bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE) + vdctrl0 |= VDCTRL0_DOTCLK_ACT_FALLING; + + writel(vdctrl0, mxsfb->base + LCDC_VDCTRL0); + + /* Frame length in lines. */ + writel(m->crtc_vtotal, mxsfb->base + LCDC_VDCTRL1); + + /* Line length in units of clocks or pixels. */ + hsync_pulse_len = m->crtc_hsync_end - m->crtc_hsync_start; + writel(set_hsync_pulse_width(mxsfb, hsync_pulse_len) | + VDCTRL2_SET_HSYNC_PERIOD(m->crtc_htotal), + mxsfb->base + LCDC_VDCTRL2); + + writel(SET_HOR_WAIT_CNT(m->crtc_htotal - m->crtc_hsync_start) | + SET_VERT_WAIT_CNT(m->crtc_vtotal - m->crtc_vsync_start), + mxsfb->base + LCDC_VDCTRL3); + + writel(SET_DOTCLK_H_VALID_DATA_CNT(m->hdisplay), + mxsfb->base + LCDC_VDCTRL4); + +} + static void mxsfb_enable_controller(struct mxsfb_drm_private *mxsfb) { u32 reg; @@ -236,7 +287,6 @@ static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb, struct drm_device *drm = mxsfb->crtc.dev; struct drm_display_mode *m = &mxsfb->crtc.state->adjusted_mode; u32 bus_flags = mxsfb->connector->display_info.bus_flags; - u32 vdctrl0, vsync_pulse_len, hsync_pulse_len; int err; /* Mandatory eLCDIF reset as per the Reference Manual */ @@ -256,49 +306,7 @@ static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb, bus_flags); DRM_DEV_DEBUG_DRIVER(drm->dev, "Mode flags: 0x%08X\n", m->flags); - writel(TRANSFER_COUNT_SET_VCOUNT(m->crtc_vdisplay) | - TRANSFER_COUNT_SET_HCOUNT(m->crtc_hdisplay), - mxsfb->base + mxsfb->devdata->transfer_count); - - vsync_pulse_len = m->crtc_vsync_end - m->crtc_vsync_start; - - vdctrl0 = VDCTRL0_ENABLE_PRESENT | /* Always in DOTCLOCK mode */ - VDCTRL0_VSYNC_PERIOD_UNIT | - VDCTRL0_VSYNC_PULSE_WIDTH_UNIT | - VDCTRL0_SET_VSYNC_PULSE_WIDTH(vsync_pulse_len); - if (m->flags & DRM_MODE_FLAG_PHSYNC) - vdctrl0 |= VDCTRL0_HSYNC_ACT_HIGH; - if (m->flags & DRM_MODE_FLAG_PVSYNC) - vdctrl0 |= VDCTRL0_VSYNC_ACT_HIGH; - /* Make sure Data Enable is high active by default */ - if (!(bus_flags & DRM_BUS_FLAG_DE_LOW)) - vdctrl0 |= VDCTRL0_ENABLE_ACT_HIGH; - /* -* DRM_BUS_FLAG_PIXDATA_DRIVE_ defines are controller centric, -* controllers VDCTRL0_DOTCLK is display centric. -* Drive on positive edge -> display samples on falling edge -* DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE -> VDCTRL0_DOTCLK_ACT_FALLING -*/ - if (bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE) - vdctrl0 |= VDCTRL0_DOTCLK_ACT_FALLING; - -
[PATCH v2 7/7] drm: mxsfb: Factor out mxsfb_update_buffer()
Pull functionality responsible for programming framebuffer address into the controller into dedicated function mxsfb_update_buffer(). This is a clean up. No functional change. Signed-off-by: Marek Vasut Cc: Alexander Stein Cc: Laurent Pinchart Cc: Lucas Stach Cc: Peng Fan Cc: Robby Cai Cc: Sam Ravnborg Cc: Stefan Agner --- V2: No change --- drivers/gpu/drm/mxsfb/mxsfb_kms.c | 28 ++-- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/mxsfb/mxsfb_kms.c b/drivers/gpu/drm/mxsfb/mxsfb_kms.c index 497603964add8..4baa3db1f3d10 100644 --- a/drivers/gpu/drm/mxsfb/mxsfb_kms.c +++ b/drivers/gpu/drm/mxsfb/mxsfb_kms.c @@ -58,6 +58,22 @@ static dma_addr_t mxsfb_get_fb_paddr(struct drm_plane *plane) return gem->paddr; } +static void +mxsfb_update_buffer(struct mxsfb_drm_private *mxsfb, struct drm_plane *plane, + bool both) +{ + dma_addr_t paddr; + + paddr = mxsfb_get_fb_paddr(plane); + if (!paddr) + return; + + if (both) + writel(paddr, mxsfb->base + mxsfb->devdata->cur_buf); + + writel(paddr, mxsfb->base + mxsfb->devdata->next_buf); +} + /* * Setup the MXSFB registers for decoding the pixels out of the framebuffer and * outputting them on the bus. @@ -352,7 +368,6 @@ static void mxsfb_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_bridge_state *bridge_state; struct drm_device *drm = mxsfb->drm; u32 bus_format = 0; - dma_addr_t paddr; /* If there is a bridge attached to the LCDIF, use its bus format */ if (mxsfb->bridge) { @@ -387,11 +402,7 @@ static void mxsfb_crtc_atomic_enable(struct drm_crtc *crtc, mxsfb_crtc_mode_set_nofb(mxsfb, bus_format); /* Write cur_buf as well to avoid an initial corrupt frame */ - paddr = mxsfb_get_fb_paddr(crtc->primary); - if (paddr) { - writel(paddr, mxsfb->base + mxsfb->devdata->cur_buf); - writel(paddr, mxsfb->base + mxsfb->devdata->next_buf); - } + mxsfb_update_buffer(mxsfb, crtc->primary, true); mxsfb_enable_controller(mxsfb); @@ -491,11 +502,8 @@ static void mxsfb_plane_primary_atomic_update(struct drm_plane *plane, struct drm_atomic_state *state) { struct mxsfb_drm_private *mxsfb = to_mxsfb_drm_private(plane->dev); - dma_addr_t paddr; - paddr = mxsfb_get_fb_paddr(plane); - if (paddr) - writel(paddr, mxsfb->base + mxsfb->devdata->next_buf); + mxsfb_update_buffer(mxsfb, plane, false); } static void mxsfb_plane_overlay_atomic_update(struct drm_plane *plane, -- 2.34.1
[PATCH v2 4/7] drm: mxsfb: Move mxsfb_get_fb_paddr() away from register IO functions
Move mxsfb_get_fb_paddr() out of the way, away from register IO functions. This is a clean up. No functional change. Signed-off-by: Marek Vasut Cc: Alexander Stein Cc: Laurent Pinchart Cc: Lucas Stach Cc: Peng Fan Cc: Robby Cai Cc: Sam Ravnborg Cc: Stefan Agner --- V2: No change --- drivers/gpu/drm/mxsfb/mxsfb_kms.c | 30 +++--- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/mxsfb/mxsfb_kms.c b/drivers/gpu/drm/mxsfb/mxsfb_kms.c index 015b289d93a3c..7b0abd0472aae 100644 --- a/drivers/gpu/drm/mxsfb/mxsfb_kms.c +++ b/drivers/gpu/drm/mxsfb/mxsfb_kms.c @@ -43,6 +43,21 @@ static u32 set_hsync_pulse_width(struct mxsfb_drm_private *mxsfb, u32 val) mxsfb->devdata->hs_wdth_shift; } +static dma_addr_t mxsfb_get_fb_paddr(struct drm_plane *plane) +{ + struct drm_framebuffer *fb = plane->state->fb; + struct drm_gem_cma_object *gem; + + if (!fb) + return 0; + + gem = drm_fb_cma_get_gem_obj(fb, 0); + if (!gem) + return 0; + + return gem->paddr; +} + /* * Setup the MXSFB registers for decoding the pixels out of the framebuffer and * outputting them on the bus. @@ -215,21 +230,6 @@ static int mxsfb_reset_block(struct mxsfb_drm_private *mxsfb) return 0; } -static dma_addr_t mxsfb_get_fb_paddr(struct drm_plane *plane) -{ - struct drm_framebuffer *fb = plane->state->fb; - struct drm_gem_cma_object *gem; - - if (!fb) - return 0; - - gem = drm_fb_cma_get_gem_obj(fb, 0); - if (!gem) - return 0; - - return gem->paddr; -} - static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb, const u32 bus_format) { -- 2.34.1
[PATCH v2 6/7] drm: mxsfb: Reorder mxsfb_crtc_mode_set_nofb()
Reorder mxsfb_crtc_mode_set_nofb() such that all functions which perform register IO are called from one single location in this function. This is a clean up. No functional change. Signed-off-by: Marek Vasut Cc: Alexander Stein Cc: Laurent Pinchart Cc: Lucas Stach Cc: Peng Fan Cc: Robby Cai Cc: Sam Ravnborg Cc: Stefan Agner --- V2: No change --- drivers/gpu/drm/mxsfb/mxsfb_kms.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/mxsfb/mxsfb_kms.c b/drivers/gpu/drm/mxsfb/mxsfb_kms.c index 14f5cc590a51b..497603964add8 100644 --- a/drivers/gpu/drm/mxsfb/mxsfb_kms.c +++ b/drivers/gpu/drm/mxsfb/mxsfb_kms.c @@ -289,13 +289,6 @@ static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb, u32 bus_flags = mxsfb->connector->display_info.bus_flags; int err; - /* Mandatory eLCDIF reset as per the Reference Manual */ - err = mxsfb_reset_block(mxsfb); - if (err) - return; - - mxsfb_set_formats(mxsfb, bus_format); - if (mxsfb->bridge && mxsfb->bridge->timings) bus_flags = mxsfb->bridge->timings->input_bus_flags; @@ -306,6 +299,13 @@ static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb, bus_flags); DRM_DEV_DEBUG_DRIVER(drm->dev, "Mode flags: 0x%08X\n", m->flags); + /* Mandatory eLCDIF reset as per the Reference Manual */ + err = mxsfb_reset_block(mxsfb); + if (err) + return; + + mxsfb_set_formats(mxsfb, bus_format); + mxsfb_set_mode(mxsfb, bus_flags); } -- 2.34.1
[PATCH v2 1/7] drm: mxsfb: Simplify LCDIF clock handling
The current clock handling in the LCDIF driver is a convoluted mess. Implement runtime PM ops which turn the clock ON and OFF and let the pm_runtime_get_sync()/pm_runtime_put_sync() calls in .atomic_enable and .atomic_disable callbacks turn the clock ON and OFF at the right time. This requires slight reordering in mxsfb_crtc_atomic_enable() and mxsfb_crtc_atomic_disable(), since all the register accesses must happen only with clock enabled and clock frequency configuration must happen with clock disabled. Signed-off-by: Marek Vasut Cc: Alexander Stein Cc: Laurent Pinchart Cc: Lucas Stach Cc: Peng Fan Cc: Robby Cai Cc: Sam Ravnborg Cc: Stefan Agner --- V2: No change --- drivers/gpu/drm/mxsfb/mxsfb_drv.c | 104 +- drivers/gpu/drm/mxsfb/mxsfb_kms.c | 27 +++- 2 files changed, 67 insertions(+), 64 deletions(-) diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsfb_drv.c index 9d71c55a31c07..c790aeff0a6f0 100644 --- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c +++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c @@ -73,18 +73,6 @@ static const struct mxsfb_devdata mxsfb_devdata[] = { }, }; -void mxsfb_enable_axi_clk(struct mxsfb_drm_private *mxsfb) -{ - if (mxsfb->clk_axi) - clk_prepare_enable(mxsfb->clk_axi); -} - -void mxsfb_disable_axi_clk(struct mxsfb_drm_private *mxsfb) -{ - if (mxsfb->clk_axi) - clk_disable_unprepare(mxsfb->clk_axi); -} - static struct drm_framebuffer * mxsfb_fb_create(struct drm_device *dev, struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd) @@ -173,13 +161,9 @@ static void mxsfb_irq_disable(struct drm_device *drm) { struct mxsfb_drm_private *mxsfb = drm->dev_private; - mxsfb_enable_axi_clk(mxsfb); - /* Disable and clear VBLANK IRQ */ writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, mxsfb->base + LCDC_CTRL1 + REG_CLR); writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR); - - mxsfb_disable_axi_clk(mxsfb); } static int mxsfb_irq_install(struct drm_device *dev, int irq) @@ -225,43 +209,41 @@ static int mxsfb_load(struct drm_device *drm, if (IS_ERR(mxsfb->clk)) return PTR_ERR(mxsfb->clk); - mxsfb->clk_axi = devm_clk_get(drm->dev, "axi"); + mxsfb->clk_axi = devm_clk_get_optional(drm->dev, "axi"); if (IS_ERR(mxsfb->clk_axi)) - mxsfb->clk_axi = NULL; + return PTR_ERR(mxsfb->clk_axi); - mxsfb->clk_disp_axi = devm_clk_get(drm->dev, "disp_axi"); + mxsfb->clk_disp_axi = devm_clk_get_optional(drm->dev, "disp_axi"); if (IS_ERR(mxsfb->clk_disp_axi)) - mxsfb->clk_disp_axi = NULL; + return PTR_ERR(mxsfb->clk_disp_axi); + + platform_set_drvdata(pdev, drm); ret = dma_set_mask_and_coherent(drm->dev, DMA_BIT_MASK(32)); if (ret) return ret; - pm_runtime_enable(drm->dev); - /* Modeset init */ drm_mode_config_init(drm); ret = mxsfb_kms_init(mxsfb); if (ret < 0) { dev_err(drm->dev, "Failed to initialize KMS pipeline\n"); - goto err_vblank; + return ret; } ret = drm_vblank_init(drm, drm->mode_config.num_crtc); if (ret < 0) { dev_err(drm->dev, "Failed to initialise vblank\n"); - goto err_vblank; + return ret; } /* Start with vertical blanking interrupt reporting disabled. */ drm_crtc_vblank_off(&mxsfb->crtc); ret = mxsfb_attach_bridge(mxsfb); - if (ret) { - dev_err_probe(drm->dev, ret, "Cannot connect bridge\n"); - goto err_vblank; - } + if (ret) + return dev_err_probe(drm->dev, ret, "Cannot connect bridge\n"); drm->mode_config.min_width = MXSFB_MIN_XRES; drm->mode_config.min_height = MXSFB_MIN_YRES; @@ -274,44 +256,37 @@ static int mxsfb_load(struct drm_device *drm, ret = platform_get_irq(pdev, 0); if (ret < 0) - goto err_vblank; + return ret; mxsfb->irq = ret; - pm_runtime_get_sync(drm->dev); ret = mxsfb_irq_install(drm, mxsfb->irq); - pm_runtime_put_sync(drm->dev); - if (ret < 0) { dev_err(drm->dev, "Failed to install IRQ handler\n"); - goto err_vblank; + return ret; } drm_kms_helper_poll_init(drm); - platform_set_drvdata(pdev, drm); - drm_helper_hpd_irq_event(drm); - return 0; - -err_vblank: - pm_runtime_disable(drm->dev); + pm_runtime_enable(drm->dev); - return ret; + return 0; } static void mxsfb_unload(struct drm_device *drm) { + pm_runtime_get_sync(drm->dev); + drm_kms_helper_poll_fini(drm); drm_mode_config_cleanup(drm); - pm_runtime_get_sync(drm->dev);
[PATCH v2 2/7] drm: mxsfb: Simplify LCDIF IRQ handling
The call to drm_crtc_vblank_off(&lcdif->crtc); disables IRQ generation from the LCDIF block already and this is called in mxsfb_load() before request_irq(), so explicitly disabling IRQ using custom function like mxsfb_irq_disable() is not needed, remove it. The request_irq() call would return -ENOTCONN if IRQ is IRQ_NOTCONNECTED already, so remove the unnecessary check. Finally, remove both mxsfb_irq_install() and mxsfb_irq_uninstall() as well, since they are no longer useful. Signed-off-by: Marek Vasut Cc: Alexander Stein Cc: Laurent Pinchart Cc: Lucas Stach Cc: Peng Fan Cc: Robby Cai Cc: Sam Ravnborg Cc: Stefan Agner --- V2: No change --- drivers/gpu/drm/mxsfb/mxsfb_drv.c | 38 +++ 1 file changed, 8 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsfb_drv.c index c790aeff0a6f0..94cafff7f68d5 100644 --- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c +++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c @@ -157,33 +157,6 @@ static irqreturn_t mxsfb_irq_handler(int irq, void *data) return IRQ_HANDLED; } -static void mxsfb_irq_disable(struct drm_device *drm) -{ - struct mxsfb_drm_private *mxsfb = drm->dev_private; - - /* Disable and clear VBLANK IRQ */ - writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, mxsfb->base + LCDC_CTRL1 + REG_CLR); - writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR); -} - -static int mxsfb_irq_install(struct drm_device *dev, int irq) -{ - if (irq == IRQ_NOTCONNECTED) - return -ENOTCONN; - - mxsfb_irq_disable(dev); - - return request_irq(irq, mxsfb_irq_handler, 0, dev->driver->name, dev); -} - -static void mxsfb_irq_uninstall(struct drm_device *dev) -{ - struct mxsfb_drm_private *mxsfb = dev->dev_private; - - mxsfb_irq_disable(dev); - free_irq(mxsfb->irq, dev); -} - static int mxsfb_load(struct drm_device *drm, const struct mxsfb_devdata *devdata) { @@ -259,7 +232,8 @@ static int mxsfb_load(struct drm_device *drm, return ret; mxsfb->irq = ret; - ret = mxsfb_irq_install(drm, mxsfb->irq); + ret = request_irq(mxsfb->irq, mxsfb_irq_handler, 0, + drm->driver->name, drm); if (ret < 0) { dev_err(drm->dev, "Failed to install IRQ handler\n"); return ret; @@ -276,16 +250,20 @@ static int mxsfb_load(struct drm_device *drm, static void mxsfb_unload(struct drm_device *drm) { + struct mxsfb_drm_private *mxsfb = drm->dev_private; + pm_runtime_get_sync(drm->dev); + drm_crtc_vblank_off(&mxsfb->crtc); + drm_kms_helper_poll_fini(drm); drm_mode_config_cleanup(drm); - mxsfb_irq_uninstall(drm); - pm_runtime_put_sync(drm->dev); pm_runtime_disable(drm->dev); + free_irq(mxsfb->irq, drm->dev); + drm->dev_private = NULL; } -- 2.34.1
[PATCH v4 4/4] dt-bindings: display/panel: Add Leadtek ltk035c5444t
Add binding for the leadtek ltk035c5444t, which is a 640x480 mipi-dbi over spi / 24-bit RGB panel based on the newvision NV03052C chipset. It is found in the Anbernic RG350M mips handheld. Signed-off-by: Christophe Branchereau --- .../display/panel/leadtek,ltk035c5444t.yaml | 59 +++ 1 file changed, 59 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/leadtek,ltk035c5444t.yaml diff --git a/Documentation/devicetree/bindings/display/panel/leadtek,ltk035c5444t.yaml b/Documentation/devicetree/bindings/display/panel/leadtek,ltk035c5444t.yaml new file mode 100644 index ..817a9bed7d5a --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/leadtek,ltk035c5444t.yaml @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/leadtek,ltk035c5444t.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Leadtek ltk035c5444t 3.5" (640x480 pixels) 24-bit IPS LCD panel + +maintainers: + - Paul Cercueil + - Christophe Branchereau + +allOf: + - $ref: panel-common.yaml# + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +properties: + compatible: +const: leadtek,ltk035c5444t + + backlight: true + port: true + power-supply: true + reg: true + reset-gpios: true + +required: + - compatible + - power-supply + - reset-gpios + +unevaluatedProperties: false + +examples: + - | +#include + +spi { +#address-cells = <1>; +#size-cells = <0>; +panel@0 { +compatible = "leadtek,ltk035c5444t"; +reg = <0>; + +spi-3wire; +spi-max-frequency = <3125000>; + +reset-gpios = <&gpe 2 GPIO_ACTIVE_LOW>; + +backlight = <&backlight>; +power-supply = <&vcc>; + +port { +panel_input: endpoint { +remote-endpoint = <&panel_output>; +}; +}; +}; +}; -- 2.35.1
[PATCH v4 3/4] drm/panel : innolux-ej030na and abt-y030xx067a : add .enable and .disable
Following the introduction of bridge_atomic_enable in the ingenic drm driver, the crtc is enabled between .prepare and .enable, if it exists. Add it so the backlight is only enabled after the crtc is, to avoid graphical issues. Signed-off-by: Christophe Branchereau --- drivers/gpu/drm/panel/panel-abt-y030xx067a.c | 23 -- drivers/gpu/drm/panel/panel-innolux-ej030na.c | 31 --- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-abt-y030xx067a.c b/drivers/gpu/drm/panel/panel-abt-y030xx067a.c index f043b484055b..b5736344e3ec 100644 --- a/drivers/gpu/drm/panel/panel-abt-y030xx067a.c +++ b/drivers/gpu/drm/panel/panel-abt-y030xx067a.c @@ -183,8 +183,6 @@ static int y030xx067a_prepare(struct drm_panel *panel) goto err_disable_regulator; } - msleep(120); - return 0; err_disable_regulator: @@ -202,6 +200,25 @@ static int y030xx067a_unprepare(struct drm_panel *panel) return 0; } +static int y030xx067a_enable(struct drm_panel *panel) +{ + if (panel->backlight) { + /* Wait for the picture to be ready before enabling backlight */ + msleep(120); + } + + return 0; +} + +static int y030xx067a_disable(struct drm_panel *panel) +{ + struct y030xx067a *priv = to_y030xx067a(panel); + + regmap_clear_bits(priv->map, 0x06, REG06_XPSAVE); + + return 0; +} + static int y030xx067a_get_modes(struct drm_panel *panel, struct drm_connector *connector) { @@ -239,6 +256,8 @@ static int y030xx067a_get_modes(struct drm_panel *panel, static const struct drm_panel_funcs y030xx067a_funcs = { .prepare= y030xx067a_prepare, .unprepare = y030xx067a_unprepare, + .enable = y030xx067a_enable, + .disable= y030xx067a_disable, .get_modes = y030xx067a_get_modes, }; diff --git a/drivers/gpu/drm/panel/panel-innolux-ej030na.c b/drivers/gpu/drm/panel/panel-innolux-ej030na.c index c558de3f99be..6de7370185cd 100644 --- a/drivers/gpu/drm/panel/panel-innolux-ej030na.c +++ b/drivers/gpu/drm/panel/panel-innolux-ej030na.c @@ -80,8 +80,6 @@ static const struct reg_sequence ej030na_init_sequence[] = { { 0x47, 0x08 }, { 0x48, 0x0f }, { 0x49, 0x0f }, - - { 0x2b, 0x01 }, }; static int ej030na_prepare(struct drm_panel *panel) @@ -109,8 +107,6 @@ static int ej030na_prepare(struct drm_panel *panel) goto err_disable_regulator; } - msleep(120); - return 0; err_disable_regulator: @@ -128,6 +124,31 @@ static int ej030na_unprepare(struct drm_panel *panel) return 0; } +static int ej030na_enable(struct drm_panel *panel) +{ + struct ej030na *priv = to_ej030na(panel); + + /* standby off */ + regmap_write(priv->map, 0x2b, 0x01); + + if (panel->backlight) { + /* Wait for the picture to be ready before enabling backlight */ + msleep(120); + } + + return 0; +} + +static int ej030na_disable(struct drm_panel *panel) +{ + struct ej030na *priv = to_ej030na(panel); + + /* standby on */ + regmap_write(priv->map, 0x2b, 0x00); + + return 0; +} + static int ej030na_get_modes(struct drm_panel *panel, struct drm_connector *connector) { @@ -165,6 +186,8 @@ static int ej030na_get_modes(struct drm_panel *panel, static const struct drm_panel_funcs ej030na_funcs = { .prepare= ej030na_prepare, .unprepare = ej030na_unprepare, + .enable = ej030na_enable, + .disable= ej030na_disable, .get_modes = ej030na_get_modes, }; -- 2.35.1
[PATCH v4 2/4] drm/panel: Add panel driver for NewVision NV3052C based LCDs
This driver supports the NewVision NV3052C based LCDs. Right now, it only supports the LeadTek LTK035C5444T 2.4" 640x480 TFT LCD panel, which can be found in the Anbernic RG-350M handheld console. Signed-off-by: Christophe Branchereau --- drivers/gpu/drm/panel/Kconfig | 9 + drivers/gpu/drm/panel/Makefile| 1 + .../gpu/drm/panel/panel-newvision-nv3052c.c | 497 ++ 3 files changed, 507 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-newvision-nv3052c.c diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index bb2e47229c68..40084f709789 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -283,6 +283,15 @@ config DRM_PANEL_NEC_NL8048HL11 panel (found on the Zoom2/3/3630 SDP boards). To compile this driver as a module, choose M here. +config DRM_PANEL_NEWVISION_NV3052C + tristate "NewVision NV3052C RGB/SPI panel" + depends on OF && SPI + depends on BACKLIGHT_CLASS_DEVICE + select DRM_MIPI_DBI + help + Say Y here if you want to enable support for the panels built + around the NewVision NV3052C display controller. + config DRM_PANEL_NOVATEK_NT35510 tristate "Novatek NT35510 RGB panel driver" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 5740911f637c..42a7ab54234b 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829) += panel-leadtek-ltk500hd1829.o obj-$(CONFIG_DRM_PANEL_LG_LB035Q02) += panel-lg-lb035q02.o obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o obj-$(CONFIG_DRM_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o +obj-$(CONFIG_DRM_PANEL_NEWVISION_NV3052C) += panel-newvision-nv3052c.o obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35510) += panel-novatek-nt35510.o obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35560) += panel-novatek-nt35560.o obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35950) += panel-novatek-nt35950.o diff --git a/drivers/gpu/drm/panel/panel-newvision-nv3052c.c b/drivers/gpu/drm/panel/panel-newvision-nv3052c.c new file mode 100644 index ..fc31df0dee12 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-newvision-nv3052c.c @@ -0,0 +1,497 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * NevVision NV3052C IPS LCD panel driver + * + * Copyright (C) 2020, Paul Cercueil + * Copyright (C) 2022, Christophe Branchereau + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +struct nv3052c_panel_info { + const struct drm_display_mode *display_modes; + unsigned int num_modes; + u16 width_mm, height_mm; + u32 bus_format, bus_flags; +}; + +struct nv3052c { + struct device *dev; + struct drm_panel panel; + struct mipi_dbi dbi; + + const struct nv3052c_panel_info *panel_info; + + struct regulator *supply; + struct gpio_desc *reset_gpio; +}; + +struct nv3052c_reg { + u8 cmd; + u8 val; +}; + +static const struct nv3052c_reg nv3052c_panel_regs[] = { + { 0xff, 0x30 }, + { 0xff, 0x52 }, + { 0xff, 0x01 }, + { 0xe3, 0x00 }, + { 0x40, 0x00 }, + { 0x03, 0x40 }, + { 0x04, 0x00 }, + { 0x05, 0x03 }, + { 0x08, 0x00 }, + { 0x09, 0x07 }, + { 0x0a, 0x01 }, + { 0x0b, 0x32 }, + { 0x0c, 0x32 }, + { 0x0d, 0x0b }, + { 0x0e, 0x00 }, + { 0x23, 0xa0 }, + + { 0x24, 0x0c }, + { 0x25, 0x06 }, + { 0x26, 0x14 }, + { 0x27, 0x14 }, + + { 0x38, 0xcc }, + { 0x39, 0xd7 }, + { 0x3a, 0x4a }, + + { 0x28, 0x40 }, + { 0x29, 0x01 }, + { 0x2a, 0xdf }, + { 0x49, 0x3c }, + { 0x91, 0x77 }, + { 0x92, 0x77 }, + { 0xa0, 0x55 }, + { 0xa1, 0x50 }, + { 0xa4, 0x9c }, + { 0xa7, 0x02 }, + { 0xa8, 0x01 }, + { 0xa9, 0x01 }, + { 0xaa, 0xfc }, + { 0xab, 0x28 }, + { 0xac, 0x06 }, + { 0xad, 0x06 }, + { 0xae, 0x06 }, + { 0xaf, 0x03 }, + { 0xb0, 0x08 }, + { 0xb1, 0x26 }, + { 0xb2, 0x28 }, + { 0xb3, 0x28 }, + { 0xb4, 0x33 }, + { 0xb5, 0x08 }, + { 0xb6, 0x26 }, + { 0xb7, 0x08 }, + { 0xb8, 0x26 }, + { 0xf0, 0x00 }, + { 0xf6, 0xc0 }, + + { 0xff, 0x30 }, + { 0xff, 0x52 }, + { 0xff, 0x02 }, + { 0xb0, 0x0b }, + { 0xb1, 0x16 }, + { 0xb2, 0x17 }, + { 0xb3, 0x2c }, + { 0xb4, 0x32 }, + { 0xb5, 0x3b }, + { 0xb6, 0x29 }, + { 0xb7, 0x40 }, + { 0xb8, 0x0d }, + { 0xb9, 0x05 }, + { 0xba, 0x12 }, + { 0xbb, 0x10 }, + { 0xbc, 0x12 }, + { 0xbd, 0x15 }, + { 0xbe, 0x19 }, + { 0xbf, 0x0e }, + { 0xc0, 0x16 }, + { 0xc1, 0x0a }, + { 0xd0, 0x0c }, + { 0xd1, 0x17 }
[PATCH v4 1/4] drm/ingenic : add ingenic_drm_bridge_atomic_enable
This allows the CRTC to be enabled after panels have slept out, and before their display is turned on, solving a graphical bug on the newvision nv3502c Signed-off-by: Christophe Branchereau --- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 19 +-- 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index dcf44cb00821..51512f41263e 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -226,6 +226,18 @@ static int ingenic_drm_update_pixclk(struct notifier_block *nb, } } +static void ingenic_drm_bridge_atomic_enable(struct drm_bridge *bridge, +struct drm_bridge_state *old_bridge_state) +{ + struct ingenic_drm *priv = drm_device_get_priv(bridge->dev); + + regmap_write(priv->map, JZ_REG_LCD_STATE, 0); + + regmap_update_bits(priv->map, JZ_REG_LCD_CTRL, + JZ_LCD_CTRL_ENABLE | JZ_LCD_CTRL_DISABLE, + JZ_LCD_CTRL_ENABLE); +} + static void ingenic_drm_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state) { @@ -237,17 +249,11 @@ static void ingenic_drm_crtc_atomic_enable(struct drm_crtc *crtc, if (WARN_ON(IS_ERR(priv_state))) return; - regmap_write(priv->map, JZ_REG_LCD_STATE, 0); - /* Set addresses of our DMA descriptor chains */ next_id = priv_state->use_palette ? HWDESC_PALETTE : 0; regmap_write(priv->map, JZ_REG_LCD_DA0, dma_hwdesc_addr(priv, next_id)); regmap_write(priv->map, JZ_REG_LCD_DA1, dma_hwdesc_addr(priv, 1)); - regmap_update_bits(priv->map, JZ_REG_LCD_CTRL, - JZ_LCD_CTRL_ENABLE | JZ_LCD_CTRL_DISABLE, - JZ_LCD_CTRL_ENABLE); - drm_crtc_vblank_on(crtc); } @@ -968,6 +974,7 @@ static const struct drm_encoder_helper_funcs ingenic_drm_encoder_helper_funcs = static const struct drm_bridge_funcs ingenic_drm_bridge_funcs = { .attach = ingenic_drm_bridge_attach, + .atomic_enable = ingenic_drm_bridge_atomic_enable, .atomic_check = ingenic_drm_bridge_atomic_check, .atomic_reset = drm_atomic_helper_bridge_reset, .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, -- 2.35.1
[PATCH v4 0/4] Ingenic DRM bridge_atomic_enable proposal
v4: fix the bindings license KR Christophe --- Hello, v3 : Drop -spi in the compatible string, adjust bindings doc accordingly KR Christophe Hello, this is the v2 for my set of patches : - use dev_err_probe() instead of dev_err() in the newvision panel driver probe function - add bindings documentation for the Leadtek ltk035c5444t Cheers - Christophe Hello, this is a set of patches to allow the upstreaming of the NV3052C panel found in the Anbernic RG350M mips gaming handheld. It was never upstreamed so far due to a longstanding graphical bug, which I propose to solve by introducing ingenic_drm_bridge_atomic_enable in the drm driver so the CRTC can be enabled after the panel itself slept out, and not before as it used to. After the drm change, 2 of the existing panels have to be modified accordingly to introduce missing .enable and .disable in their code. Christophe Branchereau (4): drm/ingenic : add ingenic_drm_bridge_atomic_enable drm/panel: Add panel driver for NewVision NV3052C based LCDs drm/panel : innolux-ej030na and abt-y030xx067a : add .enable and .disable dt-bindings: display/panel: Add Leadtek ltk035c5444t .../display/panel/leadtek,ltk035c5444t.yaml | 59 +++ drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 19 +- drivers/gpu/drm/panel/Kconfig | 9 + drivers/gpu/drm/panel/Makefile| 1 + drivers/gpu/drm/panel/panel-abt-y030xx067a.c | 23 +- drivers/gpu/drm/panel/panel-innolux-ej030na.c | 31 +- .../gpu/drm/panel/panel-newvision-nv3052c.c | 497 ++ 7 files changed, 627 insertions(+), 12 deletions(-) create mode 100644 Documentation/devicetree/bindings/display/panel/leadtek,ltk035c5444t.yaml create mode 100644 drivers/gpu/drm/panel/panel-newvision-nv3052c.c -- 2.35.1
Re: [PATCH v3 4/4] dt-bindings: display/panel: Add Leadtek ltk035c5444t
Hi Rob, Sorry something I can't explain happened with git rebase v4 on its way On Fri, Mar 11, 2022 at 3:59 PM Rob Herring wrote: > > On Fri, Mar 11, 2022 at 01:04:53PM +0100, Christophe Branchereau wrote: > > Add binding for the leadtek ltk035c5444t, which is a 640x480 > > mipi-dbi over spi / 24-bit RGB panel based on the newvision > > NV03052C chipset. > > > > It is found in the Anbernic RG350M mips handheld. > > > > Signed-off-by: Christophe Branchereau > > --- > > .../display/panel/leadtek,ltk035c5444t.yaml | 59 +++ > > 1 file changed, 59 insertions(+) > > create mode 100644 > > Documentation/devicetree/bindings/display/panel/leadtek,ltk035c5444t.yaml > > > > diff --git > > a/Documentation/devicetree/bindings/display/panel/leadtek,ltk035c5444t.yaml > > b/Documentation/devicetree/bindings/display/panel/leadtek,ltk035c5444t.yaml > > new file mode 100644 > > index ..9e728f8ce0cd > > --- /dev/null > > +++ > > b/Documentation/devicetree/bindings/display/panel/leadtek,ltk035c5444t.yaml > > @@ -0,0 +1,59 @@ > > +# SPDX-License-Identifier: GPL-2.0 > > Why did you change the license? It was correct before. > > Rob
[Bug 215648] amdgpu: Changing monitor configuration (plug/unplug/wake from DPMS) causes kernel panic
https://bugzilla.kernel.org/show_bug.cgi?id=215648 Philipp Riederer (pr_ker...@tum.fail) changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |UNREPRODUCIBLE --- Comment #6 from Philipp Riederer (pr_ker...@tum.fail) --- I can no longer reproduce this issue with 5.16.14. Sorry for the noise. Regards, Philipp -- 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 V3 05/13] drm: bridge: icn6211: Add DSI lane count DT property parsing
On Fri, Mar 11, 2022 at 11:36:58AM +0100, Marek Vasut wrote: > On 3/10/22 15:18, Maxime Ripard wrote: > > On Thu, Mar 10, 2022 at 01:47:13PM +0100, Marek Vasut wrote: > > > On 3/10/22 11:53, Maxime Ripard wrote: > > > > On Tue, Mar 08, 2022 at 10:41:05PM +0100, Marek Vasut wrote: > > > > > On 3/8/22 17:21, Maxime Ripard wrote: > > > > > > On Tue, Mar 08, 2022 at 03:47:22PM +0100, Marek Vasut wrote: > > > > > > > On 3/8/22 14:49, Maxime Ripard wrote: > > > > > > > > On Tue, Mar 08, 2022 at 02:27:40PM +0100, Marek Vasut wrote: > > > > > > > > > On 3/8/22 13:51, Maxime Ripard wrote: > > > > > > > > > > On Tue, Mar 08, 2022 at 11:29:59AM +0100, Marek Vasut wrote: > > > > > > > > > > > On 3/8/22 11:07, Jagan Teki wrote: > > > > > > > > > > > > On Tue, Mar 8, 2022 at 3:19 PM Marek Vasut > > > > > > > > > > > > wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > On 3/8/22 09:03, Jagan Teki wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > Hi, > > > > > > > > > > > > > > > > > > > > > > > > > > [...] > > > > > > > > > > > > > > > > > > > > > > > > > > > > @@ -314,7 +321,9 @@ static const struct > > > > > > > > > > > > > > > drm_bridge_funcs chipone_bridge_funcs = { > > > > > > > > > > > > > > > static int chipone_parse_dt(struct > > > > > > > > > > > > > > > chipone *icn) > > > > > > > > > > > > > > > { > > > > > > > > > > > > > > >struct device *dev = icn->dev; > > > > > > > > > > > > > > > + struct device_node *endpoint; > > > > > > > > > > > > > > >struct drm_panel *panel; > > > > > > > > > > > > > > > + int dsi_lanes; > > > > > > > > > > > > > > >int ret; > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >icn->vdd1 = > > > > > > > > > > > > > > > devm_regulator_get_optional(dev, "vdd1"); > > > > > > > > > > > > > > > @@ -350,15 +359,42 @@ static int > > > > > > > > > > > > > > > chipone_parse_dt(struct chipone *icn) > > > > > > > > > > > > > > >return > > > > > > > > > > > > > > > PTR_ERR(icn->enable_gpio); > > > > > > > > > > > > > > >} > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > + endpoint = > > > > > > > > > > > > > > > of_graph_get_endpoint_by_regs(dev->of_node, 0, 0); > > > > > > > > > > > > > > > + dsi_lanes = > > > > > > > > > > > > > > > of_property_count_u32_elems(endpoint, > > > > > > > > > > > > > > > "data-lanes"); > > > > > > > > > > > > > > > + icn->host_node = > > > > > > > > > > > > > > > of_graph_get_remote_port_parent(endpoint); > > > > > > > > > > > > > > > + of_node_put(endpoint); > > > > > > > > > > > > > > > + > > > > > > > > > > > > > > > + if (!icn->host_node) > > > > > > > > > > > > > > > + return -ENODEV; > > > > > > > > > > > > > > > > > > > > > > > > > > > > The non-ports-based OF graph returns a -19 example > > > > > > > > > > > > > > on the Allwinner > > > > > > > > > > > > > > Display pipeline in R16 [1]. > > > > > > > > > > > > > > > > > > > > > > > > > > > > We need to have a helper to return host_node for > > > > > > > > > > > > > > non-ports as I have > > > > > > > > > > > > > > done it for drm_of_find_bridge. > > > > > > > > > > > > > > > > > > > > > > > > > > > > [1] > > > > > > > > > > > > > > https://patchwork.amarulasolutions.com/patch/1805/ > > > > > > > > > > > > > > > > > > > > > > > > > > The link points to a patch marked "DO NOT MERGE", > > > > > > > > > > > > > maybe that patch is > > > > > > > > > > > > > missing the DSI host port@0 OF graph link ? Both > > > > > > > > > > > > > port@0 and port@1 are > > > > > > > > > > > > > required, see: > > > > > > > > > > > > > > > > > > > > > > > > > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/display/bridge/chipone,icn6211.yaml#n53 > > > > > > > > > > > > > > > > > > > > > > > > > > What is "non-ports-based OF graph" ? > > > > > > > > > > > > > > > > > > > > > > > > > > I don't see drm_of_find_bridge() in linux-next , what > > > > > > > > > > > > > is that ? > > > > > > > > > > > > > > > > > > > > > > > > port@0 is optional as some of the DSI host OF-graph > > > > > > > > > > > > represent the > > > > > > > > > > > > bridge or panel as child nodes instead of ports. (i > > > > > > > > > > > > think dt-binding > > > > > > > > > > > > has to fix it to make port@0 optional) > > > > > > > > > > > > > > > > > > > > > > The current upstream DT binding document says: > > > > > > > > > > > > > > > > > > > > > > required: > > > > > > > > > > >- port@0 > > > > > > > > > > >- port@1 > > > > > > > > > > > > > > > > > > > > > > So port@0 is mandatory. > > > > > > > > > > > > > > > > > > > > In the binding, sure, but fundamentally the DT excerpt > > > > > > > > > > Jagan provided is > > > > > > > > > > correct. If the bridge supports DCS, there's no reason to > > > > > > > > > > use the OF > >
Re: [PATCH 2/2] dma-buf/sync-file: fix warning about fence containers
Hi "Christian, I love your patch! Perhaps something to improve: [auto build test WARNING on linus/master] [also build test WARNING on v5.17-rc7 next-20220310] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Christian-K-nig/dma-buf-add-dma_fence_unwrap/20220311-190352 base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 79b00034e9dcd2b065c1665c8b42f62b6b80a9be config: x86_64-randconfig-m001 (https://download.01.org/0day-ci/archive/20220312/202203120047.syxpis6h-...@intel.com/config) compiler: gcc-9 (Ubuntu 9.4.0-1ubuntu1~20.04) 9.4.0 reproduce (this is a W=1 build): # https://github.com/0day-ci/linux/commit/ca3584ac05c4a450e69b1c6bcb0672b5ab026c7c git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Christian-K-nig/dma-buf-add-dma_fence_unwrap/20220311-190352 git checkout ca3584ac05c4a450e69b1c6bcb0672b5ab026c7c # save the config file to linux build tree mkdir build_dir make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash drivers/dma-buf/ If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): In file included from drivers/dma-buf/sync_file.c:8: include/linux/dma-fence-unwrap.h: In function 'dma_fence_unwrap_array': include/linux/dma-fence-unwrap.h:44:18: error: implicit declaration of function 'dma_fence_chain_contained'; did you mean 'dma_fence_chain_init'? [-Werror=implicit-function-declaration] 44 | cursor->array = dma_fence_chain_contained(cursor->chain); | ^ | dma_fence_chain_init >> include/linux/dma-fence-unwrap.h:44:16: warning: assignment to 'struct >> dma_fence *' from 'int' makes pointer from integer without a cast >> [-Wint-conversion] 44 | cursor->array = dma_fence_chain_contained(cursor->chain); |^ include/linux/dma-fence-unwrap.h:46:9: error: implicit declaration of function 'dma_fence_array_first'; did you mean 'dma_fence_array_create'? [-Werror=implicit-function-declaration] 46 | return dma_fence_array_first(cursor->array); | ^ | dma_fence_array_create >> include/linux/dma-fence-unwrap.h:46:9: warning: returning 'int' from a >> function with return type 'struct dma_fence *' makes pointer from integer >> without a cast [-Wint-conversion] 46 | return dma_fence_array_first(cursor->array); | ^~~~ include/linux/dma-fence-unwrap.h: In function 'dma_fence_unwrap_next': include/linux/dma-fence-unwrap.h:77:8: error: implicit declaration of function 'dma_fence_array_next'; did you mean 'dma_fence_unwrap_next'? [-Werror=implicit-function-declaration] 77 | tmp = dma_fence_array_next(cursor->array, cursor->index); |^~~~ |dma_fence_unwrap_next include/linux/dma-fence-unwrap.h:77:6: warning: assignment to 'struct dma_fence *' from 'int' makes pointer from integer without a cast [-Wint-conversion] 77 | tmp = dma_fence_array_next(cursor->array, cursor->index); | ^ cc1: some warnings being treated as errors vim +44 include/linux/dma-fence-unwrap.h 088aa14c0f5cad Christian König 2022-03-11 33 088aa14c0f5cad Christian König 2022-03-11 34 /** 088aa14c0f5cad Christian König 2022-03-11 35 * dma_fence_unwrap_array - helper to unwrap dma_fence_arrays 088aa14c0f5cad Christian König 2022-03-11 36 * @cursor: cursor to initialize 088aa14c0f5cad Christian König 2022-03-11 37 * 088aa14c0f5cad Christian König 2022-03-11 38 * Helper function to unwrap dma_fence_array containers, don't touch directly. 088aa14c0f5cad Christian König 2022-03-11 39 * Use dma_fence_unwrap_first/next instead. 088aa14c0f5cad Christian König 2022-03-11 40 */ 088aa14c0f5cad Christian König 2022-03-11 41 static inline struct dma_fence * 088aa14c0f5cad Christian König 2022-03-11 42 dma_fence_unwrap_array(struct dma_fence_unwrap * cursor) 088aa14c0f5cad Christian König 2022-03-11 43 { 088aa14c0f5cad Christian König 2022-03-11 @44 cursor->array = dma_fence_chain_contained(cursor->chain); 088aa14c0f5cad Christian König 2022-03-11 45 cursor->index = 0; 088aa14c0f5cad Christian König 2022-03-11 @46 return dma_fence_array_first(cursor->array); 088aa14c0f5cad Christian König 2022-03-11 47 } 088aa14c0f5cad Christian König 2022-03-11 48 --- 0-DAY CI Kernel Test Service https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org
Re: [PATCH 1/2] dma-buf: add dma_fence_unwrap
Hi "Christian, I love your patch! Perhaps something to improve: [auto build test WARNING on linus/master] [also build test WARNING on v5.17-rc7 next-20220310] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Christian-K-nig/dma-buf-add-dma_fence_unwrap/20220311-190352 base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 79b00034e9dcd2b065c1665c8b42f62b6b80a9be config: microblaze-randconfig-r011-20220310 (https://download.01.org/0day-ci/archive/20220311/202203112305.wceordi2-...@intel.com/config) compiler: microblaze-linux-gcc (GCC) 11.2.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/088aa14c0f5cad378854823fa661ee145dd2c01b git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Christian-K-nig/dma-buf-add-dma_fence_unwrap/20220311-190352 git checkout 088aa14c0f5cad378854823fa661ee145dd2c01b # save the config file to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=microblaze SHELL=/bin/bash drivers/dma-buf/ If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): In file included from drivers/dma-buf/st-dma-fence-unwrap.c:7: include/linux/dma-fence-unwrap.h: In function 'dma_fence_unwrap_array': include/linux/dma-fence-unwrap.h:44:25: error: implicit declaration of function 'dma_fence_chain_contained'; did you mean 'dma_fence_chain_init'? [-Werror=implicit-function-declaration] 44 | cursor->array = dma_fence_chain_contained(cursor->chain); | ^ | dma_fence_chain_init include/linux/dma-fence-unwrap.h:44:23: warning: assignment to 'struct dma_fence *' from 'int' makes pointer from integer without a cast [-Wint-conversion] 44 | cursor->array = dma_fence_chain_contained(cursor->chain); | ^ include/linux/dma-fence-unwrap.h:46:16: error: implicit declaration of function 'dma_fence_array_first'; did you mean 'dma_fence_array_create'? [-Werror=implicit-function-declaration] 46 | return dma_fence_array_first(cursor->array); |^ |dma_fence_array_create include/linux/dma-fence-unwrap.h:46:16: warning: returning 'int' from a function with return type 'struct dma_fence *' makes pointer from integer without a cast [-Wint-conversion] 46 | return dma_fence_array_first(cursor->array); |^~~~ include/linux/dma-fence-unwrap.h: In function 'dma_fence_unwrap_next': include/linux/dma-fence-unwrap.h:77:15: error: implicit declaration of function 'dma_fence_array_next'; did you mean 'dma_fence_unwrap_next'? [-Werror=implicit-function-declaration] 77 | tmp = dma_fence_array_next(cursor->array, cursor->index); | ^~~~ | dma_fence_unwrap_next include/linux/dma-fence-unwrap.h:77:13: warning: assignment to 'struct dma_fence *' from 'int' makes pointer from integer without a cast [-Wint-conversion] 77 | tmp = dma_fence_array_next(cursor->array, cursor->index); | ^ drivers/dma-buf/st-dma-fence-unwrap.c: In function 'unwrap_array': >> drivers/dma-buf/st-dma-fence-unwrap.c:133:13: warning: variable 'err' set >> but not used [-Wunused-but-set-variable] 133 | int err = 0; | ^~~ drivers/dma-buf/st-dma-fence-unwrap.c: In function 'unwrap_chain': drivers/dma-buf/st-dma-fence-unwrap.c:175:13: warning: variable 'err' set but not used [-Wunused-but-set-variable] 175 | int err = 0; | ^~~ drivers/dma-buf/st-dma-fence-unwrap.c: In function 'unwrap_chain_array': drivers/dma-buf/st-dma-fence-unwrap.c:217:13: warning: variable 'err' set but not used [-Wunused-but-set-variable] 217 | int err = 0; | ^~~ cc1: some warnings being treated as errors vim +/err +133 drivers/dma-buf/st-dma-fence-unwrap.c 128 129 static int unwrap_array(void *arg) 130 { 131 struct dma_fence *fence, *f1, *f2, *array
Re: [PATCH v3 3/3] drm/bridge: ti-sn65dsi86: Support hotplug detection
Hi, On Thu, Mar 10, 2022 at 9:47 PM Kieran Bingham wrote: > > > > +static void ti_sn_bridge_hpd_disable(struct drm_bridge *bridge) > > > +{ > > > + struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge); > > > + > > > + regmap_write(pdata->regmap, SN_IRQ_HPD_REG, 0); > > > + pm_runtime_put_autosuspend(pdata->dev); > > > > Before doing the pm_runtime_put_autosuspend() it feels like you should > > ensure that the interrupt has finished. Otherwise we could be midway > > through processing an interrupt and the pm_runtime reference could go > > away, right? Maybe we just disable the irq which I think will wait for > > anything outstanding to finish? > > Should the IRQ handler also call pm_runtime_get/put then? I thought about that, but I suspect it's cleaner to disable the IRQ handler (and block waiting for it to finish if it was running). That will ensure that the core isn't notified about HPD after HPD was disabled. Once you do that then there's no need to get/put in the irq handler since we always hold a pm_runtime reference when the IRQ handler is enabled. > > > @@ -1247,9 +1342,29 @@ static int ti_sn_bridge_probe(struct > > > auxiliary_device *adev, > > > pdata->bridge.type = pdata->next_bridge->type == > > > DRM_MODE_CONNECTOR_DisplayPort > > >? DRM_MODE_CONNECTOR_DisplayPort : > > > DRM_MODE_CONNECTOR_eDP; > > > > > > - if (pdata->bridge.type == DRM_MODE_CONNECTOR_DisplayPort) > > > + if (pdata->bridge.type == DRM_MODE_CONNECTOR_DisplayPort) { > > > pdata->bridge.ops = DRM_BRIDGE_OP_EDID; > > > > > > + if (!pdata->no_hpd) > > > + pdata->bridge.ops |= DRM_BRIDGE_OP_DETECT; > > > + } > > > + > > > + if (!pdata->no_hpd && pdata->irq > 0) { > > > + dev_err(pdata->dev, "registering IRQ %d\n", pdata->irq); > > > + > > > + ret = devm_request_threaded_irq(pdata->dev, pdata->irq, > > > NULL, > > > + ti_sn65dsi86_irq_handler, > > > + IRQF_ONESHOT, > > > "sn65dsi86-irq", > > > + pdata); > > > + if (ret) > > > + return dev_err_probe(pdata->dev, ret, > > > +"Failed to register DP > > > interrupt\n"); > > > + > > > + /* Enable IRQ based HPD */ > > > + regmap_write(pdata->regmap, SN_IRQ_EN_REG, IRQ_EN); > > > > Why not put the above regmap_write() in the ti_sn_bridge_hpd_enable() call? > > I assumed the IRQ handler may get used by other non-HPD events. Which is > also why it was originally registered in the main probe(). HPD is just > one feature of the interrupts. Of course it's only used for HPD now > though. I guess I could have solved the bridge dependency by splitting > the IRQ handler to have a dedicated HPD handler function which would > return if the bridge wasn't initialised, but went with the deferred > registration of the handler. > > I can move this and then leave it to anyone else implementing further > IRQ features to refactor if needed. Sounds good. In general the pm_runtime_get reference need to go with the IRQ enabling, so if someone else finds a non-HPD need then they'll have to move that too.
Re: [PATCH v2 4/4] dt-bindings: display/panel: Add Leadtek ltk035c5444t
On Fri, Mar 11, 2022 at 7:05 AM Paul Cercueil wrote: > > Hi Rob, > > Le jeu., mars 10 2022 at 16:30:26 -0600, Rob Herring > a écrit : > > On Tue, Mar 08, 2022 at 02:06:43PM +0100, Christophe Branchereau > > wrote: > >> Add binding for the leadtek ltk035c5444t, which is a 640x480 > >> mipi-dbi over spi / 24-bit RGB panel based on the newvision > >> NV03052C chipset. > >> > >> It is found in the Anbernic RG350M mips handheld. > >> > >> Signed-off-by: Christophe Branchereau > >> --- > >> .../panel/leadtek,ltk035c5444t-spi.yaml | 59 > >> +++ > >> 1 file changed, 59 insertions(+) > >> create mode 100644 > >> Documentation/devicetree/bindings/display/panel/leadtek,ltk035c5444t-spi.yaml > > > > We have 18 SPI based panels already: > > > > $ git grep -i 'spi.* {' > > Documentation/devicetree/bindings/display/panel/ > > Documentation/devicetree/bindings/display/panel/abt,y030xx067a.yaml: > > spi { > > Documentation/devicetree/bindings/display/panel/ilitek,ili9163.yaml: > > spi { > > Documentation/devicetree/bindings/display/panel/ilitek,ili9322.yaml: > > spi { > > Documentation/devicetree/bindings/display/panel/ilitek,ili9341.yaml: > > spi { > > Documentation/devicetree/bindings/display/panel/innolux,ej030na.yaml: > >spi { > > Documentation/devicetree/bindings/display/panel/kingdisplay,kd035g6-54nt.yaml: > >spi { > > Documentation/devicetree/bindings/display/panel/lg,lg4573.yaml: > > spi { > > Documentation/devicetree/bindings/display/panel/lgphilips,lb035q02.yaml: > >spi { > > Documentation/devicetree/bindings/display/panel/nec,nl8048hl11.yaml: > > spi0 { > > Documentation/devicetree/bindings/display/panel/samsung,ld9040.yaml: > > spi { > > Documentation/devicetree/bindings/display/panel/samsung,lms380kf01.yaml: > >spi { > > Documentation/devicetree/bindings/display/panel/samsung,lms397kf04.yaml: > >spi { > > Documentation/devicetree/bindings/display/panel/samsung,s6d27a1.yaml: > >spi { > > Documentation/devicetree/bindings/display/panel/samsung,s6e63m0.yaml: > >spi { > > Documentation/devicetree/bindings/display/panel/sitronix,st7789v.yaml: > >spi { > > Documentation/devicetree/bindings/display/panel/sony,acx565akm.yaml: > > spi { > > Documentation/devicetree/bindings/display/panel/tpo,td.yaml:spi { > > Documentation/devicetree/bindings/display/panel/tpo,tpg110.yaml: > > spi { > > > > Most except for the Samsung ones look like they'd fit in our > > definition > > of 'simple panels' which primarily means 1 supply. > > > > So I think it is time for a panel-simple-spi.yaml binding to combine > > all > > these. But I'm not going to make the person adding the 19th case to do > > that, and this otherwise looks fine: > > > > Reviewed-by: Rob Herring > > I actually thought you sent a patch for this already (I remember you > talking about it last a binding for a new SPI panel has been added). It was just adding spi-peripheral-props.yaml reference that I sent. > I will work on it next week - provided Cristophe's patch has been > merged before. Thanks! Rob
Re: [PATCH v3 4/4] dt-bindings: display/panel: Add Leadtek ltk035c5444t
On Fri, Mar 11, 2022 at 01:04:53PM +0100, Christophe Branchereau wrote: > Add binding for the leadtek ltk035c5444t, which is a 640x480 > mipi-dbi over spi / 24-bit RGB panel based on the newvision > NV03052C chipset. > > It is found in the Anbernic RG350M mips handheld. > > Signed-off-by: Christophe Branchereau > --- > .../display/panel/leadtek,ltk035c5444t.yaml | 59 +++ > 1 file changed, 59 insertions(+) > create mode 100644 > Documentation/devicetree/bindings/display/panel/leadtek,ltk035c5444t.yaml > > diff --git > a/Documentation/devicetree/bindings/display/panel/leadtek,ltk035c5444t.yaml > b/Documentation/devicetree/bindings/display/panel/leadtek,ltk035c5444t.yaml > new file mode 100644 > index ..9e728f8ce0cd > --- /dev/null > +++ > b/Documentation/devicetree/bindings/display/panel/leadtek,ltk035c5444t.yaml > @@ -0,0 +1,59 @@ > +# SPDX-License-Identifier: GPL-2.0 Why did you change the license? It was correct before. Rob
Re: [PATCH v8 10/24] dt-bindings: display: rockchip: dw-hdmi: Add additional clock
On Fri, 11 Mar 2022 09:33:09 +0100, Sascha Hauer wrote: > The rk3568 HDMI has an additional clock that needs to be enabled for the > HDMI controller to work. It is not needed for the HDMI controller > itself, but to make the SoC internal busses work. > > Signed-off-by: Sascha Hauer > --- > > Notes: > Changes since v7: > - rename hclk to niu > > .../bindings/display/rockchip/rockchip,dw-hdmi.yaml| 7 ++- > 1 file changed, 6 insertions(+), 1 deletion(-) > Acked-by: Rob Herring
Re: [Intel-gfx] [PATCH 2/2] drm/i915/xehp: Update topology dumps for Xe_HP
Hi Matt, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on drm-tip/drm-tip] [also build test WARNING on drm-exynos/exynos-drm-next drm/drm-next next-20220310] [cannot apply to drm-intel/for-linux-next tegra-drm/drm/tegra/for-next v5.17-rc7] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Matt-Roper/drm-i915-sseu-Don-t-overallocate-subslice-storage/20220311-141705 base: git://anongit.freedesktop.org/drm/drm-tip drm-tip config: i386-randconfig-a013 (https://download.01.org/0day-ci/archive/20220311/202203112234.rtvksbsq-...@intel.com/config) compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project 276ca87382b8f16a65bddac700202924228982f6) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/38985b2e6acdbe67dedb5de8a8aeef917b746453 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Matt-Roper/drm-i915-sseu-Don-t-overallocate-subslice-storage/20220311-141705 git checkout 38985b2e6acdbe67dedb5de8a8aeef917b746453 # save the config file to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash drivers/gpu/drm/i915/ net/core/ If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): >> drivers/gpu/drm/i915/gt/intel_sseu.c:59:5: warning: no previous prototype >> for function 'intel_sseu_get_geometry_subslices' [-Wmissing-prototypes] u32 intel_sseu_get_geometry_subslices(const struct sseu_dev_info *sseu) ^ drivers/gpu/drm/i915/gt/intel_sseu.c:59:1: note: declare 'static' if the function is not intended to be used outside of this translation unit u32 intel_sseu_get_geometry_subslices(const struct sseu_dev_info *sseu) ^ static 1 warning generated. vim +/intel_sseu_get_geometry_subslices +59 drivers/gpu/drm/i915/gt/intel_sseu.c 58 > 59 u32 intel_sseu_get_geometry_subslices(const struct sseu_dev_info *sseu) 60 { 61 return _intel_sseu_get_subslices(sseu, sseu->geometry_subslice_mask, 0); 62 } 63 --- 0-DAY CI Kernel Test Service https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org
Re: [Intel-gfx] [PATCH 2/2] drm/i915/xehp: Update topology dumps for Xe_HP
Hi Matt, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on drm-tip/drm-tip] [also build test WARNING on drm-exynos/exynos-drm-next drm/drm-next next-20220310] [cannot apply to drm-intel/for-linux-next tegra-drm/drm/tegra/for-next airlied/drm-next v5.17-rc7] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Matt-Roper/drm-i915-sseu-Don-t-overallocate-subslice-storage/20220311-141705 base: git://anongit.freedesktop.org/drm/drm-tip drm-tip config: i386-debian-10.3 (https://download.01.org/0day-ci/archive/20220311/202203112245.edvnthye-...@intel.com/config) compiler: gcc-9 (Ubuntu 9.4.0-1ubuntu1~20.04) 9.4.0 reproduce (this is a W=1 build): # https://github.com/0day-ci/linux/commit/38985b2e6acdbe67dedb5de8a8aeef917b746453 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Matt-Roper/drm-i915-sseu-Don-t-overallocate-subslice-storage/20220311-141705 git checkout 38985b2e6acdbe67dedb5de8a8aeef917b746453 # save the config file to linux build tree mkdir build_dir make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash drivers/gpu/drm/i915/ If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): >> drivers/gpu/drm/i915/gt/intel_sseu.c:59:5: warning: no previous prototype >> for 'intel_sseu_get_geometry_subslices' [-Wmissing-prototypes] 59 | u32 intel_sseu_get_geometry_subslices(const struct sseu_dev_info *sseu) | ^ vim +/intel_sseu_get_geometry_subslices +59 drivers/gpu/drm/i915/gt/intel_sseu.c 58 > 59 u32 intel_sseu_get_geometry_subslices(const struct sseu_dev_info *sseu) 60 { 61 return _intel_sseu_get_subslices(sseu, sseu->geometry_subslice_mask, 0); 62 } 63 --- 0-DAY CI Kernel Test Service https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org
Re: BUG: KASAN: use-after-free in drm_atomic_helper_wait_for_vblanks()
Hi Dmitry, On Thu, Mar 10, 2022 at 03:33:07AM +0300, Dmitry Osipenko wrote: > I was playing/testing SuperTuxKart using VirtIO-GPU driver and spotted a > UAF bug in drm_atomic_helper_wait_for_vblanks(). > > SuperTuxKart can use DRM directly, i.e. you can run game in VT without > Xorg or Wayland, this is where bugs happens. SuperTuxKart uses a > non-blocking atomic page flips and UAF happens when a new atomic state > is committed while there is a previous page flip still in-fly. > > What happens is that the new and old atomic states refer to the same > CRTC state somehow. Once the older atomic state is destroyed, the CRTC > state is freed and the newer atomic state continues to use the freed > CRTC state. I'm not sure what you mean by "the new and old atomic states refer to the same CRTC state", are those the same pointers? > The bug is easily reproducible (at least by me) by playing SuperTuxKart > for a minute. It presents on latest -next and 5.17-rc7, I haven't > checked older kernel versions. > > I'm not an expert of the non-blocking code paths in DRM, so asking for > suggestions about where the root of the problem could be. Does it occur with other platforms? Can you easily test on something else? Thanks, Maxime signature.asc Description: PGP signature
Re: [PATCH v2 4/4] dt-bindings: display/panel: Add Leadtek ltk035c5444t
Hi Rob, Le jeu., mars 10 2022 at 16:30:26 -0600, Rob Herring a écrit : On Tue, Mar 08, 2022 at 02:06:43PM +0100, Christophe Branchereau wrote: Add binding for the leadtek ltk035c5444t, which is a 640x480 mipi-dbi over spi / 24-bit RGB panel based on the newvision NV03052C chipset. It is found in the Anbernic RG350M mips handheld. Signed-off-by: Christophe Branchereau --- .../panel/leadtek,ltk035c5444t-spi.yaml | 59 +++ 1 file changed, 59 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/leadtek,ltk035c5444t-spi.yaml We have 18 SPI based panels already: $ git grep -i 'spi.* {' Documentation/devicetree/bindings/display/panel/ Documentation/devicetree/bindings/display/panel/abt,y030xx067a.yaml: spi { Documentation/devicetree/bindings/display/panel/ilitek,ili9163.yaml: spi { Documentation/devicetree/bindings/display/panel/ilitek,ili9322.yaml: spi { Documentation/devicetree/bindings/display/panel/ilitek,ili9341.yaml: spi { Documentation/devicetree/bindings/display/panel/innolux,ej030na.yaml: spi { Documentation/devicetree/bindings/display/panel/kingdisplay,kd035g6-54nt.yaml: spi { Documentation/devicetree/bindings/display/panel/lg,lg4573.yaml: spi { Documentation/devicetree/bindings/display/panel/lgphilips,lb035q02.yaml: spi { Documentation/devicetree/bindings/display/panel/nec,nl8048hl11.yaml: spi0 { Documentation/devicetree/bindings/display/panel/samsung,ld9040.yaml: spi { Documentation/devicetree/bindings/display/panel/samsung,lms380kf01.yaml: spi { Documentation/devicetree/bindings/display/panel/samsung,lms397kf04.yaml: spi { Documentation/devicetree/bindings/display/panel/samsung,s6d27a1.yaml: spi { Documentation/devicetree/bindings/display/panel/samsung,s6e63m0.yaml: spi { Documentation/devicetree/bindings/display/panel/sitronix,st7789v.yaml: spi { Documentation/devicetree/bindings/display/panel/sony,acx565akm.yaml: spi { Documentation/devicetree/bindings/display/panel/tpo,td.yaml:spi { Documentation/devicetree/bindings/display/panel/tpo,tpg110.yaml: spi { Most except for the Samsung ones look like they'd fit in our definition of 'simple panels' which primarily means 1 supply. So I think it is time for a panel-simple-spi.yaml binding to combine all these. But I'm not going to make the person adding the 19th case to do that, and this otherwise looks fine: Reviewed-by: Rob Herring I actually thought you sent a patch for this already (I remember you talking about it last a binding for a new SPI panel has been added). I will work on it next week - provided Cristophe's patch has been merged before. Cheers, -Paul With one nit fixed below: diff --git a/Documentation/devicetree/bindings/display/panel/leadtek,ltk035c5444t-spi.yaml b/Documentation/devicetree/bindings/display/panel/leadtek,ltk035c5444t-spi.yaml new file mode 100644 index ..9b6f1810adab --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/leadtek,ltk035c5444t-spi.yaml @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/leadtek,ltk035c5444t-spi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Leadtek ltk035c5444t 3.5" (640x480 pixels) 24-bit IPS LCD panel + +maintainers: + - Paul Cercueil + - Christophe Branchereau + +allOf: + - $ref: panel-common.yaml# + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +properties: + compatible: +const: leadtek,ltk035c5444t-spi '-spi' is redundant, so drop. + + backlight: true + port: true + power-supply: true + reg: true + reset-gpios: true + +required: + - compatible + - power-supply + - reset-gpios + +unevaluatedProperties: false + +examples: + - | +#include + +spi { +#address-cells = <1>; +#size-cells = <0>; +panel@0 { +compatible = "leadtek,ltk035c5444t-spi"; And update the example... +reg = <0>; + +spi-3wire; +spi-max-frequency = <3125000>; + +reset-gpios = <&gpe 2 GPIO_ACTIVE_LOW>; + +backlight = <&backlight>; +power-supply = <&vcc>; + +port { +panel_input: endpoint { +remote-endpoint = <&panel_output>; +}; +}; +}; +}; -- 2.34.1
[PATCH 2/2] drm/i915: Drop the irqs_disabled() check
The !irqs_disabled() check triggers on PREEMPT_RT even with i915_sched_engine::lock acquired. The reason is the lock is transformed into a sleeping lock on PREEMPT_RT and does not disable interrupts. There is no need to check for disabled interrupts. The lockdep annotation below already check if the lock has been acquired by the caller and will yell if the interrupts are not disabled. Remove the !irqs_disabled() check. Reported-by: Maarten Lankhorst Signed-off-by: Sebastian Andrzej Siewior --- drivers/gpu/drm/i915/i915_request.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index 76cf5ac91e946..41d7c1071ab52 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -583,7 +583,6 @@ bool __i915_request_submit(struct i915_request *request) RQ_TRACE(request, "\n"); - GEM_BUG_ON(!irqs_disabled()); lockdep_assert_held(&engine->sched_engine->lock); /* @@ -692,7 +691,6 @@ void __i915_request_unsubmit(struct i915_request *request) */ RQ_TRACE(request, "\n"); - GEM_BUG_ON(!irqs_disabled()); lockdep_assert_held(&engine->sched_engine->lock); /* -- 2.35.1
[PATCH 1/2] drm/i915/gt: Queue and wait for the irq_work item.
Disabling interrupts and invoking the irq_work function directly breaks on PREEMPT_RT. PREEMPT_RT does not invoke all irq_work from hardirq context because some of the user have spinlock_t locking in the callback function. These locks are then turned into a sleeping locks which can not be acquired with disabled interrupts. Using irq_work_queue() has the benefit that the irqwork will be invoked in the regular context. In general there is "no" delay between enqueuing the callback and its invocation because the interrupt is raised right away on architectures which support it (which includes x86). Use irq_work_queue() + irq_work_sync() instead invoking the callback directly. Reported-by: Clark Williams Signed-off-by: Sebastian Andrzej Siewior Reviewed-by: Maarten Lankhorst --- drivers/gpu/drm/i915/gt/intel_breadcrumbs.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c index 209cf265bf746..98efeb97a6ba6 100644 --- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c @@ -311,9 +311,8 @@ void __intel_breadcrumbs_park(struct intel_breadcrumbs *b) /* Kick the work once more to drain the signalers, and disarm the irq */ irq_work_sync(&b->irq_work); while (READ_ONCE(b->irq_armed) && !atomic_read(&b->active)) { - local_irq_disable(); - signal_irq_work(&b->irq_work); - local_irq_enable(); + irq_work_queue(&b->irq_work); + irq_work_sync(&b->irq_work); cond_resched(); } } -- 2.35.1
[PATCH 0/2] drm/i915: Avoid explicit IRQ-off sections.
Hi, these two patches are from the RT queue. They avoid IRQ-off checks and IRQ-off regions which are not valid/ possible on PREEMPT_RT and are not needed on !PREEMPT_RT. Sebastian
Re: [PATCH v2] drm/amdgpu: Add support for drm_privacy_screen
Hi All, On 3/9/22 18:53, Rajat Jain wrote: > On Wed, Mar 9, 2022 at 7:06 AM Sean Paul wrote: >> >> From: Sean Paul >> >> This patch adds the necessary hooks to make amdgpu aware of privacy >> screens. On devices with privacy screen drivers (such as thinkpad-acpi), >> the amdgpu driver will defer probe until it's ready and then sync the sw >> and hw state on each commit the connector is involved and enabled. >> >> Changes in v2: >> -Tweaked the drm_privacy_screen_get() error check to avoid logging >> errors when privacy screen is absent (Hans) >> >> Signed-off-by: Sean Paul >> Link: https://patchwork.freedesktop.org/patch/477640/ #v1 >> --- >> drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 9 + >> .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c| 3 +++ >> .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 16 +++- >> 3 files changed, 27 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c >> b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c >> index 2ab675123ae3..e2cfae56c020 100644 >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c >> @@ -26,6 +26,7 @@ >> #include >> #include >> #include >> +#include >> #include >> #include >> #include "amdgpu_drv.h" >> @@ -1988,6 +1989,7 @@ static int amdgpu_pci_probe(struct pci_dev *pdev, >> { >> struct drm_device *ddev; >> struct amdgpu_device *adev; >> + struct drm_privacy_screen *privacy_screen; >> unsigned long flags = ent->driver_data; >> int ret, retry = 0, i; >> bool supports_atomic = false; >> @@ -2063,6 +2065,13 @@ static int amdgpu_pci_probe(struct pci_dev *pdev, >> size = pci_resource_len(pdev, 0); >> is_fw_fb = amdgpu_is_fw_framebuffer(base, size); >> >> + /* If the LCD panel has a privacy screen, defer probe until its >> ready */ >> + privacy_screen = drm_privacy_screen_get(&pdev->dev, NULL); >> + if (IS_ERR(privacy_screen) && PTR_ERR(privacy_screen) == >> -EPROBE_DEFER) >> + return -EPROBE_DEFER; >> + >> + drm_privacy_screen_put(privacy_screen); >> + >> /* Get rid of things like offb */ >> ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, >> &amdgpu_kms_driver); >> if (ret) >> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c >> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c >> index e1d3db3fe8de..9e2bb6523add 100644 >> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c >> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c >> @@ -9781,6 +9781,9 @@ static void amdgpu_dm_atomic_commit_tail(struct >> drm_atomic_state *state) >> if (acrtc) { >> new_crtc_state = >> drm_atomic_get_new_crtc_state(state, &acrtc->base); >> old_crtc_state = >> drm_atomic_get_old_crtc_state(state, &acrtc->base); >> + >> + /* Sync the privacy screen state between hw and sw */ >> + drm_connector_update_privacy_screen(new_con_state); >> } >> >> /* Skip any modesets/resets */ >> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c >> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c >> index 740435ae3997..594a8002975a 100644 >> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c >> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c >> @@ -27,6 +27,7 @@ >> #include >> #include >> #include >> +#include >> #include "dm_services.h" >> #include "amdgpu.h" >> #include "amdgpu_dm.h" >> @@ -506,6 +507,7 @@ void amdgpu_dm_initialize_dp_connector(struct >> amdgpu_display_manager *dm, >>struct amdgpu_dm_connector >> *aconnector, >>int link_index) >> { >> + struct drm_device *dev = dm->ddev; >> struct dc_link_settings max_link_enc_cap = {0}; >> >> aconnector->dm_dp_aux.aux.name = >> @@ -519,8 +521,20 @@ void amdgpu_dm_initialize_dp_connector(struct >> amdgpu_display_manager *dm, >> drm_dp_cec_register_connector(&aconnector->dm_dp_aux.aux, >> &aconnector->base); >> >> - if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_eDP) >> + if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_eDP) { >> + struct drm_privacy_screen *privacy_screen) >> + >> + /* Reference given up in drm_connector_cleanup() */ >> + privacy_screen = drm_privacy_screen_get(dev->dev, NULL); > > Can we try to be more specific when looking up for privacy screen, e.g.: > > privacy_screen = drm_privacy_screen_get(dev->dev, "eDP-1"); > (and then also making the corresponding change in arch_init_data[] in > drm_privacy_screen_x86.c" So I just checked and yes I think we can be more specific at least for the thinkpad_acpi supporte
[PATCH v3 4/4] dt-bindings: display/panel: Add Leadtek ltk035c5444t
Add binding for the leadtek ltk035c5444t, which is a 640x480 mipi-dbi over spi / 24-bit RGB panel based on the newvision NV03052C chipset. It is found in the Anbernic RG350M mips handheld. Signed-off-by: Christophe Branchereau --- .../display/panel/leadtek,ltk035c5444t.yaml | 59 +++ 1 file changed, 59 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/leadtek,ltk035c5444t.yaml diff --git a/Documentation/devicetree/bindings/display/panel/leadtek,ltk035c5444t.yaml b/Documentation/devicetree/bindings/display/panel/leadtek,ltk035c5444t.yaml new file mode 100644 index ..9e728f8ce0cd --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/leadtek,ltk035c5444t.yaml @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/leadtek,ltk035c5444t.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Leadtek ltk035c5444t 3.5" (640x480 pixels) 24-bit IPS LCD panel + +maintainers: + - Paul Cercueil + - Christophe Branchereau + +allOf: + - $ref: panel-common.yaml# + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +properties: + compatible: +const: leadtek,ltk035c5444t + + backlight: true + port: true + power-supply: true + reg: true + reset-gpios: true + +required: + - compatible + - power-supply + - reset-gpios + +unevaluatedProperties: false + +examples: + - | +#include + +spi { +#address-cells = <1>; +#size-cells = <0>; +panel@0 { +compatible = "leadtek,ltk035c5444t"; +reg = <0>; + +spi-3wire; +spi-max-frequency = <3125000>; + +reset-gpios = <&gpe 2 GPIO_ACTIVE_LOW>; + +backlight = <&backlight>; +power-supply = <&vcc>; + +port { +panel_input: endpoint { +remote-endpoint = <&panel_output>; +}; +}; +}; +}; -- 2.35.1
[PATCH v3 3/4] drm/panel : innolux-ej030na and abt-y030xx067a : add .enable and .disable
Following the introduction of bridge_atomic_enable in the ingenic drm driver, the crtc is enabled between .prepare and .enable, if it exists. Add it so the backlight is only enabled after the crtc is, to avoid graphical issues. Signed-off-by: Christophe Branchereau --- drivers/gpu/drm/panel/panel-abt-y030xx067a.c | 23 -- drivers/gpu/drm/panel/panel-innolux-ej030na.c | 31 --- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-abt-y030xx067a.c b/drivers/gpu/drm/panel/panel-abt-y030xx067a.c index f043b484055b..b5736344e3ec 100644 --- a/drivers/gpu/drm/panel/panel-abt-y030xx067a.c +++ b/drivers/gpu/drm/panel/panel-abt-y030xx067a.c @@ -183,8 +183,6 @@ static int y030xx067a_prepare(struct drm_panel *panel) goto err_disable_regulator; } - msleep(120); - return 0; err_disable_regulator: @@ -202,6 +200,25 @@ static int y030xx067a_unprepare(struct drm_panel *panel) return 0; } +static int y030xx067a_enable(struct drm_panel *panel) +{ + if (panel->backlight) { + /* Wait for the picture to be ready before enabling backlight */ + msleep(120); + } + + return 0; +} + +static int y030xx067a_disable(struct drm_panel *panel) +{ + struct y030xx067a *priv = to_y030xx067a(panel); + + regmap_clear_bits(priv->map, 0x06, REG06_XPSAVE); + + return 0; +} + static int y030xx067a_get_modes(struct drm_panel *panel, struct drm_connector *connector) { @@ -239,6 +256,8 @@ static int y030xx067a_get_modes(struct drm_panel *panel, static const struct drm_panel_funcs y030xx067a_funcs = { .prepare= y030xx067a_prepare, .unprepare = y030xx067a_unprepare, + .enable = y030xx067a_enable, + .disable= y030xx067a_disable, .get_modes = y030xx067a_get_modes, }; diff --git a/drivers/gpu/drm/panel/panel-innolux-ej030na.c b/drivers/gpu/drm/panel/panel-innolux-ej030na.c index c558de3f99be..6de7370185cd 100644 --- a/drivers/gpu/drm/panel/panel-innolux-ej030na.c +++ b/drivers/gpu/drm/panel/panel-innolux-ej030na.c @@ -80,8 +80,6 @@ static const struct reg_sequence ej030na_init_sequence[] = { { 0x47, 0x08 }, { 0x48, 0x0f }, { 0x49, 0x0f }, - - { 0x2b, 0x01 }, }; static int ej030na_prepare(struct drm_panel *panel) @@ -109,8 +107,6 @@ static int ej030na_prepare(struct drm_panel *panel) goto err_disable_regulator; } - msleep(120); - return 0; err_disable_regulator: @@ -128,6 +124,31 @@ static int ej030na_unprepare(struct drm_panel *panel) return 0; } +static int ej030na_enable(struct drm_panel *panel) +{ + struct ej030na *priv = to_ej030na(panel); + + /* standby off */ + regmap_write(priv->map, 0x2b, 0x01); + + if (panel->backlight) { + /* Wait for the picture to be ready before enabling backlight */ + msleep(120); + } + + return 0; +} + +static int ej030na_disable(struct drm_panel *panel) +{ + struct ej030na *priv = to_ej030na(panel); + + /* standby on */ + regmap_write(priv->map, 0x2b, 0x00); + + return 0; +} + static int ej030na_get_modes(struct drm_panel *panel, struct drm_connector *connector) { @@ -165,6 +186,8 @@ static int ej030na_get_modes(struct drm_panel *panel, static const struct drm_panel_funcs ej030na_funcs = { .prepare= ej030na_prepare, .unprepare = ej030na_unprepare, + .enable = ej030na_enable, + .disable= ej030na_disable, .get_modes = ej030na_get_modes, }; -- 2.35.1
[PATCH v3 2/4] drm/panel: Add panel driver for NewVision NV3052C based LCDs
This driver supports the NewVision NV3052C based LCDs. Right now, it only supports the LeadTek LTK035C5444T 2.4" 640x480 TFT LCD panel, which can be found in the Anbernic RG-350M handheld console. Signed-off-by: Christophe Branchereau --- drivers/gpu/drm/panel/Kconfig | 9 + drivers/gpu/drm/panel/Makefile| 1 + .../gpu/drm/panel/panel-newvision-nv3052c.c | 497 ++ 3 files changed, 507 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-newvision-nv3052c.c diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index bb2e47229c68..40084f709789 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -283,6 +283,15 @@ config DRM_PANEL_NEC_NL8048HL11 panel (found on the Zoom2/3/3630 SDP boards). To compile this driver as a module, choose M here. +config DRM_PANEL_NEWVISION_NV3052C + tristate "NewVision NV3052C RGB/SPI panel" + depends on OF && SPI + depends on BACKLIGHT_CLASS_DEVICE + select DRM_MIPI_DBI + help + Say Y here if you want to enable support for the panels built + around the NewVision NV3052C display controller. + config DRM_PANEL_NOVATEK_NT35510 tristate "Novatek NT35510 RGB panel driver" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 5740911f637c..42a7ab54234b 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829) += panel-leadtek-ltk500hd1829.o obj-$(CONFIG_DRM_PANEL_LG_LB035Q02) += panel-lg-lb035q02.o obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o obj-$(CONFIG_DRM_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o +obj-$(CONFIG_DRM_PANEL_NEWVISION_NV3052C) += panel-newvision-nv3052c.o obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35510) += panel-novatek-nt35510.o obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35560) += panel-novatek-nt35560.o obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35950) += panel-novatek-nt35950.o diff --git a/drivers/gpu/drm/panel/panel-newvision-nv3052c.c b/drivers/gpu/drm/panel/panel-newvision-nv3052c.c new file mode 100644 index ..fc31df0dee12 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-newvision-nv3052c.c @@ -0,0 +1,497 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * NevVision NV3052C IPS LCD panel driver + * + * Copyright (C) 2020, Paul Cercueil + * Copyright (C) 2022, Christophe Branchereau + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +struct nv3052c_panel_info { + const struct drm_display_mode *display_modes; + unsigned int num_modes; + u16 width_mm, height_mm; + u32 bus_format, bus_flags; +}; + +struct nv3052c { + struct device *dev; + struct drm_panel panel; + struct mipi_dbi dbi; + + const struct nv3052c_panel_info *panel_info; + + struct regulator *supply; + struct gpio_desc *reset_gpio; +}; + +struct nv3052c_reg { + u8 cmd; + u8 val; +}; + +static const struct nv3052c_reg nv3052c_panel_regs[] = { + { 0xff, 0x30 }, + { 0xff, 0x52 }, + { 0xff, 0x01 }, + { 0xe3, 0x00 }, + { 0x40, 0x00 }, + { 0x03, 0x40 }, + { 0x04, 0x00 }, + { 0x05, 0x03 }, + { 0x08, 0x00 }, + { 0x09, 0x07 }, + { 0x0a, 0x01 }, + { 0x0b, 0x32 }, + { 0x0c, 0x32 }, + { 0x0d, 0x0b }, + { 0x0e, 0x00 }, + { 0x23, 0xa0 }, + + { 0x24, 0x0c }, + { 0x25, 0x06 }, + { 0x26, 0x14 }, + { 0x27, 0x14 }, + + { 0x38, 0xcc }, + { 0x39, 0xd7 }, + { 0x3a, 0x4a }, + + { 0x28, 0x40 }, + { 0x29, 0x01 }, + { 0x2a, 0xdf }, + { 0x49, 0x3c }, + { 0x91, 0x77 }, + { 0x92, 0x77 }, + { 0xa0, 0x55 }, + { 0xa1, 0x50 }, + { 0xa4, 0x9c }, + { 0xa7, 0x02 }, + { 0xa8, 0x01 }, + { 0xa9, 0x01 }, + { 0xaa, 0xfc }, + { 0xab, 0x28 }, + { 0xac, 0x06 }, + { 0xad, 0x06 }, + { 0xae, 0x06 }, + { 0xaf, 0x03 }, + { 0xb0, 0x08 }, + { 0xb1, 0x26 }, + { 0xb2, 0x28 }, + { 0xb3, 0x28 }, + { 0xb4, 0x33 }, + { 0xb5, 0x08 }, + { 0xb6, 0x26 }, + { 0xb7, 0x08 }, + { 0xb8, 0x26 }, + { 0xf0, 0x00 }, + { 0xf6, 0xc0 }, + + { 0xff, 0x30 }, + { 0xff, 0x52 }, + { 0xff, 0x02 }, + { 0xb0, 0x0b }, + { 0xb1, 0x16 }, + { 0xb2, 0x17 }, + { 0xb3, 0x2c }, + { 0xb4, 0x32 }, + { 0xb5, 0x3b }, + { 0xb6, 0x29 }, + { 0xb7, 0x40 }, + { 0xb8, 0x0d }, + { 0xb9, 0x05 }, + { 0xba, 0x12 }, + { 0xbb, 0x10 }, + { 0xbc, 0x12 }, + { 0xbd, 0x15 }, + { 0xbe, 0x19 }, + { 0xbf, 0x0e }, + { 0xc0, 0x16 }, + { 0xc1, 0x0a }, + { 0xd0, 0x0c }, + { 0xd1, 0x17 }
[PATCH v3 1/4] drm/ingenic : add ingenic_drm_bridge_atomic_enable
This allows the CRTC to be enabled after panels have slept out, and before their display is turned on, solving a graphical bug on the newvision nv3502c Signed-off-by: Christophe Branchereau --- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 19 +-- 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index dcf44cb00821..51512f41263e 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -226,6 +226,18 @@ static int ingenic_drm_update_pixclk(struct notifier_block *nb, } } +static void ingenic_drm_bridge_atomic_enable(struct drm_bridge *bridge, +struct drm_bridge_state *old_bridge_state) +{ + struct ingenic_drm *priv = drm_device_get_priv(bridge->dev); + + regmap_write(priv->map, JZ_REG_LCD_STATE, 0); + + regmap_update_bits(priv->map, JZ_REG_LCD_CTRL, + JZ_LCD_CTRL_ENABLE | JZ_LCD_CTRL_DISABLE, + JZ_LCD_CTRL_ENABLE); +} + static void ingenic_drm_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state) { @@ -237,17 +249,11 @@ static void ingenic_drm_crtc_atomic_enable(struct drm_crtc *crtc, if (WARN_ON(IS_ERR(priv_state))) return; - regmap_write(priv->map, JZ_REG_LCD_STATE, 0); - /* Set addresses of our DMA descriptor chains */ next_id = priv_state->use_palette ? HWDESC_PALETTE : 0; regmap_write(priv->map, JZ_REG_LCD_DA0, dma_hwdesc_addr(priv, next_id)); regmap_write(priv->map, JZ_REG_LCD_DA1, dma_hwdesc_addr(priv, 1)); - regmap_update_bits(priv->map, JZ_REG_LCD_CTRL, - JZ_LCD_CTRL_ENABLE | JZ_LCD_CTRL_DISABLE, - JZ_LCD_CTRL_ENABLE); - drm_crtc_vblank_on(crtc); } @@ -968,6 +974,7 @@ static const struct drm_encoder_helper_funcs ingenic_drm_encoder_helper_funcs = static const struct drm_bridge_funcs ingenic_drm_bridge_funcs = { .attach = ingenic_drm_bridge_attach, + .atomic_enable = ingenic_drm_bridge_atomic_enable, .atomic_check = ingenic_drm_bridge_atomic_check, .atomic_reset = drm_atomic_helper_bridge_reset, .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, -- 2.35.1
[PATCH v3 0/4] Ingenic DRM bridge_atomic_enable proposal
Hello, v3 : Drop -spi in the compatible string, adjust bindings doc accordingly KR Christophe Hello, this is the v2 for my set of patches : - use dev_err_probe() instead of dev_err() in the newvision panel driver probe function - add bindings documentation for the Leadtek ltk035c5444t Cheers - Christophe Hello, this is a set of patches to allow the upstreaming of the NV3052C panel found in the Anbernic RG350M mips gaming handheld. It was never upstreamed so far due to a longstanding graphical bug, which I propose to solve by introducing ingenic_drm_bridge_atomic_enable in the drm driver so the CRTC can be enabled after the panel itself slept out, and not before as it used to. After the drm change, 2 of the existing panels have to be modified accordingly to introduce missing .enable and .disable in their code. Christophe Branchereau (4): drm/ingenic : add ingenic_drm_bridge_atomic_enable drm/panel: Add panel driver for NewVision NV3052C based LCDs drm/panel : innolux-ej030na and abt-y030xx067a : add .enable and .disable dt-bindings: display/panel: Add Leadtek ltk035c5444t .../display/panel/leadtek,ltk035c5444t.yaml | 59 +++ drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 19 +- drivers/gpu/drm/panel/Kconfig | 9 + drivers/gpu/drm/panel/Makefile| 1 + drivers/gpu/drm/panel/panel-abt-y030xx067a.c | 23 +- drivers/gpu/drm/panel/panel-innolux-ej030na.c | 31 +- .../gpu/drm/panel/panel-newvision-nv3052c.c | 497 ++ 7 files changed, 627 insertions(+), 12 deletions(-) create mode 100644 Documentation/devicetree/bindings/display/panel/leadtek,ltk035c5444t.yaml create mode 100644 drivers/gpu/drm/panel/panel-newvision-nv3052c.c -- 2.35.1
Re: [PATCH] devcoredump: increase the device delete timeout to 10 mins
On Tue, 2022-03-01 at 09:45 -0800, Rob Clark wrote: > On Mon, Feb 28, 2022 at 10:49 PM David Laight wrote: > > > > From: Abhinav Kumar > > > Sent: 28 February 2022 21:38 > > ... > > > We also did some profiling around how much increasing the block size > > > helps and here is the data: > > > > > > Block sizecost > > > > > > 4KB 229s > > > 8KB86s > > > > You must have an O(n^2) operation in there - find it. > > The problem is how the devcoredump/sysfs interface works, which > results in "re-rendering" the output for each block.. it's fine for > moderate size sysfs files, but scales quite badly once you get into > couple MB size sysfs files. > > It could be fixed by having some way to keep state across successive > read callbacks. I'm not sure that's true? Perhaps for dev_coredumpm(), but only if you implemented read() badly. If you have e.g. dev_coredumpsg() or dev_coredumpv() that's just a simple read from the existing buffer. johannes
Re: [PATCH v2] drm/bridge: anx7625: Fix not correct get property counts
Hi Xin. On Fri, Mar 11, 2022 at 06:35:25PM +0800, Xin Ji wrote: > The property length which returns from "of_get_property", it means array > bytes count if the property has prefix as "/bits/ 8". The driver should > call function "of_property_read_u8_array" to get correct array value. > > Fixes: fd0310b6fe7d ("drm/bridge: anx7625: add MIPI DPI input feature") > Signed-off-by: Xin Ji > > --- > V1 -> V2: Fix Sam comment, use of_property_read_u8_array to get array > value > --- > drivers/gpu/drm/bridge/analogix/anx7625.c | 8 > drivers/gpu/drm/bridge/analogix/anx7625.h | 4 ++-- > 2 files changed, 6 insertions(+), 6 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c > b/drivers/gpu/drm/bridge/analogix/anx7625.c > index c6a9a02ed762..628cbf769141 100644 > --- a/drivers/gpu/drm/bridge/analogix/anx7625.c > +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c > @@ -1598,8 +1598,8 @@ static int anx7625_get_swing_setting(struct device *dev, > num_regs = DP_TX_SWING_REG_CNT; > > pdata->dp_lane0_swing_reg_cnt = num_regs; > - of_property_read_u32_array(dev->of_node, "analogix,lane0-swing", > -pdata->lane0_reg_data, num_regs); > + of_property_read_u8_array(dev->of_node, "analogix,lane0-swing", > + pdata->lane0_reg_data, num_regs); The current implementation do a two step approach. First is find the number of elements and then read the elements. The number of elements is only used to limit what is read. I suggest to use: of_property_read_u8_array(dev->of_node, "analogix,lane0-swing", pdata->lane0_reg_data, DP_TX_SWING_REG_CNT); Then you a guaranteed to read at maximum DP_TX_SWING_REG_CNT entries. And as the number of elements is not stored anywhere that should be fine. This looks simpler and matches what we for example do in drivers/gpu/drm/arm/malidp_drv.c - the only user in gpu/ of of_property_read_u8_array(). Sam
Re: [Intel-gfx] [PATCH v2 6/8] drm/i915/display: Check mappable aperture when pinning preallocated vma
On Thu, 10 Mar 2022 at 12:28, Matthew Auld wrote: > > From: CQ Tang > > When system does not have mappable aperture, ggtt->mappable_end=0. In > this case if we pass PIN_MAPPABLE when pinning vma, the pinning code > will return -ENOSPC. So conditionally set PIN_MAPPABLE if HAS_GMCH(). > > Suggested-by: Chris P Wilson > Signed-off-by: CQ Tang > Cc: Radhakrishna Sripada > Cc: Ap Kamal > Signed-off-by: Matthew Auld > Cc: Thomas Hellström > Cc: Ville Syrjälä This at least prevents incorrectly using PIN_MAPPABLE on discrete, Reviewed-by: Matthew Auld > --- > drivers/gpu/drm/i915/display/intel_plane_initial.c | 6 +- > 1 file changed, 5 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_plane_initial.c > b/drivers/gpu/drm/i915/display/intel_plane_initial.c > index 5227e5b35206..f797fcef18fc 100644 > --- a/drivers/gpu/drm/i915/display/intel_plane_initial.c > +++ b/drivers/gpu/drm/i915/display/intel_plane_initial.c > @@ -51,6 +51,7 @@ initial_plane_vma(struct drm_i915_private *i915, > struct drm_i915_gem_object *obj; > struct i915_vma *vma; > u32 base, size; > + u64 pinctl; > > if (!mem || plane_config->size == 0) > return NULL; > @@ -101,7 +102,10 @@ initial_plane_vma(struct drm_i915_private *i915, > if (IS_ERR(vma)) > goto err_obj; > > - if (i915_ggtt_pin(vma, NULL, 0, PIN_MAPPABLE | PIN_OFFSET_FIXED | > base)) > + pinctl = PIN_GLOBAL | PIN_OFFSET_FIXED | base; > + if (HAS_GMCH(i915)) > + pinctl |= PIN_MAPPABLE; > + if (i915_vma_pin(vma, 0, 0, pinctl)) > goto err_obj; > > if (i915_gem_object_is_tiled(obj) && > -- > 2.34.1 >
[PATCH 2/2] dma-buf/sync-file: fix warning about fence containers
The dma_fence_chain containers can show up in sync_files as well resulting in warnings that those can't be added to dma_fence_array containers when merging multiple sync_files together. Solve this by using the dma_fence_unwrap iterator to deep dive into the contained fences and then add those flatten out into a dma_fence_array. Signed-off-by: Christian König --- drivers/dma-buf/sync_file.c | 141 +++- 1 file changed, 73 insertions(+), 68 deletions(-) diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c index 394e6e1e9686..b8dea4ec123b 100644 --- a/drivers/dma-buf/sync_file.c +++ b/drivers/dma-buf/sync_file.c @@ -5,6 +5,7 @@ * Copyright (C) 2012 Google, Inc. */ +#include #include #include #include @@ -172,20 +173,6 @@ static int sync_file_set_fence(struct sync_file *sync_file, return 0; } -static struct dma_fence **get_fences(struct sync_file *sync_file, -int *num_fences) -{ - if (dma_fence_is_array(sync_file->fence)) { - struct dma_fence_array *array = to_dma_fence_array(sync_file->fence); - - *num_fences = array->num_fences; - return array->fences; - } - - *num_fences = 1; - return &sync_file->fence; -} - static void add_fence(struct dma_fence **fences, int *i, struct dma_fence *fence) { @@ -210,86 +197,97 @@ static void add_fence(struct dma_fence **fences, static struct sync_file *sync_file_merge(const char *name, struct sync_file *a, struct sync_file *b) { + struct dma_fence *a_fence, *b_fence, **fences; + struct dma_fence_unwrap a_iter, b_iter; + unsigned int index, num_fences; struct sync_file *sync_file; - struct dma_fence **fences = NULL, **nfences, **a_fences, **b_fences; - int i = 0, i_a, i_b, num_fences, a_num_fences, b_num_fences; sync_file = sync_file_alloc(); if (!sync_file) return NULL; - a_fences = get_fences(a, &a_num_fences); - b_fences = get_fences(b, &b_num_fences); - if (a_num_fences > INT_MAX - b_num_fences) - goto err; + num_fences = 0; + dma_fence_unwrap_for_each(a_fence, &a_iter, a->fence) + ++num_fences; + dma_fence_unwrap_for_each(b_fence, &b_iter, b->fence) + ++num_fences; - num_fences = a_num_fences + b_num_fences; + if (num_fences > INT_MAX) + goto err_free_sync_file; fences = kcalloc(num_fences, sizeof(*fences), GFP_KERNEL); if (!fences) - goto err; + goto err_free_sync_file; /* -* Assume sync_file a and b are both ordered and have no -* duplicates with the same context. +* We can't guarantee that fences in both a and b are ordered, but it is +* still quite likely. * -* If a sync_file can only be created with sync_file_merge -* and sync_file_create, this is a reasonable assumption. +* So attempt to order the fences as we pass over them and merge fences +* with the same context. */ - for (i_a = i_b = 0; i_a < a_num_fences && i_b < b_num_fences; ) { - struct dma_fence *pt_a = a_fences[i_a]; - struct dma_fence *pt_b = b_fences[i_b]; - if (pt_a->context < pt_b->context) { - add_fence(fences, &i, pt_a); + index = 0; + for (a_fence = dma_fence_unwrap_first(a->fence, &a_iter), +b_fence = dma_fence_unwrap_first(b->fence, &b_iter); +a_fence || b_fence; ) { + + if (!b_fence) { + add_fence(fences, &index, a_fence); + a_fence = dma_fence_unwrap_next(&a_iter); + + } else if (!a_fence) { + add_fence(fences, &index, b_fence); + b_fence = dma_fence_unwrap_next(&b_iter); + + } else if (a_fence->context < b_fence->context) { + add_fence(fences, &index, a_fence); + a_fence = dma_fence_unwrap_next(&a_iter); - i_a++; - } else if (pt_a->context > pt_b->context) { - add_fence(fences, &i, pt_b); + } else if (b_fence->context < a_fence->context) { + add_fence(fences, &index, b_fence); + b_fence = dma_fence_unwrap_next(&b_iter); + + } else if (__dma_fence_is_later(a_fence->seqno, b_fence->seqno, + a_fence->ops)) { + add_fence(fences, &index, a_fence); + a_fence = dma_fence_unwrap_next(&a_iter); + b_fence = dma_fence_unwrap_next(&b_iter); - i_b++; } else { - if (__dma_fe
[PATCH 1/2] dma-buf: add dma_fence_unwrap
Add a general purpose helper to deep dive into dma_fence_chain/dma_fence_array structures and iterate over all the fences in them. This is useful when we need to flatten out all fences in those structures. Signed-off-by: Christian König --- Documentation/driver-api/dma-buf.rst | 6 + drivers/dma-buf/Makefile | 1 + drivers/dma-buf/selftests.h | 1 + drivers/dma-buf/st-dma-fence-unwrap.c | 279 ++ include/linux/dma-fence-unwrap.h | 99 + 5 files changed, 386 insertions(+) create mode 100644 drivers/dma-buf/st-dma-fence-unwrap.c create mode 100644 include/linux/dma-fence-unwrap.h diff --git a/Documentation/driver-api/dma-buf.rst b/Documentation/driver-api/dma-buf.rst index 2cd7db82d9fe..7209500f08c8 100644 --- a/Documentation/driver-api/dma-buf.rst +++ b/Documentation/driver-api/dma-buf.rst @@ -194,6 +194,12 @@ DMA Fence Chain .. kernel-doc:: include/linux/dma-fence-chain.h :internal: +DMA Fence unwrap + + +.. kernel-doc:: include/linux/dma-fence-unwrap.h + :internal: + DMA Fence uABI/Sync File diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile index 511805dbeb75..4c9eb53ba3f8 100644 --- a/drivers/dma-buf/Makefile +++ b/drivers/dma-buf/Makefile @@ -12,6 +12,7 @@ dmabuf_selftests-y := \ selftest.o \ st-dma-fence.o \ st-dma-fence-chain.o \ + st-dma-fence-unwrap.o \ st-dma-resv.o obj-$(CONFIG_DMABUF_SELFTESTS) += dmabuf_selftests.o diff --git a/drivers/dma-buf/selftests.h b/drivers/dma-buf/selftests.h index 97d73aaa31da..851965867d9c 100644 --- a/drivers/dma-buf/selftests.h +++ b/drivers/dma-buf/selftests.h @@ -12,4 +12,5 @@ selftest(sanitycheck, __sanitycheck__) /* keep first (igt selfcheck) */ selftest(dma_fence, dma_fence) selftest(dma_fence_chain, dma_fence_chain) +selftest(dma_fence_unwrap, dma_fence_unwrap) selftest(dma_resv, dma_resv) diff --git a/drivers/dma-buf/st-dma-fence-unwrap.c b/drivers/dma-buf/st-dma-fence-unwrap.c new file mode 100644 index ..d821faaebe93 --- /dev/null +++ b/drivers/dma-buf/st-dma-fence-unwrap.c @@ -0,0 +1,279 @@ +// SPDX-License-Identifier: MIT + +/* + * Copyright (C) 2022 Advanced Micro Devices, Inc. + */ + +#include +#if 0 +#include +#include +#include +#include +#include +#include +#include +#endif + +#include "selftest.h" + +#define CHAIN_SZ (4 << 10) + +static struct kmem_cache *slab_fences; + +static inline struct mock_fence { + struct dma_fence base; + spinlock_t lock; +} *to_mock_fence(struct dma_fence *f) { + return container_of(f, struct mock_fence, base); +} + +static const char *mock_name(struct dma_fence *f) +{ + return "mock"; +} + +static void mock_fence_release(struct dma_fence *f) +{ + kmem_cache_free(slab_fences, to_mock_fence(f)); +} + +static const struct dma_fence_ops mock_ops = { + .get_driver_name = mock_name, + .get_timeline_name = mock_name, + .release = mock_fence_release, +}; + +static struct dma_fence *mock_fence(void) +{ + struct mock_fence *f; + + f = kmem_cache_alloc(slab_fences, GFP_KERNEL); + if (!f) + return NULL; + + spin_lock_init(&f->lock); + dma_fence_init(&f->base, &mock_ops, &f->lock, 0, 0); + + return &f->base; +} + +static struct dma_fence *mock_array(unsigned int num_fences, ...) +{ + struct dma_fence_array *array; + struct dma_fence **fences; + va_list valist; + int i; + + fences = kcalloc(num_fences, sizeof(*fences), GFP_KERNEL); + if (!fences) + return NULL; + + va_start(valist, num_fences); + for (i = 0; i < num_fences; ++i) + fences[i] = va_arg(valist, typeof(*fences)); + va_end(valist); + + array = dma_fence_array_create(num_fences, fences, + dma_fence_context_alloc(1), + 1, false); + if (!array) + goto cleanup; + return &array->base; + +cleanup: + for (i = 0; i < num_fences; ++i) + dma_fence_put(fences[i]); + kfree(fences); + return NULL; +} + +static struct dma_fence *mock_chain(struct dma_fence *prev, + struct dma_fence *fence) +{ + struct dma_fence_chain *f; + + f = dma_fence_chain_alloc(); + if (!f) { + dma_fence_put(prev); + dma_fence_put(fence); + return NULL; + } + + dma_fence_chain_init(f, prev, fence, 1); + return &f->base; +} + +static int sanitycheck(void *arg) +{ + struct dma_fence *f, *chain, *array; + int err = 0; + + f = mock_fence(); + if (!f) + return -ENOMEM; + + array = mock_array(1, f); + if (!array) + return -ENOMEM; + + chain = mock_chain(NULL, array); + if (!chain) + return -ENOMEM; + +
Re: [Intel-gfx] [PATCH v2 0/8] Some more bits for small BAR enabling
The series is Acked-by: Nirmoy Das On 10/03/2022 13:27, Matthew Auld wrote: The leftover bits around dealing with stolen-local memory + small BAR, plus some related fixes. v2: some tweaks based on feedback from Ville
Re: [Intel-gfx] [PATCH v3 4/4] drm/i915: Improve long running OCL w/a for GuC submission
On 11/03/2022 10:07, Tvrtko Ursulin wrote: On 10/03/2022 20:24, John Harrison wrote: On 3/10/2022 01:27, Tvrtko Ursulin wrote: On 09/03/2022 21:16, John Harrison wrote: On 3/8/2022 01:41, Tvrtko Ursulin wrote: On 03/03/2022 22:37, john.c.harri...@intel.com wrote: From: John Harrison A workaround was added to the driver to allow OpenCL workloads to run 'forever' by disabling pre-emption on the RCS engine for Gen12. It is not totally unbound as the heartbeat will kick in eventually and cause a reset of the hung engine. However, this does not work well in GuC submission mode. In GuC mode, the pre-emption timeout is how GuC detects hung contexts and triggers a per engine reset. Thus, disabling the timeout means also losing all per engine reset ability. A full GT reset will still occur when the heartbeat finally expires, but that is a much more destructive and undesirable mechanism. The purpose of the workaround is actually to give OpenCL tasks longer to reach a pre-emption point after a pre-emption request has been issued. This is necessary because Gen12 does not support mid-thread pre-emption and OpenCL can have long running threads. So, rather than disabling the timeout completely, just set it to a 'long' value. v2: Review feedback from Tvrtko - must hard code the 'long' value instead of determining it algorithmically. So make it an extra CONFIG definition. Also, remove the execlist centric comment from the existing pre-emption timeout CONFIG option given that it applies to more than just execlists. Signed-off-by: John Harrison Reviewed-by: Daniele Ceraolo Spurio (v1) Acked-by: Michal Mrozek --- drivers/gpu/drm/i915/Kconfig.profile | 26 +++ drivers/gpu/drm/i915/gt/intel_engine_cs.c | 9 ++-- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/Kconfig.profile b/drivers/gpu/drm/i915/Kconfig.profile index 39328567c200..7cc38d25ee5c 100644 --- a/drivers/gpu/drm/i915/Kconfig.profile +++ b/drivers/gpu/drm/i915/Kconfig.profile @@ -57,10 +57,28 @@ config DRM_I915_PREEMPT_TIMEOUT default 640 # milliseconds help How long to wait (in milliseconds) for a preemption event to occur - when submitting a new context via execlists. If the current context - does not hit an arbitration point and yield to HW before the timer - expires, the HW will be reset to allow the more important context - to execute. + when submitting a new context. If the current context does not hit + an arbitration point and yield to HW before the timer expires, the + HW will be reset to allow the more important context to execute. + + This is adjustable via + /sys/class/drm/card?/engine/*/preempt_timeout_ms + + May be 0 to disable the timeout. + + The compiled in default may get overridden at driver probe time on + certain platforms and certain engines which will be reflected in the + sysfs control. + +config DRM_I915_PREEMPT_TIMEOUT_COMPUTE + int "Preempt timeout for compute engines (ms, jiffy granularity)" + default 7500 # milliseconds + help + How long to wait (in milliseconds) for a preemption event to occur + when submitting a new context to a compute capable engine. If the + current context does not hit an arbitration point and yield to HW + before the timer expires, the HW will be reset to allow the more + important context to execute. This is adjustable via /sys/class/drm/card?/engine/*/preempt_timeout_ms diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c index 4185c7338581..cc0954ad836a 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -438,9 +438,14 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id, engine->props.timeslice_duration_ms = CONFIG_DRM_I915_TIMESLICE_DURATION; - /* Override to uninterruptible for OpenCL workloads. */ + /* + * Mid-thread pre-emption is not available in Gen12. Unfortunately, + * some OpenCL workloads run quite long threads. That means they get + * reset due to not pre-empting in a timely manner. So, bump the + * pre-emption timeout value to be much higher for compute engines. + */ if (GRAPHICS_VER(i915) == 12 && (engine->flags & I915_ENGINE_HAS_RCS_REG_STATE)) - engine->props.preempt_timeout_ms = 0; + engine->props.preempt_timeout_ms = CONFIG_DRM_I915_PREEMPT_TIMEOUT_COMPUTE; I wouldn't go as far as adding a config option since as it is it only applies to Gen12 but Kconfig text says nothing about that. And I am not saying you should add a Gen12 specific config option, that would be weird. So IMO just drop it. You were the one arguing that the driver was illegally overriding the user's explicitly chosen settings, including the compile time config This is a
Re: [PATCH V3 05/13] drm: bridge: icn6211: Add DSI lane count DT property parsing
On 3/10/22 15:18, Maxime Ripard wrote: On Thu, Mar 10, 2022 at 01:47:13PM +0100, Marek Vasut wrote: On 3/10/22 11:53, Maxime Ripard wrote: On Tue, Mar 08, 2022 at 10:41:05PM +0100, Marek Vasut wrote: On 3/8/22 17:21, Maxime Ripard wrote: On Tue, Mar 08, 2022 at 03:47:22PM +0100, Marek Vasut wrote: On 3/8/22 14:49, Maxime Ripard wrote: On Tue, Mar 08, 2022 at 02:27:40PM +0100, Marek Vasut wrote: On 3/8/22 13:51, Maxime Ripard wrote: On Tue, Mar 08, 2022 at 11:29:59AM +0100, Marek Vasut wrote: On 3/8/22 11:07, Jagan Teki wrote: On Tue, Mar 8, 2022 at 3:19 PM Marek Vasut wrote: On 3/8/22 09:03, Jagan Teki wrote: Hi, [...] @@ -314,7 +321,9 @@ static const struct drm_bridge_funcs chipone_bridge_funcs = { static int chipone_parse_dt(struct chipone *icn) { struct device *dev = icn->dev; + struct device_node *endpoint; struct drm_panel *panel; + int dsi_lanes; int ret; icn->vdd1 = devm_regulator_get_optional(dev, "vdd1"); @@ -350,15 +359,42 @@ static int chipone_parse_dt(struct chipone *icn) return PTR_ERR(icn->enable_gpio); } + endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, 0); + dsi_lanes = of_property_count_u32_elems(endpoint, "data-lanes"); + icn->host_node = of_graph_get_remote_port_parent(endpoint); + of_node_put(endpoint); + + if (!icn->host_node) + return -ENODEV; The non-ports-based OF graph returns a -19 example on the Allwinner Display pipeline in R16 [1]. We need to have a helper to return host_node for non-ports as I have done it for drm_of_find_bridge. [1] https://patchwork.amarulasolutions.com/patch/1805/ The link points to a patch marked "DO NOT MERGE", maybe that patch is missing the DSI host port@0 OF graph link ? Both port@0 and port@1 are required, see: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/display/bridge/chipone,icn6211.yaml#n53 What is "non-ports-based OF graph" ? I don't see drm_of_find_bridge() in linux-next , what is that ? port@0 is optional as some of the DSI host OF-graph represent the bridge or panel as child nodes instead of ports. (i think dt-binding has to fix it to make port@0 optional) The current upstream DT binding document says: required: - port@0 - port@1 So port@0 is mandatory. In the binding, sure, but fundamentally the DT excerpt Jagan provided is correct. If the bridge supports DCS, there's no reason to use the OF graph in the first place: the bridge node will be a child node of the MIPI-DSI controller (and there's no obligation to use the OF-graph for a MIPI-DSI controller). I believe port@0 should be made optional (or downright removed if MIPI-DCS in the only control bus). That's out of scope of this series anyway, so Jagan can implement patches for that mode if needed. Not really? You can't count on the port@0 being there generally speaking, so you can't count on data-lanes being there either, which exactly what you're doing in this patch. I can because the upstream DT bindings currently say port@0 must be present, see above. If that requirement should be relaxed, sure, but that's a separate series. And another upstream DT bindings say that you don't need them at all. Which "another upstream DT bindings" do you refer to ? https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt Yes, there's a conflict. Yes, it's unfortunate. But the generic DSI binding is far more relevant than a single bridge driver. That seems to be the wrong way around, how can generic subsystem-wide binding take precedence over specific driver binding ? This is the binding of the bus. You're part of that bus. You're a child node of that bus, but nothing ever mandates that your parent node uses the same convention. And some don't. And since your bridge can be connected to pretty much any DSI controller, you have to use the lowest common denominator, not make up some new constraints that not all controller will be able to comply with. It seems to me the ICN6211 DT bindings currently further constraint the generic DSI bus bindings, and that seems OK to me. Let me reiterate this again -- if someone wants to relax the requirements currently imposed by the ICN6211 DT bindings, fine, but that can be done in a separate patchset AND that needs DT bindings update. Furthermore, there are no users of this ICN6211 bridge in upstream DTs, so there is currently no bridge which would operate without OF graph using this driver. And let me reiterate this again: something that used to work for a user doesn't anymore when your series is applied. This is a textbook regression. I suggested a way forward, that you don't like for some reason, fine. But pushing through a regression is just not acceptable. How can
[PATCH v2] drm/bridge: anx7625: Fix not correct get property counts
The property length which returns from "of_get_property", it means array bytes count if the property has prefix as "/bits/ 8". The driver should call function "of_property_read_u8_array" to get correct array value. Fixes: fd0310b6fe7d ("drm/bridge: anx7625: add MIPI DPI input feature") Signed-off-by: Xin Ji --- V1 -> V2: Fix Sam comment, use of_property_read_u8_array to get array value --- drivers/gpu/drm/bridge/analogix/anx7625.c | 8 drivers/gpu/drm/bridge/analogix/anx7625.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index c6a9a02ed762..628cbf769141 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1598,8 +1598,8 @@ static int anx7625_get_swing_setting(struct device *dev, num_regs = DP_TX_SWING_REG_CNT; pdata->dp_lane0_swing_reg_cnt = num_regs; - of_property_read_u32_array(dev->of_node, "analogix,lane0-swing", - pdata->lane0_reg_data, num_regs); + of_property_read_u8_array(dev->of_node, "analogix,lane0-swing", + pdata->lane0_reg_data, num_regs); } if (of_get_property(dev->of_node, @@ -1608,8 +1608,8 @@ static int anx7625_get_swing_setting(struct device *dev, num_regs = DP_TX_SWING_REG_CNT; pdata->dp_lane1_swing_reg_cnt = num_regs; - of_property_read_u32_array(dev->of_node, "analogix,lane1-swing", - pdata->lane1_reg_data, num_regs); + of_property_read_u8_array(dev->of_node, "analogix,lane1-swing", + pdata->lane1_reg_data, num_regs); } return 0; diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.h b/drivers/gpu/drm/bridge/analogix/anx7625.h index edbbfe410a56..2c340f16f2c3 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.h +++ b/drivers/gpu/drm/bridge/analogix/anx7625.h @@ -426,9 +426,9 @@ struct anx7625_platform_data { int mipi_lanes; int audio_en; int dp_lane0_swing_reg_cnt; - int lane0_reg_data[DP_TX_SWING_REG_CNT]; int dp_lane1_swing_reg_cnt; - int lane1_reg_data[DP_TX_SWING_REG_CNT]; + u8 lane0_reg_data[DP_TX_SWING_REG_CNT]; + u8 lane1_reg_data[DP_TX_SWING_REG_CNT]; u32 low_power_mode; struct device_node *mipi_host_node; }; -- 2.25.1
Re: [Intel-gfx] [PATCH v3 4/4] drm/i915: Improve long running OCL w/a for GuC submission
On 10/03/2022 20:24, John Harrison wrote: On 3/10/2022 01:27, Tvrtko Ursulin wrote: On 09/03/2022 21:16, John Harrison wrote: On 3/8/2022 01:41, Tvrtko Ursulin wrote: On 03/03/2022 22:37, john.c.harri...@intel.com wrote: From: John Harrison A workaround was added to the driver to allow OpenCL workloads to run 'forever' by disabling pre-emption on the RCS engine for Gen12. It is not totally unbound as the heartbeat will kick in eventually and cause a reset of the hung engine. However, this does not work well in GuC submission mode. In GuC mode, the pre-emption timeout is how GuC detects hung contexts and triggers a per engine reset. Thus, disabling the timeout means also losing all per engine reset ability. A full GT reset will still occur when the heartbeat finally expires, but that is a much more destructive and undesirable mechanism. The purpose of the workaround is actually to give OpenCL tasks longer to reach a pre-emption point after a pre-emption request has been issued. This is necessary because Gen12 does not support mid-thread pre-emption and OpenCL can have long running threads. So, rather than disabling the timeout completely, just set it to a 'long' value. v2: Review feedback from Tvrtko - must hard code the 'long' value instead of determining it algorithmically. So make it an extra CONFIG definition. Also, remove the execlist centric comment from the existing pre-emption timeout CONFIG option given that it applies to more than just execlists. Signed-off-by: John Harrison Reviewed-by: Daniele Ceraolo Spurio (v1) Acked-by: Michal Mrozek --- drivers/gpu/drm/i915/Kconfig.profile | 26 +++ drivers/gpu/drm/i915/gt/intel_engine_cs.c | 9 ++-- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/Kconfig.profile b/drivers/gpu/drm/i915/Kconfig.profile index 39328567c200..7cc38d25ee5c 100644 --- a/drivers/gpu/drm/i915/Kconfig.profile +++ b/drivers/gpu/drm/i915/Kconfig.profile @@ -57,10 +57,28 @@ config DRM_I915_PREEMPT_TIMEOUT default 640 # milliseconds help How long to wait (in milliseconds) for a preemption event to occur - when submitting a new context via execlists. If the current context - does not hit an arbitration point and yield to HW before the timer - expires, the HW will be reset to allow the more important context - to execute. + when submitting a new context. If the current context does not hit + an arbitration point and yield to HW before the timer expires, the + HW will be reset to allow the more important context to execute. + + This is adjustable via + /sys/class/drm/card?/engine/*/preempt_timeout_ms + + May be 0 to disable the timeout. + + The compiled in default may get overridden at driver probe time on + certain platforms and certain engines which will be reflected in the + sysfs control. + +config DRM_I915_PREEMPT_TIMEOUT_COMPUTE + int "Preempt timeout for compute engines (ms, jiffy granularity)" + default 7500 # milliseconds + help + How long to wait (in milliseconds) for a preemption event to occur + when submitting a new context to a compute capable engine. If the + current context does not hit an arbitration point and yield to HW + before the timer expires, the HW will be reset to allow the more + important context to execute. This is adjustable via /sys/class/drm/card?/engine/*/preempt_timeout_ms diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c index 4185c7338581..cc0954ad836a 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -438,9 +438,14 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id, engine->props.timeslice_duration_ms = CONFIG_DRM_I915_TIMESLICE_DURATION; - /* Override to uninterruptible for OpenCL workloads. */ + /* + * Mid-thread pre-emption is not available in Gen12. Unfortunately, + * some OpenCL workloads run quite long threads. That means they get + * reset due to not pre-empting in a timely manner. So, bump the + * pre-emption timeout value to be much higher for compute engines. + */ if (GRAPHICS_VER(i915) == 12 && (engine->flags & I915_ENGINE_HAS_RCS_REG_STATE)) - engine->props.preempt_timeout_ms = 0; + engine->props.preempt_timeout_ms = CONFIG_DRM_I915_PREEMPT_TIMEOUT_COMPUTE; I wouldn't go as far as adding a config option since as it is it only applies to Gen12 but Kconfig text says nothing about that. And I am not saying you should add a Gen12 specific config option, that would be weird. So IMO just drop it. You were the one arguing that the driver was illegally overriding the user's explicitly chosen settings, including the compile time config This is a bit out of context and illegally don't think use
Re: [PATCH v15 00/22] Add MediaTek SoC DRM (vdosys1) support for mt8195
Il 11/03/22 02:54, Nancy.Lin ha scritto: The hardware path of vdosys1 with DPTx output need to go through by several modules, such as, OVL_ADAPTOR and MERGE. Add DRM and these modules support by the patches below: Hello maintainers, I have tested this series (and its dependencies - where [1] is needed to even be able to apply this one) on multiple machines featuring different MediaTek SoCs and everything works as expected on both oldies and new ones. I want to make sure you know that series [1] is also fine and has R-b tags, apart from the first commit (1/8) that in my opinion should be removed (or simply ignored while applying, as it's not impacting on any other change in that series, nor in this one). In my opinion, the two (vdosys0 and 1) series are ready to be picked. [1]: https://patchwork.kernel.org/project/linux-mediatek/list/?series=620795 Thank you all, Angelo Changes in v15: - fix ethdr uppercase hex number in dts Changes in v14: - remove MTK_MMSYS 64 bit dependency - add ethdr.yaml back and fix dt_schema check fail Resend v13 - add related maintainer in maillist Changes in v13: - fix reviewer comment in v12 - fix rdma dt-binding format - fix dts node naming - fix 32 bit build error - modify 64bit dependency for mtk-mmsys - rebase to vdosys0 series v16. (ref [5]) Changes in v12: - fix reviewer comment in v11 - modify mbox index - refine dma dev for ovl_adaptor sub driver Changes in v11: - remove ethdr vblank spin lock - refine ovl_adaptor print message Changes in v10: - refine ethdr reset control using devm_reset_control_array_get_optional_exclusive - fix ovl_adaptor mtk_ovl_adaptor_clk_enable error handle issue Changes in v9: - rebase on kernel-5.16-rc1 - rebase on vdosys0 series v13. (ref [5]) - fix ovl_adaptor sub driver is brought up unintentionally - fix clang build test fail- duplicate ethdr/mdp_rdma init_module/cleanup_module symbol issue Changes in v8: - separate merge async reset to new patch. - separate drm ovl_adaptor sub driver to new patch. - fix reviewer comment in v7. Changes in v7: - rebase on vdosys0 series v12 (ref[5]) - add dma description in ethdr binding document. - refine vdosys1 bit definition of mmsys routing table. - separate merge modification into 3 pathces. - separate mutex modification into 2 patches. - add plane color coding for mdp_rdma csc. - move mdp_rdma pm control to ovl_adaptor. - fix reviewer comment in v6. Changes in v6: - rebase on kernel-5.15-rc1. - change mbox label to gce0 for dts node of vdosys1. - modify mmsys reset num for mt8195. - rebase on vdosys0 series v10. (ref [5]) - use drm to bring up ovl_adaptor driver. - move drm iommu/mutex check from kms init to drm bind. - modify rdma binding doc location. (Documentation/devicetree/bindings/arm/) - modify for reviewer's comment in v5. Changes in v5: - add mmsys reset controller reference. Changes in v4: - use merge common driver for merge1~4. - refine ovl_adaptor rdma driver. - use ovl_adaptor ddp_comp function instead of ethdr. - modify for reviewer's comment in v3. Changes in v3: - modify for reviewer's comment in v2. - add vdosys1 2 pixels align limit. - add mixer odd offset support. Changes in v2: - Merge PSEUDO_OVL and ETHDR into one DRM component. - Add mmsys config API for vdosys1 hardware setting. - Add mmsys reset control using linux reset framework. Signed-off-by: Nancy.Lin This series are based on the following patch: [1] arm64: dts: Add mediatek SoC mt8195 and evaluation board https://patchwork.kernel.org/project/linux-mediatek/patch/20220112114724.1953-4-tinghan.s...@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/20220126090109.32143-1-jason-jh@mediatek.com/ [4] [v2] arm64: dts: mt8195: add display node for vdosys0 https://patchwork.kernel.org/project/linux-mediatek/patch/20220225021535.2655-1-jason-jh@mediatek.com/ [5] Add MediaTek SoC DRM (vdosys0) support for mt8195 https://patchwork.kernel.org/project/linux-mediatek/list/?series=620795 [6] dt-bindings: mediatek: mt8195: Add binding for MM IOMMU https://patchwork.kernel.org/project/linux-mediatek/patch/20220217113453.13658-2-yong...@mediatek.com/ Nancy.Lin (22): dt-bindings: mediatek: add vdosys1 RDMA definition for mt8195 dt-bindings: reset: mt8195: add vdosys1 reset control bit dt-bindings: mediatek: add ethdr definition for mt8195 soc: mediatek: add mtk-mmsys support for mt8195 vdosys1 soc: mediatek: add mtk-mmsys config API for mt8195 vdosys1 soc: mediatek: add cmdq support of mtk-mmsys config API for mt8195 vdosys1 soc: mediatek: mmsys: modify reset controller for MT8195 vdosys1 soc: mediatek: change the mutex defines and the mutex_mod type soc: mediatek: add mtk-mutex support for mt8195 vdosys1
Re: [Intel-gfx] [PATCH v6 2/2] drm/i915/gem: Don't try to map and fence large scanout buffers (v9)
On Mon, 7 Mar 2022 at 21:38, Vivek Kasireddy wrote: > > On platforms capable of allowing 8K (7680 x 4320) modes, pinning 2 or > more framebuffers/scanout buffers results in only one that is mappable/ > fenceable. Therefore, pageflipping between these 2 FBs where only one > is mappable/fenceable creates latencies large enough to miss alternate > vblanks thereby producing less optimal framerate. > > This mainly happens because when i915_gem_object_pin_to_display_plane() > is called to pin one of the FB objs, the associated vma is identified > as misplaced and therefore i915_vma_unbind() is called which unbinds and > evicts it. This misplaced vma gets subseqently pinned only when > i915_gem_object_ggtt_pin_ww() is called without PIN_MAPPABLE. This > results in a latency of ~10ms and happens every other vblank/repaint cycle. > Therefore, to fix this issue, we try to see if there is space to map > at-least two objects of a given size and return early if there isn't. This > would ensure that we do not try with PIN_MAPPABLE for any objects that > are too big to map thereby preventing unncessary unbind. > > Testcase: > Running Weston and weston-simple-egl on an Alderlake_S (ADLS) platform > with a 8K@60 mode results in only ~40 FPS. Since upstream Weston submits > a frame ~7ms before the next vblank, the latencies seen between atomic > commit and flip event are 7, 24 (7 + 16.66), 7, 24. suggesting that > it misses the vblank every other frame. > > Here is the ftrace snippet that shows the source of the ~10ms latency: > i915_gem_object_pin_to_display_plane() { > 0.102 us |i915_gem_object_set_cache_level(); > i915_gem_object_ggtt_pin_ww() { > 0.390 us | i915_vma_instance(); > 0.178 us | i915_vma_misplaced(); > i915_vma_unbind() { > __i915_active_wait() { > 0.082 us |i915_active_acquire_if_busy(); > 0.475 us | } > intel_runtime_pm_get() { > 0.087 us |intel_runtime_pm_acquire(); > 0.259 us | } > __i915_active_wait() { > 0.085 us |i915_active_acquire_if_busy(); > 0.240 us | } > __i915_vma_evict() { > ggtt_unbind_vma() { > gen8_ggtt_clear_range() { > 10507.255 us |} > 10507.689 us | } > 10508.516 us | } > > v2: Instead of using bigjoiner checks, determine whether a scanout > buffer is too big by checking to see if it is possible to map > two of them into the ggtt. > > v3 (Ville): > - Count how many fb objects can be fit into the available holes > instead of checking for a hole twice the object size. > - Take alignment constraints into account. > - Limit this large scanout buffer check to >= Gen 11 platforms. > > v4: > - Remove existing heuristic that checks just for size. (Ville) > - Return early if we find space to map at-least two objects. (Tvrtko) > - Slightly update the commit message. > > v5: (Tvrtko) > - Rename the function to indicate that the object may be too big to > map into the aperture. > - Account for guard pages while calculating the total size required > for the object. > - Do not subject all objects to the heuristic check and instead > consider objects only of a certain size. > - Do the hole walk using the rbtree. > - Preserve the existing PIN_NONBLOCK logic. > - Drop the PIN_MAPPABLE check while pinning the VMA. > > v6: (Tvrtko) > - Return 0 on success and the specific error code on failure to > preserve the existing behavior. > > v7: (Ville) > - Drop the HAS_GMCH(i915), DISPLAY_VER(i915) < 11 and > size < ggtt->mappable_end / 4 checks. > - Drop the redundant check that is based on previous heuristic. > > v8: > - Make sure that we are holding the mutex associated with ggtt vm > as we traverse the hole nodes. > > v9: (Tvrtko) > - Use mutex_lock_interruptible_nested() instead of mutex_lock(). > > Cc: Ville Syrjälä > Cc: Maarten Lankhorst > Cc: Tvrtko Ursulin > Cc: Manasi Navare > Reviewed-by: Tvrtko Ursulin > Signed-off-by: Vivek Kasireddy > --- > drivers/gpu/drm/i915/i915_gem.c | 128 +++- > 1 file changed, 94 insertions(+), 34 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c > index 9747924cc57b..e0d731b3f215 100644 > --- a/drivers/gpu/drm/i915/i915_gem.c > +++ b/drivers/gpu/drm/i915/i915_gem.c > @@ -49,6 +49,7 @@ > #include "gem/i915_gem_pm.h" > #include "gem/i915_gem_region.h" > #include "gem/i915_gem_userptr.h" > +#include "gem/i915_gem_tiling.h" > #include "gt/intel_engine_user.h" > #include "gt/intel_gt.h" > #include "gt/intel_gt_pm.h" > @@ -882,6 +883,96 @@ static void discard_ggtt_vma(struct i915_vma *vma) > spin_unlock(&obj->vma.lock); > } > > +static int > +i915_gem_object_fits_in_aperture(struct drm_i915_gem_object *obj, > +u64 alignment, u64 flags) Tvrtko asked me to ack the first patch, but th
[PATCH 2/2 RESEND] drm/bridge: Add extra checks in pre_enable and post_enable
Depending on the bridge code, certain userspace events during a driver teardown (such as a DRM ioctl call) might cause a race condition where the drm_bridge_chain_pre_enable() and drm_bridge_chain_post_enable() functions could be called for a bridge that has just been detached and removed from the bridge chain of an encoder. This change makes these functions a bit more robust by bailing out if the bridge has already been detached. Tested on an Acer Chromebook R13 (Elm, MT8173) with Debian Sid. Signed-off-by: Ricardo Cañuelo --- drivers/gpu/drm/drm_bridge.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index c96847fc0ebc..e074aa456dd1 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -529,7 +529,7 @@ void drm_bridge_chain_post_disable(struct drm_bridge *bridge) { struct drm_encoder *encoder; - if (!bridge) + if (!bridge || !bridge->dev) return; encoder = bridge->encoder; @@ -585,7 +585,7 @@ void drm_bridge_chain_pre_enable(struct drm_bridge *bridge) struct drm_encoder *encoder; struct drm_bridge *iter; - if (!bridge) + if (!bridge || !bridge->dev) return; encoder = bridge->encoder; -- 2.25.1
[PATCH 1/2 RESEND] drm/bridge: parade-ps8640: avoid race condition on driver unbinding
When unbinding a DRM master driver there's a race condition that sometimes results in an invalid vm access when userspace (gnome-shell) issues a DRM_IOCTL_MODE_GETCONNECTOR ioctl right after a bridge has been removed from an encoder's bridge chain. This means that once a bridge has been disabled and gone through ps8640_post_disable(), if ps8640_bridge_get_edid() runs afterwards as a result of that ioctl call it will call drm_bridge_chain_pre_enable() and drm_bridge_chain_post_disable() again in a bridge that has been already detached. Setting `ps_bridge->pre_enabled = false` at a later stage of the bringdown path and calling drm_bridge_chain_pre_enable() inside ps8640_bridge_get_edid() only if needed avoid this, although a proper subsystem-wide fix would be the proper solution, since the same type of race conditions might happen somewhere else. Tested on an Acer Chromebook R13 (Elm, MT8173) with Debian Sid. Signed-off-by: Ricardo Cañuelo --- drivers/gpu/drm/bridge/parade-ps8640.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c b/drivers/gpu/drm/bridge/parade-ps8640.c index 3f17337ee389..a927787a89bf 100644 --- a/drivers/gpu/drm/bridge/parade-ps8640.c +++ b/drivers/gpu/drm/bridge/parade-ps8640.c @@ -434,8 +434,6 @@ static void ps8640_post_disable(struct drm_bridge *bridge) { struct ps8640 *ps_bridge = bridge_to_ps8640(bridge); - ps_bridge->pre_enabled = false; - ps8640_bridge_vdo_control(ps_bridge, DISABLE); pm_runtime_put_sync_suspend(&ps_bridge->page[PAGE0_DP_CNTL]->dev); } @@ -487,6 +485,7 @@ static void ps8640_bridge_detach(struct drm_bridge *bridge) drm_dp_aux_unregister(&ps_bridge->aux); if (ps_bridge->link) device_link_del(ps_bridge->link); + ps_bridge->pre_enabled = false; } static struct edid *ps8640_bridge_get_edid(struct drm_bridge *bridge, @@ -508,7 +507,8 @@ static struct edid *ps8640_bridge_get_edid(struct drm_bridge *bridge, * EDID, for this chip, we need to do a full poweron, otherwise it will * fail. */ - drm_bridge_chain_pre_enable(bridge); + if (poweroff) + drm_bridge_chain_pre_enable(bridge); edid = drm_get_edid(connector, ps_bridge->page[PAGE0_DP_CNTL]->adapter); -- 2.25.1
[PATCH 0/2 RESEND] Mitigate race condition problems when unbinding DRM driver
Hi all, I'm sending these patches to try to improve the current situation for a particular corner case (DRM driver unbinding). I could reproduce a specific race condition during the unbinding of the mediatek-drm driver that caused an invalid memory address. The race condition is triggered by a userspace event (gnome-shell requesting a DRM GET_CONNECTOR ioctl) while the encoders and drivers are in the process of being disabled. While I tried to mitigate this by making a small change in the parade-ps8640 driver (for the bridge I'm testing on) and by making a couple of functions in drm_bridge.c more robust, this is only a symptom of a larger problem that might not be getting enough attention, understandably, because this is an unusual corner case. The scenario looks like this: : unbind mediatek-drm + || | || ... | | ... mtk_dsi_unbind | || `- drm_encoder_cleanup v | | gnome-shell ... `- drm_bridge_detach *<-- ioctl (GET_CONNECTOR) | | ... | | ps8640_bridge_get_edid | `drm_bridge_chain_post_disable which causes drm_bridge_chain_post_disable() to walk the bridge chain after the bridge has already been detached and removed from the list. I guess a more radical and subsystem-wide solution would be to not allow or to block certain ioctl calls once the driver has started to unbind, but I'd like to hear your opinion on this. This was tested on an Acer Chromebook R13 (Elm, MT8173) running Debian Sid, the command that triggers the race condition is echo mediatek-drm.12.auto > /sys/bus/platform/drivers/mediatek-drm/unbind Cheers, Ricardo Ricardo Cañuelo (2): drm/bridge: parade-ps8640: avoid race condition on driver unbinding drm/bridge: Add extra checks in pre_enable and post_enable drivers/gpu/drm/bridge/parade-ps8640.c | 6 +++--- drivers/gpu/drm/drm_bridge.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) -- 2.25.1
Re: [PATCH v15 01/22] dt-bindings: mediatek: add vdosys1 RDMA definition for mt8195
Il 11/03/22 02:54, Nancy.Lin ha scritto: Add vdosys1 RDMA definition. Signed-off-by: Nancy.Lin Reviewed-by: AngeloGioacchino Del Regno --- .../arm/mediatek/mediatek,mdp-rdma.yaml | 86 +++ 1 file changed, 86 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mdp-rdma.yaml diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mdp-rdma.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mdp-rdma.yaml new file mode 100644 index ..6ab773569462 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mdp-rdma.yaml @@ -0,0 +1,86 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/arm/mediatek/mediatek,mdp-rdma.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Mediatek MDP RDMA + +maintainers: + - Matthias Brugger + +description: | + The mediatek MDP RDMA stands for Read Direct Memory Access. + It provides real time data to the back-end panel driver, such as DSI, + DPI and DP_INTF. + It contains one line buffer to store the sufficient pixel data. + RDMA device node must be siblings to the central MMSYS_CONFIG node. + For a description of the MMSYS_CONFIG binding, see + Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details. + +properties: + compatible: +oneOf: + - items: + - const: mediatek,mt8195-vdo1-rdma + + reg: +maxItems: 1 + + interrupts: +maxItems: 1 + + power-domains: +description: A phandle and PM domain specifier as defined by bindings of + the power controller specified by phandle. See + Documentation/devicetree/bindings/power/power-domain.yaml for details. + + clocks: +items: + - description: RDMA Clock + + iommus: +description: + This property should point to the respective IOMMU block with master port as argument, + see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details. + + mediatek,gce-client-reg: +description: + The register of display function block to be set by gce. There are 4 arguments, + such as gce node, subsys id, offset and register size. The subsys id that is + mapping to the register of display function blocks is defined in the gce header + include/include/dt-bindings/gce/-gce.h of each chips. +$ref: /schemas/types.yaml#/definitions/phandle-array +maxItems: 1 + +required: + - compatible + - reg + - power-domains + - clocks + - iommus + +additionalProperties: false + +examples: + - | +#include +#include +#include +#include +#include + +soc { +#address-cells = <2>; +#size-cells = <2>; + +vdo1_rdma0: mdp-rdma@1c104000 { +compatible = "mediatek,mt8195-vdo1-rdma"; +reg = <0 0x1c104000 0 0x1000>; +interrupts = ; +clocks = <&vdosys1 CLK_VDO1_MDP_RDMA0>; +power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; +iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA0>; +mediatek,gce-client-reg = <&gce0 SUBSYS_1c10 0x4000 0x1000>; +}; +};
Re: [PATCH 1/3] drm/msm/gpu: Rename runtime suspend/resume functions
Il 11/03/22 00:46, Rob Clark ha scritto: From: Rob Clark Hey Rob, looks like you've somehow lost the commit description on this one! Cheers, Angelo Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/adreno_device.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
Re: [PATCH v5 1/5] arm64/dts/qcom/sc7280: remove assigned-clock-rate property for mdp clk
On Fri, 11 Mar 2022 at 11:06, Vinod Polimera wrote: > > > > > -Original Message- > > From: Stephen Boyd > > Sent: Wednesday, March 9, 2022 1:36 AM > > To: quic_vpolimer ; > > devicet...@vger.kernel.org; dri-devel@lists.freedesktop.org; > > freedr...@lists.freedesktop.org; linux-arm-...@vger.kernel.org > > Cc: linux-ker...@vger.kernel.org; robdcl...@gmail.com; > > diand...@chromium.org; quic_kalyant > > Subject: Re: [PATCH v5 1/5] arm64/dts/qcom/sc7280: remove assigned-clock- > > rate property for mdp clk > > > > WARNING: This email originated from outside of Qualcomm. Please be wary > > of any links or attachments, and do not enable macros. > > > > Quoting Vinod Polimera (2022-03-08 08:54:56) > > > Kernel clock driver assumes that initial rate is the > > > max rate for that clock and was not allowing it to scale > > > beyond the assigned clock value. > > > > How? I see ftbl_disp_cc_mdss_mdp_clk_src[] has multiple frequencies and > > clk_rcg2_shared_ops so it doesn't look like anything in the clk driver > > is preventing the frequency from changing beyond the assigned value. > > Folowing the comment of Stephen, i have checked a bit more. it appears that > clock driver is not setting the max clock from assgined clocks, dpu driver is > doing that. > i am planning to fix it as below. > 1) assign ULONG_MAX to max_rate while initializing clock in dpu driver. > 2) remove unnecessary checks in the core_perf library. If rate doesn't match > with the entries in the opp table, it will throw error, hence furthur checks > are not needed. > 3) no changes in dt are required. (we can drop all the posted ones) Why? They made perfect sense. The dts assignments should be replaced by the opp setting in the bind function, as this would also set the performance point of the respective power domain. > > Changes : > ```--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c > @@ -284,17 +284,6 @@ void dpu_core_perf_crtc_release_bw(struct drm_crtc *crtc) > } > } > > -static int _dpu_core_perf_set_core_clk_rate(struct dpu_kms *kms, u64 rate) > -{ > - struct dss_clk *core_clk = kms->perf.core_clk; > - > - if (core_clk->max_rate && (rate > core_clk->max_rate)) > - rate = core_clk->max_rate; > - > - core_clk->rate = rate; > - return dev_pm_opp_set_rate(&kms->pdev->dev, core_clk->rate); > -} > - > static u64 _dpu_core_perf_get_core_clk_rate(struct dpu_kms *kms) > { > u64 clk_rate = kms->perf.perf_tune.min_core_clk; > @@ -405,7 +394,7 @@ int dpu_core_perf_crtc_update(struct drm_crtc *crtc, > > trace_dpu_core_perf_update_clk(kms->dev, stop_req, clk_rate); > > - ret = _dpu_core_perf_set_core_clk_rate(kms, clk_rate); > + ret = dev_pm_opp_set_rate(&kms->pdev->dev, clk_rate); > if (ret) { > DPU_ERROR("failed to set %s clock rate %llu\n", > kms->perf.core_clk->clk_name, > clk_rate); > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c This file has been removed in msm/next > @@ -175,7 +175,7 @@ int msm_dss_parse_clock(struct platform_device *pdev, > continue; > mp->clk_config[i].rate = rate; > mp->clk_config[i].type = DSS_CLK_PCLK; > - mp->clk_config[i].max_rate = rate; > + mp->clk_config[i].max_rate = ULONG_MAX; > } > > mp->num_clk = num_clk; > --``` > > Thanks, > Vinod. > > > > > > > > > Drop the assigned clock rate property and vote on the mdp clock as per > > > calculated value during the usecase. > > > > > > Changes in v2: > > > - Remove assigned-clock-rate property and set mdp clk during resume > > sequence. > > > - Add fixes tag. > > > > > > Changes in v3: > > > - Remove extra line after fixes tag.(Stephen Boyd) > > > > This changelog should be removed. > > > > > > > > Fixes: 62fbdce91("arm64: dts: qcom: sc7280: add display dt nodes") > > > > I thought folks were saying that this is bad to keep? I don't really > > mind either way, but I guess it's better to drop the fixes tag because > > this is largely a performance improvement? > > > > > Signed-off-by: Vinod Polimera > > > Reviewed-by: Stephen Boyd -- With best wishes Dmitry