Re: (subset) [PATCH v2 07/22] drm/object: Add default zpos value at reset

2022-02-25 Thread Maxime Ripard
On Mon, 21 Feb 2022 10:59:03 +0100, Maxime Ripard wrote:
> From: Dave Stevenson 
> 
> The drm_plane_create_zpos_property() function asks for an initial value,
> and will set the associated plane state variable with that value if a
> state is present.
> 
> However, that function is usually called at a time where there's no
> state yet. Since the drm_plane_state reset helper doesn't take care of
> reading that value when it's called, it means that in most cases the
> initial value will be 0, or the drivers will have to work around it.
> 
> [...]

Applied to drm/drm-misc (drm-misc-next).

Thanks!
Maxime


Re: (subset) [PATCH v2 04/22] drm/omap: plane: Fix zpos initial value mismatch

2022-02-25 Thread Maxime Ripard
On Mon, 21 Feb 2022 10:59:00 +0100, Maxime Ripard wrote:
> While the omap_plane_init() function calls
> drm_plane_create_zpos_property() with an initial value of 0,
> omap_plane_reset() will force it to another value depending on the plane
> type.
> 
> Fix the discrepancy by setting the initial zpos value to the same value
> in the drm_plane_create_zpos_property() call.
> 
> [...]

Applied to drm/drm-misc (drm-misc-next).

Thanks!
Maxime


Re: (subset) [Nouveau] [PATCH v2 13/22] drm/nouveau/kms: Remove redundant zpos initialisation

2022-02-25 Thread Maxime Ripard
On Mon, 21 Feb 2022 10:59:09 +0100, Maxime Ripard wrote:
> The nouveau KMS driver will call drm_plane_create_zpos_property() with
> an init value depending on the plane purpose.
> 
> Since the initial value wasn't carried over in the state, the driver had
> to set it again in nv50_wndw_reset(). However, the helpers have been
> adjusted to set it properly at reset, so this is not needed anymore.
> 
> [...]

Applied to drm/drm-misc (drm-misc-next).

Thanks!
Maxime


Re: [Intel-gfx] [PATCH 0/3] Improve anti-pre-emption w/a for compute workloads

2022-02-25 Thread John Harrison

On 2/25/2022 08:36, Tvrtko Ursulin wrote:

On 24/02/2022 20:02, John Harrison wrote:

On 2/23/2022 04:00, Tvrtko Ursulin wrote:

On 23/02/2022 02:22, John Harrison wrote:

On 2/22/2022 01:53, Tvrtko Ursulin wrote:

On 18/02/2022 21:33, john.c.harri...@intel.com wrote:

From: John Harrison 

Compute workloads are inherently not pre-emptible on current 
hardware.

Thus the pre-emption timeout was disabled as a workaround to prevent
unwanted resets. Instead, the hang detection was left to the 
heartbeat

and its (longer) timeout. This is undesirable with GuC submission as
the heartbeat is a full GT reset rather than a per engine reset 
and so

is much more destructive. Instead, just bump the pre-emption timeout


Can we have a feature request to allow asking GuC for an engine 
reset?

For what purpose?


To allow "stopped heartbeat" to reset the engine, however..

GuC manages the scheduling of contexts across engines. With virtual 
engines, the KMD has no knowledge of which engine a context might 
be executing on. Even without virtual engines, the KMD still has no 
knowledge of which context is currently executing on any given 
engine at any given time.


There is a reason why hang detection should be left to the entity 
that is doing the scheduling. Any other entity is second guessing 
at best.


The reason for keeping the heartbeat around even when GuC 
submission is enabled is for the case where the KMD/GuC have got 
out of sync with either other somehow or GuC itself has just 
crashed. I.e. when no submission at all is working and we need to 
reset the GuC itself and start over.


.. I wasn't really up to speed to know/remember heartbeats are 
nerfed already in GuC mode.
Not sure what you mean by that claim. Engine resets are handled by 
GuC because GuC handles the scheduling. You can't do the former if 
you aren't doing the latter. However, the heartbeat is still present 
and is still the watchdog by which engine resets are triggered. As 
per the rest of the submission process, the hang detection and 
recovery is split between i915 and GuC.


I meant that "stopped heartbeat on engine XXX" can only do a full GPU 
reset on GuC.
I mean that there is no 'stopped heartbeat on engine XXX' when i915 is 
not handling the recovery part of the process.





intel_gt_handle_error(engine->gt, engine->mask,
  I915_ERROR_CAPTURE,
  "stopped heartbeat on %s",
  engine->name);

intel_gt_handle_error:

/*
 * Try engine reset when available. We fall back to full reset if
 * single reset fails.
 */
if (!intel_uc_uses_guc_submission(>uc) &&
    intel_has_reset_engine(gt) && !intel_gt_is_wedged(gt)) {
    local_bh_disable();
    for_each_engine_masked(engine, gt, engine_mask, tmp) {

You said "However, the heartbeat is still present and is still the 
watchdog by which engine resets are triggered", now I don't know what 
you meant by this. It actually triggers a single engine reset in GuC 
mode? Where in code does that happen if this block above shows it not 
taking the engine reset path?

i915 sends down the per engine pulse.
GuC schedules the pulse
GuC attempts to pre-empt the currently active context
GuC detects the pre-emption timeout
GuC resets the engine

The fundamental process is exactly the same as in execlist mode. It's 
just that the above blocks of code (calls to intel_gt_handle_error and 
such) are now inside the GuC not i915.


Without the heartbeat going ping, there would be no context switching 
and thus no pre-emption, no pre-emption timeout and so no hang and reset 
recovery. And GuC cannot sent pulses by itself - it has no ability to 
generate context workloads. So we need i915 to send the pings and to 
gradually raise their priority. But the back half of the heartbeat code 
is now inside the GuC. It will simply never reach the i915 side timeout 
if GuC is doing the recovery (unless the heartbeat's final period is too 
short). We should only reach the i915 side timeout if GuC itself is 
toast. At which point we need the full GT reset to recover the GuC.


John.




I am not sure it was the best way since full reset penalizes 
everyone for one hanging engine. Better question would be why leave 
heartbeats around to start with with GuC? If you want to use it to 
health check GuC, as you say, maybe just send a CT message and 
expect replies? Then full reset would make sense. It also achieves 
the goal of not seconding guessing the submission backend you raise.
Adding yet another hang detection mechanism is yet more complication 
and is unnecessary when we already have one that works well enough. 
As above, the heartbeat is still required for sending the pulses that 
cause pre-emptions and so let GuC detect hangs. It also provides a 
fallback against a dead GuC by default. So why invent yet another wheel?


Lets first clarify the previous block to make sure there aren't any 
misunderstandings there.


Regards,

Tvrtko

Like it 

Re: [Freedreno] [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment

2022-02-25 Thread Abhinav Kumar




On 2/25/2022 1:04 AM, Dmitry Baryshkov wrote:

On Fri, 25 Feb 2022 at 07:45, Abhinav Kumar  wrote:




On 2/24/2022 8:22 PM, Dmitry Baryshkov wrote:

On Fri, 25 Feb 2022 at 05:01, Abhinav Kumar  wrote:




On 2/24/2022 12:41 PM, Dmitry Baryshkov wrote:

On Thu, 24 Feb 2022 at 21:25, Abhinav Kumar  wrote:




On 2/18/2022 6:26 PM, Dmitry Baryshkov wrote:

On 19/02/2022 02:56, Stephen Boyd wrote:

Quoting Dmitry Baryshkov (2022-02-11 14:40:02)

In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
enable and disable") the DP driver received a drm_bridge instance, which
is always attached to the encoder as a root bridge. However it conflicts
with the panel_bridge support for eDP panels. The panel bridge attaches
to the encoder before the "dp" bridge has a chace to do so. Change


s/chace/chance/


panel_bridge attachment to come after dp_bridge attachment.


s/panel_bridge/panel bridge/ possibly? And maybe clarify that dp_bridge
is the "DP driver's drm_bridge instance created in
msm_dp_bridge_init()"?

My understanding is that we want to pass the bridge created in
msm_dp_bridge_init() as the 'previous' bridge so that it attaches the
panel bridge to the output of the DP bridge that's attached to the
encoder.


Thanks! I'll update the commit log when pushing the patches.


Please correct if i am missing something here.

You are right that the eDP panel's panel bridge attaches to the encoder
in dp_drm_connector_init() which happens before msm_dp_bridge_init() and
hence it will attach directly to the encoder.

But we are talking about different encoders here. DP's dp_display has a
different encoder compared to the EDP's dp_display.


The encoders are different. However both encoders use the same
codepath, which includes dp_bridge. It controls dp_display by calling
msm_dp_display_foo() functions.




So DP's bridge will still be attached to its encoder's root.


There is one dp_bridge per each encoder. Consider sc8180x which has 3
DP controllers (and thus 3 dp_bridges).



Sorry, but I still didnt follow this.

So for eDP, dp_drm_connector_init() will attach the panel_bridge
and then msm_dp_bridge_init() will add a drm_bridge.

And yes in that case, the drm_bridge will be after the panel_bridge

But since panel_bridge is at the root for eDP it should be okay.


No. It is not.
For both DP and eDP the chain should be:
dpu_encoder -> dp_bridge -> external (panel) bridge, optional for DP
-> [other bridges] -> connector

Otherwise drm_bridge_chain_foo() functions would be called in the
incorrect order.


Agreed. For drm_bridge_chain_foo() ordering to be correct, for eDP chain
the order should be what you mentioned and panel_bridge should be at the
end ( should be the last one ).

For the above reason,

Reviewed-by: Abhinav Kumar 

I still didnt understand what gets affected by this for the
msm_dp_display_foo() functions you mentioned earlier and wanted to get
some clarity on that.


They should be called at the correct time.



Thus the dp_bridge should be attached directly to the encoder
(drm_encoder) and panel_bridge should use dp_bridge as the 'previous'
bridge.



Agreed.


For example, for the DP port one can use a display-connector (which
actually implements drm_bridge) as an external bridge to provide hpd
or dp power GPIOs.

Note, that the current dp_connector breaks layering. It makes calls
directly into dp_display, not allowing external bridge (and other
bridges) to override get_modes/mode_valid and other callbacks.
Thus one of the next patches in series (the one that Kuogee had issues
with) tries to replace the chain with the following one:
dpu_encoder -> dp_bridge -> external (panel) bridge -> [other bridges]
-> drm_bridge_connector.





So originally the plan was always that the DP connector layer intercepts
the call because panel-eDP file did not support reading of the EDID ( we
have not provided the aux bus ). So it was intended that we did not want
to goto the eDP panel to get the modes. Not an error but something which
we wanted to cleanup later when we moved to panel-eDP completely.


panel_edp_get_modes() correctly handles this case and returns modes
specified in the panel description. So the code should work even with
panel-eDP and w/o the AUX bus.



If hard-coded modes are not present, it will fail in below case:

/*
 * Add hard-coded panel modes. Don't call this if there are no timings
 * and no modes (the generic edp-panel case) because it will clobber
 * the display_info that was already set by drm_add_edid_modes().
 */
if (p->desc->num_timings || p->desc->num_modes)
num += panel_edp_get_non_edid_modes(p, connector);
else if (!num)
dev_warn(p->base.dev, "No display modes\n");

Thats exactly the error he was seeing.



Till then we wanted the dp_connector to read the EDID and get the modes.

So this was actually intended to happen till the point where we moved to
panel-eDP to get the modes.

Hence what you have mentioned in your 

linux-next: manual merge of the drm-intel tree with the drm-intel-fixes tree

2022-02-25 Thread broonie
Hi all,

Today's linux-next merge of the drm-intel tree got a conflict in:

  drivers/gpu/drm/i915/display/intel_snps_phy.c

between commit:

  28adef861233c ("drm/i915/dg2: Print PHY name properly on calibration error")

from the drm-intel-fixes tree and commits:

  84073e568eec7 ("drm/i915/dg2: Print PHY name properly on calibration error")
  b4eb76d82a0ea ("drm/i915/dg2: Skip output init on PHY calibration failure")

from the drm-intel tree.

I fixed it up (see below) and can carry the fix as necessary. This
is now fixed as far as linux-next is concerned, but any non trivial
conflicts should be mentioned to your upstream maintainer when your tree
is submitted for merging.  You may also want to consider cooperating
with the maintainer of the conflicting tree to minimise any particularly
complex conflicts.

[Used drm-intel version]


Re: [Intel-gfx] [PATCH 1/3] drm/i915/guc: Limit scheduling properties to avoid overflow

2022-02-25 Thread Tvrtko Ursulin



On 24/02/2022 19:19, John Harrison wrote:

[snip]


./gt/uc/intel_guc_fwif.h:   u32 execution_quantum;

./gt/uc/intel_guc_submission.c: desc->execution_quantum = 
engine->props.timeslice_duration_ms * 1000;


./gt/intel_engine_types.h:  unsigned long 
timeslice_duration_ms;


timeslice_store/preempt_timeout_store:
err = kstrtoull(buf, 0, );

So both kconfig and sysfs can already overflow GuC, not only 
because of tick conversion internally but because at backend level 
nothing was done for assigning 64-bit into 32-bit. Or I failed to 
find where it is handled.
That's why I'm adding this range check to make sure we don't allow 
overflows.


Yes and no, this fixes it, but the first bug was not only due GuC 
internal tick conversion. It was present ever since the u64 from 
i915 was shoved into u32 sent to GuC. So even if GuC used the value 
without additional multiplication, bug was be there. My point being 
when GuC backend was added timeout_ms values should have been 
limited/clamped to U32_MAX. The tick discovery is additional limit 
on top.
I'm not disagreeing. I'm just saying that the truncation wasn't 
noticed until I actually tried using very long timeouts to debug a 
particular problem. Now that it is noticed, we need some method of 
range checking and this simple clamp solves all the truncation problems.


Agreed in principle, just please mention in the commit message all 
aspects of the problem.


I think we can get away without a Fixes: tag since it requires user 
fiddling to break things in unexpected ways.


I would though put in a code a clamping which expresses both, 
something like min(u32, ..GUC LIMIT..). So the full story is 
documented forever. Or "if > u32 || > ..GUC LIMIT..) return -EINVAL". 
Just in case GuC limit one day changes but u32 stays. Perhaps internal 
ticks go away or anything and we are left with plain 1:1 millisecond 
relationship.
Can certainly add a comment along the lines of "GuC API only takes a 
32bit field but that is further reduced to GUC_LIMIT due to internal 
calculations which would otherwise overflow".


But if the GuC limit is > u32 then, by definition, that means the GuC 
API has changed to take a u64 instead of a u32. So there will no u32 
truncation any more. So I'm not seeing a need to explicitly test the 
integer size when the value check covers that.


Hmm I was thinking if the internal conversion in the GuC fw changes so that 
GUC_POLICY_MAX_PREEMPT_TIMEOUT_MS goes above u32, then to be extra safe by 
documenting in code there is the additional limit of the data structure field. 
Say the field was changed to take some unit larger than a millisecond. Then the 
check against the GuC MAX limit define would not be enough, unless that would 
account both for internal implementation and u32 in the protocol. Maybe that is 
overdefensive but I don't see that it harms. 50-50, but it's do it once and 
forget so I'd do it.


Signed-off-by: John Harrison 
---
  drivers/gpu/drm/i915/gt/intel_engine_cs.c   | 15 +++
  drivers/gpu/drm/i915/gt/sysfs_engines.c | 14 ++
  drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h |  9 +
  3 files changed, 38 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
b/drivers/gpu/drm/i915/gt/intel_engine_cs.c

index e53008b4dd05..2a1e9f36e6f5 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -389,6 +389,21 @@ static int intel_engine_setup(struct 
intel_gt *gt, enum intel_engine_id id,

  if (GRAPHICS_VER(i915) == 12 && engine->class == RENDER_CLASS)
  engine->props.preempt_timeout_ms = 0;
  +    /* Cap timeouts to prevent overflow inside GuC */
+    if (intel_guc_submission_is_wanted(>uc.guc)) {
+    if (engine->props.timeslice_duration_ms > 
GUC_POLICY_MAX_EXEC_QUANTUM_MS) {


Hm "wanted".. There's been too much back and forth on the GuC load 
options over the years to keep track.. intel_engine_uses_guc work 
sounds like would work and read nicer.
I'm not adding a new feature check here. I'm just using the 
existing one. If we want to rename it yet again then that would be 
a different patch set.


$ grep intel_engine_uses_guc . -rl
./i915_perf.c
./i915_request.c
./selftests/intel_scheduler_helpers.c
./gem/i915_gem_context.c
./gt/intel_context.c
./gt/intel_engine.h
./gt/intel_engine_cs.c
./gt/intel_engine_heartbeat.c
./gt/intel_engine_pm.c
./gt/intel_reset.c
./gt/intel_lrc.c
./gt/selftest_context.c
./gt/selftest_engine_pm.c
./gt/selftest_hangcheck.c
./gt/selftest_mocs.c
./gt/selftest_workarounds.c

Sounds better to me than intel_guc_submission_is_wanted. What does 
the reader know whether "is wanted" translates to "is actually 
used". Shrug on "is wanted".
Yes, but isn't '_uses' the one that hits a BUG_ON if you call it too 
early in the boot up sequence? I never understood why that was 
necessary or why we need so many different ways to ask the same 
question. But this version already exists and 

Re: [PATCH v12 1/6] drm: Add arch arm64 for drm_clflush_virt_range

2022-02-25 Thread Michael Cheng

Hi Tvrtko,

It seems without cacheflush.h being included, when I build for arm64 or 
x86, it stills pulls in cacheflush.h:


./.drm_cache.o.cmd:838: include/linux/cacheflush.h \
./.drm_cache.o.cmd:839: arch/x86/include/asm/cacheflush.h \
./.drm_cache.o.cmd:920: include/asm-generic/cacheflush.h \
./.drm_cache.o.cmd:830: include/linux/cacheflush.h \
./.drm_cache.o.cmd:831: arch/arm64/include/asm/cacheflush.h \
./.drm_cache.o.cmd:1085: include/asm-generic/cacheflush.h \
So it seems without including it, cacheflush.h stills get pulled in,
I think its because its a required kernel source to build the kernel
per specific architecture, but please correct if I am wrong,as I am still
trying to understand how things works!
Michael Cheng
On 2022-02-25 8:28 a.m., Tvrtko Ursulin wrote:


On 25/02/2022 03:24, Michael Cheng wrote:

Add arm64 support for drm_clflush_virt_range. caches_clean_inval_pou
performs a flush by first performing a clean, follow by an invalidation
operation.

v2 (Michael Cheng): Use correct macro for cleaning and invalidation the
    dcache. Thanks Tvrtko for the suggestion.

v3 (Michael Cheng): Replace asm/cacheflush.h with linux/cacheflush.h

v4 (Michael Cheng): Arm64 does not export dcache_clean_inval_poc as a
    symbol that could be use by other modules, thus use
    caches_clean_inval_pou instead. Also this version
    removes include for cacheflush, since its already
    included base on architecture type.


What does it mean that it is included based on architecture type? Some 
of the other header already pulls it in?


Regards,

Tvrtko


Signed-off-by: Michael Cheng 
Reviewed-by: Matt Roper 
---
  drivers/gpu/drm/drm_cache.c | 5 +
  1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c
index c3e6e615bf09..81c28714f930 100644
--- a/drivers/gpu/drm/drm_cache.c
+++ b/drivers/gpu/drm/drm_cache.c
@@ -174,6 +174,11 @@ drm_clflush_virt_range(void *addr, unsigned long 
length)

    if (wbinvd_on_all_cpus())
  pr_err("Timed out waiting for cache flush\n");
+
+#elif defined(CONFIG_ARM64)
+    void *end = addr + length;
+    caches_clean_inval_pou((unsigned long)addr, (unsigned long)end);
+
  #else
  WARN_ONCE(1, "Architecture has no drm_cache.c support\n");
  #endif

Re: [Intel-gfx] [PATCH v5 1/4] drm/i915/guc: Add fetch of hwconfig table

2022-02-25 Thread John Harrison

On 2/25/2022 05:26, Tvrtko Ursulin wrote:

On 25/02/2022 09:44, Michal Wajdeczko wrote:

On 25.02.2022 06:03, Jordan Justen wrote:

John Harrison  writes:


On 2/22/2022 02:36, Jordan Justen wrote:

From: John Harrison 

Implement support for fetching the hardware description table from 
the

GuC. The call is made twice - once without a destination buffer to
query the size and then a second time to fill in the buffer.

Note that the table is only available on ADL-P and later platforms.

v5 (of Jordan's posting):
   * Various changes made by Jordan and recommended by Michal
 - Makefile ordering
 - Adjust "struct intel_guc_hwconfig hwconfig" comment
 - Set Copyright year to 2022 in intel_guc_hwconfig.c/.h
 - Drop inline from hwconfig_to_guc()
 - Replace hwconfig param with guc in __guc_action_get_hwconfig()
 - Move zero size check into guc_hwconfig_discover_size()
 - Change comment to say zero size offset/size is needed to 
get size

 - Add has_guc_hwconfig to devinfo and drop has_table()
 - Change drm_err to notice in __uc_init_hw() and use %pe

Cc: Michal Wajdeczko 
Signed-off-by: Rodrigo Vivi 
Signed-off-by: John Harrison 
Reviewed-by: Matthew Brost 
Acked-by: Jon Bloomfield 
Signed-off-by: Jordan Justen 
---
   +    ret = intel_guc_hwconfig_init(>hwconfig);
+    if (ret)
+    drm_notice(>drm, "Failed to retrieve hwconfig 
table: %pe\n",

Why only drm_notice? As you are keen to point out, the UMDs won't work
if the table is not available. All the failure paths in your own
verification function are 'drm_err'. So why is it only a 'notice' if
there is no table at all?


This was requested by Michal in my v3 posting:

https://patchwork.freedesktop.org/patch/472936/?series=99787=3

I don't think that it should be a failure for i915 if it is unable to
read the table, or if the table read is invalid. I think it should 
be up

to the UMD to react to the missing hwconfig however they think is
appropriate, but I would like the i915 to guarantee & document the
format returned to userspace to whatever extent is feasible.

As you point out there is a discrepancy, and I think I should be
consistent with whatever is used here in my "drm/i915/guc: Verify
hwconfig blob matches supported format" patch.

I guess I'd tend to agree with Michal that "maybe drm_notice since we
continue probe", but I would go along with either if you two want to
discuss further.


having consistent message level is a clear benefit but on other hand
these other 'errors' may indicate more serious problems related to use
of wrong/incompatible firmware that returns corrupted HWconfig (or we
use wrong actions), while since we are not using this HWconfig in the
As stated ad nauseam, you can rule out 'corrupted' hwconfig. The GuC 
firmware is signed and will not load if it has become corrupted somehow. 
Likewise, a 'wrong/incompatible' firmware will refuse to load. So it is 
physically impossible for the later verification stage to ever find an 
error.




driver we don't care that much that we failed to load HWconfig and
'notice' is enough.

but I'm fine with all messages being drm_err (as we will not have to
change that once again after HWconfig will be mandatory for the driver
as well)


I would be against drm_err.

#define KERN_EMERG  KERN_SOH "0"    /* system is unusable */
#define KERN_ALERT  KERN_SOH "1"    /* action must be taken 
immediately */

#define KERN_CRIT   KERN_SOH "2"    /* critical conditions */
#define KERN_ERR    KERN_SOH "3"    /* error conditions */
#define KERN_WARNING    KERN_SOH "4"    /* warning conditions */
#define KERN_NOTICE KERN_SOH "5"    /* normal but significant 
condition */

#define KERN_INFO   KERN_SOH "6"    /* informational */
#define KERN_DEBUG  KERN_SOH "7"    /* debug-level messages */

From the point of view of the kernel driver, this is not an error to 
its operation. It can at most be a warning, but notice is also fine by 
me. One could argue when reading "normal but significant condition" 
that it is not normal, when it is in fact unexpected, so if people 
prefer warning that is also okay by me. I still lean towards notice 
becuase of the hands-off nature i915 has with the pass-through of this 
blob.
From the point of view of the KMD, i915 will load and be 'functional' 
if it can't talk to the hardware at all. The UMDs won't work at all but 
the driver load will be 'fine'. That's a requirement to be able to get 
the user to a software fallback desktop in order to work out why the 
hardware isn't working (e.g. no GuC firmware file). I would view this as 
similar. The KMD might have loaded but the UMDs are not functional. That 
is definitely an error condition to me.





Note that this function is called as part of the reset path. The reset
path is not allowed to allocate memory. The table is stored in a
dynamically allocated object. Hence the IGT test failure. The table
query has to be done elsewhere at driver init time only.


Thanks 

linux-next: build failure after merge of the drm tree

2022-02-25 Thread broonie
Hi all,

After merging the drm tree, today's linux-next build (x86 allmodconfig)
failed like this:

lib/strncpy_from_user.o: warning: objtool: strncpy_from_user()+0x10b: call to 
do_strncpy_from_user() with UACCESS enabled
lib/strnlen_user.o: warning: objtool: strnlen_user()+0xbb: call to 
do_strnlen_user() with UACCESS enabled
/tmp/next/build/drivers/gpu/drm/bridge/ite-it6505.c: In function 
'receive_timing_debugfs_show':
/tmp/next/build/drivers/gpu/drm/bridge/ite-it6505.c:3077:23: error: array 
subscript 4096 is outside array bounds of 'u8[200]' {aka 'unsigned char[200]'} 
[-Werror=array-bounds]
 3077 |  u8 *str = read_buf, *end = read_buf + PAGE_SIZE;
  |   ^~~
/tmp/next/build/drivers/gpu/drm/bridge/ite-it6505.c:3076:5: note: while 
referencing 'read_buf'
 3076 |  u8 read_buf[READ_BUFFER_SIZE];
  | ^~~~
/tmp/next/build/drivers/gpu/drm/bridge/ite-it6505.c:3077:23: error: array 
subscript 4096 is outside array bounds of 'u8[200]' {aka 'unsigned char[200]'} 
[-Werror=array-bounds]
 3077 |  u8 *str = read_buf, *end = read_buf + PAGE_SIZE;
  |   ^~~
/tmp/next/build/drivers/gpu/drm/bridge/ite-it6505.c:3076:5: note: while 
referencing 'read_buf'
 3076 |  u8 read_buf[READ_BUFFER_SIZE];
  | ^~~~
/tmp/next/build/drivers/gpu/drm/bridge/ite-it6505.c:3077:23: error: array 
subscript 4096 is outside array bounds of 'u8[200]' {aka 'unsigned char[200]'} 
[-Werror=array-bounds]
 3077 |  u8 *str = read_buf, *end = read_buf + PAGE_SIZE;
  |   ^~~
/tmp/next/build/drivers/gpu/drm/bridge/ite-it6505.c:3076:5: note: while 
referencing 'read_buf'
 3076 |  u8 read_buf[READ_BUFFER_SIZE];
  | ^~~~
/tmp/next/build/drivers/gpu/drm/bridge/ite-it6505.c:3077:23: error: array 
subscript 4096 is outside array bounds of 'u8[200]' {aka 'unsigned char[200]'} 
[-Werror=array-bounds]
 3077 |  u8 *str = read_buf, *end = read_buf + PAGE_SIZE;
  |   ^~~
/tmp/next/build/drivers/gpu/drm/bridge/ite-it6505.c:3076:5: note: while 
referencing 'read_buf'
 3076 |  u8 read_buf[READ_BUFFER_SIZE];
  | ^~~~
/tmp/next/build/drivers/gpu/drm/bridge/ite-it6505.c:3077:23: error: array 
subscript 4096 is outside array bounds of 'u8[200]' {aka 'unsigned char[200]'} 
[-Werror=array-bounds]
 3077 |  u8 *str = read_buf, *end = read_buf + PAGE_SIZE;
  |   ^~~
/tmp/next/build/drivers/gpu/drm/bridge/ite-it6505.c:3076:5: note: while 
referencing 'read_buf'
 3076 |  u8 read_buf[READ_BUFFER_SIZE];
  | ^~~~
/tmp/next/build/drivers/gpu/drm/bridge/ite-it6505.c:3077:23: error: array 
subscript 4096 is outside array bounds of 'u8[200]' {aka 'unsigned char[200]'} 
[-Werror=array-bounds]
 3077 |  u8 *str = read_buf, *end = read_buf + PAGE_SIZE;
  |   ^~~
/tmp/next/build/drivers/gpu/drm/bridge/ite-it6505.c:3076:5: note: while 
referencing 'read_buf'
 3076 |  u8 read_buf[READ_BUFFER_SIZE];
  | ^~~~
/tmp/next/build/drivers/gpu/drm/bridge/ite-it6505.c:3077:23: error: array 
subscript 4096 is outside array bounds of 'u8[200]' {aka 'unsigned char[200]'} 
[-Werror=array-bounds]
 3077 |  u8 *str = read_buf, *end = read_buf + PAGE_SIZE;
  |   ^~~
/tmp/next/build/drivers/gpu/drm/bridge/ite-it6505.c:3076:5: note: while 
referencing 'read_buf'
 3076 |  u8 read_buf[READ_BUFFER_SIZE];
  | ^~~~
/tmp/next/build/drivers/gpu/drm/bridge/ite-it6505.c:3077:23: error: array 
subscript 4096 is outside array bounds of 'u8[200]' {aka 'unsigned char[200]'} 
[-Werror=array-bounds]
 3077 |  u8 *str = read_buf, *end = read_buf + PAGE_SIZE;
  |   ^~~
/tmp/next/build/drivers/gpu/drm/bridge/ite-it6505.c:3076:5: note: while 
referencing 'read_buf'
 3076 |  u8 read_buf[READ_BUFFER_SIZE];
  | ^~~~
/tmp/next/build/drivers/gpu/drm/bridge/ite-it6505.c:3077:23: error: array 
subscript 4096 is outside array bounds of 'u8[200]' {aka 'unsigned char[200]'} 
[-Werror=array-bounds]
 3077 |  u8 *str = read_buf, *end = read_buf + PAGE_SIZE;
  |   ^~~
/tmp/next/build/drivers/gpu/drm/bridge/ite-it6505.c:3076:5: note: while 
referencing 'read_buf'
 3076 |  u8 read_buf[READ_BUFFER_SIZE];
  | ^~~~
/tmp/next/build/drivers/gpu/drm/bridge/ite-it6505.c:3077:23: error: array 
subscript 4096 is outside array bounds of 'u8[200]' {aka 'unsigned char[200]'} 
[-Werror=array-bounds]
 3077 |  u8 *str = read_buf, *end = read_buf + PAGE_SIZE;
  |   ^~~
/tmp/next/build/drivers/gpu/drm/bridge/ite-it6505.c:3076:5: note: while 
referencing 'read_buf'
 3076 |  u8 read_buf[READ_BUFFER_SIZE];
  | ^~~~
/tmp/next/build/drivers/gpu/drm/bridge/ite-it6505.c:3077:23: error: array 
subscript 4096 is outside array bounds of 'u8[200]' {aka 'unsigned char[200]'} 
[-Werror=array-bounds]
 3077 |  u8 *str = read_buf, *end = read_buf + PAGE_SIZE;
  |   ^~~

linux-next: manual merge of the drm tree with the drm-fixes tree

2022-02-25 Thread broonie
Hi all,

Today's linux-next merge of the drm tree got a conflict in:

  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c

between commit:

  e2b993302f40c ("drm/amdgpu: bypass tiling flag check in virtual display case 
(v2)")

from the drm-fixes tree and commit:

  2af104290da5e ("drm: introduce fb_modifiers_not_supported flag in 
mode_config")

from the drm tree.

I fixed it up (see below) and can carry the fix as necessary. This
is now fixed as far as linux-next is concerned, but any non trivial
conflicts should be mentioned to your upstream maintainer when your tree
is submitted for merging.  You may also want to consider cooperating
with the maintainer of the conflicting tree to minimise any particularly
complex conflicts.

diff --cc drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index c4387b38229c2,9e5fc4cdb8ec9..0
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@@ -1141,7 -1148,7 +1148,7 @@@ int amdgpu_display_framebuffer_init(str
if (ret)
return ret;
  
-   if (!dev->mode_config.allow_fb_modifiers && 
!adev->enable_virtual_display) {
 -  if (dev->mode_config.fb_modifiers_not_supported) {
++  if (dev->mode_config.fb_modifiers_not_supported && 
!adev->enable_virtual_display) {
drm_WARN_ONCE(dev, adev->family >= AMDGPU_FAMILY_AI,
  "GFX9+ requires FB check based on format 
modifier\n");
ret = check_tiling_flags_gfx6(rfb);


Re: [Intel-gfx] [PATCH 0/3] Improve anti-pre-emption w/a for compute workloads

2022-02-25 Thread Tvrtko Ursulin



On 24/02/2022 20:02, John Harrison wrote:

On 2/23/2022 04:00, Tvrtko Ursulin wrote:

On 23/02/2022 02:22, John Harrison wrote:

On 2/22/2022 01:53, Tvrtko Ursulin wrote:

On 18/02/2022 21:33, john.c.harri...@intel.com wrote:

From: John Harrison 

Compute workloads are inherently not pre-emptible on current hardware.
Thus the pre-emption timeout was disabled as a workaround to prevent
unwanted resets. Instead, the hang detection was left to the heartbeat
and its (longer) timeout. This is undesirable with GuC submission as
the heartbeat is a full GT reset rather than a per engine reset and so
is much more destructive. Instead, just bump the pre-emption timeout


Can we have a feature request to allow asking GuC for an engine reset?

For what purpose?


To allow "stopped heartbeat" to reset the engine, however..

GuC manages the scheduling of contexts across engines. With virtual 
engines, the KMD has no knowledge of which engine a context might be 
executing on. Even without virtual engines, the KMD still has no 
knowledge of which context is currently executing on any given engine 
at any given time.


There is a reason why hang detection should be left to the entity 
that is doing the scheduling. Any other entity is second guessing at 
best.


The reason for keeping the heartbeat around even when GuC submission 
is enabled is for the case where the KMD/GuC have got out of sync 
with either other somehow or GuC itself has just crashed. I.e. when 
no submission at all is working and we need to reset the GuC itself 
and start over.


.. I wasn't really up to speed to know/remember heartbeats are nerfed 
already in GuC mode.
Not sure what you mean by that claim. Engine resets are handled by GuC 
because GuC handles the scheduling. You can't do the former if you 
aren't doing the latter. However, the heartbeat is still present and is 
still the watchdog by which engine resets are triggered. As per the rest 
of the submission process, the hang detection and recovery is split 
between i915 and GuC.


I meant that "stopped heartbeat on engine XXX" can only do a full GPU reset on 
GuC.

intel_gt_handle_error(engine->gt, engine->mask,
  I915_ERROR_CAPTURE,
  "stopped heartbeat on %s",
  engine->name);

intel_gt_handle_error:

/*
 * Try engine reset when available. We fall back to full reset if
 * single reset fails.
 */
if (!intel_uc_uses_guc_submission(>uc) &&
intel_has_reset_engine(gt) && !intel_gt_is_wedged(gt)) {
local_bh_disable();
for_each_engine_masked(engine, gt, engine_mask, tmp) {

You said "However, the heartbeat is still present and is still the watchdog by which 
engine resets are triggered", now I don't know what you meant by this. It actually 
triggers a single engine reset in GuC mode? Where in code does that happen if this block 
above shows it not taking the engine reset path?

I am not sure it was the best way since full reset penalizes everyone 
for one hanging engine. Better question would be why leave heartbeats 
around to start with with GuC? If you want to use it to health check 
GuC, as you say, maybe just send a CT message and expect replies? Then 
full reset would make sense. It also achieves the goal of not 
seconding guessing the submission backend you raise.
Adding yet another hang detection mechanism is yet more complication and 
is unnecessary when we already have one that works well enough. As 
above, the heartbeat is still required for sending the pulses that cause 
pre-emptions and so let GuC detect hangs. It also provides a fallback 
against a dead GuC by default. So why invent yet another wheel?


Lets first clarify the previous block to make sure there aren't any 
misunderstandings there.

Regards,

Tvrtko

Like it is now, and the need for this series demonstrates it, the 
whole thing has a pretty poor "impedance" match. Not even sure what 
intel_guc_find_hung_context is doing in intel_engine_hearbeat.c - why 
is that not in intel_gt_handle_error at least? Why is hearbeat code 
special and other callers of intel_gt_handle_error don't need it?
There is no guilty context if the reset was triggered via debugfs or 
similar. And as stated ad nauseam, i915 is no longer handling the 
scheduling and so cannot make assumptions about what is or is not 
running on the hardware at any given time. And obviously, if the reset 
initiated by GuC itself then i915 should not be second guessing the 
guilty context as the GuC notification has already told us who was 
responsible.


And to be clear, the 'poor impedance match' is purely because we don't 
have mid-thread pre-emption and so need a stupidly huge timeout on 
compute capable engines. Whereas, we don't want a total heatbeat timeout 
of a minute or more. That is the impedance mis-match. If the 640ms was 
acceptable for RCS then none of this hacky timeout 

[GIT PULL] drm/tegra: Changes for v5.18-rc1

2022-02-25 Thread Thierry Reding
Hi Dave, Daniel,

The following changes since commit 8913e1aea4b32a866343b14e565c62cec54f3f78:

  drm/tegra: dpaux: Populate AUX bus (2022-02-23 13:00:37 +0100)

are available in the Git repository at:

  https://gitlab.freedesktop.org/drm/tegra.git tags/drm/tegra/for-5.18-rc1

for you to fetch changes up to b53c24f69199b88671293de503f1f999a762f4f9:

  drm/tegra: Support YVYU, VYUY and YU24 formats (2022-02-25 16:37:40 +0100)

Thanks,
Thierry


drm/tegra: Changes for v5.18-rc1

This contains a couple more minor fixes that didn't seem urgent enough
for v5.17. On top of that this improves YUV format support on older
chips.


Christophe JAILLET (2):
  gpu: host1x: Fix an error handling path in 'host1x_probe()'
  gpu: host1x: Fix a memory leak in 'host1x_remove()'

Dmitry Osipenko (1):
  drm/tegra: Use dev_err_probe()

Miaoqian Lin (1):
  drm/tegra: Fix reference leak in tegra_dsi_ganged_probe

Thierry Reding (3):
  drm/tegra: Fix planar formats on Tegra186 and later
  drm/tegra: Support semi-planar formats on Tegra114+
  drm/tegra: Support YVYU, VYUY and YU24 formats

chiminghao (1):
  drm/tegra: dpaux: Remove unneeded variable

 drivers/gpu/drm/tegra/dc.c| 50 ++---
 drivers/gpu/drm/tegra/dc.h|  7 +
 drivers/gpu/drm/tegra/dpaux.c |  3 +-
 drivers/gpu/drm/tegra/dsi.c   |  4 ++-
 drivers/gpu/drm/tegra/hdmi.c  | 34 ++--
 drivers/gpu/drm/tegra/hub.c   | 24 --
 drivers/gpu/drm/tegra/plane.c | 73 ++-
 drivers/gpu/drm/tegra/plane.h |  2 +-
 drivers/gpu/host1x/dev.c  |  8 +++--
 9 files changed, 140 insertions(+), 65 deletions(-)


Re: [PATCH v3, 1/7] dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for lat soc

2022-02-25 Thread Rob Herring
On Thu, 17 Feb 2022 15:57:52 +0800, Yunfei Dong wrote:
> Adds decoder dt-bindings for compatible "mediatek,mtk-vcodec-lat-soc".
> 
> Signed-off-by: Yunfei Dong 
> ---
>  .../media/mediatek,vcodec-subdev-decoder.yaml | 51 +--
>  1 file changed, 35 insertions(+), 16 deletions(-)
> 

Acked-by: Rob Herring 


Re: [PATCH v12 1/6] drm: Add arch arm64 for drm_clflush_virt_range

2022-02-25 Thread Tvrtko Ursulin



On 25/02/2022 03:24, Michael Cheng wrote:

Add arm64 support for drm_clflush_virt_range. caches_clean_inval_pou
performs a flush by first performing a clean, follow by an invalidation
operation.

v2 (Michael Cheng): Use correct macro for cleaning and invalidation the
dcache. Thanks Tvrtko for the suggestion.

v3 (Michael Cheng): Replace asm/cacheflush.h with linux/cacheflush.h

v4 (Michael Cheng): Arm64 does not export dcache_clean_inval_poc as a
symbol that could be use by other modules, thus use
caches_clean_inval_pou instead. Also this version
removes include for cacheflush, since its already
included base on architecture type.


What does it mean that it is included based on architecture type? Some 
of the other header already pulls it in?


Regards,

Tvrtko


Signed-off-by: Michael Cheng 
Reviewed-by: Matt Roper 
---
  drivers/gpu/drm/drm_cache.c | 5 +
  1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c
index c3e6e615bf09..81c28714f930 100644
--- a/drivers/gpu/drm/drm_cache.c
+++ b/drivers/gpu/drm/drm_cache.c
@@ -174,6 +174,11 @@ drm_clflush_virt_range(void *addr, unsigned long length)
  
  	if (wbinvd_on_all_cpus())

pr_err("Timed out waiting for cache flush\n");
+
+#elif defined(CONFIG_ARM64)
+   void *end = addr + length;
+   caches_clean_inval_pou((unsigned long)addr, (unsigned long)end);
+
  #else
WARN_ONCE(1, "Architecture has no drm_cache.c support\n");
  #endif


Re: [PATCH][next] drm/amdgpu: Fix missing assignment to variable r

2022-02-25 Thread Alex Deucher
Already fixed.  Thanks for the patch.

Alex

On Thu, Feb 24, 2022 at 5:43 PM Colin Ian King  wrote:
>
> Currently the call to function amdgpu_benchmark_move should be
> assigning the return value to variable r as this is checked in
> the next statement, however, this assignment is missing. Fix
> this by adding in the missing assignment.
>
> Addresses clang scan warning:
> drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c:168:7: warning:
> variable 'r' is uninitialized when used here [-Wuninitialized]
>
> Fixes: 9645c9c9fb15 ("drm/amdgpu: plumb error handling though 
> amdgpu_benchmark()")
> Signed-off-by: Colin Ian King 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c
> index 3136a9ad2d54..bb293a5c6fd5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c
> @@ -163,7 +163,7 @@ int amdgpu_benchmark(struct amdgpu_device *adev, int 
> test_number)
>  "benchmark test: %d (simple test, VRAM to VRAM)\n",
>  test_number);
> /* simple test, VRAM to VRAM */
> -   amdgpu_benchmark_move(adev, 1024*1024, AMDGPU_GEM_DOMAIN_VRAM,
> +   r = amdgpu_benchmark_move(adev, 1024*1024, 
> AMDGPU_GEM_DOMAIN_VRAM,
>   AMDGPU_GEM_DOMAIN_VRAM);
> if (r)
> goto done;
> --
> 2.34.1
>


linux-next: manual merge of the drm tree with the drm-intel-fixes tree

2022-02-25 Thread broonie
Hi all,

Today's linux-next merge of the drm tree got a conflict in:

  drivers/gpu/drm/i915/display/intel_snps_phy.c

between commit:

  28adef861233c ("drm/i915/dg2: Print PHY name properly on calibration error")

from the drm-intel-fixes tree and commits:

  c5274e86da5fe ("drm/i915/snps: convert to drm device based logging")
  84073e568eec7 ("drm/i915/dg2: Print PHY name properly on calibration error")

from the drm tree.

I fixed it up (see below) and can carry the fix as necessary. This
is now fixed as far as linux-next is concerned, but any non trivial
conflicts should be mentioned to your upstream maintainer when your tree
is submitted for merging.  You may also want to consider cooperating
with the maintainer of the conflicting tree to minimise any particularly
complex conflicts.

[Used drm version]


Re: [PATCH v5 3/7] PCI: Drop the `is_thunderbolt` attribute from PCI core

2022-02-25 Thread Alex Deucher
On Thu, Feb 24, 2022 at 8:23 PM Bjorn Helgaas  wrote:
>
> On Thu, Feb 24, 2022 at 03:51:12PM -0600, Mario Limonciello wrote:
> > The `is_thunderbolt` attribute originally had a well defined list of
> > quirks that it existed for, but it has been overloaded with more
> > meaning.
> >
> > Instead use the driver core removable attribute to indicate the
> > detail a device is attached to a thunderbolt or USB4 chain.
> >
> > Signed-off-by: Mario Limonciello 
> > ---
> >  drivers/pci/probe.c   | 2 +-
> >  drivers/platform/x86/apple-gmux.c | 2 +-
> >  include/linux/pci.h   | 5 ++---
> >  3 files changed, 4 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> > index 17a969942d37..1b752d425c47 100644
> > --- a/drivers/pci/probe.c
> > +++ b/drivers/pci/probe.c
> > @@ -1584,7 +1584,7 @@ static void set_pcie_thunderbolt(struct pci_dev *dev)
> >   /* Is the device part of a Thunderbolt controller? */
> >   vsec = pci_find_vsec_capability(dev, PCI_VENDOR_ID_INTEL, 
> > PCI_VSEC_ID_INTEL_TBT);
> >   if (vsec)
> > - dev->is_thunderbolt = 1;
> > + dev->external_facing = true;
>
> I assume there's a spec for the PCI_VSEC_ID_INTEL_TBT Capability.  Is
> that public?  Does the spec say that a device with that capability
> must be external-facing?
>
> Even if it's not public, I think a citation (name, revision, section)
> would be useful.
>
> >  }
> >
> >  static void set_pcie_untrusted(struct pci_dev *dev)
> > diff --git a/drivers/platform/x86/apple-gmux.c 
> > b/drivers/platform/x86/apple-gmux.c
> > index 57553f9b4d1d..da0c39b0 100644
> > --- a/drivers/platform/x86/apple-gmux.c
> > +++ b/drivers/platform/x86/apple-gmux.c
> > @@ -596,7 +596,7 @@ static int gmux_resume(struct device *dev)
> >
> >  static int is_thunderbolt(struct device *dev, void *data)
> >  {
> > - return to_pci_dev(dev)->is_thunderbolt;
> > + return to_pci_dev(dev)->external_facing;
>
> This looks ... sort of weird.  I don't know anything about
> apple-gmux.c, so I guess I don't care, but assuming any
> external-facing device must be a Thunderbolt device seems like a
> stretch.
>
> Ugh.  This is used via "bus_for_each_dev(_bus_type)", which means
> it's not hotplug-safe.  I'm sure we "know" implicitly that hotplug
> isn't an issue in apple-gmux, but it's better not to have examples
> that get copied to places where it *is* an issue.
>
> >  }
> >
> >  static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
> > diff --git a/include/linux/pci.h b/include/linux/pci.h
> > index 1e5b769e42fc..d9719eb14654 100644
> > --- a/include/linux/pci.h
> > +++ b/include/linux/pci.h
> > @@ -442,7 +442,6 @@ struct pci_dev {
> >   unsigned intis_virtfn:1;
> >   unsigned intis_hotplug_bridge:1;
> >   unsigned intshpc_managed:1; /* SHPC owned by shpchp */
> > - unsigned intis_thunderbolt:1;   /* Thunderbolt controller */
> >   unsigned intno_cmd_complete:1;  /* Lies about command 
> > completed events */
> >
> >   /*
> > @@ -2447,11 +2446,11 @@ static inline bool 
> > pci_is_thunderbolt_attached(struct pci_dev *pdev)
> >  {
> >   struct pci_dev *parent = pdev;
> >
> > - if (pdev->is_thunderbolt)
> > + if (dev_is_removable(>dev))
> >   return true;
> >
> >   while ((parent = pci_upstream_bridge(parent)))
> > - if (parent->is_thunderbolt)
> > + if (dev_is_removable(>dev))
> >   return true;
>
> I don't get this.  Plain old PCI devices can be removable, too.
>
> pci_is_thunderbolt_attached() is only used by GPU drivers.  What
> property of Thunderbolt do they care about?
>
> nouveau_vga_init() and radeon_device_init() use it to decide to
> register with vga_switcheroo.  So maybe that's something to do with
> removability?  Of course, that's not specific to Thunderbolt, because
> garden-variety PCIe devices are removable.
>
> amdgpu_driver_load_kms() and radeon_driver_load_kms() apparently use
> it for something related to power control.  I don't know what the
> Thunderbolt connection is.

For GPU drivers, we need to determine which dGPU on the system has
d3cold control via ACPI and which GPU would use a mux for display
switching between the iGPU and the dGPU for hybrid graphics platforms
(e.g., iGPU + dGPU built into a laptop or all-in-one PC).  The dGPU
built into the platform would be the one we want to use for mux
switching and ACPI power control.  You would not want that for the
dGPU connected via thunderbolt (or some other hot pluggable
interface).  I had suggested that we could check if there is an ACPI
device associated with the dGPU and use that to determine this, but I
think someone brought up a case where that didn't work.  We need to
know whether the dGPU uses platform power control to determine whether
the driver should let the platform manage the power state via ACPI or
if the driver should do it (e.g., for 

Re: [PATCH] drm/vc4: add tracepoints for CL submissions

2022-02-25 Thread Maxime Ripard
Hi Melissa,

On Tue, Feb 01, 2022 at 08:26:51PM -0100, Melissa Wen wrote:
> Trace submit_cl_ioctl and related IRQs for CL submission and bin/render
> jobs execution. It might be helpful to get a rendering timeline and
> track job throttling.
> 
> Signed-off-by: Melissa Wen 

I'm not really sure what to do about this patch to be honest.

My understanding is that tracepoints are considered as userspace ABI,
but I can't really judge whether your traces are good enough or if it's
something that will bit us some time down the road.

Emma, Daniel, David, any insight?

Thanks,
Maxime


signature.asc
Description: PGP signature


[PATCH v2 1/2] arm64/dts/qcom/sc7280: remove assigned-clock-rate property for mdp clk

2022-02-25 Thread Vinod Polimera
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.

drop the assigned clock rate property and set it
during resume sequence with max value in the opp table.

Fixes: 62fbdce91("arm64: dts: qcom: sc7280: add display dt nodes")

Signed-off-by: Vinod Polimera 
---
 arch/arm64/boot/dts/qcom/sc7280.dtsi | 9 ++---
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi 
b/arch/arm64/boot/dts/qcom/sc7280.dtsi
index baf1653..408cf6c 100644
--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
@@ -2856,9 +2856,6 @@
  "ahb",
  "core";
 
-   assigned-clocks = < DISP_CC_MDSS_MDP_CLK>;
-   assigned-clock-rates = <3>;
-
interrupts = ;
interrupt-controller;
#interrupt-cells = <1>;
@@ -2892,11 +2889,9 @@
  "lut",
  "core",
  "vsync";
-   assigned-clocks = < 
DISP_CC_MDSS_MDP_CLK>,
-   < 
DISP_CC_MDSS_VSYNC_CLK>,
+   assigned-clocks = < 
DISP_CC_MDSS_VSYNC_CLK>,
< DISP_CC_MDSS_AHB_CLK>;
-   assigned-clock-rates = <3>,
-   <1920>,
+   assigned-clock-rates = <1920>,
<1920>;
operating-points-v2 = <_opp_table>;
power-domains = < SC7280_CX>;
-- 
2.7.4



[PATCH v2 2/2] drm/msm/disp/dpu1: set mdp clk to the maximum frequency in opp table

2022-02-25 Thread Vinod Polimera
use max clock during resume sequence from the opp table.
The clock will be scaled down when framework sends an update.

Fixes: 62fbdce91("arm64: dts: qcom: sc7280: add display dt nodes")

Signed-off-by: Vinod Polimera 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index d550f90..3288f52 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -1319,6 +1319,7 @@ static int __maybe_unused dpu_runtime_resume(struct 
device *dev)
struct drm_device *ddev;
struct dss_module_power *mp = _kms->mp;
int i;
+   unsigned long max_freq = ULONG_MAX;
 
ddev = dpu_kms->dev;
 
@@ -1333,6 +1334,8 @@ static int __maybe_unused dpu_runtime_resume(struct 
device *dev)
return rc;
}
 
+   dev_pm_opp_find_freq_floor(dev, _freq);
+   dev_pm_opp_set_rate(dev, max_freq);
dpu_vbif_init_memtypes(dpu_kms);
 
drm_for_each_encoder(encoder, ddev)
-- 
2.7.4



[PATCH v2 0/2] Update mdp clk to max supported value to support higher refresh rates

2022-02-25 Thread Vinod Polimera
*** BLURB HERE ***

Vinod Polimera (2):
  arm64/dts/qcom/sc7280: remove assigned-clock-rate property for mdp clk
  drm/msm/disp/dpu1: set mdp clk to the maximum frequency in opp table

 arch/arm64/boot/dts/qcom/sc7280.dtsi| 9 ++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 3 +++
 2 files changed, 5 insertions(+), 7 deletions(-)

-- 
2.7.4



[CI 7/7] drm/i915/selftests: mock test io_size

2022-02-25 Thread Matthew Auld
Check that mappable vs non-mappable matches our expectations.

Signed-off-by: Matthew Auld 
Cc: Thomas Hellström 
Reviewed-by: Thomas Hellström 
---
 .../drm/i915/selftests/intel_memory_region.c  | 143 ++
 1 file changed, 143 insertions(+)

diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c 
b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
index 247f65f02bbf..56dec9723601 100644
--- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
@@ -17,6 +17,7 @@
 #include "gem/i915_gem_context.h"
 #include "gem/i915_gem_lmem.h"
 #include "gem/i915_gem_region.h"
+#include "gem/i915_gem_ttm.h"
 #include "gem/selftests/igt_gem_utils.h"
 #include "gem/selftests/mock_context.h"
 #include "gt/intel_engine_pm.h"
@@ -512,6 +513,147 @@ static int igt_mock_max_segment(void *arg)
return err;
 }
 
+static u64 igt_object_mappable_total(struct drm_i915_gem_object *obj)
+{
+   struct intel_memory_region *mr = obj->mm.region;
+   struct i915_ttm_buddy_resource *bman_res =
+   to_ttm_buddy_resource(obj->mm.res);
+   struct drm_buddy *mm = bman_res->mm;
+   struct drm_buddy_block *block;
+   u64 total;
+
+   total = 0;
+   list_for_each_entry(block, _res->blocks, link) {
+   u64 start = drm_buddy_block_offset(block);
+   u64 end = start + drm_buddy_block_size(mm, block);
+
+   if (start < mr->io_size)
+   total += min_t(u64, end, mr->io_size) - start;
+   }
+
+   return total;
+}
+
+static int igt_mock_io_size(void *arg)
+{
+   struct intel_memory_region *mr = arg;
+   struct drm_i915_private *i915 = mr->i915;
+   struct drm_i915_gem_object *obj;
+   u64 mappable_theft_total;
+   u64 io_size;
+   u64 total;
+   u64 ps;
+   u64 rem;
+   u64 size;
+   I915_RND_STATE(prng);
+   LIST_HEAD(objects);
+   int err = 0;
+
+   ps = SZ_4K;
+   if (i915_prandom_u64_state() & 1)
+   ps = SZ_64K; /* For something like DG2 */
+
+   div64_u64_rem(i915_prandom_u64_state(), SZ_8G, );
+   total = round_down(total, ps);
+   total = max_t(u64, total, SZ_1G);
+
+   div64_u64_rem(i915_prandom_u64_state(), total - ps, _size);
+   io_size = round_down(io_size, ps);
+   io_size = max_t(u64, io_size, SZ_256M); /* 256M seems to be the common 
lower limit */
+
+   pr_info("%s with ps=%llx, io_size=%llx, total=%llx\n",
+   __func__, ps, io_size, total);
+
+   mr = mock_region_create(i915, 0, total, ps, 0, io_size);
+   if (IS_ERR(mr)) {
+   err = PTR_ERR(mr);
+   goto out_err;
+   }
+
+   mappable_theft_total = 0;
+   rem = total - io_size;
+   do {
+   div64_u64_rem(i915_prandom_u64_state(), rem, );
+   size = round_down(size, ps);
+   size = max(size, ps);
+
+   obj = igt_object_create(mr, , size,
+   I915_BO_ALLOC_GPU_ONLY);
+   if (IS_ERR(obj)) {
+   pr_err("%s TOPDOWN failed with rem=%llx, size=%llx\n",
+  __func__, rem, size);
+   err = PTR_ERR(obj);
+   goto out_close;
+   }
+
+   mappable_theft_total += igt_object_mappable_total(obj);
+   rem -= size;
+   } while (rem);
+
+   pr_info("%s mappable theft=(%lluMiB/%lluMiB), total=%lluMiB\n",
+   __func__,
+   (u64)mappable_theft_total >> 20,
+   (u64)io_size >> 20,
+   (u64)total >> 20);
+
+   /*
+* Even if we allocate all of the non-mappable portion, we should still
+* be able to dip into the mappable portion.
+*/
+   obj = igt_object_create(mr, , io_size,
+   I915_BO_ALLOC_GPU_ONLY);
+   if (IS_ERR(obj)) {
+   pr_err("%s allocation unexpectedly failed\n", __func__);
+   err = PTR_ERR(obj);
+   goto out_close;
+   }
+
+   close_objects(mr, );
+
+   rem = io_size;
+   do {
+   div64_u64_rem(i915_prandom_u64_state(), rem, );
+   size = round_down(size, ps);
+   size = max(size, ps);
+
+   obj = igt_object_create(mr, , size, 0);
+   if (IS_ERR(obj)) {
+   pr_err("%s MAPPABLE failed with rem=%llx, size=%llx\n",
+  __func__, rem, size);
+   err = PTR_ERR(obj);
+   goto out_close;
+   }
+
+   if (igt_object_mappable_total(obj) != size) {
+   pr_err("%s allocation is not mappable(size=%llx)\n",
+  __func__, size);
+   err = -EINVAL;
+   goto out_close;
+   }
+   rem -= size;
+   } while 

[CI 6/7] drm/i915/buddy: tweak 2big check

2022-02-25 Thread Matthew Auld
Otherwise we get -EINVAL, instead of the more useful -E2BIG if the
allocation doesn't fit within the pfn range, like with mappable lmem.
The hugepages selftest, for example, needs this to know if a smaller
size is needed.

Signed-off-by: Matthew Auld 
Cc: Thomas Hellström 
Reviewed-by: Thomas Hellström 
Acked-by: Nirmoy Das 
---
 drivers/gpu/drm/i915/i915_ttm_buddy_manager.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_ttm_buddy_manager.c 
b/drivers/gpu/drm/i915/i915_ttm_buddy_manager.c
index 0ac6b2463fd5..92d49a3c378c 100644
--- a/drivers/gpu/drm/i915/i915_ttm_buddy_manager.c
+++ b/drivers/gpu/drm/i915/i915_ttm_buddy_manager.c
@@ -82,7 +82,7 @@ static int i915_ttm_buddy_man_alloc(struct 
ttm_resource_manager *man,
lpfn = pages;
}
 
-   if (size > mm->size) {
+   if (size > lpfn << PAGE_SHIFT) {
err = -E2BIG;
goto err_free_res;
}
-- 
2.34.1



[CI 3/7] drm/i915: add I915_BO_ALLOC_GPU_ONLY

2022-02-25 Thread Matthew Auld
If the user doesn't require CPU access for the buffer, then
ALLOC_GPU_ONLY should be used, in order to prioritise allocating in the
non-mappable portion of LMEM, on devices with small BAR.

v2(Thomas):
  - The BO_ALLOC_TOPDOWN naming here is poor, since this is pure lies on
systems that don't even have small BAR. A better name is GPU_ONLY,
which is accurate regardless of the configuration.

Signed-off-by: Matthew Auld 
Cc: Thomas Hellström 
Reviewed-by: Thomas Hellström 
Acked-by: Nirmoy Das 
---
 .../gpu/drm/i915/gem/i915_gem_object_types.h| 17 -
 drivers/gpu/drm/i915/gem/i915_gem_pages.c   |  3 +++
 drivers/gpu/drm/i915/gem/i915_gem_region.c  |  5 +
 drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 13 ++---
 drivers/gpu/drm/i915/gt/intel_gt.c  |  4 +++-
 drivers/gpu/drm/i915/i915_vma.c |  3 +++
 drivers/gpu/drm/i915/intel_region_ttm.c | 11 ---
 drivers/gpu/drm/i915/selftests/mock_region.c|  7 +--
 8 files changed, 45 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
index 0098a32490f0..fd54eb8f4826 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -319,16 +319,23 @@ struct drm_i915_gem_object {
 #define I915_BO_ALLOC_PM_VOLATILE BIT(4)
 /* Object needs to be restored early using memcpy during resume */
 #define I915_BO_ALLOC_PM_EARLYBIT(5)
+/*
+ * Object is likely never accessed by the CPU. This will prioritise the BO to 
be
+ * allocated in the non-mappable portion of lmem. This is merely a hint, and if
+ * dealing with userspace objects the CPU fault handler is free to ignore this.
+ */
+#define I915_BO_ALLOC_GPU_ONLY   BIT(6)
 #define I915_BO_ALLOC_FLAGS (I915_BO_ALLOC_CONTIGUOUS | \
 I915_BO_ALLOC_VOLATILE | \
 I915_BO_ALLOC_CPU_CLEAR | \
 I915_BO_ALLOC_USER | \
 I915_BO_ALLOC_PM_VOLATILE | \
-I915_BO_ALLOC_PM_EARLY)
-#define I915_BO_READONLY  BIT(6)
-#define I915_TILING_QUIRK_BIT 7 /* unknown swizzling; do not release! */
-#define I915_BO_PROTECTED BIT(8)
-#define I915_BO_WAS_BOUND_BIT 9
+I915_BO_ALLOC_PM_EARLY | \
+I915_BO_ALLOC_GPU_ONLY)
+#define I915_BO_READONLY  BIT(7)
+#define I915_TILING_QUIRK_BIT 8 /* unknown swizzling; do not release! */
+#define I915_BO_PROTECTED BIT(9)
+#define I915_BO_WAS_BOUND_BIT 10
/**
 * @mem_flags - Mutable placement-related flags
 *
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c 
b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
index 183b861620b8..97c820eee115 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
@@ -358,6 +358,9 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object 
*obj,
!i915_gem_object_has_iomem(obj))
return ERR_PTR(-ENXIO);
 
+   if (WARN_ON_ONCE(obj->flags & I915_BO_ALLOC_GPU_ONLY))
+   return ERR_PTR(-EINVAL);
+
assert_object_held(obj);
 
pinned = !(type & I915_MAP_OVERRIDE);
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.c 
b/drivers/gpu/drm/i915/gem/i915_gem_region.c
index a4350227e9ae..873d52f872c5 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_region.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_region.c
@@ -45,6 +45,11 @@ i915_gem_object_create_region(struct intel_memory_region 
*mem,
 
GEM_BUG_ON(flags & ~I915_BO_ALLOC_FLAGS);
 
+   if (WARN_ON_ONCE(flags & I915_BO_ALLOC_GPU_ONLY &&
+(flags & I915_BO_ALLOC_CPU_CLEAR ||
+ flags & I915_BO_ALLOC_PM_EARLY)))
+   return ERR_PTR(-EINVAL);
+
if (!mem)
return ERR_PTR(-ENODEV);
 
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c 
b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
index 0363987dee97..a13e0204a139 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
@@ -129,10 +129,14 @@ i915_ttm_place_from_region(const struct 
intel_memory_region *mr,
place->mem_type = intel_region_to_ttm_type(mr);
 
if (flags & I915_BO_ALLOC_CONTIGUOUS)
-   place->flags = TTM_PL_FLAG_CONTIGUOUS;
+   place->flags |= TTM_PL_FLAG_CONTIGUOUS;
if (mr->io_size && mr->io_size < mr->total) {
-   place->fpfn = 0;
-   place->lpfn = mr->io_size >> PAGE_SHIFT;
+   if (flags & I915_BO_ALLOC_GPU_ONLY) {
+   place->flags |= TTM_PL_FLAG_TOPDOWN;
+   } else {
+   place->fpfn = 0;
+   place->lpfn = mr->io_size >> PAGE_SHIFT;
+   }
}
 }
 
@@ -890,6 +894,9 @@ static vm_fault_t 

[CI 5/7] drm/i915/buddy: adjust res->start

2022-02-25 Thread Matthew Auld
Differentiate between mappable vs non-mappable resources, also if this
is an actual range allocation ensure we set res->start as the starting
pfn. Later when we need to do non-mappable -> mappable moves then we
want TTM to see that the current placement is not compatible, which
should result in an actual move, instead of being turned into a noop.

Signed-off-by: Matthew Auld 
Cc: Thomas Hellström 
Reviewed-by: Thomas Hellström 
Acked-by: Nirmoy Das 
---
 drivers/gpu/drm/i915/i915_ttm_buddy_manager.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_ttm_buddy_manager.c 
b/drivers/gpu/drm/i915/i915_ttm_buddy_manager.c
index e47a3d46c6ff..0ac6b2463fd5 100644
--- a/drivers/gpu/drm/i915/i915_ttm_buddy_manager.c
+++ b/drivers/gpu/drm/i915/i915_ttm_buddy_manager.c
@@ -141,6 +141,13 @@ static int i915_ttm_buddy_man_alloc(struct 
ttm_resource_manager *man,
mutex_unlock(>lock);
}
 
+   if (place->lpfn - place->fpfn == n_pages)
+   bman_res->base.start = place->fpfn;
+   else if (lpfn <= bman->visible_size)
+   bman_res->base.start = 0;
+   else
+   bman_res->base.start = bman->visible_size;
+
*res = _res->base;
return 0;
 
-- 
2.34.1



[CI 4/7] drm/i915/buddy: track available visible size

2022-02-25 Thread Matthew Auld
Track the total amount of available visible memory, and also track
per-resource the amount of used visible memory. For now this is useful
for our debug output, and deciding if it is even worth calling into the
buddy allocator. In the future tracking the per-resource visible usage
will be useful for when deciding if we should attempt to evict certain
buffers.

v2:
 - s/place->lpfn/lpfn/, that way we can avoid scanning the list if the
   entire range is already mappable.
 - Move the end declaration inside the if block(Thomas).
 - Make sure to also account for reserved memory.

Signed-off-by: Matthew Auld 
Cc: Thomas Hellström 
Reviewed-by: Thomas Hellström 
Acked-by: Nirmoy Das 
---
 drivers/gpu/drm/i915/i915_ttm_buddy_manager.c | 68 ++-
 drivers/gpu/drm/i915/i915_ttm_buddy_manager.h |  8 ++-
 drivers/gpu/drm/i915/intel_region_ttm.c   |  1 +
 3 files changed, 75 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_ttm_buddy_manager.c 
b/drivers/gpu/drm/i915/i915_ttm_buddy_manager.c
index 76d5211c25eb..e47a3d46c6ff 100644
--- a/drivers/gpu/drm/i915/i915_ttm_buddy_manager.c
+++ b/drivers/gpu/drm/i915/i915_ttm_buddy_manager.c
@@ -19,6 +19,9 @@ struct i915_ttm_buddy_manager {
struct drm_buddy mm;
struct list_head reserved;
struct mutex lock;
+   unsigned long visible_size;
+   unsigned long visible_avail;
+   unsigned long visible_reserved;
u64 default_page_size;
 };
 
@@ -87,6 +90,12 @@ static int i915_ttm_buddy_man_alloc(struct 
ttm_resource_manager *man,
n_pages = size >> ilog2(mm->chunk_size);
 
mutex_lock(>lock);
+   if (lpfn <= bman->visible_size && n_pages > bman->visible_avail) {
+   mutex_unlock(>lock);
+   err = -ENOSPC;
+   goto err_free_res;
+   }
+
err = drm_buddy_alloc_blocks(mm, (u64)place->fpfn << PAGE_SHIFT,
 (u64)lpfn << PAGE_SHIFT,
 (u64)n_pages << PAGE_SHIFT,
@@ -107,6 +116,31 @@ static int i915_ttm_buddy_man_alloc(struct 
ttm_resource_manager *man,
mutex_unlock(>lock);
}
 
+   if (lpfn <= bman->visible_size) {
+   bman_res->used_visible_size = bman_res->base.num_pages;
+   } else {
+   struct drm_buddy_block *block;
+
+   list_for_each_entry(block, _res->blocks, link) {
+   unsigned long start =
+   drm_buddy_block_offset(block) >> PAGE_SHIFT;
+
+   if (start < bman->visible_size) {
+   unsigned long end = start +
+   (drm_buddy_block_size(mm, block) >> 
PAGE_SHIFT);
+
+   bman_res->used_visible_size +=
+   min(end, bman->visible_size) - start;
+   }
+   }
+   }
+
+   if (bman_res->used_visible_size) {
+   mutex_lock(>lock);
+   bman->visible_avail -= bman_res->used_visible_size;
+   mutex_unlock(>lock);
+   }
+
*res = _res->base;
return 0;
 
@@ -128,6 +162,7 @@ static void i915_ttm_buddy_man_free(struct 
ttm_resource_manager *man,
 
mutex_lock(>lock);
drm_buddy_free_list(>mm, _res->blocks);
+   bman->visible_avail += bman_res->used_visible_size;
mutex_unlock(>lock);
 
ttm_resource_fini(man, res);
@@ -143,6 +178,12 @@ static void i915_ttm_buddy_man_debug(struct 
ttm_resource_manager *man,
mutex_lock(>lock);
drm_printf(printer, "default_page_size: %lluKiB\n",
   bman->default_page_size >> 10);
+   drm_printf(printer, "visible_avail: %lluMiB\n",
+  (u64)bman->visible_avail << PAGE_SHIFT >> 20);
+   drm_printf(printer, "visible_size: %lluMiB\n",
+  (u64)bman->visible_size << PAGE_SHIFT >> 20);
+   drm_printf(printer, "visible_reserved: %lluMiB\n",
+  (u64)bman->visible_reserved << PAGE_SHIFT >> 20);
 
drm_buddy_print(>mm, printer);
 
@@ -164,6 +205,7 @@ static const struct ttm_resource_manager_func 
i915_ttm_buddy_manager_func = {
  * @type: Memory type we want to manage
  * @use_tt: Set use_tt for the manager
  * @size: The size in bytes to manage
+ * @visible_size: The CPU visible size in bytes to manage
  * @default_page_size: The default minimum page size in bytes for allocations,
  * this must be at least as large as @chunk_size, and can be overridden by
  * setting the BO page_alignment, to be larger or smaller as needed.
@@ -187,7 +229,7 @@ static const struct ttm_resource_manager_func 
i915_ttm_buddy_manager_func = {
  */
 int i915_ttm_buddy_man_init(struct ttm_device *bdev,
unsigned int type, bool use_tt,
-   u64 size, u64 default_page_size,
+   u64 size, u64 visible_size, u64 default_page_size,

[CI 2/7] drm/i915/ttm: require mappable by default

2022-02-25 Thread Matthew Auld
On devices with non-mappable LMEM ensure we always allocate the pages
within the mappable portion. For now we assume that all LMEM buffers
will require CPU access, which is also inline with pretty much all
current kernel internal users. In the next patch we will introduce a new
flag to override this behaviour.

Signed-off-by: Matthew Auld 
Cc: Thomas Hellström 
Reviewed-by: Thomas Hellström 
Acked-by: Nirmoy Das 
---
 drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 4 
 drivers/gpu/drm/i915/intel_region_ttm.c | 5 +
 2 files changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c 
b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
index 53c183f13a38..0363987dee97 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
@@ -130,6 +130,10 @@ i915_ttm_place_from_region(const struct 
intel_memory_region *mr,
 
if (flags & I915_BO_ALLOC_CONTIGUOUS)
place->flags = TTM_PL_FLAG_CONTIGUOUS;
+   if (mr->io_size && mr->io_size < mr->total) {
+   place->fpfn = 0;
+   place->lpfn = mr->io_size >> PAGE_SHIFT;
+   }
 }
 
 static void
diff --git a/drivers/gpu/drm/i915/intel_region_ttm.c 
b/drivers/gpu/drm/i915/intel_region_ttm.c
index 7dea07c579aa..5a40310d6fdd 100644
--- a/drivers/gpu/drm/i915/intel_region_ttm.c
+++ b/drivers/gpu/drm/i915/intel_region_ttm.c
@@ -199,6 +199,11 @@ intel_region_ttm_resource_alloc(struct intel_memory_region 
*mem,
struct ttm_resource *res;
int ret;
 
+   if (mem->io_size && mem->io_size < mem->total) {
+   place.fpfn = 0;
+   place.lpfn = mem->io_size >> PAGE_SHIFT;
+   }
+
mock_bo.base.size = size;
mock_bo.bdev = >i915->bdev;
place.flags = flags;
-- 
2.34.1



[CI 1/7] drm/i915: add io_size plumbing

2022-02-25 Thread Matthew Auld
With small LMEM-BAR we need to be able to differentiate between the
total size of LMEM, and how much of it is CPU mappable. The end goal is
to be able to utilize the entire range, even if part of is it not CPU
accessible.

v2: also update intelfb_create

Signed-off-by: Matthew Auld 
Cc: Thomas Hellström 
Reviewed-by: Thomas Hellström 
Acked-by: Nirmoy Das 
---
 drivers/gpu/drm/i915/display/intel_fbdev.c   | 2 +-
 drivers/gpu/drm/i915/gem/i915_gem_shmem.c| 2 +-
 drivers/gpu/drm/i915/gem/i915_gem_stolen.c   | 8 +---
 drivers/gpu/drm/i915/gem/i915_gem_ttm.c  | 2 +-
 drivers/gpu/drm/i915/gem/selftests/huge_pages.c  | 2 +-
 drivers/gpu/drm/i915/gt/intel_region_lmem.c  | 5 -
 drivers/gpu/drm/i915/intel_memory_region.c   | 6 --
 drivers/gpu/drm/i915/intel_memory_region.h   | 2 ++
 drivers/gpu/drm/i915/selftests/intel_memory_region.c | 8 
 drivers/gpu/drm/i915/selftests/mock_region.c | 6 --
 drivers/gpu/drm/i915/selftests/mock_region.h | 3 ++-
 11 files changed, 29 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c 
b/drivers/gpu/drm/i915/display/intel_fbdev.c
index fd5bc7acf08d..2cd62a187df3 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
@@ -265,7 +265,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
struct intel_memory_region *mem = obj->mm.region;
 
info->apertures->ranges[0].base = mem->io_start;
-   info->apertures->ranges[0].size = mem->total;
+   info->apertures->ranges[0].size = mem->io_size;
 
/* Use fbdev's framebuffer from lmem for discrete */
info->fix.smem_start =
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c 
b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
index 4efa821f3cb1..3a1c782ed791 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
@@ -699,7 +699,7 @@ struct intel_memory_region *i915_gem_shmem_setup(struct 
drm_i915_private *i915,
 {
return intel_memory_region_create(i915, 0,
  totalram_pages() << PAGE_SHIFT,
- PAGE_SIZE, 0,
+ PAGE_SIZE, 0, 0,
  type, instance,
  _region_ops);
 }
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c 
b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
index 636cdf8a73b0..0bf8f61134af 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
@@ -492,6 +492,7 @@ static int i915_gem_init_stolen(struct intel_memory_region 
*mem)
 
/* Exclude the reserved region from driver use */
mem->region.end = reserved_base - 1;
+   mem->io_size = resource_size(>region);
 
/* It is possible for the reserved area to end before the end of stolen
 * memory, so just consider the start. */
@@ -751,7 +752,7 @@ static int init_stolen_lmem(struct intel_memory_region *mem)
 
if (!io_mapping_init_wc(>iomap,
mem->io_start,
-   resource_size(>region)))
+   mem->io_size))
return -EIO;
 
/*
@@ -806,7 +807,8 @@ i915_gem_stolen_lmem_setup(struct drm_i915_private *i915, 
u16 type,
I915_GTT_PAGE_SIZE_4K;
 
mem = intel_memory_region_create(i915, lmem_base, lmem_size,
-min_page_size, io_start,
+min_page_size,
+io_start, lmem_size,
 type, instance,
 _region_stolen_lmem_ops);
if (IS_ERR(mem))
@@ -837,7 +839,7 @@ i915_gem_stolen_smem_setup(struct drm_i915_private *i915, 
u16 type,
mem = intel_memory_region_create(i915,
 intel_graphics_stolen_res.start,
 
resource_size(_graphics_stolen_res),
-PAGE_SIZE, 0, type, instance,
+PAGE_SIZE, 0, 0, type, instance,
 _region_stolen_smem_ops);
if (IS_ERR(mem))
return mem;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c 
b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
index 8419096d4056..53c183f13a38 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
@@ -1103,7 +1103,7 @@ i915_gem_ttm_system_setup(struct drm_i915_private *i915,
 
mr = intel_memory_region_create(i915, 0,
totalram_pages() << PAGE_SHIFT,
-  

[PATCH v7 12/12] drm/vc4: hdmi: Remove clock rate initialization

2022-02-25 Thread Maxime Ripard
Now that the clock driver makes sure we never end up with a rate of 0,
the HDMI driver doesn't need to care anymore.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 13 -
 1 file changed, 13 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 92b1530aa17b..21aff3ad96cf 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -2576,19 +2576,6 @@ static int vc4_hdmi_bind(struct device *dev, struct 
device *master, void *data)
vc4_hdmi->disable_4kp60 = true;
}
 
-   /*
-* If we boot without any cable connected to the HDMI connector,
-* the firmware will skip the HSM initialization and leave it
-* with a rate of 0, resulting in a bus lockup when we're
-* accessing the registers even if it's enabled.
-*
-* Let's put a sensible default at runtime_resume so that we
-* don't end up in this situation.
-*/
-   ret = clk_set_min_rate(vc4_hdmi->hsm_clock, HSM_MIN_CLOCK_FREQ);
-   if (ret)
-   goto err_put_ddc;
-
/*
 * We need to have the device powered up at this point to call
 * our reset hook and for the CEC init.
-- 
2.35.1



[PATCH v7 11/12] drm/vc4: Add logging and comments

2022-02-25 Thread Maxime Ripard
The HVS core clock isn't really obvious, so let's add a bunch more
comments and some logging for easier debugging.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_kms.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
index 24de29bc1cda..6fe03fc17d73 100644
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -389,8 +389,15 @@ static void vc4_atomic_commit_tail(struct drm_atomic_state 
*state)
5,
new_hvs_state->core_clock_rate);
 
+   drm_dbg(dev, "Raising the core clock at %lu Hz\n", core_rate);
+
+   /*
+* Do a temporary request on the core clock during the
+* modeset.
+*/
clk_set_min_rate(hvs->core_clk, core_rate);
}
+
drm_atomic_helper_commit_modeset_disables(dev, state);
 
vc4_ctm_commit(vc4, state);
@@ -416,6 +423,10 @@ static void vc4_atomic_commit_tail(struct drm_atomic_state 
*state)
drm_dbg(dev, "Running the core clock at %lu Hz\n",
new_hvs_state->core_clock_rate);
 
+   /*
+* Request a clock rate based on the current HVS
+* requirements.
+*/
clk_set_min_rate(hvs->core_clk, new_hvs_state->core_clock_rate);
}
 }
-- 
2.35.1



[PATCH v7 10/12] clk: bcm: rpi: Run some clocks at the minimum rate allowed

2022-02-25 Thread Maxime Ripard
The core clock and M2MC clocks are shared between some devices (Unicam
controllers and the HVS, and the HDMI controllers, respectively) that
will have various, varying, requirements depending on their current work
load.

Since those loads can require a fairly high clock rate in extreme
conditions (up to ~600MHz), we can end up running those clocks at their
maximum frequency even though we no longer require such a high rate.

Fortunately, those devices don't require an exact rate but a minimum
rate, and all the drivers are using clk_set_min_rate. Thus, we can just
rely on the fact that the clk_request minimum (which is the aggregated
minimum of all the clock users) is what we want at all times.

Signed-off-by: Maxime Ripard 
---
 drivers/clk/bcm/clk-raspberrypi.c | 37 +++
 1 file changed, 37 insertions(+)

diff --git a/drivers/clk/bcm/clk-raspberrypi.c 
b/drivers/clk/bcm/clk-raspberrypi.c
index c879f2e9a4a7..9d09621549b9 100644
--- a/drivers/clk/bcm/clk-raspberrypi.c
+++ b/drivers/clk/bcm/clk-raspberrypi.c
@@ -77,6 +77,7 @@ struct raspberrypi_clk_variant {
boolexport;
char*clkdev;
unsigned long   min_rate;
+   boolminimize;
 };
 
 static struct raspberrypi_clk_variant
@@ -87,6 +88,18 @@ raspberrypi_clk_variants[RPI_FIRMWARE_NUM_CLK_ID] = {
},
[RPI_FIRMWARE_CORE_CLK_ID] = {
.export = true,
+
+   /*
+* The clock is shared between the HVS and the CSI
+* controllers, on the BCM2711 and will change depending
+* on the pixels composited on the HVS and the capture
+* resolution on Unicam.
+*
+* Since the rate can get quite large, and we need to
+* coordinate between both driver instances, let's
+* always use the minimum the drivers will let us.
+*/
+   .minimize = true,
},
[RPI_FIRMWARE_M2MC_CLK_ID] = {
.export = true,
@@ -102,6 +115,16 @@ raspberrypi_clk_variants[RPI_FIRMWARE_NUM_CLK_ID] = {
 * in this situation.
 */
.min_rate = 12000,
+
+   /*
+* The clock is shared between the two HDMI controllers
+* on the BCM2711 and will change depending on the
+* resolution output on each. Since the rate can get
+* quite large, and we need to coordinate between both
+* driver instances, let's always use the minimum the
+* drivers will let us.
+*/
+   .minimize = true,
},
[RPI_FIRMWARE_V3D_CLK_ID] = {
.export = true,
@@ -206,12 +229,26 @@ static int raspberrypi_fw_set_rate(struct clk_hw *hw, 
unsigned long rate,
 static int raspberrypi_fw_dumb_determine_rate(struct clk_hw *hw,
  struct clk_rate_request *req)
 {
+   struct raspberrypi_clk_data *data =
+   container_of(hw, struct raspberrypi_clk_data, hw);
+   struct raspberrypi_clk_variant *variant = data->variant;
+
/*
 * The firmware will do the rounding but that isn't part of
 * the interface with the firmware, so we just do our best
 * here.
 */
+
req->rate = clamp(req->rate, req->min_rate, req->max_rate);
+
+   /*
+* We want to aggressively reduce the clock rate here, so let's
+* just ignore the requested rate and return the bare minimum
+* rate we can get away with.
+*/
+   if (variant->minimize && req->min_rate > 0)
+   req->rate = req->min_rate;
+
return 0;
 }
 
-- 
2.35.1



[PATCH v7 01/12] clk: Fix clk_hw_get_clk() when dev is NULL

2022-02-25 Thread Maxime Ripard
Any registered clk_core structure can have a NULL pointer in its dev
field. While never actually documented, this is evidenced by the wide
usage of clk_register and clk_hw_register with a NULL device pointer,
and the fact that the core of_clk_hw_register() function also passes a
NULL device pointer.

A call to clk_hw_get_clk() on a clk_hw struct whose clk_core is in that
case will result in a NULL pointer derefence when it calls dev_name() on
that NULL device pointer.

Add a test for this case and use NULL as the dev_id if the device
pointer is NULL.

Fixes: 30d6f8c15d2c ("clk: add api to get clk consumer from clk_hw")
Signed-off-by: Maxime Ripard 
---
 drivers/clk/clk.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 8de6a22498e7..fff5edb89d6d 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -3773,8 +3773,9 @@ struct clk *clk_hw_create_clk(struct device *dev, struct 
clk_hw *hw,
 struct clk *clk_hw_get_clk(struct clk_hw *hw, const char *con_id)
 {
struct device *dev = hw->core->dev;
+   const char *name = dev ? dev_name(dev) : NULL;
 
-   return clk_hw_create_clk(dev, hw, dev_name(dev), con_id);
+   return clk_hw_create_clk(dev, hw, name, con_id);
 }
 EXPORT_SYMBOL(clk_hw_get_clk);
 
-- 
2.35.1



[PATCH v7 09/12] clk: bcm: rpi: Set a default minimum rate

2022-02-25 Thread Maxime Ripard
The M2MC clock provides the state machine clock for both HDMI
controllers.

However, if no HDMI monitor is plugged in at boot, its clock rate will
be left at 0 by the firmware and will make any register access end up in
a CPU stall, even though the clock was enabled.

We had some code in the HDMI controller to deal with this before, but it
makes more sense to have it in the clock driver. Move it there.

Signed-off-by: Maxime Ripard 
---
 drivers/clk/bcm/clk-raspberrypi.c | 26 ++
 1 file changed, 26 insertions(+)

diff --git a/drivers/clk/bcm/clk-raspberrypi.c 
b/drivers/clk/bcm/clk-raspberrypi.c
index f7185d421085..c879f2e9a4a7 100644
--- a/drivers/clk/bcm/clk-raspberrypi.c
+++ b/drivers/clk/bcm/clk-raspberrypi.c
@@ -76,6 +76,7 @@ struct raspberrypi_clk_data {
 struct raspberrypi_clk_variant {
boolexport;
char*clkdev;
+   unsigned long   min_rate;
 };
 
 static struct raspberrypi_clk_variant
@@ -89,6 +90,18 @@ raspberrypi_clk_variants[RPI_FIRMWARE_NUM_CLK_ID] = {
},
[RPI_FIRMWARE_M2MC_CLK_ID] = {
.export = true,
+
+   /*
+* If we boot without any cable connected to any of the
+* HDMI connector, the firmware will skip the HSM
+* initialization and leave it with a rate of 0,
+* resulting in a bus lockup when we're accessing the
+* registers even if it's enabled.
+*
+* Let's put a sensible default so that we don't end up
+* in this situation.
+*/
+   .min_rate = 12000,
},
[RPI_FIRMWARE_V3D_CLK_ID] = {
.export = true,
@@ -267,6 +280,19 @@ static struct clk_hw *raspberrypi_clk_register(struct 
raspberrypi_clk *rpi,
}
}
 
+   if (variant->min_rate) {
+   unsigned long rate;
+
+   clk_hw_set_rate_range(>hw, variant->min_rate, max_rate);
+
+   rate = raspberrypi_fw_get_rate(>hw, 0);
+   if (rate < variant->min_rate) {
+   ret = raspberrypi_fw_set_rate(>hw, 
variant->min_rate, 0);
+   if (ret)
+   return ERR_PTR(ret);
+   }
+   }
+
return >hw;
 }
 
-- 
2.35.1



[PATCH v7 07/12] clk: Add clk_drop_range

2022-02-25 Thread Maxime Ripard
In order to reset the range on a clock, we need to call
clk_set_rate_range with a minimum of 0 and a maximum of ULONG_MAX. Since
it's fairly inconvenient, let's introduce a clk_drop_range() function
that will do just this.

Suggested-by: Stephen Boyd 
Signed-off-by: Maxime Ripard 
---
 drivers/clk/clk_test.c |  4 ++--
 include/linux/clk.h| 11 +++
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/clk_test.c b/drivers/clk/clk_test.c
index 2c5d30a9372e..a92600311506 100644
--- a/drivers/clk/clk_test.c
+++ b/drivers/clk/clk_test.c
@@ -645,7 +645,7 @@ static void 
clk_range_test_multiple_set_range_rate_maximized(struct kunit *test)
KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_1);
 
KUNIT_ASSERT_EQ(test,
-   clk_set_rate_range(user2, 0, ULONG_MAX),
+   clk_drop_range(user2),
0);
 
rate = clk_get_rate(clk);
@@ -762,7 +762,7 @@ static void 
clk_range_test_multiple_set_range_rate_minimized(struct kunit *test)
KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_2);
 
KUNIT_ASSERT_EQ(test,
-   clk_set_rate_range(user2, 0, ULONG_MAX),
+   clk_drop_range(user2),
0);
 
rate = clk_get_rate(clk);
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 266e8de3cb51..39faa54efe88 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -986,6 +986,17 @@ static inline void clk_bulk_disable_unprepare(int num_clks,
clk_bulk_unprepare(num_clks, clks);
 }
 
+/**
+ * clk_drop_range - Reset any range set on that clock
+ * @clk: clock source
+ *
+ * Returns success (0) or negative errno.
+ */
+static inline int clk_drop_range(struct clk *clk)
+{
+   return clk_set_rate_range(clk, 0, ULONG_MAX);
+}
+
 /**
  * clk_get_optional - lookup and obtain a reference to an optional clock
  *   producer.
-- 
2.35.1



[PATCH v7 08/12] clk: bcm: rpi: Add variant structure

2022-02-25 Thread Maxime Ripard
We only export a bunch of firmware clocks, and some of them require
special treatment.

This has been do so far using some tests on the clock id in various
places, but this is fairly hard to extend and doesn't scale very well.

Since we'll need some more cases in the next patches, let's switch to a
variant structure that defines the behaviour we need to have for a given
clock.

Signed-off-by: Maxime Ripard 
---
 drivers/clk/bcm/clk-raspberrypi.c | 62 +++
 1 file changed, 46 insertions(+), 16 deletions(-)

diff --git a/drivers/clk/bcm/clk-raspberrypi.c 
b/drivers/clk/bcm/clk-raspberrypi.c
index dd3b71eafabf..f7185d421085 100644
--- a/drivers/clk/bcm/clk-raspberrypi.c
+++ b/drivers/clk/bcm/clk-raspberrypi.c
@@ -56,6 +56,8 @@ static char *rpi_firmware_clk_names[] = {
 #define RPI_FIRMWARE_STATE_ENABLE_BIT  BIT(0)
 #define RPI_FIRMWARE_STATE_WAIT_BITBIT(1)
 
+struct raspberrypi_clk_variant;
+
 struct raspberrypi_clk {
struct device *dev;
struct rpi_firmware *firmware;
@@ -66,10 +68,36 @@ struct raspberrypi_clk_data {
struct clk_hw hw;
 
unsigned int id;
+   struct raspberrypi_clk_variant *variant;
 
struct raspberrypi_clk *rpi;
 };
 
+struct raspberrypi_clk_variant {
+   boolexport;
+   char*clkdev;
+};
+
+static struct raspberrypi_clk_variant
+raspberrypi_clk_variants[RPI_FIRMWARE_NUM_CLK_ID] = {
+   [RPI_FIRMWARE_ARM_CLK_ID] = {
+   .export = true,
+   .clkdev = "cpu0",
+   },
+   [RPI_FIRMWARE_CORE_CLK_ID] = {
+   .export = true,
+   },
+   [RPI_FIRMWARE_M2MC_CLK_ID] = {
+   .export = true,
+   },
+   [RPI_FIRMWARE_V3D_CLK_ID] = {
+   .export = true,
+   },
+   [RPI_FIRMWARE_PIXEL_BVB_CLK_ID] = {
+   .export = true,
+   },
+};
+
 /*
  * Structure of the message passed to Raspberry Pi's firmware in order to
  * change clock rates. The 'disable_turbo' option is only available to the ARM
@@ -183,7 +211,8 @@ static const struct clk_ops raspberrypi_firmware_clk_ops = {
 
 static struct clk_hw *raspberrypi_clk_register(struct raspberrypi_clk *rpi,
   unsigned int parent,
-  unsigned int id)
+  unsigned int id,
+  struct raspberrypi_clk_variant 
*variant)
 {
struct raspberrypi_clk_data *data;
struct clk_init_data init = {};
@@ -195,6 +224,7 @@ static struct clk_hw *raspberrypi_clk_register(struct 
raspberrypi_clk *rpi,
return ERR_PTR(-ENOMEM);
data->rpi = rpi;
data->id = id;
+   data->variant = variant;
 
init.name = devm_kasprintf(rpi->dev, GFP_KERNEL,
   "fw-clk-%s",
@@ -228,9 +258,9 @@ static struct clk_hw *raspberrypi_clk_register(struct 
raspberrypi_clk *rpi,
 
clk_hw_set_rate_range(>hw, min_rate, max_rate);
 
-   if (id == RPI_FIRMWARE_ARM_CLK_ID) {
+   if (variant->clkdev) {
ret = devm_clk_hw_register_clkdev(rpi->dev, >hw,
- NULL, "cpu0");
+ NULL, variant->clkdev);
if (ret) {
dev_err(rpi->dev, "Failed to initialize clkdev\n");
return ERR_PTR(ret);
@@ -264,27 +294,27 @@ static int raspberrypi_discover_clocks(struct 
raspberrypi_clk *rpi,
return ret;
 
while (clks->id) {
-   struct clk_hw *hw;
+   struct raspberrypi_clk_variant *variant;
+
+   if (clks->id > RPI_FIRMWARE_NUM_CLK_ID) {
+   dev_err(rpi->dev, "Unknown clock id: %u", clks->id);
+   return -EINVAL;
+   }
+
+   variant = _clk_variants[clks->id];
+   if (variant->export) {
+   struct clk_hw *hw;
 
-   switch (clks->id) {
-   case RPI_FIRMWARE_ARM_CLK_ID:
-   case RPI_FIRMWARE_CORE_CLK_ID:
-   case RPI_FIRMWARE_M2MC_CLK_ID:
-   case RPI_FIRMWARE_V3D_CLK_ID:
-   case RPI_FIRMWARE_PIXEL_BVB_CLK_ID:
hw = raspberrypi_clk_register(rpi, clks->parent,
- clks->id);
+ clks->id, variant);
if (IS_ERR(hw))
return PTR_ERR(hw);
 
data->hws[clks->id] = hw;
data->num = clks->id + 1;
-   fallthrough;
-
-   default:
-   clks++;
-   break;
}
+
+   clks++;
}
 
return 0;
-- 
2.35.1



[PATCH v7 06/12] clk: Always set the rate on clk_set_range_rate

2022-02-25 Thread Maxime Ripard
When we change a clock minimum or maximum using clk_set_rate_range(),
clk_set_min_rate() or clk_set_max_rate(), the current code will only
trigger a new rate change if the rate is outside of the new boundaries.

However, a clock driver might want to always keep the clock rate to
one of its boundary, for example the minimum to keep the power
consumption as low as possible.

Since they don't always get called though, clock providers don't have the
opportunity to implement this behaviour.

Let's trigger a clk_set_rate() on the previous requested rate every time
clk_set_rate_range() is called. That way, providers that care about the
new boundaries have a chance to adjust the rate, while providers that
don't care about those new boundaries will return the same rate than
before, which will be ignored by clk_set_rate() and won't result in a
new rate change.

Suggested-by: Stephen Boyd 
Signed-off-by: Maxime Ripard 
---
 drivers/clk/clk.c  | 45 
 drivers/clk/clk_test.c | 58 +++---
 2 files changed, 49 insertions(+), 54 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index c15ee5070f52..9bc8bf434b94 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -2373,28 +2373,29 @@ int clk_set_rate_range(struct clk *clk, unsigned long 
min, unsigned long max)
goto out;
}
 
-   rate = clk_core_get_rate_nolock(clk->core);
-   if (rate < min || rate > max) {
-   /*
-* FIXME:
-* We are in bit of trouble here, current rate is outside the
-* the requested range. We are going try to request appropriate
-* range boundary but there is a catch. It may fail for the
-* usual reason (clock broken, clock protected, etc) but also
-* because:
-* - round_rate() was not favorable and fell on the wrong
-*   side of the boundary
-* - the determine_rate() callback does not really check for
-*   this corner case when determining the rate
-*/
-
-   rate = clamp(clk->core->req_rate, min, max);
-   ret = clk_core_set_rate_nolock(clk->core, rate);
-   if (ret) {
-   /* rollback the changes */
-   clk->min_rate = old_min;
-   clk->max_rate = old_max;
-   }
+   /*
+* Since the boundaries have been changed, let's give the
+* opportunity to the provider to adjust the clock rate based on
+* the new boundaries.
+*
+* We also need to handle the case where the clock is currently
+* outside of the boundaries. Clamping the last requested rate
+* to the current minimum and maximum will also handle this.
+*
+* FIXME:
+* There is a catch. It may fail for the usual reason (clock
+* broken, clock protected, etc) but also because:
+* - round_rate() was not favorable and fell on the wrong
+*   side of the boundary
+* - the determine_rate() callback does not really check for
+*   this corner case when determining the rate
+*/
+   rate = clamp(clk->core->req_rate, min, max);
+   ret = clk_core_set_rate_nolock(clk->core, rate);
+   if (ret) {
+   /* rollback the changes */
+   clk->min_rate = old_min;
+   clk->max_rate = old_max;
}
 
 out:
diff --git a/drivers/clk/clk_test.c b/drivers/clk/clk_test.c
index 2279be699001..2c5d30a9372e 100644
--- a/drivers/clk/clk_test.c
+++ b/drivers/clk/clk_test.c
@@ -549,13 +549,12 @@ static struct kunit_suite clk_range_test_suite = {
 };
 
 /*
- * Test that if:
- * - we have several subsequent calls to clk_set_rate_range();
- * - and we have a round_rate ops that always return the maximum
- *   frequency allowed;
+ * Test that if we have several subsequent calls to
+ * clk_set_rate_range(), the core will reevaluate whether a new rate is
+ * needed each and every time.
  *
- * The clock will run at the minimum of all maximum boundaries
- * requested, even if those boundaries aren't there anymore.
+ * With clk_dummy_maximize_rate_ops, this means that the the rate will
+ * trail along the maximum as it evolves.
  */
 static void clk_range_test_set_range_rate_maximized(struct kunit *test)
 {
@@ -596,18 +595,16 @@ static void 
clk_range_test_set_range_rate_maximized(struct kunit *test)
 
rate = clk_get_rate(clk);
KUNIT_ASSERT_GT(test, rate, 0);
-   KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_2 - 1000);
+   KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_2);
 }
 
 /*
- * Test that if:
- * - we have several subsequent calls to clk_set_rate_range(), across
- *   multiple users;
- * - and we have a round_rate ops that always return the maximum
- *   frequency allowed;
+ * Test that if we have several subsequent calls to
+ * 

[PATCH v7 04/12] clk: Always clamp the rounded rate

2022-02-25 Thread Maxime Ripard
The current core while setting the min and max rate properly in the
clk_request structure will not make sure that the requested rate is
within these boundaries, leaving it to each and every driver to make
sure it is.

It's not clear if this was on purpose or not, but this introduces some
inconsistencies within the API.

For example, a user setting a range and then calling clk_round_rate()
with a value outside of that range will get the same value back
(ignoring any driver adjustements), effectively ignoring the range that
was just set.

Another one, arguably worse, is that it also makes clk_round_rate() and
clk_set_rate() behave differently if there's a range and the rate being
used for both is outside that range. As we have seen, the rate will be
returned unchanged by clk_round_rate(), but clk_set_rate() will error
out returning -EINVAL.

Let's make sure the framework will always clamp the rate to the current
range found on the clock, which will fix both these inconsistencies.

Signed-off-by: Maxime Ripard 
---
 drivers/clk/clk.c  |  2 ++
 drivers/clk/clk_test.c | 50 +++---
 2 files changed, 34 insertions(+), 18 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 112911138a7b..6c4e10209568 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1348,6 +1348,8 @@ static int clk_core_determine_round_nolock(struct 
clk_core *core,
if (!core)
return 0;
 
+   req->rate = clamp(req->rate, req->min_rate, req->max_rate);
+
/*
 * At this point, core protection will be disabled
 * - if the provider is not protected at all
diff --git a/drivers/clk/clk_test.c b/drivers/clk/clk_test.c
index a8d7eba01de7..2279be699001 100644
--- a/drivers/clk/clk_test.c
+++ b/drivers/clk/clk_test.c
@@ -310,8 +310,7 @@ static void clk_range_test_multiple_disjoints_range(struct 
kunit *test)
 
 /*
  * Test that if our clock has some boundaries and we try to round a rate
- * lower than the minimum, the returned rate won't be affected by the
- * boundaries.
+ * lower than the minimum, the returned rate will be within range.
  */
 static void clk_range_test_set_range_round_rate_lower(struct kunit *test)
 {
@@ -328,18 +327,20 @@ static void 
clk_range_test_set_range_round_rate_lower(struct kunit *test)
 
rate = clk_round_rate(clk, DUMMY_CLOCK_RATE_1 - 1000);
KUNIT_ASSERT_GT(test, rate, 0);
-   KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_1 - 1000);
+   KUNIT_EXPECT_GE(test, rate, DUMMY_CLOCK_RATE_1);
+   KUNIT_EXPECT_LE(test, rate, DUMMY_CLOCK_RATE_2);
 }
 
 /*
  * Test that if our clock has some boundaries and we try to set a rate
- * lower than the minimum, we'll get an error.
+ * higher than the maximum, the new rate will be within range.
  */
 static void clk_range_test_set_range_set_rate_lower(struct kunit *test)
 {
struct clk_dummy_context *ctx = test->priv;
struct clk_hw *hw = >hw;
struct clk *clk = hw->clk;
+   unsigned long rate;
 
KUNIT_ASSERT_EQ(test,
clk_set_rate_range(clk,
@@ -347,15 +348,21 @@ static void 
clk_range_test_set_range_set_rate_lower(struct kunit *test)
   DUMMY_CLOCK_RATE_2),
0);
 
-   KUNIT_ASSERT_LT(test,
+   KUNIT_ASSERT_EQ(test,
clk_set_rate(clk, DUMMY_CLOCK_RATE_1 - 1000),
0);
+
+   rate = clk_get_rate(clk);
+   KUNIT_ASSERT_GT(test, rate, 0);
+   KUNIT_EXPECT_GE(test, rate, DUMMY_CLOCK_RATE_1);
+   KUNIT_EXPECT_LE(test, rate, DUMMY_CLOCK_RATE_2);
 }
 
 /*
  * Test that if our clock has some boundaries and we try to round and
- * set a rate lower than the minimum, the values won't be consistent
- * between clk_round_rate() and clk_set_rate().
+ * set a rate lower than the minimum, the rate returned by
+ * clk_round_rate() will be consistent with the new rate set by
+ * clk_set_rate().
  */
 static void clk_range_test_set_range_set_round_rate_consistent_lower(struct 
kunit *test)
 {
@@ -373,17 +380,16 @@ static void 
clk_range_test_set_range_set_round_rate_consistent_lower(struct kuni
rounded = clk_round_rate(clk, DUMMY_CLOCK_RATE_1 - 1000);
KUNIT_ASSERT_GT(test, rounded, 0);
 
-   KUNIT_EXPECT_LT(test,
+   KUNIT_ASSERT_EQ(test,
clk_set_rate(clk, DUMMY_CLOCK_RATE_1 - 1000),
0);
 
-   KUNIT_EXPECT_NE(test, rounded, clk_get_rate(clk));
+   KUNIT_EXPECT_EQ(test, rounded, clk_get_rate(clk));
 }
 
 /*
  * Test that if our clock has some boundaries and we try to round a rate
- * higher than the maximum, the returned rate won't be affected by the
- * boundaries.
+ * higher than the maximum, the returned rate will be within range.
  */
 static void clk_range_test_set_range_round_rate_higher(struct kunit *test)
 {
@@ -400,18 +406,20 @@ static void 
clk_range_test_set_range_round_rate_higher(struct kunit 

[PATCH v7 03/12] clk: Enforce that disjoints limits are invalid

2022-02-25 Thread Maxime Ripard
If we were to have two users of the same clock, doing something like:

clk_set_rate_range(user1, 1000, 2000);
clk_set_rate_range(user2, 3000, 4000);

The second call would fail with -EINVAL, preventing from getting in a
situation where we end up with impossible limits.

However, this is never explicitly checked against and enforced, and
works by relying on an undocumented behaviour of clk_set_rate().

Indeed, on the first clk_set_rate_range will make sure the current clock
rate is within the new range, so it will be between 1000 and 2000Hz. On
the second clk_set_rate_range(), it will consider (rightfully), that our
current clock is outside of the 3000-4000Hz range, and will call
clk_core_set_rate_nolock() to set it to 3000Hz.

clk_core_set_rate_nolock() will then call clk_calc_new_rates() that will
eventually check that our rate 3000Hz rate is outside the min 3000Hz max
2000Hz range, will bail out, the error will propagate and we'll
eventually return -EINVAL.

This solely relies on the fact that clk_calc_new_rates(), and in
particular clk_core_determine_round_nolock(), won't modify the new rate
allowing the error to be reported. That assumption won't be true for all
drivers, and most importantly we'll break that assumption in a later
patch.

It can also be argued that we shouldn't even reach the point where we're
calling clk_core_set_rate_nolock().

Let's make an explicit check for disjoints range before we're doing
anything.

Signed-off-by: Maxime Ripard 
---
 drivers/clk/clk.c | 24 
 1 file changed, 24 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index fff5edb89d6d..112911138a7b 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -632,6 +632,24 @@ static void clk_core_get_boundaries(struct clk_core *core,
*max_rate = min(*max_rate, clk_user->max_rate);
 }
 
+static bool clk_core_check_boundaries(struct clk_core *core,
+ unsigned long min_rate,
+ unsigned long max_rate)
+{
+   struct clk *user;
+
+   lockdep_assert_held(_lock);
+
+   if (min_rate > core->max_rate || max_rate < core->min_rate)
+   return false;
+
+   hlist_for_each_entry(user, >clks, clks_node)
+   if (min_rate > user->max_rate || max_rate < user->min_rate)
+   return false;
+
+   return true;
+}
+
 void clk_hw_set_rate_range(struct clk_hw *hw, unsigned long min_rate,
   unsigned long max_rate)
 {
@@ -2348,6 +2366,11 @@ int clk_set_rate_range(struct clk *clk, unsigned long 
min, unsigned long max)
clk->min_rate = min;
clk->max_rate = max;
 
+   if (!clk_core_check_boundaries(clk->core, min, max)) {
+   ret = -EINVAL;
+   goto out;
+   }
+
rate = clk_core_get_rate_nolock(clk->core);
if (rate < min || rate > max) {
/*
@@ -2376,6 +2399,7 @@ int clk_set_rate_range(struct clk *clk, unsigned long 
min, unsigned long max)
}
}
 
+out:
if (clk->exclusive_count)
clk_core_rate_protect(clk->core);
 
-- 
2.35.1



[PATCH v7 05/12] clk: Use clamp instead of open-coding our own

2022-02-25 Thread Maxime Ripard
The code in clk_set_rate_range() will, if the current rate is outside of
the new range, force it to the minimum or maximum.

Since it's running under the condition that the rate is either lower
than the minimum, or higher than the maximum, this is equivalent to
using clamp, while being less readable. Let's switch to using clamp
instead.

Signed-off-by: Maxime Ripard 
---
 drivers/clk/clk.c | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 6c4e10209568..c15ee5070f52 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -2388,11 +2388,7 @@ int clk_set_rate_range(struct clk *clk, unsigned long 
min, unsigned long max)
 *   this corner case when determining the rate
 */
 
-   if (rate < min)
-   rate = min;
-   else
-   rate = max;
-
+   rate = clamp(clk->core->req_rate, min, max);
ret = clk_core_set_rate_nolock(clk->core, rate);
if (ret) {
/* rollback the changes */
-- 
2.35.1



[PATCH v7 02/12] clk: Introduce Kunit Tests for the framework

2022-02-25 Thread Maxime Ripard
Let's test various parts of the rate-related clock API with the kunit
testing framework.

Cc: kunit-...@googlegroups.com
Tested-by: Daniel Latypov 
Suggested-by: Stephen Boyd 
Signed-off-by: Maxime Ripard 
---
 drivers/clk/.kunitconfig |   1 +
 drivers/clk/Kconfig  |   7 +
 drivers/clk/Makefile |   1 +
 drivers/clk/clk_test.c   | 787 +++
 4 files changed, 796 insertions(+)
 create mode 100644 drivers/clk/clk_test.c

diff --git a/drivers/clk/.kunitconfig b/drivers/clk/.kunitconfig
index 3754fdb9485a..cdbc7d7deba9 100644
--- a/drivers/clk/.kunitconfig
+++ b/drivers/clk/.kunitconfig
@@ -1,3 +1,4 @@
 CONFIG_KUNIT=y
 CONFIG_COMMON_CLK=y
+CONFIG_CLK_KUNIT_TEST=y
 CONFIG_CLK_GATE_KUNIT_TEST=y
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 3cdf33470a75..2ef6eca297ff 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -429,6 +429,13 @@ source "drivers/clk/xilinx/Kconfig"
 source "drivers/clk/zynqmp/Kconfig"
 
 # Kunit test cases
+config CLK_KUNIT_TEST
+   tristate "Basic Clock Framework Kunit Tests" if !KUNIT_ALL_TESTS
+   depends on KUNIT
+   default KUNIT_ALL_TESTS
+   help
+ Kunit tests for the common clock framework.
+
 config CLK_GATE_KUNIT_TEST
tristate "Basic gate type Kunit test" if !KUNIT_ALL_TESTS
depends on KUNIT
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 6a98291350b6..8f9b1daba411 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -2,6 +2,7 @@
 # common clock types
 obj-$(CONFIG_HAVE_CLK) += clk-devres.o clk-bulk.o clkdev.o
 obj-$(CONFIG_COMMON_CLK)   += clk.o
+obj-$(CONFIG_CLK_KUNIT_TEST)   += clk_test.o
 obj-$(CONFIG_COMMON_CLK)   += clk-divider.o
 obj-$(CONFIG_COMMON_CLK)   += clk-fixed-factor.o
 obj-$(CONFIG_COMMON_CLK)   += clk-fixed-rate.o
diff --git a/drivers/clk/clk_test.c b/drivers/clk/clk_test.c
new file mode 100644
index ..a8d7eba01de7
--- /dev/null
+++ b/drivers/clk/clk_test.c
@@ -0,0 +1,787 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Kunit test for clk rate management
+ */
+#include 
+#include 
+
+/* Needed for clk_hw_get_clk() */
+#include "clk.h"
+
+#include 
+
+#define DUMMY_CLOCK_INIT_RATE  (42 * 1000 * 1000)
+#define DUMMY_CLOCK_RATE_1 (142 * 1000 * 1000)
+#define DUMMY_CLOCK_RATE_2 (242 * 1000 * 1000)
+
+struct clk_dummy_context {
+   struct clk_hw hw;
+   unsigned long rate;
+};
+
+static unsigned long clk_dummy_recalc_rate(struct clk_hw *hw,
+  unsigned long parent_rate)
+{
+   struct clk_dummy_context *ctx =
+   container_of(hw, struct clk_dummy_context, hw);
+
+   return ctx->rate;
+}
+
+static int clk_dummy_determine_rate(struct clk_hw *hw,
+   struct clk_rate_request *req)
+{
+   /* Just return the same rate without modifying it */
+   return 0;
+}
+
+static int clk_dummy_maximize_rate(struct clk_hw *hw,
+  struct clk_rate_request *req)
+{
+   /*
+* If there's a maximum set, always run the clock at the maximum
+* allowed.
+*/
+   if (req->max_rate < ULONG_MAX)
+   req->rate = req->max_rate;
+
+   return 0;
+}
+
+static int clk_dummy_minimize_rate(struct clk_hw *hw,
+  struct clk_rate_request *req)
+{
+   /*
+* If there's a minimum set, always run the clock at the minimum
+* allowed.
+*/
+   if (req->min_rate > 0)
+   req->rate = req->min_rate;
+
+   return 0;
+}
+
+static int clk_dummy_set_rate(struct clk_hw *hw,
+ unsigned long rate,
+ unsigned long parent_rate)
+{
+   struct clk_dummy_context *ctx =
+   container_of(hw, struct clk_dummy_context, hw);
+
+   ctx->rate = rate;
+   return 0;
+}
+
+static const struct clk_ops clk_dummy_rate_ops = {
+   .recalc_rate = clk_dummy_recalc_rate,
+   .determine_rate = clk_dummy_determine_rate,
+   .set_rate = clk_dummy_set_rate,
+};
+
+static const struct clk_ops clk_dummy_maximize_rate_ops = {
+   .recalc_rate = clk_dummy_recalc_rate,
+   .determine_rate = clk_dummy_maximize_rate,
+   .set_rate = clk_dummy_set_rate,
+};
+
+static const struct clk_ops clk_dummy_minimize_rate_ops = {
+   .recalc_rate = clk_dummy_recalc_rate,
+   .determine_rate = clk_dummy_minimize_rate,
+   .set_rate = clk_dummy_set_rate,
+};
+
+static int clk_test_init_with_ops(struct kunit *test, const struct clk_ops 
*ops)
+{
+   struct clk_dummy_context *ctx;
+   struct clk_init_data init = { };
+   int ret;
+
+   ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
+   if (!ctx)
+   return -ENOMEM;
+   ctx->rate = DUMMY_CLOCK_INIT_RATE;
+   test->priv = ctx;
+
+   init.name = "test_dummy_rate";
+   init.ops = ops;
+   ctx->hw.init = 
+
+   ret = 

[PATCH v7 00/12] clk: Improve clock range handling

2022-02-25 Thread Maxime Ripard
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
Maxime

Changes from v6:
  - Removed unused header
  - Used more fitting KUNIT macros
  - Enhanced some comments
  - Reworded a commit message

Changes from v5:
  - Changed clk_hw_create_clk for clk_hw_get_clk since the former isn't
exported to modules.
  - Added fix for clk_hw_get_clk

Changes from v4:
  - Rename the test file
  - Move all the tests to the first patch, and fix them up as fixes are done
  - Improved the test conditions
  - Added more tests
  - Improved commit messages
  - Fixed a regression where two disjoints clock ranges would now be accepted

Changes from v3:
  - Renamed the test file and Kconfig option
  - Add option to .kunitconfig
  - Switch to kunit_kzalloc
  - Use KUNIT_EXPECT_* instead of KUNIT_ASSERT_* where relevant
  - Test directly relevant calls instead of going through a temporary variable
  - Switch to more precise KUNIT_ASSERT_* macros where relevant

Changes from v2:
  - Rebased on current next
  - Rewrote the whole thing according to Stephen reviews
  - Implemented some kunit tests

Changes from v1:
  - Return NULL in clk_request_start if clk pointer is NULL
  - Test for clk_req pointer in clk_request_done
  - Add another user in vc4
  - Rebased on top of v5.15-rc1

Maxime Ripard (12):
  clk: Fix clk_hw_get_clk() when dev is NULL
  clk: Introduce Kunit Tests for the framework
  clk: Enforce that disjoints limits are invalid
  clk: Always clamp the rounded rate
  clk: Use clamp instead of open-coding our own
  clk: Always set the rate on clk_set_range_rate
  clk: Add clk_drop_range
  clk: bcm: rpi: Add variant structure
  clk: bcm: rpi: Set a default minimum rate
  clk: bcm: rpi: Run some clocks at the minimum rate allowed
  drm/vc4: Add logging and comments
  drm/vc4: hdmi: Remove clock rate initialization

 drivers/clk/.kunitconfig  |   1 +
 drivers/clk/Kconfig   |   7 +
 drivers/clk/Makefile  |   1 +
 drivers/clk/bcm/clk-raspberrypi.c | 125 -
 drivers/clk/clk.c |  76 ++-
 drivers/clk/clk_test.c| 795 ++
 drivers/gpu/drm/vc4/vc4_hdmi.c|  13 -
 drivers/gpu/drm/vc4/vc4_kms.c |  11 +
 include/linux/clk.h   |  11 +
 9 files changed, 985 insertions(+), 55 deletions(-)
 create mode 100644 drivers/clk/clk_test.c

-- 
2.35.1



Re: [PATCH v6 02/12] clk: Introduce Kunit Tests for the framework

2022-02-25 Thread Maxime Ripard
Hi Stephen,

On Thu, Feb 24, 2022 at 02:54:20PM -0800, Stephen Boyd wrote:
> Quoting Daniel Latypov (2022-02-23 14:50:59)
> > On Wed, Feb 23, 2022 at 2:56 AM Maxime Ripard  wrote:
> > Incremental coverage for 3/9 files in --diff_file
> > Total incremental: 99.29% coverage (281/283 lines)
> >   drivers/clk/clk.c: 84.62% coverage (11/13 lines)
> >   drivers/clk/clk_test.c: 100.00% coverage (269/269 lines)
> >   include/linux/clk.h: 100.00% coverage (1/1 lines)
> > 
> > Missing lines are drivers/clk/clk.c:2397-8, i.e. this part of the diff:
> > +   if (ret) {
> > +   /* rollback the changes */
> > +   clk->min_rate = old_min; <- 2397
> > +   clk->max_rate = old_max; <- 2398
> > 
> > These are from before and were just moved around.
> 
> We could trigger a failure in the provider when the rate is set, and
> then we could call round_rate() again and make sure the boundaries from
> before are maintained.

I tried to do that, and it turns out we can't, since we ignore the
set_rate return code:

https://elixir.bootlin.com/linux/latest/source/drivers/clk/clk.c#L2107

We could make determine_rate fail, but then clk_round_rate would fail as
well and wouldn't allow us to test whether the boundaries are still in
place.

Maxime


signature.asc
Description: PGP signature


[Bug 201957] amdgpu: ring gfx timeout

2022-02-25 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=201957

--- Comment #67 from Alex Deucher (alexdeuc...@gmail.com) ---
(In reply to Randune from comment #66)
> 
> I understand that amdgpu.runpm=0 is related to power management but I don't
> know the specifics. Possibly Alex Deucher can chime in and specify exactly
> what this parameter does?

The runpm parameter allows you to disable runtime power management which powers
down dGPUs at runtime if they are not being used (e.g., hybrid graphics laptops
or desktop systems with multiple GPUs) to save power.  It does not affect
dynamic power management while the chip is powered up.  Disabling it will
increase idle power usage.

-- 
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 2/2] gpu: host1x: Fix a memory leak in 'host1x_remove()'

2022-02-25 Thread Thierry Reding
On Sun, Nov 07, 2021 at 10:16:36PM +0100, Christophe JAILLET wrote:
> Add a missing 'host1x_channel_list_free()' call in the remove function,
> as already done in the error handling path of the probe function.
> 
> Fixes: 8474b02531c4 ("gpu: host1x: Refactor channel allocation code")
> Signed-off-by: Christophe JAILLET 
> ---
>  drivers/gpu/host1x/dev.c | 1 +
>  1 file changed, 1 insertion(+)

Applied, thanks.

Thierry


signature.asc
Description: PGP signature


Re: [PATCH 1/2] gpu: host1x: Fix an error handling path in 'host1x_probe()'

2022-02-25 Thread Thierry Reding
On Sun, Nov 07, 2021 at 10:16:25PM +0100, Christophe JAILLET wrote:
> Add the missing 'host1x_bo_cache_destroy()' call in the error handling
> path of the probe, as already done in the remove function.
> 
> In order to simplify the error handling, move the 'host1x_bo_cache_init()'
> call after all the devm_ function.
> 
> Fixes: e3166698a8a0 ("drm/tegra: Implement buffer object cache")
> Signed-off-by: Christophe JAILLET 
> ---
> Untested.
> I hope that moving host1x_bo_cache_init() is just fine.
> ---
>  drivers/gpu/host1x/dev.c | 7 +--
>  1 file changed, 5 insertions(+), 2 deletions(-)

Applied, thanks.

Thierry


signature.asc
Description: PGP signature


[PATCH 1/2] drm/bridge: parade-ps8640: avoid race condition on driver unbinding

2022-02-25 Thread Ricardo Cañuelo
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(_bridge->page[PAGE0_DP_CNTL]->dev);
 }
@@ -487,6 +485,7 @@ static void ps8640_bridge_detach(struct drm_bridge *bridge)
drm_dp_aux_unregister(_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 2/2] drm/bridge: Add extra checks in pre_enable and post_enable

2022-02-25 Thread Ricardo Cañuelo
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 0/2] Mitigate race condition problems when unbinding DRM driver

2022-02-25 Thread Ricardo Cañuelo
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 v7 10/24] drm/rockchip: dw_hdmi: Add support for hclk

2022-02-25 Thread Robin Murphy

On 2022-02-25 13:11, Sascha Hauer wrote:

On Fri, Feb 25, 2022 at 12:41:23PM +, Robin Murphy wrote:

On 2022-02-25 11:10, Dmitry Osipenko wrote:

25.02.2022 13:49, Sascha Hauer пишет:

On Fri, Feb 25, 2022 at 01:26:14PM +0300, Dmitry Osipenko wrote:

25.02.2022 10:51, Sascha Hauer пишет:

The rk3568 HDMI has an additional clock that needs to be enabled for the
HDMI controller to work. The purpose of that clock is not clear. It is
named "hclk" in the downstream driver, so use the same name.

Signed-off-by: Sascha Hauer 
---

Notes:
  Changes since v5:
  - Use devm_clk_get_optional rather than devm_clk_get

   drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 
   1 file changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 
b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index fe4f9556239ac..c6c00e8779ab5 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -76,6 +76,7 @@ struct rockchip_hdmi {
const struct rockchip_hdmi_chip_data *chip_data;
struct clk *ref_clk;
struct clk *grf_clk;
+   struct clk *hclk_clk;
struct dw_hdmi *hdmi;
struct regulator *avdd_0v9;
struct regulator *avdd_1v8;
@@ -229,6 +230,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi 
*hdmi)
return PTR_ERR(hdmi->grf_clk);
}
+   hdmi->hclk_clk = devm_clk_get_optional(hdmi->dev, "hclk");
+   if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) {


Have you tried to investigate the hclk? I'm still thinking that's not
only HDMI that needs this clock and then the hardware description
doesn't look correct.


I am still not sure what you mean. Yes, it's not only the HDMI that
needs this clock. The VOP2 needs it as well and the driver handles that.


I'm curious whether DSI/DP also need that clock to be enabled. If they
do, then you aren't modeling h/w properly AFAICS.


Assuming nobody at Rockchip decided to make things needlessly inconsistent
with previous SoCs, HCLK_VOP should be the clock for the VOP's AHB slave
interface. Usually, if that affected anything other than accessing VOP
registers, indeed it would smell of something being wrong in the clock tree,
but in this case I'd also be suspicious of whether it might have ended up
clocking related GRF registers as well (either directly, or indirectly via
some gate that the clock driver hasn't modelled yet).


Ok, I am beginning to understand. I verified that hdmi, mipi and dp are
hanging when HCLK_VOP is disabled by disabling that clock via sysfs
using CLOCK_ALLOW_WRITE_DEBUGFS. When it's disabled then the registers
of that units can't be accessed. However, when I disable HCLK_VOP by
directly writing to the gate bit RK3568_CLKGATE_CON(20) then only
accessing VOP registers hangs, the other units stay functional.
So it seems it must be the parent clock which must be enabled. The
parent clock is hclk_vo. This clock should be handled as part of the
RK3568_PD_VO power domain:

power-domain@RK3568_PD_VO {
 reg = ;
 clocks = < HCLK_VO>,
  < PCLK_VO>,
  < ACLK_VOP_PRE>;
  pm_qos = <_hdcp>,
   <_vop_m0>,
   <_vop_m1>;
  #power-domain-cells = <0>;
 };

The HDMI controller is part of that domain, so I think this should work,
but it doesn't. That's where I am now, I'll have a closer look.


Ah, interesting. Looking at the clock driver, I'd also be suspicious 
whether pclk_vo is somehow messed up such that we're currently relying 
on hclk_vo to keep the common grandparent enabled. Seems like the DSI 
and eDP (and HDCP if anyone ever used it) registers would be similarly 
affected if so, and sure enough they both have a similarly suspect extra 
"hclk" in the downstream DT too.


Robin.


Re: [Intel-gfx] [PATCH v5 1/4] drm/i915/guc: Add fetch of hwconfig table

2022-02-25 Thread Tvrtko Ursulin



On 25/02/2022 09:44, Michal Wajdeczko wrote:

On 25.02.2022 06:03, Jordan Justen wrote:

John Harrison  writes:


On 2/22/2022 02:36, Jordan Justen wrote:

From: John Harrison 

Implement support for fetching the hardware description table from the
GuC. The call is made twice - once without a destination buffer to
query the size and then a second time to fill in the buffer.

Note that the table is only available on ADL-P and later platforms.

v5 (of Jordan's posting):
   * Various changes made by Jordan and recommended by Michal
 - Makefile ordering
 - Adjust "struct intel_guc_hwconfig hwconfig" comment
 - Set Copyright year to 2022 in intel_guc_hwconfig.c/.h
 - Drop inline from hwconfig_to_guc()
 - Replace hwconfig param with guc in __guc_action_get_hwconfig()
 - Move zero size check into guc_hwconfig_discover_size()
 - Change comment to say zero size offset/size is needed to get size
 - Add has_guc_hwconfig to devinfo and drop has_table()
 - Change drm_err to notice in __uc_init_hw() and use %pe

Cc: Michal Wajdeczko 
Signed-off-by: Rodrigo Vivi 
Signed-off-by: John Harrison 
Reviewed-by: Matthew Brost 
Acked-by: Jon Bloomfield 
Signed-off-by: Jordan Justen 
---
   
+	ret = intel_guc_hwconfig_init(>hwconfig);

+   if (ret)
+   drm_notice(>drm, "Failed to retrieve hwconfig table: 
%pe\n",

Why only drm_notice? As you are keen to point out, the UMDs won't work
if the table is not available. All the failure paths in your own
verification function are 'drm_err'. So why is it only a 'notice' if
there is no table at all?


This was requested by Michal in my v3 posting:

https://patchwork.freedesktop.org/patch/472936/?series=99787=3

I don't think that it should be a failure for i915 if it is unable to
read the table, or if the table read is invalid. I think it should be up
to the UMD to react to the missing hwconfig however they think is
appropriate, but I would like the i915 to guarantee & document the
format returned to userspace to whatever extent is feasible.

As you point out there is a discrepancy, and I think I should be
consistent with whatever is used here in my "drm/i915/guc: Verify
hwconfig blob matches supported format" patch.

I guess I'd tend to agree with Michal that "maybe drm_notice since we
continue probe", but I would go along with either if you two want to
discuss further.


having consistent message level is a clear benefit but on other hand
these other 'errors' may indicate more serious problems related to use
of wrong/incompatible firmware that returns corrupted HWconfig (or we
use wrong actions), while since we are not using this HWconfig in the
driver we don't care that much that we failed to load HWconfig and
'notice' is enough.

but I'm fine with all messages being drm_err (as we will not have to
change that once again after HWconfig will be mandatory for the driver
as well)


I would be against drm_err.

#define KERN_EMERG  KERN_SOH "0"/* system is unusable */
#define KERN_ALERT  KERN_SOH "1"/* action must be taken immediately */
#define KERN_CRIT   KERN_SOH "2"/* critical conditions */
#define KERN_ERRKERN_SOH "3"/* error conditions */
#define KERN_WARNINGKERN_SOH "4"/* warning conditions */
#define KERN_NOTICE KERN_SOH "5"/* normal but significant condition */
#define KERN_INFO   KERN_SOH "6"/* informational */
#define KERN_DEBUG  KERN_SOH "7"/* debug-level messages */

From the point of view of the kernel driver, this is not an error to its operation. It 
can at most be a warning, but notice is also fine by me. One could argue when reading 
"normal but significant condition" that it is not normal, when it is in fact 
unexpected, so if people prefer warning that is also okay by me. I still lean towards 
notice becuase of the hands-off nature i915 has with the pass-through of this blob.


Note that this function is called as part of the reset path. The reset
path is not allowed to allocate memory. The table is stored in a
dynamically allocated object. Hence the IGT test failure. The table
query has to be done elsewhere at driver init time only.


Thanks for clearing this up. I did notice on dg2 that gpu resets were
causing a re-read of the hwconfig from GuC, but it definitely was not
clear to me that there would be a connection to the IGT failure that you
pointed out.




+  ERR_PTR(ret));
+
ret = guc_enable_communication(guc);
if (ret)
goto err_log_capture;
@@ -562,6 +567,8 @@ static void __uc_fini_hw(struct intel_uc *uc)
if (intel_uc_uses_guc_submission(uc))
intel_guc_submission_disable(guc);
   
+	intel_guc_hwconfig_fini(>hwconfig);

+
__uc_sanitize(uc);
   }
   
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c

index 76e590fcb903..1d31e35a5154 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -990,6 

Re: [PATCH v6 02/12] clk: Introduce Kunit Tests for the framework

2022-02-25 Thread Maxime Ripard
Hi Daniel,

On Wed, Feb 23, 2022 at 02:50:59PM -0800, Daniel Latypov wrote:
> On Wed, Feb 23, 2022 at 2:56 AM Maxime Ripard  wrote:
> >
> > Let's test various parts of the rate-related clock API with the kunit
> > testing framework.
> >
> > Cc: kunit-...@googlegroups.com
> > Suggested-by: Stephen Boyd 
> > Signed-off-by: Maxime Ripard 
> 
> Tested-by: Daniel Latypov 
> 
> Looks good to me on the KUnit side.
> Two small nits below.
> 
> FYI, I computed the incremental coverage for this series, i.e.:
> 1) applied the full series
> 2) computed the absolute coverage
> 
> $  ./tools/testing/kunit/kunit.py run  --kunitconfig=drivers/clk
> --make_options=CC=/usr/bin/gcc-6 --kconfig_add=CONFIG_DEBUG_KERNEL=y
> --kconfig_add=CONFIG_DEBUG_INFO=y --kconfig_add=CONFIG_GCOV=y

I built a docker container based on ubuntu 18.04 to have gcc6 and
python3.7, but this doesn't seem to be working, I'm not entirely sure why:

[13:11:22] Configuring KUnit Kernel ...
Regenerating .config ...
Populating config with:
$ make ARCH=um olddefconfig CC=/usr/bin/gcc-6 O=.kunit
ERROR:root:Not all Kconfig options selected in kunitconfig were in the 
generated .config.
This is probably due to unsatisfied dependencies.
Missing: CONFIG_DEBUG_INFO=y, CONFIG_GCOV=y
Note: many Kconfig options aren't available on UML. You can try running on a 
different architecture with something like "--arch=x86_64".

Thanks,
Maxime


signature.asc
Description: PGP signature


[PATCH 3/3] drm/prime: Update docs

2022-02-25 Thread Gwan-gyeong Mun
It updates the name of the structure with the target function callback is
incorrect
 : drm_gem_object_funcs.gem_prime_import_sg_table to 
drm_driver.gem_prime_import_sg_table
And it updates the part where the description and the function callback
name are different.
 : drm_gem_object_funcs.pin to drm_gem_object_funcs.unpin

Signed-off-by: Gwan-gyeong Mun 
---
 drivers/gpu/drm/drm_prime.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index e3f09f18110c..87595f5871f9 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -588,7 +588,7 @@ EXPORT_SYMBOL(drm_gem_map_attach);
  * @dma_buf: buffer to detach from
  * @attach: attachment to be detached
  *
- * Calls _gem_object_funcs.pin for device specific handling.  Cleans up
+ * Calls _gem_object_funcs.unpin for device specific handling.  Cleans up
  * _buf_attachment from drm_gem_map_attach(). This can be used as the
  * _buf_ops.detach callback.
  */
@@ -842,7 +842,7 @@ EXPORT_SYMBOL(drm_prime_pages_to_sg);
  * of the the buffer described by the provided sg_table.
  *
  * This is useful for implementing
- * _gem_object_funcs.gem_prime_import_sg_table.
+ * _driver.gem_prime_import_sg_table.
  */
 unsigned long drm_prime_get_contiguous_size(struct sg_table *sgt)
 {
-- 
2.34.1



[PATCH 1/3] drm/doc: Fix typos and update outdated structure and API names

2022-02-25 Thread Gwan-gyeong Mun
It fixes typo and updates outdated struct and API names that are currently
deprecated or in use but have changed on the kernel documents of DRM section
and comments.

Signed-off-by: Gwan-gyeong Mun 
---
 Documentation/gpu/drm-mm.rst  |  8 
 drivers/gpu/drm/drm_file.c| 10 +-
 drivers/gpu/drm/drm_gem_vram_helper.c | 18 --
 drivers/gpu/drm/ttm/ttm_pool.c|  2 +-
 include/drm/drm_device.h  |  8 ++--
 include/drm/drm_drv.h |  6 +++---
 include/drm/drm_gem_cma_helper.h  |  2 +-
 include/drm/drm_gem_vram_helper.h |  1 -
 8 files changed, 28 insertions(+), 27 deletions(-)

diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst
index 198bcc1affa1..0451e6ca7402 100644
--- a/Documentation/gpu/drm-mm.rst
+++ b/Documentation/gpu/drm-mm.rst
@@ -266,13 +266,13 @@ argument.
 The GEM core provides a helper method drm_gem_mmap() to
 handle object mapping. The method can be set directly as the mmap file
 operation handler. It will look up the GEM object based on the offset
-value and set the VMA operations to the :c:type:`struct drm_driver
-` gem_vm_ops field. Note that drm_gem_mmap() doesn't map memory to
+value and set the VMA operations to the :c:type:`struct drm_gem_object_funcs
+` vm_ops field. Note that drm_gem_mmap() doesn't map 
memory to
 userspace, but relies on the driver-provided fault handler to map pages
 individually.
 
-To use drm_gem_mmap(), drivers must fill the struct :c:type:`struct drm_driver
-` gem_vm_ops field with a pointer to VM operations.
+To use drm_gem_mmap(), drivers must fill the struct :c:type:`struct 
drm_gem_object_funcs
+` vm_ops field with a pointer to VM operations.
 
 The VM operations is a :c:type:`struct vm_operations_struct 
`
 made up of several fields, the more interesting ones being:
diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
index ed25168619fc..21ca97cf7670 100644
--- a/drivers/gpu/drm/drm_file.c
+++ b/drivers/gpu/drm/drm_file.c
@@ -553,8 +553,8 @@ EXPORT_SYMBOL(drm_release_noglobal);
  * means all modern display drivers must use it.
  *
  * @offset is ignored, DRM events are read like a pipe. Therefore drivers also
- * must set the _operation.llseek to no_llseek(). Polling support is
- * provided by drm_poll().
+ * must set the _operation.llseek to no_llseek() or noop_llseek().
+ * Polling support is provided by drm_poll().
  *
  * This function will only ever read a full event. Therefore userspace must
  * supply a big enough buffer to fit any event to ensure forward progress. 
Since
@@ -640,7 +640,7 @@ EXPORT_SYMBOL(drm_read);
  * @filp: file pointer
  * @wait: poll waiter table
  *
- * This function must be used by drivers as their _operations.read method
+ * This function must be used by drivers as their _operations.poll method
  * if they use DRM events for asynchronous signalling to userspace.  Since
  * events are used by the KMS API for vblank and page flip completion this 
means
  * all modern display drivers must use it.
@@ -674,7 +674,7 @@ EXPORT_SYMBOL(drm_poll);
  *
  * This function prepares the passed in event for eventual delivery. If the 
event
  * doesn't get delivered (because the IOCTL fails later on, before queuing up
- * anything) then the even must be cancelled and freed using
+ * anything) then the event must be cancelled and freed using
  * drm_event_cancel_free(). Successfully initialized events should be sent out
  * using drm_send_event() or drm_send_event_locked() to signal completion of 
the
  * asynchronous event to userspace.
@@ -716,7 +716,7 @@ EXPORT_SYMBOL(drm_event_reserve_init_locked);
  *
  * This function prepares the passed in event for eventual delivery. If the 
event
  * doesn't get delivered (because the IOCTL fails later on, before queuing up
- * anything) then the even must be cancelled and freed using
+ * anything) then the event must be cancelled and freed using
  * drm_event_cancel_free(). Successfully initialized events should be sent out
  * using drm_send_event() or drm_send_event_locked() to signal completion of 
the
  * asynchronous event to userspace.
diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c 
b/drivers/gpu/drm/drm_gem_vram_helper.c
index dc7f938bfff2..a43c550900ec 100644
--- a/drivers/gpu/drm/drm_gem_vram_helper.c
+++ b/drivers/gpu/drm/drm_gem_vram_helper.c
@@ -39,25 +39,23 @@ static const struct drm_gem_object_funcs 
drm_gem_vram_object_funcs;
  * provide an implementation that suits the hardware. If the hardware device
  * contains dedicated video memory, the DRM driver can use the VRAM helper
  * library. Each active buffer object is stored in video RAM. Active
- * buffer are used for drawing the current frame, typically something like
+ * buffers are used for drawing the current frame, typically something like
  * the frame's scanout buffer or the cursor image. If there's no more space
  * left in VRAM, inactive GEM objects can be moved to system memory.
  *
- * To 

[PATCH 2/3] drm/i915: Update mismatched structure name

2022-02-25 Thread Gwan-gyeong Mun
It updates i915_gem_ctx to i915_gem_ww_ctx and adds missing indefinite
article to doc.

Signed-off-by: Gwan-gyeong Mun 
---
 Documentation/gpu/i915.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst
index bcaefc952764..806454296b52 100644
--- a/Documentation/gpu/i915.rst
+++ b/Documentation/gpu/i915.rst
@@ -275,7 +275,7 @@ An Intel GPU has multiple engines. There are several engine 
types.
   space.
 - VCS is a video encode and decode engine, this is named `I915_EXEC_BSD`
   in user space
-- VECS is video enhancement engine, this is named `I915_EXEC_VEBOX` in user
+- VECS is a video enhancement engine, this is named `I915_EXEC_VEBOX` in user
   space.
 - The enumeration `I915_EXEC_DEFAULT` does not refer to specific engine;
   instead it is to be used by user space to specify a default rendering
@@ -346,7 +346,7 @@ Locking Guidelines
 #. No struct_mutex anywhere in the code
 
 #. dma_resv will be the outermost lock (when needed) and ww_acquire_ctx
-   is to be hoisted at highest level and passed down within i915_gem_ctx
+   is to be hoisted at highest level and passed down within i915_gem_ww_ctx
in the call chain
 
 #. While holding lru/memory manager (buddy, drm_mm, whatever) locks
-- 
2.34.1



Re: [PATCH v2] drm/stm: Avoid using val uninitialized in ltdc_set_ycbcr_config()

2022-02-25 Thread Philippe CORNU




On 2/22/22 16:20, Nathan Chancellor wrote:

Clang warns:

   drivers/gpu/drm/stm/ltdc.c:625:2: warning: variable 'val' is used 
uninitialized whenever switch default is taken [-Wsometimes-uninitialized]
   default:
   ^~~
   drivers/gpu/drm/stm/ltdc.c:635:2: note: uninitialized use occurs here
   val |= LxPCR_YCEN;
   ^~~
   drivers/gpu/drm/stm/ltdc.c:600:9: note: initialize the variable 'val' to 
silence this warning
   u32 val;
  ^
   = 0
   1 warning generated.

Use a return instead of break in the default case to fix the warning.
Add an error message so that this return is not silent, which could hide
issues in the future.

Fixes: 484e72d3146b ("drm/stm: ltdc: add support of ycbcr pixel formats")
Link: https://github.com/ClangBuiltLinux/linux/issues/1575
Acked-by: Yannick Fertre 
Reviewed-by: Nick Desaulniers 
Reviewed-by: Raphael Gallais-Pou 
Signed-off-by: Nathan Chancellor 
---

v1 -> v2: https://lore.kernel.org/r/20220207165304.1046867-1-nat...@kernel.org/

* Use DRM_ERROR() instead of drm_err() (Philippe).


Hi Nathan,

Applied on drm-misc-next.
Many thanks for your patch,
Philippe :-)



* Collect tags from v1, as nothing substantial has changed.

  drivers/gpu/drm/stm/ltdc.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 5eeb32c9c9ce..c9bc4ccb6d43 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -624,7 +624,8 @@ static inline void ltdc_set_ycbcr_config(struct drm_plane 
*plane, u32 drm_pix_fm
break;
default:
/* RGB or not a YCbCr supported format */
-   break;
+   DRM_ERROR("Unsupported pixel format: %u\n", drm_pix_fmt);
+   return;
}
  
  	/* Enable limited range */


base-commit: 542898c5aa5c6a3179dffb1d1606884a63f75fed


Re: [PATCH] drm/stm: ltdc: add support for CRC hashing feature

2022-02-25 Thread Philippe CORNU




On 2/11/22 11:46, Raphaël Gallais-Pou wrote:

From: Raphael Gallais-Pou 

This patch adds the CRC hashing feature supported by some recent hardware
versions of the LTDC. This is useful for test suite such as IGT-GPU-tools
[1] where a CRTC output frame can be compared to a test reference frame
thanks to their respective CRC hash.

[1] https://cgit.freedesktop.org/drm/igt-gpu-tools

Signed-off-by: Raphael Gallais-Pou 


Applied on drm-misc-next.
Many thanks for your patch,
Philippe :-)


---
  drivers/gpu/drm/stm/ltdc.c | 104 +++--
  drivers/gpu/drm/stm/ltdc.h |   3 ++
  2 files changed, 104 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 5eeb32c9c9ce..b29476aec3a1 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -77,6 +77,7 @@
  #define LTDC_CPSR 0x0044  /* Current Position Status */
  #define LTDC_CDSR 0x0048  /* Current Display Status */
  #define LTDC_EDCR 0x0060  /* External Display Control */
+#define LTDC_CCRCR 0x007C  /* Computed CRC value */
  #define LTDC_FUT  0x0090  /* Fifo underrun Threshold */
  
  /* Layer register offsets */

@@ -121,6 +122,7 @@
  
  #define GCR_LTDCEN	BIT(0)		/* LTDC ENable */

  #define GCR_DEN   BIT(16) /* Dither ENable */
+#define GCR_CRCEN  BIT(19) /* CRC ENable */
  #define GCR_PCPOL BIT(28) /* Pixel Clock POLarity-Inverted */
  #define GCR_DEPOL BIT(29) /* Data Enable POLarity-High */
  #define GCR_VSPOL BIT(30) /* Vertical Synchro POLarity-High */
@@ -227,6 +229,13 @@
  
  #define NB_PF		8		/* Max nb of HW pixel format */
  
+/*

+ * Skip the first value and the second in case CRC was enabled during
+ * the thread irq. This is to be sure CRC value is relevant for the
+ * frame.
+ */
+#define CRC_SKIP_FRAMES 2
+
  enum ltdc_pix_fmt {
PF_NONE,
/* RGB formats */
@@ -664,6 +673,26 @@ static inline void ltdc_set_ycbcr_coeffs(struct drm_plane 
*plane)
 ltdc_ycbcr2rgb_coeffs[enc][ran][1]);
  }
  
+static inline void ltdc_irq_crc_handle(struct ltdc_device *ldev,

+  struct drm_crtc *crtc)
+{
+   u32 crc;
+   int ret;
+
+   if (ldev->crc_skip_count < CRC_SKIP_FRAMES) {
+   ldev->crc_skip_count++;
+   return;
+   }
+
+   /* Get the CRC of the frame */
+   ret = regmap_read(ldev->regmap, LTDC_CCRCR, );
+   if (ret)
+   return;
+
+   /* Report to DRM the CRC (hw dependent feature) */
+   drm_crtc_add_crc_entry(crtc, true, drm_crtc_accurate_vblank_count(crtc), 
);
+}
+
  static irqreturn_t ltdc_irq_thread(int irq, void *arg)
  {
struct drm_device *ddev = arg;
@@ -671,9 +700,14 @@ static irqreturn_t ltdc_irq_thread(int irq, void *arg)
struct drm_crtc *crtc = drm_crtc_from_index(ddev, 0);
  
  	/* Line IRQ : trigger the vblank event */

-   if (ldev->irq_status & ISR_LIF)
+   if (ldev->irq_status & ISR_LIF) {
drm_crtc_handle_vblank(crtc);
  
+		/* Early return if CRC is not active */

+   if (ldev->crc_active)
+   ltdc_irq_crc_handle(ldev, crtc);
+   }
+
/* Save FIFO Underrun & Transfer Error status */
mutex_lock(>err_lock);
if (ldev->irq_status & ISR_FUIF)
@@ -1079,6 +1113,48 @@ static void ltdc_crtc_disable_vblank(struct drm_crtc 
*crtc)
regmap_clear_bits(ldev->regmap, LTDC_IER, IER_LIE);
  }
  
+static int ltdc_crtc_set_crc_source(struct drm_crtc *crtc, const char *source)

+{
+   struct ltdc_device *ldev = crtc_to_ltdc(crtc);
+   int ret;
+
+   DRM_DEBUG_DRIVER("\n");
+
+   if (!crtc)
+   return -ENODEV;
+
+   if (source && strcmp(source, "auto") == 0) {
+   ldev->crc_active = true;
+   ret = regmap_set_bits(ldev->regmap, LTDC_GCR, GCR_CRCEN);
+   } else if (!source) {
+   ldev->crc_active = false;
+   ret = regmap_clear_bits(ldev->regmap, LTDC_GCR, GCR_CRCEN);
+   } else {
+   ret = -EINVAL;
+   }
+
+   ldev->crc_skip_count = 0;
+   return ret;
+}
+
+static int ltdc_crtc_verify_crc_source(struct drm_crtc *crtc,
+  const char *source, size_t *values_cnt)
+{
+   DRM_DEBUG_DRIVER("\n");
+
+   if (!crtc)
+   return -ENODEV;
+
+   if (source && strcmp(source, "auto") != 0) {
+   DRM_DEBUG_DRIVER("Unknown CRC source %s for %s\n",
+source, crtc->name);
+   return -EINVAL;
+   }
+
+   *values_cnt = 1;
+   return 0;
+}
+
  static const struct drm_crtc_funcs ltdc_crtc_funcs = {
.destroy = drm_crtc_cleanup,
.set_config = drm_atomic_helper_set_config,
@@ -1091,6 +1167,20 @@ static const struct drm_crtc_funcs ltdc_crtc_funcs = {

Re: [PATCH v7 10/24] drm/rockchip: dw_hdmi: Add support for hclk

2022-02-25 Thread Sascha Hauer
On Fri, Feb 25, 2022 at 12:41:23PM +, Robin Murphy wrote:
> On 2022-02-25 11:10, Dmitry Osipenko wrote:
> > 25.02.2022 13:49, Sascha Hauer пишет:
> > > On Fri, Feb 25, 2022 at 01:26:14PM +0300, Dmitry Osipenko wrote:
> > > > 25.02.2022 10:51, Sascha Hauer пишет:
> > > > > The rk3568 HDMI has an additional clock that needs to be enabled for 
> > > > > the
> > > > > HDMI controller to work. The purpose of that clock is not clear. It is
> > > > > named "hclk" in the downstream driver, so use the same name.
> > > > > 
> > > > > Signed-off-by: Sascha Hauer 
> > > > > ---
> > > > > 
> > > > > Notes:
> > > > >  Changes since v5:
> > > > >  - Use devm_clk_get_optional rather than devm_clk_get
> > > > > 
> > > > >   drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 
> > > > >   1 file changed, 16 insertions(+)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 
> > > > > b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> > > > > index fe4f9556239ac..c6c00e8779ab5 100644
> > > > > --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> > > > > +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> > > > > @@ -76,6 +76,7 @@ struct rockchip_hdmi {
> > > > >   const struct rockchip_hdmi_chip_data *chip_data;
> > > > >   struct clk *ref_clk;
> > > > >   struct clk *grf_clk;
> > > > > + struct clk *hclk_clk;
> > > > >   struct dw_hdmi *hdmi;
> > > > >   struct regulator *avdd_0v9;
> > > > >   struct regulator *avdd_1v8;
> > > > > @@ -229,6 +230,14 @@ static int rockchip_hdmi_parse_dt(struct 
> > > > > rockchip_hdmi *hdmi)
> > > > >   return PTR_ERR(hdmi->grf_clk);
> > > > >   }
> > > > > + hdmi->hclk_clk = devm_clk_get_optional(hdmi->dev, "hclk");
> > > > > + if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) {
> > > > 
> > > > Have you tried to investigate the hclk? I'm still thinking that's not
> > > > only HDMI that needs this clock and then the hardware description
> > > > doesn't look correct.
> > > 
> > > I am still not sure what you mean. Yes, it's not only the HDMI that
> > > needs this clock. The VOP2 needs it as well and the driver handles that.
> > 
> > I'm curious whether DSI/DP also need that clock to be enabled. If they
> > do, then you aren't modeling h/w properly AFAICS.
> 
> Assuming nobody at Rockchip decided to make things needlessly inconsistent
> with previous SoCs, HCLK_VOP should be the clock for the VOP's AHB slave
> interface. Usually, if that affected anything other than accessing VOP
> registers, indeed it would smell of something being wrong in the clock tree,
> but in this case I'd also be suspicious of whether it might have ended up
> clocking related GRF registers as well (either directly, or indirectly via
> some gate that the clock driver hasn't modelled yet).

Ok, I am beginning to understand. I verified that hdmi, mipi and dp are
hanging when HCLK_VOP is disabled by disabling that clock via sysfs
using CLOCK_ALLOW_WRITE_DEBUGFS. When it's disabled then the registers
of that units can't be accessed. However, when I disable HCLK_VOP by
directly writing to the gate bit RK3568_CLKGATE_CON(20) then only
accessing VOP registers hangs, the other units stay functional.
So it seems it must be the parent clock which must be enabled. The
parent clock is hclk_vo. This clock should be handled as part of the
RK3568_PD_VO power domain:

power-domain@RK3568_PD_VO {
reg = ;
clocks = < HCLK_VO>,
 < PCLK_VO>,
 < ACLK_VOP_PRE>;
 pm_qos = <_hdcp>,
  <_vop_m0>,
  <_vop_m1>;
 #power-domain-cells = <0>;
};

The HDMI controller is part of that domain, so I think this should work,
but it doesn't. That's where I am now, I'll have a closer look.

Sascha

-- 
Pengutronix e.K.   | |
Steuerwalder Str. 21   | http://www.pengutronix.de/  |
31137 Hildesheim, Germany  | Phone: +49-5121-206917-0|
Amtsgericht Hildesheim, HRA 2686   | Fax:   +49-5121-206917- |


Re: [PATCH v8 15/19] drm/mediatek: Add mt8195 Embedded DisplayPort driver

2022-02-25 Thread Guillaume Ranquet
Quoting CK Hu (2022-02-25 10:45:26)
> Hi, Guillaume:
>
> On Fri, 2022-02-18 at 15:54 +0100, Guillaume Ranquet wrote:
> > From: Markus Schneider-Pargmann 
> >
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> >
> > It supports the mt8195, the embedded DisplayPort units. It offers
> > hot-plug-detection and DisplayPort 1.4 with up to 4 lanes.
> >
> > The driver creates a child device for the phy. The child device will
> > never exist without the parent being active. As they are sharing a
> > register range, the parent passes a regmap pointer to the child so
> > that
> > both can work with the same register range. The phy driver sets
> > device
> > data that is read by the parent to get the phy device that can be
> > used
> > to control the phy properties.
> >
> > This driver is based on an initial version by
> > Jason-JH.Lin .
> >
> > Signed-off-by: Markus Schneider-Pargmann 
> > Signed-off-by: Guillaume Ranquet 
> > Reported-by: kernel test robot 
> > ---
> >  drivers/gpu/drm/mediatek/Kconfig   |7 +
> >  drivers/gpu/drm/mediatek/Makefile  |2 +
> >  drivers/gpu/drm/mediatek/mtk_dp.c  | 2358
> > 
> >  drivers/gpu/drm/mediatek/mtk_dp_reg.h  |  568 ++
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.c |1 +
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.h |1 +
> >  6 files changed, 2937 insertions(+)
> >  create mode 100644 drivers/gpu/drm/mediatek/mtk_dp.c
> >  create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_reg.h
> >
> >
>
> [snip]
>
> > +
> > +static u32 *mtk_dp_bridge_atomic_get_output_bus_fmts(struct
> > drm_bridge *bridge,
> > +  struct
> > drm_bridge_state *bridge_state,
> > +  struct
> > drm_crtc_state *crtc_state,
> > +  struct
> > drm_connector_state *conn_state,
> > +  unsigned int
> > *num_output_fmts)
> > +{
> > + u32 *output_fmts;
> > +
> > + *num_output_fmts = 0;
> > + output_fmts = kcalloc(1, sizeof(*output_fmts), GFP_KERNEL);
> > + if (!output_fmts)
> > + return NULL;
> > + *num_output_fmts = 1;
> > + output_fmts[0] = MEDIA_BUS_FMT_FIXED;
> > + return output_fmts;
> > +}
> > +
> > +static const u32 mt8195_input_fmts[] = {
> > + MEDIA_BUS_FMT_RGB888_1X24,
> > + MEDIA_BUS_FMT_YUV8_1X24,
> > + MEDIA_BUS_FMT_YUYV8_1X16,
> > +};
>
> This means DPINTF output format, right? Does DPINTF switch output
> buffer format?
>
I'll circle back with mediatek engineers, as I don't have a clue here.

> > +
> > +static u32 *mtk_dp_bridge_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;
> > + struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
> > + struct drm_display_mode *mode = _state->adjusted_mode;
> > + struct drm_display_info *display_info =
> > + _state->connector->display_info;
> > + u32 rx_linkrate;
> > + u32 bpp;
> > +
> > + bpp = (display_info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
> > ? 16 :
> > +
> >   24;
> > + rx_linkrate = (u32)mtk_dp->train_info.link_rate * 27000;
> > + *num_input_fmts = 0;
> > + input_fmts = kcalloc(ARRAY_SIZE(mt8195_input_fmts),
> > sizeof(*input_fmts),
> > +  GFP_KERNEL);
> > + if (!input_fmts)
> > + return NULL;
> > +
> > + *num_input_fmts = ARRAY_SIZE(mt8195_input_fmts);
> > +
> > + memcpy(input_fmts, mt8195_input_fmts,
> > +sizeof(*input_fmts) * ARRAY_SIZE(mt8195_input_fmts));
> > +
> > + if (((rx_linkrate * mtk_dp->train_info.lane_count) <
> > +  (mode->clock * 24 / 8)) &&
> > + ((rx_linkrate * mtk_dp->train_info.lane_count) >
> > +  (mode->clock * 16 / 8)) &&
> > + (display_info->color_formats & DRM_COLOR_FORMAT_YCRCB422))
> > {
> > + kfree(input_fmts);
> > + input_fmts = kcalloc(1, sizeof(*input_fmts),
> > GFP_KERNEL);
> > + *num_input_fmts = 1;
> > + input_fmts[0] = MEDIA_BUS_FMT_YUYV8_1X16;
> > + }
> > +
> > + return input_fmts;
> > +}
> > +
>
> [snip]
>
> > +
> > +static int mtk_dp_probe(struct platform_device *pdev)
> > +{
> > + struct mtk_dp *mtk_dp;
> > + struct device *dev = >dev;
> > + int ret;
> > + int irq_num = 0;
> > +
> > + mtk_dp = devm_kzalloc(dev, sizeof(*mtk_dp), GFP_KERNEL);
> > + if (!mtk_dp)
> > + return -ENOMEM;
> > +
> > +   

RE: [PATCH] gpu/amd: vega10_hwmgr: fix inappropriate private variable name

2022-02-25 Thread Quan, Evan
[AMD Official Use Only]

Thanks!
The patch is reviewed-by: Evan Quan 

> -Original Message-
> From: Meng Tang 
> Sent: Friday, February 25, 2022 5:47 PM
> To: airl...@linux.ie; dan...@ffwll.ch
> Cc: Quan, Evan ; Deucher, Alexander
> ; Koenig, Christian
> ; Pan, Xinhui ; amd-
> g...@lists.freedesktop.org; dri-devel@lists.freedesktop.org; linux-
> ker...@vger.kernel.org; Meng Tang 
> Subject: [PATCH] gpu/amd: vega10_hwmgr: fix inappropriate private variable
> name
> 
> In file vega10_hwmgr.c, the names of struct vega10_power_state *
> and struct pp_power_state * are confusingly used, which may lead
> to some confusion.
> 
> Status quo is that variables of type struct vega10_power_state *
> are named "vega10_ps", "ps", "vega10_power_state". A more
> appropriate usage is that struct are named "ps" is used for
> variabled of type struct pp_power_state *.
> 
> So rename struct vega10_power_state * which are named "ps" and
> "vega10_power_state" to "vega10_ps", I also renamed "psa" to
> "vega10_psa" and "psb" to "vega10_psb" to make it more clearly.
> 
> The rows longer than 100 columns are involved.
> 
> Signed-off-by: Meng Tang 
> ---
>  .../drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c | 68 +++---
> -
>  1 file changed, 38 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c
> b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c
> index 3f040be0d158..37324f2009ca 100644
> --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c
> +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c
> @@ -3095,7 +3095,7 @@ static int
> vega10_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr,
>   void *pp_table, uint32_t classification_flag)
>  {
>   ATOM_Vega10_GFXCLK_Dependency_Record_V2
> *patom_record_V2;
> - struct vega10_power_state *vega10_power_state =
> + struct vega10_power_state *vega10_ps =
>   cast_phw_vega10_power_state(&(power_state-
> >hardware));
>   struct vega10_performance_level *performance_level;
>   ATOM_Vega10_State *state_entry = (ATOM_Vega10_State *)state;
> @@ -3145,17 +3145,17 @@ static int
> vega10_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr,
>   power_state->temperatures.min = 0;
>   power_state->temperatures.max = 0;
> 
> - performance_level = &(vega10_power_state->performance_levels
> - [vega10_power_state-
> >performance_level_count++]);
> + performance_level = &(vega10_ps->performance_levels
> + [vega10_ps->performance_level_count++]);
> 
>   PP_ASSERT_WITH_CODE(
> - (vega10_power_state->performance_level_count <
> + (vega10_ps->performance_level_count <
>   NUM_GFXCLK_DPM_LEVELS),
>   "Performance levels exceeds SMC limit!",
>   return -1);
> 
>   PP_ASSERT_WITH_CODE(
> - (vega10_power_state->performance_level_count
> <=
> + (vega10_ps->performance_level_count <=
>   hwmgr->platform_descriptor.
>   hardwareActivityPerformanceLevels),
>   "Performance levels exceeds Driver limit!",
> @@ -3169,8 +3169,8 @@ static int
> vega10_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr,
>   performance_level->mem_clock = mclk_dep_table->entries
>   [state_entry->ucMemClockIndexLow].ulMemClk;
> 
> - performance_level = &(vega10_power_state->performance_levels
> - [vega10_power_state-
> >performance_level_count++]);
> + performance_level = &(vega10_ps->performance_levels
> + [vega10_ps->performance_level_count++]);
>   performance_level->soc_clock = socclk_dep_table->entries
>   [state_entry->ucSocClockIndexHigh].ulClk;
>   if (gfxclk_dep_table->ucRevId == 0) {
> @@ -3201,11 +3201,11 @@ static int vega10_get_pp_table_entry(struct
> pp_hwmgr *hwmgr,
>   unsigned long entry_index, struct pp_power_state *state)
>  {
>   int result;
> - struct vega10_power_state *ps;
> + struct vega10_power_state *vega10_ps;
> 
>   state->hardware.magic = PhwVega10_Magic;
> 
> - ps = cast_phw_vega10_power_state(>hardware);
> + vega10_ps = cast_phw_vega10_power_state(>hardware);
> 
>   result = vega10_get_powerplay_table_entry(hwmgr, entry_index,
> state,
>   vega10_get_pp_table_entry_callback_func);
> @@ -3218,10 +3218,10 @@ static int vega10_get_pp_table_entry(struct
> pp_hwmgr *hwmgr,
>*/
>   /* set DC compatible flag if this state supports DC */
>   if (!state->validation.disallowOnDC)
> - ps->dc_compatible = true;
> + vega10_ps->dc_compatible = true;
> 
> - ps->uvd_clks.vclk = state->uvd_clocks.VCLK;
> - ps->uvd_clks.dclk = 

Re: [PATCH v7 10/24] drm/rockchip: dw_hdmi: Add support for hclk

2022-02-25 Thread Robin Murphy

On 2022-02-25 11:10, Dmitry Osipenko wrote:

25.02.2022 13:49, Sascha Hauer пишет:

On Fri, Feb 25, 2022 at 01:26:14PM +0300, Dmitry Osipenko wrote:

25.02.2022 10:51, Sascha Hauer пишет:

The rk3568 HDMI has an additional clock that needs to be enabled for the
HDMI controller to work. The purpose of that clock is not clear. It is
named "hclk" in the downstream driver, so use the same name.

Signed-off-by: Sascha Hauer 
---

Notes:
 Changes since v5:
 - Use devm_clk_get_optional rather than devm_clk_get

  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 
  1 file changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 
b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index fe4f9556239ac..c6c00e8779ab5 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -76,6 +76,7 @@ struct rockchip_hdmi {
const struct rockchip_hdmi_chip_data *chip_data;
struct clk *ref_clk;
struct clk *grf_clk;
+   struct clk *hclk_clk;
struct dw_hdmi *hdmi;
struct regulator *avdd_0v9;
struct regulator *avdd_1v8;
@@ -229,6 +230,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi 
*hdmi)
return PTR_ERR(hdmi->grf_clk);
}
  
+	hdmi->hclk_clk = devm_clk_get_optional(hdmi->dev, "hclk");

+   if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) {


Have you tried to investigate the hclk? I'm still thinking that's not
only HDMI that needs this clock and then the hardware description
doesn't look correct.


I am still not sure what you mean. Yes, it's not only the HDMI that
needs this clock. The VOP2 needs it as well and the driver handles that.


I'm curious whether DSI/DP also need that clock to be enabled. If they
do, then you aren't modeling h/w properly AFAICS.


Assuming nobody at Rockchip decided to make things needlessly 
inconsistent with previous SoCs, HCLK_VOP should be the clock for the 
VOP's AHB slave interface. Usually, if that affected anything other than 
accessing VOP registers, indeed it would smell of something being wrong 
in the clock tree, but in this case I'd also be suspicious of whether it 
might have ended up clocking related GRF registers as well (either 
directly, or indirectly via some gate that the clock driver hasn't 
modelled yet).


If the symptom of not claiming HCLK_VOP is hanging on some register 
access in the HDMI driver while the VOP is idle, then it should be 
relatively straightforward to narrow down with some logging, and see if 
it looks like this is really just another "grf" clock. If not, then 
we're back to suspecting something more insidiously wrong elsewhere.


Robin.


Re: [PATCH v8 14/19] phy: phy-mtk-dp: Add driver for DP phy

2022-02-25 Thread AngeloGioacchino Del Regno

Il 25/02/22 12:49, Guillaume Ranquet ha scritto:

Quoting AngeloGioacchino Del Regno (2022-02-21 15:31:51)

Il 18/02/22 15:54, Guillaume Ranquet ha scritto:

From: Markus Schneider-Pargmann 

This is a new driver that supports the integrated DisplayPort phy for
mediatek SoCs, especially the mt8195. The phy is integrated into the
DisplayPort controller and will be created by the mtk-dp driver. This
driver expects a struct regmap to be able to work on the same registers
as the DisplayPort controller. It sets the device data to be the struct
phy so that the DisplayPort controller can easily work with it.

The driver does not have any devicetree bindings because the datasheet
does not list the controller and the phy as distinct units.

The interaction with the controller can be covered by the configure
callback of the phy framework and its displayport parameters.

Signed-off-by: Markus Schneider-Pargmann 
Signed-off-by: Guillaume Ranquet 
---
   MAINTAINERS   |   1 +
   drivers/phy/mediatek/Kconfig  |   8 ++
   drivers/phy/mediatek/Makefile |   1 +
   drivers/phy/mediatek/phy-mtk-dp.c | 199 ++
   4 files changed, 209 insertions(+)
   create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c



..snip..


+static int mtk_dp_phy_reset(struct phy *phy)
+{
+ struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
+
+ regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
+DP_GLB_SW_RST_PHYD, 0);


Please, when you add delays/sleeps, add a comment explaining the reason for 
that.

To you.. and to me as well.. the reason is very much known and honestly obvious,
but let's be nice with people that don't know the MediaTek platforms :)


It's sadly not obvious to me, I've asked mediatek engineers mutlple
times for these
kind of information, but I'm rather short on information... :-/



Clearly, the PHY needs at least 50uS to perform software reset (SW_RST) of
the digital (controller? my brain doesn't want to cooperate on giving the
right word right now, sorry), so we sleep that time after asserting the
reset bit to comply with this timing.


+ usleep_range(50, 200);
+ regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
+DP_GLB_SW_RST_PHYD, 1);
+
+ return 0;
+}
+
+static const struct phy_ops mtk_dp_phy_dev_ops = {
+ .init = mtk_dp_phy_init,
+ .configure = mtk_dp_phy_configure,
+ .reset = mtk_dp_phy_reset,
+ .owner = THIS_MODULE,
+};
+
+static int mtk_dp_phy_probe(struct platform_device *pdev)
+{
+ struct device *dev = >dev;
+ struct mtk_dp_phy *dp_phy;
+ struct phy *phy;


 struct regmap *regs = (blah);

 if (!dp_phy->regs)
 return -EINVAL;

Doing that before allocating the dp_phy struct seems sensible as, even
if it's unlikely that this platform data is not passed, we'd be sparing
some time around.

Besides - I think that the error message is not necessary here, but, if
you really want to keep it, please return dev_err_probe(): using it in
these cases is also allowed.


You are right, it's logical to return as early as possible.


+
+ dp_phy = devm_kzalloc(dev, sizeof(*dp_phy), GFP_KERNEL);
+ if (!dp_phy)
+ return -ENOMEM;
+
+ dp_phy->regs = *(struct regmap **)dev->platform_data;
+ if (!dp_phy->regs) {
+ dev_err(dev, "No data passed, requires struct regmap**\n");
+ return -EINVAL;
+ }
+
+ phy = devm_phy_create(dev, NULL, _dp_phy_dev_ops);


 if (IS_ERR(phy))
 return dev_err_probe(dev, PTR_ERR(phy), "Cannot create DP 
PHY\n");


+ if (IS_ERR(phy)) {
+ dev_err(dev, "Failed to create DP PHY: %ld\n", PTR_ERR(phy));
+ return PTR_ERR(phy);
+ }
+ phy_set_drvdata(phy, dp_phy);
+
+ if (!dev->of_node)


This will never happen if you use DT to probe this driver - and please do!

An example device-tree binding would be:

dp_phy: phy@somewhere {
 compatible = "mediatek,mt8195-dp-phy", "mediatek,dp-phy";
 reg = <...>;
 #phy-cells = <0>;
};

mtk_dp: displayport-controller@somewhere_else {
 compatible = "mediatek,mt8195-edp-tx", "mediatek,edp-tx";
 reg = <>;
 other-properties;

 phys = <_phy>;
 phy-names = "dp";
};

Also, remember: since you're nicely using regmap, if you - for any reason - need
to share the same iospace between the two drivers, you can always use a
syscon node for that purpose.


Sadly, I'm not using DT to prove this driver... and this driver will
probably never
be used with DT.
This phy is actually an integral part of the dp ip, this driver is
only a "logical"
separation between the DP/phy functionnalities.
It's probed from the DP driver with a call to `platform_register_device()`.
Both the DP and phy driver share the same regmap struct.

Markus tried to explain that in the commit message, please tell me if this needs
a reword?
The original discussion 

Re: [PATCH v8 14/19] phy: phy-mtk-dp: Add driver for DP phy

2022-02-25 Thread Guillaume Ranquet
Quoting AngeloGioacchino Del Regno (2022-02-21 15:31:51)
> Il 18/02/22 15:54, Guillaume Ranquet ha scritto:
> > From: Markus Schneider-Pargmann 
> >
> > This is a new driver that supports the integrated DisplayPort phy for
> > mediatek SoCs, especially the mt8195. The phy is integrated into the
> > DisplayPort controller and will be created by the mtk-dp driver. This
> > driver expects a struct regmap to be able to work on the same registers
> > as the DisplayPort controller. It sets the device data to be the struct
> > phy so that the DisplayPort controller can easily work with it.
> >
> > The driver does not have any devicetree bindings because the datasheet
> > does not list the controller and the phy as distinct units.
> >
> > The interaction with the controller can be covered by the configure
> > callback of the phy framework and its displayport parameters.
> >
> > Signed-off-by: Markus Schneider-Pargmann 
> > Signed-off-by: Guillaume Ranquet 
> > ---
> >   MAINTAINERS   |   1 +
> >   drivers/phy/mediatek/Kconfig  |   8 ++
> >   drivers/phy/mediatek/Makefile |   1 +
> >   drivers/phy/mediatek/phy-mtk-dp.c | 199 ++
> >   4 files changed, 209 insertions(+)
> >   create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index fca970a46e77a..33a05d396dd03 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -6467,6 +6467,7 @@ L:  linux-media...@lists.infradead.org (moderated 
> > for non-subscribers)
> >   S:  Supported
> >   F:  Documentation/devicetree/bindings/display/mediatek/
> >   F:  drivers/gpu/drm/mediatek/
> > +F:   drivers/phy/mediatek/phy-mtk-dp.c
> >   F:  drivers/phy/mediatek/phy-mtk-hdmi*
> >   F:  drivers/phy/mediatek/phy-mtk-mipi*
> >
> > diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig
> > index 55f8e6c048ab3..f7ec860590492 100644
> > --- a/drivers/phy/mediatek/Kconfig
> > +++ b/drivers/phy/mediatek/Kconfig
> > @@ -55,3 +55,11 @@ config PHY_MTK_MIPI_DSI
> >   select GENERIC_PHY
> >   help
> > Support MIPI DSI for Mediatek SoCs.
> > +
> > +config PHY_MTK_DP
> > + tristate "MediaTek DP-PHY Driver"
> > + depends on ARCH_MEDIATEK || COMPILE_TEST
> > + depends on OF
> > + select GENERIC_PHY
> > + help
> > +   Support DisplayPort PHY for Mediatek SoCs.
> > diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
> > index ace660fbed3a1..4ba1e06504346 100644
> > --- a/drivers/phy/mediatek/Makefile
> > +++ b/drivers/phy/mediatek/Makefile
> > @@ -3,6 +3,7 @@
> >   # Makefile for the phy drivers.
> >   #
> >
> > +obj-$(CONFIG_PHY_MTK_DP) += phy-mtk-dp.o
> >   obj-$(CONFIG_PHY_MTK_TPHY)  += phy-mtk-tphy.o
> >   obj-$(CONFIG_PHY_MTK_UFS)   += phy-mtk-ufs.o
> >   obj-$(CONFIG_PHY_MTK_XSPHY) += phy-mtk-xsphy.o
> > diff --git a/drivers/phy/mediatek/phy-mtk-dp.c 
> > b/drivers/phy/mediatek/phy-mtk-dp.c
> > new file mode 100644
> > index 0..2841dd3f22543
> > --- /dev/null
> > +++ b/drivers/phy/mediatek/phy-mtk-dp.c
> > @@ -0,0 +1,199 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
>
> Would be nice to add:
>
>   * phy-mtk-dp.c - MediaTek DisplayPort PHY driver
>   *
>
> > + * Copyright (c) 2021 BayLibre
> > + * Author: Markus Schneider-Pargmann 
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define PHY_OFFSET 0x1000
> > +
> > +#define MTK_DP_PHY_DIG_PLL_CTL_1 (PHY_OFFSET + 0x014)
> > +#define TPLL_SSC_EN  BIT(3)
> > +
> > +#define MTK_DP_PHY_DIG_BIT_RATE  (PHY_OFFSET + 0x03C)
> > +#define BIT_RATE_RBR 0
> > +#define BIT_RATE_HBR 1
> > +#define BIT_RATE_HBR22
> > +#define BIT_RATE_HBR33
> > +
> > +#define MTK_DP_PHY_DIG_SW_RST(PHY_OFFSET + 0x038)
> > +#define DP_GLB_SW_RST_PHYD   BIT(0)
> > +
> > +#define MTK_DP_LANE0_DRIVING_PARAM_3 (PHY_OFFSET + 0x138)
> > +#define MTK_DP_LANE1_DRIVING_PARAM_3 (PHY_OFFSET + 0x238)
> > +#define MTK_DP_LANE2_DRIVING_PARAM_3 (PHY_OFFSET + 0x338)
> > +#define MTK_DP_LANE3_DRIVING_PARAM_3 (PHY_OFFSET + 0x438)
> > +#define XTP_LN_TX_LCTXC0_SW0_PRE0_DEFAULT0x10
>
> BIT(4)
>
> > +#define XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT(0x14 << 8)
> > +#define XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT(0x18 << 16)
> > +#define XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT(0x20 << 24)
>
> Please use the GENMASK() macro for these definitions.
>
I will convert all the definitions to BIT() and GENMASK() for v9

> > +#define DRIVING_PARAM_3_DEFAULT  
> > (XTP_LN_TX_LCTXC0_SW0_PRE0_DEFAULT | \
> > +  
> > XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT | \
> > +  
> > 

Re: [Intel-gfx] [PATCH 2/2] hda/i915: split the wait for the component binding

2022-02-25 Thread Takashi Iwai
On Thu, 24 Feb 2022 17:34:54 +0100,
Kai Vehmanen wrote:
> 
> Hi,
> 
> On Thu, 24 Feb 2022, Ramalingam C wrote:
> 
> > Split the wait for component binding from i915 in multiples of
> > sysctl_hung_task_timeout_secs. This helps to avoid the possible kworker
> > thread hung detection given below.
> 
> while I understand the problem, I'm not sure whether a simpler option
> should be chosen. Maybe just split the wait_for_completion_timeout()
> into small 5sec iterations, without consulting value of hung_task_timeout.
> This would seem unligned with more mainstream use of 
> wait_for_completion_timeout() in kernel and still do the job.
> 
> I'll loop in Takashi here as well. Basicly the 60 sec timeout in 
> hda/hdac_i915.c is getting caught by hung_task_detection logic in builds
> where the hung_task_timeout is below 60secs.
> 
> I have a patch that tries to avoid hitting the timeout in some of the more 
> common cases:
> "ALSA: hda/i915 - skip acomp init if no matching display"
> https://lists.freedesktop.org/archives/intel-gfx-trybot/2022-February/128278.html
> ... but we'll still be stuck with some configurations where the timeout 
> will be hit. And above needs careful testing.
> 
> One logic comment below as well, but I'll quote the whole patch to give
> context to Takashi.

I agree with Kai, we can just make the wait_for_completion_timeout()
split in a loop independently from hung_task_timeout.  It's simpler,
less error-prone.


thanks,

Takashi


Re: [PATCH v7 10/24] drm/rockchip: dw_hdmi: Add support for hclk

2022-02-25 Thread Sascha Hauer
On Fri, Feb 25, 2022 at 02:10:55PM +0300, Dmitry Osipenko wrote:
> 25.02.2022 13:49, Sascha Hauer пишет:
> > On Fri, Feb 25, 2022 at 01:26:14PM +0300, Dmitry Osipenko wrote:
> >> 25.02.2022 10:51, Sascha Hauer пишет:
> >>> The rk3568 HDMI has an additional clock that needs to be enabled for the
> >>> HDMI controller to work. The purpose of that clock is not clear. It is
> >>> named "hclk" in the downstream driver, so use the same name.
> >>>
> >>> Signed-off-by: Sascha Hauer 
> >>> ---
> >>>
> >>> Notes:
> >>> Changes since v5:
> >>> - Use devm_clk_get_optional rather than devm_clk_get
> >>>
> >>>  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 
> >>>  1 file changed, 16 insertions(+)
> >>>
> >>> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 
> >>> b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> >>> index fe4f9556239ac..c6c00e8779ab5 100644
> >>> --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> >>> +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> >>> @@ -76,6 +76,7 @@ struct rockchip_hdmi {
> >>>   const struct rockchip_hdmi_chip_data *chip_data;
> >>>   struct clk *ref_clk;
> >>>   struct clk *grf_clk;
> >>> + struct clk *hclk_clk;
> >>>   struct dw_hdmi *hdmi;
> >>>   struct regulator *avdd_0v9;
> >>>   struct regulator *avdd_1v8;
> >>> @@ -229,6 +230,14 @@ static int rockchip_hdmi_parse_dt(struct 
> >>> rockchip_hdmi *hdmi)
> >>>   return PTR_ERR(hdmi->grf_clk);
> >>>   }
> >>>  
> >>> + hdmi->hclk_clk = devm_clk_get_optional(hdmi->dev, "hclk");
> >>> + if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) {
> >>
> >> Have you tried to investigate the hclk? I'm still thinking that's not
> >> only HDMI that needs this clock and then the hardware description
> >> doesn't look correct.
> > 
> > I am still not sure what you mean. Yes, it's not only the HDMI that
> > needs this clock. The VOP2 needs it as well and the driver handles that.
> 
> I'm curious whether DSI/DP also need that clock to be enabled. If they
> do, then you aren't modeling h/w properly AFAICS.

Indeed I can confirm that DSI and DP need that clock enabled for
register access as well. Do you think these devices should be under an
additional bus layer in the device tree which drives the clock? Or
should HCLK_VOP be enabled as part of the RK3568_PD_VO power domain?

Sascha

-- 
Pengutronix e.K.   | |
Steuerwalder Str. 21   | http://www.pengutronix.de/  |
31137 Hildesheim, Germany  | Phone: +49-5121-206917-0|
Amtsgericht Hildesheim, HRA 2686   | Fax:   +49-5121-206917- |


Re: [PATCH v8 13/19] drm/mediatek: dpi: Add dpintf support

2022-02-25 Thread Guillaume Ranquet
Quoting Maxime Ripard (2022-02-21 10:44:20)
> Hi
>
> (Now I remember your series ;)
Hi,

I'm not sure this is a good thing though :)

>
> On Fri, Feb 18, 2022 at 03:54:31PM +0100, Guillaume Ranquet wrote:
> > dpintf is the displayport interface hardware unit. This unit is similar
> > to dpi and can reuse most of the code.
> >
> > This patch adds support for mt8195-dpintf to this dpi driver. Main
> > differences are:
> >  - Some features/functional components are not available for dpintf
> >which are now excluded from code execution once is_dpintf is set
> >  - dpintf can and needs to choose between different clockdividers based
> >on the clockspeed. This is done by choosing a different clock parent.
> >  - There are two additional clocks that need to be managed. These are
> >only set for dpintf and will be set to NULL if not supplied. The
> >clk_* calls handle these as normal clocks then.
> >  - Some register contents differ slightly between the two components. To
> >work around this I added register bits/masks with a DPINTF_ prefix
> >and use them where different.
> >
> > Based on a separate driver for dpintf created by
> > Jason-JH.Lin .
> >
> > Signed-off-by: Markus Schneider-Pargmann 
> > Signed-off-by: Guillaume Ranquet 
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dpi.c  | 164 +---
> >  drivers/gpu/drm/mediatek/mtk_dpi_regs.h |  38 +
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   8 +
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.c  |   5 +-
> >  include/linux/soc/mediatek/mtk-mmsys.h  |   2 +
> >  6 files changed, 198 insertions(+), 20 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c 
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index be99399faf1bb..c5639ada868f8 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -63,6 +63,14 @@ enum mtk_dpi_out_color_format {
> >   MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL
> >  };
> >
> > +enum TVDPLL_CLK {
> > + TVDPLL_PLL = 0,
> > + TVDPLL_D2 = 2,
> > + TVDPLL_D4 = 4,
> > + TVDPLL_D8 = 8,
> > + TVDPLL_D16 = 16,
> > +};
> > +
> >  struct mtk_dpi {
> >   struct drm_encoder encoder;
> >   struct drm_bridge bridge;
> > @@ -71,8 +79,10 @@ struct mtk_dpi {
> >   void __iomem *regs;
> >   struct device *dev;
> >   struct clk *engine_clk;
> > + struct clk *dpi_ck_cg;
> >   struct clk *pixel_clk;
> >   struct clk *tvd_clk;
> > + struct clk *pclk_src[5];
> >   int irq;
> >   struct drm_display_mode mode;
> >   const struct mtk_dpi_conf *conf;
> > @@ -126,6 +136,7 @@ struct mtk_dpi_conf {
> >   const u32 *output_fmts;
> >   u32 num_output_fmts;
> >   bool is_ck_de_pol;
> > + bool is_dpintf;
> >   bool swap_input_support;
> >   // Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no 
> > shift)
> >   u32 dimension_mask;
> > @@ -384,6 +395,25 @@ static void mtk_dpi_config_disable_edge(struct mtk_dpi 
> > *dpi)
> >   mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, 0, EDGE_SEL_EN);
> >  }
> >
> > +static void mtk_dpi_matrix_sel(struct mtk_dpi *dpi, enum 
> > mtk_dpi_out_color_format format)
> > +{
> > + u32 matrix_sel = 0;
> > +
> > + switch (format) {
> > + case MTK_DPI_COLOR_FORMAT_YCBCR_422:
> > + case MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL:
> > + case MTK_DPI_COLOR_FORMAT_YCBCR_444:
> > + case MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL:
> > + case MTK_DPI_COLOR_FORMAT_XV_YCC:
> > + if (dpi->mode.hdisplay <= 720)
> > + matrix_sel = 0x2;
> > + break;
> > + default:
> > + break;
> > + }
> > + mtk_dpi_mask(dpi, DPI_MATRIX_SET, matrix_sel, INT_MATRIX_SEL_MASK);
> > +}
> > +
> >  static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
> >   enum mtk_dpi_out_color_format format)
> >  {
> > @@ -391,6 +421,7 @@ static void mtk_dpi_config_color_format(struct mtk_dpi 
> > *dpi,
> >   (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
> >   mtk_dpi_config_yuv422_enable(dpi, false);
> >   mtk_dpi_config_csc_enable(dpi, true);
> > + mtk_dpi_matrix_sel(dpi, format);
> >   if (dpi->conf->swap_input_support)
> >   mtk_dpi_config_swap_input(dpi, false);
> >   mtk_dpi_config_channel_swap(dpi, 
> > MTK_DPI_OUT_CHANNEL_SWAP_BGR);
> > @@ -398,6 +429,7 @@ static void mtk_dpi_config_color_format(struct mtk_dpi 
> > *dpi,
> >  (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
> >   mtk_dpi_config_yuv422_enable(dpi, true);
> >   mtk_dpi_config_csc_enable(dpi, true);
> > + mtk_dpi_matrix_sel(dpi, format);
> >   if (dpi->conf->swap_input_support)
> >   mtk_dpi_config_swap_input(dpi, true);
> >   

Re: [PATCH v7 10/24] drm/rockchip: dw_hdmi: Add support for hclk

2022-02-25 Thread Dmitry Osipenko
25.02.2022 13:49, Sascha Hauer пишет:
> On Fri, Feb 25, 2022 at 01:26:14PM +0300, Dmitry Osipenko wrote:
>> 25.02.2022 10:51, Sascha Hauer пишет:
>>> The rk3568 HDMI has an additional clock that needs to be enabled for the
>>> HDMI controller to work. The purpose of that clock is not clear. It is
>>> named "hclk" in the downstream driver, so use the same name.
>>>
>>> Signed-off-by: Sascha Hauer 
>>> ---
>>>
>>> Notes:
>>> Changes since v5:
>>> - Use devm_clk_get_optional rather than devm_clk_get
>>>
>>>  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 
>>>  1 file changed, 16 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 
>>> b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>> index fe4f9556239ac..c6c00e8779ab5 100644
>>> --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>> +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>> @@ -76,6 +76,7 @@ struct rockchip_hdmi {
>>> const struct rockchip_hdmi_chip_data *chip_data;
>>> struct clk *ref_clk;
>>> struct clk *grf_clk;
>>> +   struct clk *hclk_clk;
>>> struct dw_hdmi *hdmi;
>>> struct regulator *avdd_0v9;
>>> struct regulator *avdd_1v8;
>>> @@ -229,6 +230,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi 
>>> *hdmi)
>>> return PTR_ERR(hdmi->grf_clk);
>>> }
>>>  
>>> +   hdmi->hclk_clk = devm_clk_get_optional(hdmi->dev, "hclk");
>>> +   if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) {
>>
>> Have you tried to investigate the hclk? I'm still thinking that's not
>> only HDMI that needs this clock and then the hardware description
>> doesn't look correct.
> 
> I am still not sure what you mean. Yes, it's not only the HDMI that
> needs this clock. The VOP2 needs it as well and the driver handles that.

I'm curious whether DSI/DP also need that clock to be enabled. If they
do, then you aren't modeling h/w properly AFAICS.


Re: [PATCH v8 10/19] drm/mediatek: dpi: move swap_shift to board config

2022-02-25 Thread Guillaume Ranquet
Quoting Chun-Kuang Hu (2022-02-21 04:24:32)
> Hi, Guillaume:
>
> Guillaume Ranquet  於 2022年2月18日 週五 下午10:56寫道:
> >
> > Add flexibility by moving the swap shift value to board config
> >
> > Signed-off-by: Guillaume Ranquet 
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++-
> >  1 file changed, 7 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c 
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index 0d3acd08ea358..ec221e24e0fee 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -131,6 +131,7 @@ struct mtk_dpi_conf {
> > u32 dimension_mask;
> > // Mask used for HSIZE and VSIZE (no shift)
> > u32 hvsize_mask;
> > +   u32 channel_swap_shift;
> > const struct mtk_dpi_yc_limit *limit;
> >  };
> >
> > @@ -349,7 +350,8 @@ static void mtk_dpi_config_channel_swap(struct mtk_dpi 
> > *dpi,
> > break;
> > }
> >
> > -   mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP, CH_SWAP_MASK);
> > +   mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP,
> > +CH_SWAP_MASK << dpi->conf->channel_swap_shift);
>
> This may be wrong because of these definition:
>
> #define DPINTF_CH_SWAP BIT(1)
> #define DPINTF_CH_SWAP_MASK (0x7 << 1)
>
> Regards,
> Chun-Kuang.
>

You are right, DPINTF_CH_SWAP_MASK is unused, which is wrong on multiple levels.

> >  }
> >
> >  static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable)
> > @@ -821,6 +823,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
> > .swap_input_support = true,
> > .dimension_mask = HPW_MASK,
> > .hvsize_mask = HSIZE_MASK,
> > +   .channel_swap_shift = CH_SWAP,
> > .limit = _dpi_limit,
> >  };
> >
> > @@ -835,6 +838,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
> > .swap_input_support = true,
> > .dimension_mask = HPW_MASK,
> > .hvsize_mask = HSIZE_MASK,
> > +   .channel_swap_shift = CH_SWAP,
> > .limit = _dpi_limit,
> >  };
> >
> > @@ -848,6 +852,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
> > .swap_input_support = true,
> > .dimension_mask = HPW_MASK,
> > .hvsize_mask = HSIZE_MASK,
> > +   .channel_swap_shift = CH_SWAP,
> > .limit = _dpi_limit,
> >  };
> >
> > @@ -861,6 +866,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
> > .swap_input_support = true,
> > .dimension_mask = HPW_MASK,
> > .hvsize_mask = HSIZE_MASK,
> > +   .channel_swap_shift = CH_SWAP,
> > .limit = _dpi_limit,
> >  };
> >
> > --
> > 2.34.1
> >


Re: [PATCH 22/23] video: omapfb: dss: Make use of the helper component_compare_dev

2022-02-25 Thread Greg Kroah-Hartman
On Tue, Feb 15, 2022 at 09:46:24PM +0100, Helge Deller wrote:
> On 2/14/22 07:08, Yong Wu wrote:
> > Use the common compare helper from component.
> >
> > Cc: Helge Deller 
> > Cc: linux-o...@vger.kernel.org
> > Cc: linux-fb...@vger.kernel.org
> > Signed-off-by: Yong Wu 
> 
> Applied to the fbdev for-next branch.

That will break the build, it needs patch 1/23 to build properly :(



Re: [PATCH v8 07/19] drm/mediatek: dpi: implement a swap_input toggle in board config

2022-02-25 Thread Guillaume Ranquet
Quoting Chun-Kuang Hu (2022-02-21 03:32:32)
> Hi, Guillaume:
>
> Guillaume Ranquet  於 2022年2月18日 週五 下午10:56寫道:
> >
> > Adds a bit of flexibility to support boards without swap_input support
> >
> > Signed-off-by: Guillaume Ranquet 
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dpi.c | 14 +++---
> >  1 file changed, 11 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c 
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index 545a1337cc899..454f8563efae4 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -126,6 +126,7 @@ struct mtk_dpi_conf {
> > const u32 *output_fmts;
> > u32 num_output_fmts;
> > bool is_ck_de_pol;
> > +   bool swap_input_support;
> > const struct mtk_dpi_yc_limit *limit;
> >  };
> >
> > @@ -378,18 +379,21 @@ static void mtk_dpi_config_color_format(struct 
> > mtk_dpi *dpi,
> > (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
> > mtk_dpi_config_yuv422_enable(dpi, false);
> > mtk_dpi_config_csc_enable(dpi, true);
> > -   mtk_dpi_config_swap_input(dpi, false);
> > +   if (dpi->conf->swap_input_support)
> > +   mtk_dpi_config_swap_input(dpi, false);
> > mtk_dpi_config_channel_swap(dpi, 
> > MTK_DPI_OUT_CHANNEL_SWAP_BGR);
> > } else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) ||
> >(format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
> > mtk_dpi_config_yuv422_enable(dpi, true);
> > mtk_dpi_config_csc_enable(dpi, true);
> > -   mtk_dpi_config_swap_input(dpi, true);
> > +   if (dpi->conf->swap_input_support)
> > +   mtk_dpi_config_swap_input(dpi, true);
>
> In MT8173, MT2701, MT8183, MT8192, YCBCR_444 would not swap but
> YCBCR_422 would swap. But In MT8195, both YCBCR_444 and YCBCR_422
> would not swap, So I think one of these format would be abnormal in
> MT8195, right? Or would you provide more information about how this
> swap work?
>
> Regards,
> Chun-Kuang.
>

I'm not sure I have access to that level of information... and my
knowledge on mediatek
SoC is rather limited, I will circle back with mediatek engineers to
have a definite
answer.

Thx,
Guillaume
> > mtk_dpi_config_channel_swap(dpi, 
> > MTK_DPI_OUT_CHANNEL_SWAP_RGB);
> > } else {
> > mtk_dpi_config_yuv422_enable(dpi, false);
> > mtk_dpi_config_csc_enable(dpi, false);
> > -   mtk_dpi_config_swap_input(dpi, false);
> > +   if (dpi->conf->swap_input_support)
> > +   mtk_dpi_config_swap_input(dpi, false);
> > mtk_dpi_config_channel_swap(dpi, 
> > MTK_DPI_OUT_CHANNEL_SWAP_RGB);
> > }
> >  }
> > @@ -808,6 +812,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
> > .output_fmts = mt8173_output_fmts,
> > .num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> > .is_ck_de_pol = true,
> > +   .swap_input_support = true,
> > .limit = _dpi_limit,
> >  };
> >
> > @@ -819,6 +824,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
> > .output_fmts = mt8173_output_fmts,
> > .num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> > .is_ck_de_pol = true,
> > +   .swap_input_support = true,
> > .limit = _dpi_limit,
> >  };
> >
> > @@ -829,6 +835,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
> > .output_fmts = mt8183_output_fmts,
> > .num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
> > .is_ck_de_pol = true,
> > +   .swap_input_support = true,
> > .limit = _dpi_limit,
> >  };
> >
> > @@ -839,6 +846,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
> > .output_fmts = mt8173_output_fmts,
> > .num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> > .is_ck_de_pol = true,
> > +   .swap_input_support = true,
> > .limit = _dpi_limit,
> >  };
> >
> > --
> > 2.34.1
> >


Re: [PATCH v8 06/19] drm/mediatek: dpi: implement a CK/DE pol toggle in board config

2022-02-25 Thread Guillaume Ranquet
Quoting Chun-Kuang Hu (2022-02-21 03:14:02)
> HI, Guillaume:
>
> Guillaume Ranquet  於 2022年2月18日 週五 下午10:56寫道:
> >
> > Adds a bit of flexibility to support boards without CK/DE pol support
>
> I'm not sure what the term 'board' mean. Do you mean different board
> with different panel but all with mt8195-dpintf? If so, you should get
> CK/DE support from panel driver not fix this information in dpi
> driver.
>
> Regards,
> Chun-Kuang.
>

Hi Chun-Kuang,

The correct term (as pointed by Angelo) would be 'SoC' instead of
'board' I guess.
My understanding is that every SoC might have or might not have CK/DE support.


I'll try to dig into the documentation I have to understand exactly
where this support
is coming from.

Thx,
Guillaume.

> >
> > Signed-off-by: Guillaume Ranquet 
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dpi.c | 22 +-
> >  1 file changed, 17 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c 
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index 4746eb3425674..545a1337cc899 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -125,6 +125,7 @@ struct mtk_dpi_conf {
> > bool edge_sel_en;
> > const u32 *output_fmts;
> > u32 num_output_fmts;
> > +   bool is_ck_de_pol;
> > const struct mtk_dpi_yc_limit *limit;
> >  };
> >
> > @@ -211,13 +212,20 @@ static void mtk_dpi_config_pol(struct mtk_dpi *dpi,
> >struct mtk_dpi_polarities *dpi_pol)
> >  {
> > unsigned int pol;
> > +   unsigned int mask;
> >
> > -   pol = (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ? 0 : CK_POL) |
> > - (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ? 0 : DE_POL) |
> > - (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 : 
> > HSYNC_POL) |
> > +   mask = HSYNC_POL | VSYNC_POL;
> > +   pol = (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 : 
> > HSYNC_POL) |
> >   (dpi_pol->vsync_pol == MTK_DPI_POLARITY_RISING ? 0 : 
> > VSYNC_POL);
> > -   mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol,
> > -CK_POL | DE_POL | HSYNC_POL | VSYNC_POL);
> > +   if (dpi->conf->is_ck_de_pol) {
> > +   mask |= CK_POL | DE_POL;
> > +   pol |= (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ?
> > +   0 : CK_POL) |
> > +  (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ?
> > +   0 : DE_POL);
> > +   }
> > +
> > +   mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol, mask);
> >  }
> >
> >  static void mtk_dpi_config_3d(struct mtk_dpi *dpi, bool en_3d)
> > @@ -799,6 +807,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
> > .max_clock_khz = 30,
> > .output_fmts = mt8173_output_fmts,
> > .num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> > +   .is_ck_de_pol = true,
> > .limit = _dpi_limit,
> >  };
> >
> > @@ -809,6 +818,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
> > .max_clock_khz = 15,
> > .output_fmts = mt8173_output_fmts,
> > .num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> > +   .is_ck_de_pol = true,
> > .limit = _dpi_limit,
> >  };
> >
> > @@ -818,6 +828,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
> > .max_clock_khz = 10,
> > .output_fmts = mt8183_output_fmts,
> > .num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
> > +   .is_ck_de_pol = true,
> > .limit = _dpi_limit,
> >  };
> >
> > @@ -827,6 +838,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
> > .max_clock_khz = 15,
> > .output_fmts = mt8173_output_fmts,
> > .num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> > +   .is_ck_de_pol = true,
> > .limit = _dpi_limit,
> >  };
> >
> > --
> > 2.34.1
> >


Re: [PATCH 3/7] drm/bridge: Extend struct drm_bus_cfg with clock field

2022-02-25 Thread Maxime Ripard
On Thu, Feb 24, 2022 at 09:07:19PM +0100, Marek Vasut wrote:
> On 2/24/22 16:19, Maxime Ripard wrote:
> > On Sat, Feb 19, 2022 at 01:28:40AM +0100, Marek Vasut wrote:
> > > diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
> > > index 1701c2128a5cb..32455cf28f0bc 100644
> > > --- a/include/drm/drm_atomic.h
> > > +++ b/include/drm/drm_atomic.h
> > > @@ -1077,6 +1077,11 @@ struct drm_bus_cfg {
> > >* @flags: DRM_BUS_* flags used on this bus
> > >*/
> > >   u32 flags;
> > > +
> > > + /**
> > > +  * @clock: Clock frequency in kHz used on this bus
> > > +  */
> > > + u32 clock;
> > >   };
> > 
> > This is fairly vague. You were mentioning DSI: is it the pixel clock?
> 
> DSI HS clock is the one I need.
> 
> I hope we can flesh out what exactly should be in here.
> 
> > The HS clock rate?
> 
> Yes
> 
> > With or without counting the lanes? What about the
> 
> Without
> 
> > burst mode: would it be the lane or pixel rate?
> 
> Still the HS clock rate.
> 
> > It would be just as confusing for HDMI: is it the the TMDS character
> > rate? The TMDS bit rate ? TMDS Clock rate?
> 
> For HDMI I would expect 148.5 MHz here , and if HDMI needs additional
> extras, they might have to be added to struct drm_bus_cfg as extra fields ?

The thing is: you're patching some core code here. Whatever you come up
with needs to be properly defined, documented, and should apply to all
the display interfaces we support. It cannot be an after-thought.

Even for DSI, I don't think that the HS clock is something that is
desirable: how does it interacts with virtual channels? burst mode or
not?

The pixel clock is a better choice I think for this, since this is
abstract enough to apply to all the interfaces, and the devices can
easily compute whatever they want to based on the pixel clock as well.

If you *really* need the HS clock itself, then the struct
mipi_dsi_device feels like a better abstraction. Which raises the
question: why can't you use hs_rate?

Maxime


signature.asc
Description: PGP signature


Re: [PATCH v7 10/24] drm/rockchip: dw_hdmi: Add support for hclk

2022-02-25 Thread Sascha Hauer
On Fri, Feb 25, 2022 at 01:26:14PM +0300, Dmitry Osipenko wrote:
> 25.02.2022 10:51, Sascha Hauer пишет:
> > The rk3568 HDMI has an additional clock that needs to be enabled for the
> > HDMI controller to work. The purpose of that clock is not clear. It is
> > named "hclk" in the downstream driver, so use the same name.
> > 
> > Signed-off-by: Sascha Hauer 
> > ---
> > 
> > Notes:
> > Changes since v5:
> > - Use devm_clk_get_optional rather than devm_clk_get
> > 
> >  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 
> >  1 file changed, 16 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 
> > b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> > index fe4f9556239ac..c6c00e8779ab5 100644
> > --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> > +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> > @@ -76,6 +76,7 @@ struct rockchip_hdmi {
> > const struct rockchip_hdmi_chip_data *chip_data;
> > struct clk *ref_clk;
> > struct clk *grf_clk;
> > +   struct clk *hclk_clk;
> > struct dw_hdmi *hdmi;
> > struct regulator *avdd_0v9;
> > struct regulator *avdd_1v8;
> > @@ -229,6 +230,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi 
> > *hdmi)
> > return PTR_ERR(hdmi->grf_clk);
> > }
> >  
> > +   hdmi->hclk_clk = devm_clk_get_optional(hdmi->dev, "hclk");
> > +   if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) {
> 
> Have you tried to investigate the hclk? I'm still thinking that's not
> only HDMI that needs this clock and then the hardware description
> doesn't look correct.

I am still not sure what you mean. Yes, it's not only the HDMI that
needs this clock. The VOP2 needs it as well and the driver handles that.

Sascha

-- 
Pengutronix e.K.   | |
Steuerwalder Str. 21   | http://www.pengutronix.de/  |
31137 Hildesheim, Germany  | Phone: +49-5121-206917-0|
Amtsgericht Hildesheim, HRA 2686   | Fax:   +49-5121-206917- |


Re: [PATCH v8 05/19] drm/mediatek: dpi: move dpi limits to board config

2022-02-25 Thread Guillaume Ranquet
Quoting Chun-Kuang Hu (2022-02-21 02:46:15)
> Hi, Guillaume:
>
> Guillaume Ranquet  於 2022年2月18日 週五 下午10:56寫道:
> >
> > Add flexibility by moving the dpi limits to the board config
>
> This patch looks good to me. But I would like to know what's this
> limit and why it vary in different SoC. If possible, would you please
> provide more description for this?
>
> Regards,
> Chun-Kuang.
>

Hi Chun-Kuang,

You are right, the commit message is rather vague and deserves more details.
I'll have to dig into the documentations I have access to and ask maybe ask
the engineers at mediatek for a detailed description.

Thx,
Guillaume.

> >
> > Signed-off-by: Guillaume Ranquet 
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dpi.c | 25 -
> >  1 file changed, 16 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c 
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index 4554e2de14309..4746eb3425674 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -125,6 +125,7 @@ struct mtk_dpi_conf {
> > bool edge_sel_en;
> > const u32 *output_fmts;
> > u32 num_output_fmts;
> > +   const struct mtk_dpi_yc_limit *limit;
> >  };
> >
> >  static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 
> > mask)
> > @@ -235,9 +236,10 @@ static void mtk_dpi_config_fb_size(struct mtk_dpi 
> > *dpi, u32 width, u32 height)
> > mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, VSIZE_MASK);
> >  }
> >
> > -static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi,
> > -struct mtk_dpi_yc_limit *limit)
> > +static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi)
> >  {
> > +   const struct mtk_dpi_yc_limit *limit = dpi->conf->limit;
> > +
> > mtk_dpi_mask(dpi, DPI_Y_LIMIT, limit->y_bottom << Y_LIMINT_BOT,
> >  Y_LIMINT_BOT_MASK);
> > mtk_dpi_mask(dpi, DPI_Y_LIMIT, limit->y_top << Y_LIMINT_TOP,
> > @@ -449,7 +451,6 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
> >  static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
> > struct drm_display_mode *mode)
> >  {
> > -   struct mtk_dpi_yc_limit limit;
> > struct mtk_dpi_polarities dpi_pol;
> > struct mtk_dpi_sync_param hsync;
> > struct mtk_dpi_sync_param vsync_lodd = { 0 };
> > @@ -484,11 +485,6 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi 
> > *dpi,
> > dev_dbg(dpi->dev, "Got  PLL %lu Hz, pixel clock %lu Hz\n",
> > pll_rate, vm.pixelclock);
> >
> > -   limit.c_bottom = 0x0010;
> > -   limit.c_top = 0x0FE0;
> > -   limit.y_bottom = 0x0010;
> > -   limit.y_top = 0x0FE0;
> > -
> > dpi_pol.ck_pol = MTK_DPI_POLARITY_FALLING;
> > dpi_pol.de_pol = MTK_DPI_POLARITY_RISING;
> > dpi_pol.hsync_pol = vm.flags & DISPLAY_FLAGS_HSYNC_HIGH ?
> > @@ -536,7 +532,7 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
> > else
> > mtk_dpi_config_fb_size(dpi, vm.hactive, vm.vactive);
> >
> > -   mtk_dpi_config_channel_limit(dpi, );
> > +   mtk_dpi_config_channel_limit(dpi);
> > mtk_dpi_config_bit_num(dpi, dpi->bit_num);
> > mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
> > mtk_dpi_config_yc_map(dpi, dpi->yc_map);
> > @@ -790,12 +786,20 @@ static const u32 mt8183_output_fmts[] = {
> > MEDIA_BUS_FMT_RGB888_2X12_BE,
> >  };
> >
> > +static const struct mtk_dpi_yc_limit mtk_dpi_limit = {
> > +   .c_bottom = 0x0010,
> > +   .c_top = 0x0FE0,
> > +   .y_bottom = 0x0010,
> > +   .y_top = 0x0FE0,
> > +};
> > +
> >  static const struct mtk_dpi_conf mt8173_conf = {
> > .cal_factor = mt8173_calculate_factor,
> > .reg_h_fre_con = 0xe0,
> > .max_clock_khz = 30,
> > .output_fmts = mt8173_output_fmts,
> > .num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> > +   .limit = _dpi_limit,
> >  };
> >
> >  static const struct mtk_dpi_conf mt2701_conf = {
> > @@ -805,6 +809,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
> > .max_clock_khz = 15,
> > .output_fmts = mt8173_output_fmts,
> > .num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> > +   .limit = _dpi_limit,
> >  };
> >
> >  static const struct mtk_dpi_conf mt8183_conf = {
> > @@ -813,6 +818,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
> > .max_clock_khz = 10,
> > .output_fmts = mt8183_output_fmts,
> > .num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
> > +   .limit = _dpi_limit,
> >  };
> >
> >  static const struct mtk_dpi_conf mt8192_conf = {
> > @@ -821,6 +827,7 @@ static const struct mtk_dpi_conf mt8192_conf = {
> > .max_clock_khz = 15,
> > .output_fmts = mt8173_output_fmts,
> > .num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
> > +   .limit = _dpi_limit,
> >  };

Re: [PATCH] drm/i915: apply PM_EARLY for non-GTT mappable objects

2022-02-25 Thread Thomas Hellström



On 2/25/22 11:34, Matthew Auld wrote:

On DG2 we allow objects that are smaller than the min_page_size, under
the premise that these are never mapped by the GTT, like with the paging
structures. Currently the suspend-resume path will try to map such
objects through the migration vm, which hits:

[  560.529217] kernel BUG at drivers/gpu/drm/i915/gt/intel_migrate.c:431!
[  560.536081] invalid opcode:  [#1] PREEMPT SMP NOPTI
[  560.541629] CPU: 4 PID: 2062 Comm: rtcwake Tainted: GW 
5.17.0-rc5-demarchi+ #175
[  560.550716] Hardware name: Intel Corporation CoffeeLake Client 
Platform/CoffeeLake S UDIMM RVP, BIOS CNLSFWR1.R00.X220.B00.2103302221 
03/30/2021
[  560.563627] RIP: 0010:emit_pte+0x2e7/0x380 [i915]
[  560.568665] Code: ee 02 48 89 69 04 83 c6 05 83 c0 05 39 f0 0f 4f c6 48 8b 73 08 
39 d0 0f 4f c2 44 89 f2 4c 8d 4a ff 49 85 f1 0f 84 62 fe ff ff <0f> 0b 48 c7 03 
00 00 00 00 4d 89 c6 8b 01 48 29 ce 48 8d 57 0c 48
[  560.587691] RSP: 0018:c9000104f8a0 EFLAGS: 00010206
[  560.592906] RAX: 0040 RBX: c9000104f908 RCX: c900025114d0
[  560.600024] RDX: 0001 RSI: 0003f9fe2000 RDI: c900025114dc
[  560.607458] RBP: 0184 R08: 88810f335540 R09: 
[  560.614865] R10: 081b R11: 0001 R12: 081b
[  560.622300] R13:  R14: 0001 R15: 888107c3e240
[  560.629716] FS:  7f5b7c086580() GS:88846dc0() 
knlGS:
[  560.638090] CS:  0010 DS:  ES:  CR0: 80050033
[  560.644132] CR2: 7f3ab0a133a8 CR3: 00010a43e003 CR4: 003706e0
[  560.651590] DR0:  DR1:  DR2: 
[  560.659002] DR3:  DR6: fffe0ff0 DR7: 0400
[  560.666438] Call Trace:
[  560.668885]  
[  560.670983]  intel_context_migrate_copy+0x1b1/0x4c0 [i915]
[  560.676794]  __i915_ttm_move+0x628/0x790 [i915]
[  560.681704]  ? dma_resv_iter_next+0x8f/0xb0
[  560.686223]  ? dma_resv_iter_first+0xe5/0x140
[  560.690894]  ? i915_deps_add_resv+0x4b/0x110 [i915]
[  560.696147]  ? dma_resv_reserve_shared+0x161/0x310
[  560.701228]  i915_gem_obj_copy_ttm+0x10f/0x220 [i915]
[  560.706650]  i915_ttm_backup+0x191/0x2f0 [i915]
[  560.711558]  i915_gem_process_region+0x266/0x3b0 [i915]
[  560.717153]  ? verify_cpu+0xf0/0x100
[  560.721040]  ? pci_pm_resume_early+0x20/0x20
[  560.725603]  i915_ttm_backup_region+0x47/0x70 [i915]
[  560.730927]  i915_gem_backup_suspend+0x141/0x170 [i91

For now let's just force the memcpy path for such objects during
suspend-resume.

Fixes: 00e27ad85bc9 ("drm/i915/migrate: add acceleration support for DG2")
Reported-by: Lucas De Marchi 
Signed-off-by: Matthew Auld 
Cc: Thomas Hellström 
---
  drivers/gpu/drm/i915/gem/i915_gem_region.c | 11 +++
  1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.c 
b/drivers/gpu/drm/i915/gem/i915_gem_region.c
index a4350227e9ae..6d65c5849874 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_region.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_region.c
@@ -67,6 +67,17 @@ i915_gem_object_create_region(struct intel_memory_region 
*mem,
if (!obj)
return ERR_PTR(-ENOMEM);
  
+	/*

+* Anything smaller than the min_page_size can't be freely inserted into
+* the GTT, due to alignemnt restrictions. For such special objects,


s/alignemnt/alignment/

Reviewed-by: Thomas Hellström 



+* make sure we force memcpy based suspend-resume. In the future we can
+* revisit this, either by allowing special mis-aligned objects in the
+* migration path, or by mapping all of LMEM upfront using cheap 1G
+* GTT entries.
+*/
+   if (default_page_size < mem->min_page_size)
+   flags |= I915_BO_ALLOC_PM_EARLY;
+
err = mem->ops->init_object(mem, obj, size, page_size, flags);
if (err)
goto err_object_free;


Re: [PATCH v8 04/19] video/hdmi: Add audio_infoframe packing for DP

2022-02-25 Thread Guillaume Ranquet
Quoting AngeloGioacchino Del Regno (2022-02-22 16:16:48)
> Il 18/02/22 15:54, Guillaume Ranquet ha scritto:
> > From: Markus Schneider-Pargmann 
> >
> > Similar to HDMI, DP uses audio infoframes as well which are structured
> > very similar to the HDMI ones.
> >
> > This patch adds a helper function to pack the HDMI audio infoframe for
> > DP, called hdmi_audio_infoframe_pack_for_dp().
> > hdmi_audio_infoframe_pack_only() is split into two parts. One of them
> > packs the payload only and can be used for HDMI and DP.
> >
> > Signed-off-by: Markus Schneider-Pargmann 
> > Signed-off-by: Guillaume Ranquet 
>
> Hello Guillaume,
>
> I've just noticed that this patch will not apply against the latest 
> linux-next,
> as the include/drm/drm_dp_helper.h header was moved to
> include/drm/dp/drm_dp_helper.h
>
> Can you please rebase for v9?
>
> Thanks,
> Angelo
>

I'm sorry, I'm a bit of a noob, I rebased this series against 5.17-rc4 ...
I'll rebase v9 against linux-next.

Thx,
Guillaume.

> > ---
> >   drivers/video/hdmi.c| 83 -
> >   include/drm/drm_dp_helper.h |  2 +
> >   include/linux/hdmi.h|  7 +++-
> >   3 files changed, 72 insertions(+), 20 deletions(-)
> >


Re: [PATCH v8 04/19] video/hdmi: Add audio_infoframe packing for DP

2022-02-25 Thread Guillaume Ranquet
Quoting AngeloGioacchino Del Regno (2022-02-21 15:30:07)
> Il 18/02/22 15:54, Guillaume Ranquet ha scritto:
> > From: Markus Schneider-Pargmann 
> >
> > Similar to HDMI, DP uses audio infoframes as well which are structured
> > very similar to the HDMI ones.
> >
> > This patch adds a helper function to pack the HDMI audio infoframe for
> > DP, called hdmi_audio_infoframe_pack_for_dp().
> > hdmi_audio_infoframe_pack_only() is split into two parts. One of them
> > packs the payload only and can be used for HDMI and DP.
> >
> > Signed-off-by: Markus Schneider-Pargmann 
> > Signed-off-by: Guillaume Ranquet 
> > ---
> >   drivers/video/hdmi.c| 83 -
> >   include/drm/drm_dp_helper.h |  2 +
> >   include/linux/hdmi.h|  7 +++-
> >   3 files changed, 72 insertions(+), 20 deletions(-)
> >
> > diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
> > index 947be761dfa40..63e74d9fd210e 100644
> > --- a/drivers/video/hdmi.c
> > +++ b/drivers/video/hdmi.c
> > @@ -21,6 +21,7 @@
> >* DEALINGS IN THE SOFTWARE.
> >*/
> >
> > +#include 
> >   #include 
> >   #include 
> >   #include 
> > @@ -381,12 +382,34 @@ static int hdmi_audio_infoframe_check_only(const 
> > struct hdmi_audio_infoframe *fr
> >*
> >* Returns 0 on success or a negative error code on failure.
> >*/
> > -int hdmi_audio_infoframe_check(struct hdmi_audio_infoframe *frame)
> > +int hdmi_audio_infoframe_check(const struct hdmi_audio_infoframe *frame)
> >   {
> >   return hdmi_audio_infoframe_check_only(frame);
> >   }
> >   EXPORT_SYMBOL(hdmi_audio_infoframe_check);
> >
> > +static void
> > +hdmi_audio_infoframe_pack_payload(const struct hdmi_audio_infoframe *frame,
> > +   u8 *buffer)
> > +{
> > + u8 channels;
> > +
> > + if (frame->channels >= 2)
> > + channels = frame->channels - 1;
> > + else
> > + channels = 0;
> > +
> > + buffer[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
> > + buffer[1] = ((frame->sample_frequency & 0x7) << 2) |
> > +  (frame->sample_size & 0x3);
> > + buffer[2] = frame->coding_type_ext & 0x1f;
> > + buffer[3] = frame->channel_allocation;
> > + buffer[4] = (frame->level_shift_value & 0xf) << 3;
> > +
> > + if (frame->downmix_inhibit)
> > + buffer[4] |= BIT(7);
> > +}
> > +
> >   /**
> >* hdmi_audio_infoframe_pack_only() - write HDMI audio infoframe to 
> > binary buffer
> >* @frame: HDMI audio infoframe
> > @@ -404,7 +427,6 @@ EXPORT_SYMBOL(hdmi_audio_infoframe_check);
> >   ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe 
> > *frame,
> >  void *buffer, size_t size)
> >   {
> > - unsigned char channels;
> >   u8 *ptr = buffer;
> >   size_t length;
> >   int ret;
> > @@ -420,28 +442,13 @@ ssize_t hdmi_audio_infoframe_pack_only(const struct 
> > hdmi_audio_infoframe *frame,
> >
> >   memset(buffer, 0, size);
> >
> > - if (frame->channels >= 2)
> > - channels = frame->channels - 1;
> > - else
> > - channels = 0;
> > -
> >   ptr[0] = frame->type;
> >   ptr[1] = frame->version;
> >   ptr[2] = frame->length;
> >   ptr[3] = 0; /* checksum */
> >
> > - /* start infoframe payload */
> > - ptr += HDMI_INFOFRAME_HEADER_SIZE;
> > -
> > - ptr[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
> > - ptr[1] = ((frame->sample_frequency & 0x7) << 2) |
> > -  (frame->sample_size & 0x3);
> > - ptr[2] = frame->coding_type_ext & 0x1f;
> > - ptr[3] = frame->channel_allocation;
> > - ptr[4] = (frame->level_shift_value & 0xf) << 3;
> > -
> > - if (frame->downmix_inhibit)
> > - ptr[4] |= BIT(7);
> > + hdmi_audio_infoframe_pack_payload(frame,
> > +   ptr + HDMI_INFOFRAME_HEADER_SIZE);
> >
> >   hdmi_infoframe_set_checksum(buffer, length);
> >
> > @@ -479,6 +486,44 @@ ssize_t hdmi_audio_infoframe_pack(struct 
> > hdmi_audio_infoframe *frame,
> >   }
> >   EXPORT_SYMBOL(hdmi_audio_infoframe_pack);
> >
> > +/**
> > + * hdmi_audio_infoframe_pack_for_dp - Pack a HDMI Audio infoframe for
> > + *displayport
>
> This fits in one line (82 cols is ok)... but, anyway, please capitalize D and 
> P
> in the DisplayPort word.
>

Yeah, I ran clang-format and didn't want to contradict the tool :)
I'll fix that for v9

> > + *
> > + * @frame HDMI Audio infoframe
>
> You're almost there! You missed a colon after each description.
> Also, I personally like seeing indented descriptions as, in my opinion, this
> enhances human readability, as it's a bit more pleasing to the eye... but
> it's not a requirement, so you be the judge.
>
> * @frame:  HDMI Audio infoframe
> * @sdp:Secondary data packet..
> * @dp_version: DisplayPort version..
>
> Please fix.
>

I completly forgot to generate 

Re: [PATCH] drm/msm/dpu: wire up MSM8998's DSPP blocks

2022-02-25 Thread Marijn Suijten
On 2022-02-22 06:19:48, Dmitry Baryshkov wrote:
> The commit adding msm8998 support didn't added msm8998's DSPP blocks

You might have meant: [did*] add(ed) msm8998's DSPP blocks configuration
[to the source /code file], but did not...

Or however you wish to word this :)

- Marijn

> configuration, but did not use them in msm8998_cfg_init(). Wire them up
> to be used for display post processing.
> 
> Reported-by: kernel test robot 
> Fixes: 94391a14fc27 ("drm/msm/dpu1: Add MSM8998 to hw catalog")
> Cc: AngeloGioacchino Del Regno 
> Cc: Jami Kettunen 
> Signed-off-by: Dmitry Baryshkov 
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> index aa4d20762ccb..f74bc7acd901 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> @@ -1496,6 +1496,8 @@ static void msm8998_cfg_init(struct dpu_mdss_cfg 
> *dpu_cfg)
>   .sspp = msm8998_sspp,
>   .mixer_count = ARRAY_SIZE(msm8998_lm),
>   .mixer = msm8998_lm,
> + .dspp_count = ARRAY_SIZE(msm8998_dspp),
> + .dspp = msm8998_dspp,
>   .pingpong_count = ARRAY_SIZE(sdm845_pp),
>   .pingpong = sdm845_pp,
>   .intf_count = ARRAY_SIZE(msm8998_intf),
> -- 
> 2.34.1
> 


Re: [PATCH v8 03/19] drm/edid: Add cea_sad helpers for freq/length

2022-02-25 Thread Guillaume Ranquet
Quoting AngeloGioacchino Del Regno (2022-02-21 15:30:04)
> Il 18/02/22 15:54, Guillaume Ranquet ha scritto:
> > From: Markus Schneider-Pargmann 
> >
> > This patch adds two helper functions that extract the frequency and word
> > length from a struct cea_sad.
> >
> > For these helper functions new defines are added that help translate the
> > 'freq' and 'byte2' fields into real numbers.
> >
> > Signed-off-by: Markus Schneider-Pargmann 
> > Signed-off-by: Guillaume Ranquet 
> > ---
> >   drivers/gpu/drm/drm_edid.c | 74 ++
> >   include/drm/drm_edid.h | 18 --
> >   2 files changed, 90 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> > index 12893e7be89bb..500279a82167a 100644
> > --- a/drivers/gpu/drm/drm_edid.c
> > +++ b/drivers/gpu/drm/drm_edid.c
> > @@ -4747,6 +4747,80 @@ int drm_edid_to_speaker_allocation(struct edid 
> > *edid, u8 **sadb)
> >   }
> >   EXPORT_SYMBOL(drm_edid_to_speaker_allocation);
> >
> > +/**
> > + * drm_cea_sad_get_sample_rate - Extract the sample rate from cea_sad
> > + * @sad: Pointer to the cea_sad struct
> > + *
> > + * Extracts the cea_sad frequency field and returns the sample rate in Hz.
> > + *
> > + * Return: Sample rate in Hz or a negative errno if parsing failed.
> > + */
> > +int drm_cea_sad_get_sample_rate(const struct cea_sad *sad)
> > +{
> > + switch (sad->freq) {
> > + case DRM_CEA_SAD_FREQ_32KHZ:
> > + return 32000;
> > + case DRM_CEA_SAD_FREQ_44KHZ:
> > + return 44100;
> > + case DRM_CEA_SAD_FREQ_48KHZ:
> > + return 48000;
> > + case DRM_CEA_SAD_FREQ_88KHZ:
> > + return 88200;
> > + case DRM_CEA_SAD_FREQ_96KHZ:
> > + return 96000;
> > + case DRM_CEA_SAD_FREQ_176KHZ:
> > + return 176400;
> > + case DRM_CEA_SAD_FREQ_192KHZ:
> > + return 192000;
> > + default:
> > + return -EINVAL;
> > + }
> > +}
> > +EXPORT_SYMBOL(drm_cea_sad_get_sample_rate);
> > +
> > +static bool drm_cea_sad_is_uncompressed(const struct cea_sad *sad)
> > +{
> > + switch (sad->format) {
> > + case HDMI_AUDIO_CODING_TYPE_STREAM:
> > + case HDMI_AUDIO_CODING_TYPE_PCM:
> > + return true;
> > + default:
> > + return false;
> > + }
> > +}
> > +
> > +/**
> > + * drm_cea_sad_get_uncompressed_word_length - Extract word length
> > + * @sad: Pointer to the cea_sad struct
> > + *
> > + * Extracts the cea_sad byte2 field and returns the word length for an
> > + * uncompressed stream.
> > + *
> > + * Note: This function may only be called for uncompressed audio.
> > + *
> > + * Return: Word length in bits or a negative errno if parsing failed.
> > + */
> > +int drm_cea_sad_get_uncompressed_word_length(const struct cea_sad *sad)
> > +{
> > + if (!drm_cea_sad_is_uncompressed(sad)) {
> > + DRM_WARN("Unable to get the uncompressed word length for a 
> > compressed format: %u\n",
> > +  sad->format);
> > + return -EINVAL;
> > + }
> > +
> > + switch (sad->byte2) {
> > + case DRM_CEA_SAD_UNCOMPRESSED_WORD_16BIT:
> > + return 16;
> > + case DRM_CEA_SAD_UNCOMPRESSED_WORD_20BIT:
> > + return 20;
> > + case DRM_CEA_SAD_UNCOMPRESSED_WORD_24BIT:
> > + return 24;
> > + default:
> > + return -EINVAL;
> > + }
> > +}
> > +EXPORT_SYMBOL(drm_cea_sad_get_uncompressed_word_length);
> > +
> >   /**
> >* drm_av_sync_delay - compute the HDMI/DP sink audio-video sync delay
> >* @connector: connector associated with the HDMI/DP sink
> > diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> > index 18f6c700f6d02..a30452b313979 100644
> > --- a/include/drm/drm_edid.h
> > +++ b/include/drm/drm_edid.h
> > @@ -361,12 +361,24 @@ struct edid {
> >
> >   /* Short Audio Descriptor */
> >   struct cea_sad {
> > - u8 format;
> > + u8 format; /* See HDMI_AUDIO_CODING_TYPE_* */
>
> Hello Guillaume,
>
> since you're adding comments to all the rest of the struct members,
> I think that a small effort to instead convert this to kerneldoc is
> totally worth it.
> Can you please do that?
>
> Thanks,
> Angelo
>
Hello Angelo,

Sure, that's a good suggestion.

Thx,
Guillaume.
> >   u8 channels; /* max number of channels - 1 */
> > - u8 freq;
> > + u8 freq; /* See CEA_SAD_FREQ_* */
> >   u8 byte2; /* meaning depends on format */
> >   };
> >
> > +#define DRM_CEA_SAD_FREQ_32KHZ  BIT(0)
> > +#define DRM_CEA_SAD_FREQ_44KHZ  BIT(1)
> > +#define DRM_CEA_SAD_FREQ_48KHZ  BIT(2)
> > +#define DRM_CEA_SAD_FREQ_88KHZ  BIT(3)
> > +#define DRM_CEA_SAD_FREQ_96KHZ  BIT(4)
> > +#define DRM_CEA_SAD_FREQ_176KHZ BIT(5)
> > +#define DRM_CEA_SAD_FREQ_192KHZ BIT(6)
> > +
> > +#define DRM_CEA_SAD_UNCOMPRESSED_WORD_16BIT BIT(0)
> > +#define DRM_CEA_SAD_UNCOMPRESSED_WORD_20BIT BIT(1)
> > +#define DRM_CEA_SAD_UNCOMPRESSED_WORD_24BIT BIT(2)

[PATCH] drm/i915: apply PM_EARLY for non-GTT mappable objects

2022-02-25 Thread Matthew Auld
On DG2 we allow objects that are smaller than the min_page_size, under
the premise that these are never mapped by the GTT, like with the paging
structures. Currently the suspend-resume path will try to map such
objects through the migration vm, which hits:

[  560.529217] kernel BUG at drivers/gpu/drm/i915/gt/intel_migrate.c:431!
[  560.536081] invalid opcode:  [#1] PREEMPT SMP NOPTI
[  560.541629] CPU: 4 PID: 2062 Comm: rtcwake Tainted: GW 
5.17.0-rc5-demarchi+ #175
[  560.550716] Hardware name: Intel Corporation CoffeeLake Client 
Platform/CoffeeLake S UDIMM RVP, BIOS CNLSFWR1.R00.X220.B00.2103302221 
03/30/2021
[  560.563627] RIP: 0010:emit_pte+0x2e7/0x380 [i915]
[  560.568665] Code: ee 02 48 89 69 04 83 c6 05 83 c0 05 39 f0 0f 4f c6 48 8b 
73 08 39 d0 0f 4f c2 44 89 f2 4c 8d 4a ff 49 85 f1 0f 84 62 fe ff ff <0f> 0b 48 
c7 03 00 00 00 00 4d 89 c6 8b 01 48 29 ce 48 8d 57 0c 48
[  560.587691] RSP: 0018:c9000104f8a0 EFLAGS: 00010206
[  560.592906] RAX: 0040 RBX: c9000104f908 RCX: c900025114d0
[  560.600024] RDX: 0001 RSI: 0003f9fe2000 RDI: c900025114dc
[  560.607458] RBP: 0184 R08: 88810f335540 R09: 
[  560.614865] R10: 081b R11: 0001 R12: 081b
[  560.622300] R13:  R14: 0001 R15: 888107c3e240
[  560.629716] FS:  7f5b7c086580() GS:88846dc0() 
knlGS:
[  560.638090] CS:  0010 DS:  ES:  CR0: 80050033
[  560.644132] CR2: 7f3ab0a133a8 CR3: 00010a43e003 CR4: 003706e0
[  560.651590] DR0:  DR1:  DR2: 
[  560.659002] DR3:  DR6: fffe0ff0 DR7: 0400
[  560.666438] Call Trace:
[  560.668885]  
[  560.670983]  intel_context_migrate_copy+0x1b1/0x4c0 [i915]
[  560.676794]  __i915_ttm_move+0x628/0x790 [i915]
[  560.681704]  ? dma_resv_iter_next+0x8f/0xb0
[  560.686223]  ? dma_resv_iter_first+0xe5/0x140
[  560.690894]  ? i915_deps_add_resv+0x4b/0x110 [i915]
[  560.696147]  ? dma_resv_reserve_shared+0x161/0x310
[  560.701228]  i915_gem_obj_copy_ttm+0x10f/0x220 [i915]
[  560.706650]  i915_ttm_backup+0x191/0x2f0 [i915]
[  560.711558]  i915_gem_process_region+0x266/0x3b0 [i915]
[  560.717153]  ? verify_cpu+0xf0/0x100
[  560.721040]  ? pci_pm_resume_early+0x20/0x20
[  560.725603]  i915_ttm_backup_region+0x47/0x70 [i915]
[  560.730927]  i915_gem_backup_suspend+0x141/0x170 [i91

For now let's just force the memcpy path for such objects during
suspend-resume.

Fixes: 00e27ad85bc9 ("drm/i915/migrate: add acceleration support for DG2")
Reported-by: Lucas De Marchi 
Signed-off-by: Matthew Auld 
Cc: Thomas Hellström 
---
 drivers/gpu/drm/i915/gem/i915_gem_region.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.c 
b/drivers/gpu/drm/i915/gem/i915_gem_region.c
index a4350227e9ae..6d65c5849874 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_region.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_region.c
@@ -67,6 +67,17 @@ i915_gem_object_create_region(struct intel_memory_region 
*mem,
if (!obj)
return ERR_PTR(-ENOMEM);
 
+   /*
+* Anything smaller than the min_page_size can't be freely inserted into
+* the GTT, due to alignemnt restrictions. For such special objects,
+* make sure we force memcpy based suspend-resume. In the future we can
+* revisit this, either by allowing special mis-aligned objects in the
+* migration path, or by mapping all of LMEM upfront using cheap 1G
+* GTT entries.
+*/
+   if (default_page_size < mem->min_page_size)
+   flags |= I915_BO_ALLOC_PM_EARLY;
+
err = mem->ops->init_object(mem, obj, size, page_size, flags);
if (err)
goto err_object_free;
-- 
2.34.1



Re: [PATCH v7 10/24] drm/rockchip: dw_hdmi: Add support for hclk

2022-02-25 Thread Dmitry Osipenko
25.02.2022 10:51, Sascha Hauer пишет:
> The rk3568 HDMI has an additional clock that needs to be enabled for the
> HDMI controller to work. The purpose of that clock is not clear. It is
> named "hclk" in the downstream driver, so use the same name.
> 
> Signed-off-by: Sascha Hauer 
> ---
> 
> Notes:
> Changes since v5:
> - Use devm_clk_get_optional rather than devm_clk_get
> 
>  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 
>  1 file changed, 16 insertions(+)
> 
> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 
> b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> index fe4f9556239ac..c6c00e8779ab5 100644
> --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> @@ -76,6 +76,7 @@ struct rockchip_hdmi {
>   const struct rockchip_hdmi_chip_data *chip_data;
>   struct clk *ref_clk;
>   struct clk *grf_clk;
> + struct clk *hclk_clk;
>   struct dw_hdmi *hdmi;
>   struct regulator *avdd_0v9;
>   struct regulator *avdd_1v8;
> @@ -229,6 +230,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi 
> *hdmi)
>   return PTR_ERR(hdmi->grf_clk);
>   }
>  
> + hdmi->hclk_clk = devm_clk_get_optional(hdmi->dev, "hclk");
> + if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) {

Have you tried to investigate the hclk? I'm still thinking that's not
only HDMI that needs this clock and then the hardware description
doesn't look correct.


Re: [PATCH] dma-fance: Add dma_fence_assert_in_signalling_section

2022-02-25 Thread Christian König

Am 25.02.22 um 08:33 schrieb Daniel Vetter:

Useful for checking for dma-fence signalling annotations since they
don't quite nest as freely as we'd like to.

Cc: Matthew Brost 
Signed-off-by: Daniel Vetter 
Cc: Sumit Semwal 
Cc: Gustavo Padovan 
Cc: "Christian König" 
Cc: linux-me...@vger.kernel.org
Cc: linaro-mm-...@lists.linaro.org
---
  drivers/dma-buf/dma-fence.c | 19 +++
  include/linux/dma-fence.h   |  2 ++
  2 files changed, 21 insertions(+)

diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
index 066400ed8841..2b7c3fc965e6 100644
--- a/drivers/dma-buf/dma-fence.c
+++ b/drivers/dma-buf/dma-fence.c
@@ -307,6 +307,25 @@ bool dma_fence_begin_signalling(void)
  }
  EXPORT_SYMBOL(dma_fence_begin_signalling);
  
+/**

+ * dma_fence_assert_in_signalling_section - check fence signalling annotations
+ *
+ * Since dma_fence_begin_signalling() and dma_fence_end_signalling() are built
+ * using lockdep annotations they have limitations on how freely they can be
+ * nested. Specifically, they cannot be on both inside and outside of locked
+ * sections, which in practice means the annotations often have to be pushed 
out
+ * to the top level callers.
+ *
+ * To ensure low-level functions are only called with the correction
+ * annotations, this function can be used to check for that.


I think I need a concrete example to understand what this is good for.

Christian.


+ */
+void dma_fence_assert_in_signalling_section(void)
+{
+   if (!in_atomic())
+   lockdep_assert(lock_is_held(_fence_lockdep_map));
+}
+EXPORT_SYMBOL(dma_fence_assert_in_signalling_section);
+
  /**
   * dma_fence_end_signalling - end a critical DMA fence signalling section
   * @cookie: opaque cookie from dma_fence_begin_signalling()
diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h
index 775cdc0b4f24..7179a5692f72 100644
--- a/include/linux/dma-fence.h
+++ b/include/linux/dma-fence.h
@@ -356,6 +356,7 @@ dma_fence_get_rcu_safe(struct dma_fence __rcu **fencep)
  
  #ifdef CONFIG_LOCKDEP

  bool dma_fence_begin_signalling(void);
+void dma_fence_assert_in_signalling_section(void);
  void dma_fence_end_signalling(bool cookie);
  void __dma_fence_might_wait(void);
  #else
@@ -363,6 +364,7 @@ static inline bool dma_fence_begin_signalling(void)
  {
return true;
  }
+static inline void dma_fence_assert_in_signalling_section(void) {}
  static inline void dma_fence_end_signalling(bool cookie) {}
  static inline void __dma_fence_might_wait(void) {}
  #endif




Re: [PATCH] drm/todo: Update panic handling todo

2022-02-25 Thread Pekka Paalanen
On Thu, 24 Feb 2022 14:24:25 +0100
Daniel Vetter  wrote:

> Some things changed, and add two useful links.
> 
> v2: Also include a link to the QR encoding work. Plus review from
> Javier.
> 
> Reviewed-by: Javier Martinez Canillas 
> Cc: Javier Martinez Canillas 
> Cc: Pekka Paalanen 
> Cc: gpicc...@igalia.com
> Signed-off-by: Daniel Vetter 
> ---
>  Documentation/gpu/todo.rst | 25 ++---
>  1 file changed, 14 insertions(+), 11 deletions(-)

Acked-by: Pekka Paalanen 

Thanks,
pq


> 
> diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
> index 7bf7f2111696..2b1e7fa45603 100644
> --- a/Documentation/gpu/todo.rst
> +++ b/Documentation/gpu/todo.rst
> @@ -475,8 +475,12 @@ This is a really varied tasks with lots of little bits 
> and pieces:
>achieved by using an IPI to the local processor.
>  
>  * There's a massive confusion of different panic handlers. DRM fbdev 
> emulation
> -  helpers have one, but on top of that the fbcon code itself also has one. We
> -  need to make sure that they stop fighting over each another.
> +  helpers had their own (long removed), but on top of that the fbcon code 
> itself
> +  also has one. We need to make sure that they stop fighting over each other.
> +  This is worked around by checking ``oops_in_progress`` at various entry 
> points
> +  into the DRM fbdev emulation helpers. A much cleaner approach here would 
> be to
> +  switch fbcon to the `threaded printk support
> +  `_.
>  
>  * ``drm_can_sleep()`` is a mess. It hides real bugs in normal operations and
>isn't a full solution for panic paths. We need to make sure that it only
> @@ -488,16 +492,15 @@ This is a really varied tasks with lots of little bits 
> and pieces:
>even spinlocks (because NMI and hardirq can panic too). We need to either
>make sure to not call such paths, or trylock everything. Really tricky.
>  
> -* For the above locking troubles reasons it's pretty much impossible to
> -  attempt a synchronous modeset from panic handlers. The only thing we could
> -  try to achive is an atomic ``set_base`` of the primary plane, and hope that
> -  it shows up. Everything else probably needs to be delayed to some worker or
> -  something else which happens later on. Otherwise it just kills the box
> -  harder, prevent the panic from going out on e.g. netconsole.
> +* A clean solution would be an entirely separate panic output support in KMS,
> +  bypassing the current fbcon support. See `[PATCH v2 0/3] drm: Add panic 
> handling
> +  
> `_.
>  
> -* There's also proposal for a simplied DRM console instead of the full-blown
> -  fbcon and DRM fbdev emulation. Any kind of panic handling tricks should
> -  obviously work for both console, in case we ever get kmslog merged.
> +* Encoding the actual oops and preceeding dmesg in a QR might help with the
> +  dread "important stuff scrolled away" problem. See `[RFC][PATCH] Oops 
> messages
> +  transfer using QR codes
> +  
> `_
> +  for some example code that could be reused.
>  
>  Contact: Daniel Vetter
>  



pgp9bTxi_5Tvj.pgp
Description: OpenPGP digital signature


Re: [PATCH v4 02/10] clk: Always clamp the rounded rate

2022-02-25 Thread Maxime Ripard
Hi,

On Thu, Feb 24, 2022 at 02:32:37PM -0800, Stephen Boyd wrote:
> Quoting Maxime Ripard (2022-02-21 08:18:21)
> > Hi,
> > 
> > On Fri, Feb 18, 2022 at 03:15:06PM -0800, Stephen Boyd wrote:
> > > Quoting Maxime Ripard (2022-01-25 06:15:41)
> > > > The current core while setting the min and max rate properly in the
> > > > clk_request structure will not make sure that the requested rate is
> > > > within these boundaries, leaving it to each and every driver to make
> > > > sure it is.
> > > 
> > > It would be good to describe why. Or decide that it was an oversight and
> > > write that down here.
> > > 
> > > > Add a clamp call to make sure it's always done, and add a few unit tests
> > > > to make sure we don't have any regression there.
> > > 
> > > I looked through the per-user constraint patch history on the list but I
> > > couldn't really figure out why it was done this way. I guess we didn't
> > > clamp the rate in the core because we wanted to give the clk providers
> > > all the information, i.e. the rate that was requested and the boundaries
> > > that the consumers have placed on the rate.
> > 
> > I'm not really sure we should really leave it to the users, something like:
> > 
> > clk_set_range_rate(clk, 1000, 2000);
> > clk_set_rate(clk, 500);
> > clk_get_rate(clk) # == 500
> > 
> > Is definitely weird, and would break the least surprise :)
> > 
> > We shouldn't leave that to drivers, especially since close to none of
> > them handle this properly.
> 
> Ok.
> 
> > > With the round_rate() clk_op the providers don't know the min/max
> > > because the rate request structure isn't passed. I think my concern a
> > > long time ago was that a consumer could call clk_round_rate() and get
> > > one frequency and then call clk_set_rate() and get another frequency.
> > 
> > I'm not sure I follow you there.
> > 
> > The function affected is clk_core_determine_round_nolock(), which is
> > called by clk_core_round_rate_nolock() and clk_calc_new_rates(). In
> > turn, they will be part of clk(_hw_)_round_clock for the former, and
> > clk_core_set_rate_nolock() (and thus clk_set_rate()) for the latter.
> > 
> > I don't see how you can get a discrepancy between clk_round_rate() and
> > clk_set_rate().
> > 
> > And yeah, it's true that the round_rate op won't have the min and max
> > passed to them, but i'd consider this an argument for doing this check
> > here, since you don't have that option at all for those clocks.
> 
> When the range setting API was introduced the rounding logic and the
> rate setting logic didn't use the same code paths. It looks like that
> code got consolidated now though so we should be fine.

Actually, there was a discrepancy. If you are doing, before this patch
series:

clk_set_range_rate(clk, 1000, 2000)
clk_round_rate(500);

Unless the driver was involved, the returned rate would be 500.

Now, if you call clk_set_rate(500), it will return -EINVAL, hitting the
check here:
https://elixir.bootlin.com/linux/latest/source/drivers/clk/clk.c#L1973

If the driver was looking at the min and max and clamping the rate, you
would get clk_round_rate() == 1000 and clk_set_rate() would succeed,
with the rate set to 1000.

This seems like an abstraction leakage to me.

This patch fixes that discrepancy, but in the last version I sent, I
added a test that would check that once you have a range in place, then
clk_round_rate and clk_set_rate/clk_get_rate would return the same
value.

Maxime


signature.asc
Description: PGP signature


Re: [PATCH v5 1/4] drm/i915/guc: Add fetch of hwconfig table

2022-02-25 Thread Michal Wajdeczko



On 25.02.2022 06:03, Jordan Justen wrote:
> John Harrison  writes:
> 
>> On 2/22/2022 02:36, Jordan Justen wrote:
>>> From: John Harrison 
>>>
>>> Implement support for fetching the hardware description table from the
>>> GuC. The call is made twice - once without a destination buffer to
>>> query the size and then a second time to fill in the buffer.
>>>
>>> Note that the table is only available on ADL-P and later platforms.
>>>
>>> v5 (of Jordan's posting):
>>>   * Various changes made by Jordan and recommended by Michal
>>> - Makefile ordering
>>> - Adjust "struct intel_guc_hwconfig hwconfig" comment
>>> - Set Copyright year to 2022 in intel_guc_hwconfig.c/.h
>>> - Drop inline from hwconfig_to_guc()
>>> - Replace hwconfig param with guc in __guc_action_get_hwconfig()
>>> - Move zero size check into guc_hwconfig_discover_size()
>>> - Change comment to say zero size offset/size is needed to get size
>>> - Add has_guc_hwconfig to devinfo and drop has_table()
>>> - Change drm_err to notice in __uc_init_hw() and use %pe
>>>
>>> Cc: Michal Wajdeczko 
>>> Signed-off-by: Rodrigo Vivi 
>>> Signed-off-by: John Harrison 
>>> Reviewed-by: Matthew Brost 
>>> Acked-by: Jon Bloomfield 
>>> Signed-off-by: Jordan Justen 
>>> ---
>>>   
>>> +   ret = intel_guc_hwconfig_init(>hwconfig);
>>> +   if (ret)
>>> +   drm_notice(>drm, "Failed to retrieve hwconfig table: 
>>> %pe\n",
>> Why only drm_notice? As you are keen to point out, the UMDs won't work 
>> if the table is not available. All the failure paths in your own 
>> verification function are 'drm_err'. So why is it only a 'notice' if 
>> there is no table at all?
> 
> This was requested by Michal in my v3 posting:
> 
> https://patchwork.freedesktop.org/patch/472936/?series=99787=3
> 
> I don't think that it should be a failure for i915 if it is unable to
> read the table, or if the table read is invalid. I think it should be up
> to the UMD to react to the missing hwconfig however they think is
> appropriate, but I would like the i915 to guarantee & document the
> format returned to userspace to whatever extent is feasible.
> 
> As you point out there is a discrepancy, and I think I should be
> consistent with whatever is used here in my "drm/i915/guc: Verify
> hwconfig blob matches supported format" patch.
> 
> I guess I'd tend to agree with Michal that "maybe drm_notice since we
> continue probe", but I would go along with either if you two want to
> discuss further.

having consistent message level is a clear benefit but on other hand
these other 'errors' may indicate more serious problems related to use
of wrong/incompatible firmware that returns corrupted HWconfig (or we
use wrong actions), while since we are not using this HWconfig in the
driver we don't care that much that we failed to load HWconfig and
'notice' is enough.

but I'm fine with all messages being drm_err (as we will not have to
change that once again after HWconfig will be mandatory for the driver
as well)

> 
>> Note that this function is called as part of the reset path. The reset 
>> path is not allowed to allocate memory. The table is stored in a 
>> dynamically allocated object. Hence the IGT test failure. The table 
>> query has to be done elsewhere at driver init time only.
> 
> Thanks for clearing this up. I did notice on dg2 that gpu resets were
> causing a re-read of the hwconfig from GuC, but it definitely was not
> clear to me that there would be a connection to the IGT failure that you
> pointed out.
> 
>>
>>> +  ERR_PTR(ret));
>>> +
>>> ret = guc_enable_communication(guc);
>>> if (ret)
>>> goto err_log_capture;
>>> @@ -562,6 +567,8 @@ static void __uc_fini_hw(struct intel_uc *uc)
>>> if (intel_uc_uses_guc_submission(uc))
>>> intel_guc_submission_disable(guc);
>>>   
>>> +   intel_guc_hwconfig_fini(>hwconfig);
>>> +
>>> __uc_sanitize(uc);
>>>   }
>>>   
>>> diff --git a/drivers/gpu/drm/i915/i915_pci.c 
>>> b/drivers/gpu/drm/i915/i915_pci.c
>>> index 76e590fcb903..1d31e35a5154 100644
>>> --- a/drivers/gpu/drm/i915/i915_pci.c
>>> +++ b/drivers/gpu/drm/i915/i915_pci.c
>>> @@ -990,6 +990,7 @@ static const struct intel_device_info adl_p_info = {
>>> BIT(RCS0) | BIT(BCS0) | BIT(VECS0) | BIT(VCS0) | BIT(VCS2),
>>> .ppgtt_size = 48,
>>> .dma_mask_size = 39,
>>> +   .has_guc_hwconfig = 1,
>> Who requested this change? It was previously done this way but the 
>> instruction was that i915_pci.c is for hardware features only but that 
>> this, as you seem extremely keen about pointing out at every 
>> opportunity, is a software feature.
> 
> This was requested by Michal as well. I definitely agree it is a
> software feature, but I was not aware that "i915_pci.c is for hardware
> features only".
> 
> Michal, do you agree with this and returning to the previous method for
> enabling the feature?

now I'm little confused as some arch direction was to treat FW as
extension 

Re: [PATCH v4 9/9] drm: vkms: Add support to the RGB565 format

2022-02-25 Thread Pekka Paalanen
On Thu, 24 Feb 2022 22:03:42 -0300
Igor Torrente  wrote:

> Hi Pekka,
> 
> On Thu, Feb 10, 2022 at 6:50 AM Pekka Paalanen  wrote:
> 
> > On Fri, 21 Jan 2022 18:38:31 -0300
> > Igor Torrente  wrote:
> >  
> > > Adds this common format to vkms.
> > >
> > > This commit also adds new helper macros to deal with fixed-point
> > > arithmetic.
> > >
> > > It was done to improve the precision of the conversion to ARGB16161616
> > > since the "conversion ratio" is not an integer.
> > >
> > > Signed-off-by: Igor Torrente 
> > > ---
> > > V3: Adapt the handlers to the new format introduced in patch 7 V3.
> > > ---
> > >  drivers/gpu/drm/vkms/vkms_formats.c   | 74 +++
> > >  drivers/gpu/drm/vkms/vkms_formats.h   |  6 +++
> > >  drivers/gpu/drm/vkms/vkms_plane.c |  6 ++-
> > >  drivers/gpu/drm/vkms/vkms_writeback.c |  3 +-
> > >  4 files changed, 86 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/vkms/vkms_formats.c  
> > b/drivers/gpu/drm/vkms/vkms_formats.c  
> > > index 661da39d1276..dc612882dd8c 100644
> > > --- a/drivers/gpu/drm/vkms/vkms_formats.c
> > > +++ b/drivers/gpu/drm/vkms/vkms_formats.c
> > > @@ -11,6 +11,8 @@ format_transform_func get_fmt_transform_function(u32  
> > format)  
> > >   return _ARGB16161616;
> > >   else if (format == DRM_FORMAT_XRGB16161616)
> > >   return _to_ARGB16161616;
> > > + else if (format == DRM_FORMAT_RGB565)
> > > + return _to_ARGB16161616;
> > >   else
> > >   return _to_ARGB16161616;
> > >  }
> > > @@ -23,6 +25,8 @@ format_transform_func  
> > get_wb_fmt_transform_function(u32 format)  
> > >   return _to_ARGB16161616;
> > >   else if (format == DRM_FORMAT_XRGB16161616)
> > >   return _to_XRGB16161616;
> > > + else if (format == DRM_FORMAT_RGB565)
> > > + return _to_RGB565;
> > >   else
> > >   return _to_XRGB;
> > >  }
> > > @@ -33,6 +37,26 @@ static int pixel_offset(struct vkms_frame_info  
> > *frame_info, int x, int y)  
> > > + (x * frame_info->cpp);
> > >  }
> > >
> > > +/*
> > > + * FP stands for _Fixed Point_ and **not** _Float Point_  
> >
> > Is it common in the kernel that FP always means fixed-point?
> >  
> 
> I cannot say for sure, but I don't think so. I put it for people like me
> that goes automatically to Floating-Point because never worked with
> fixed-point before.

Indeed, so do not use "FP" at all as an abbreviation, please. Use a
name or abbreviation that does not need a comment to prevent easy
misunderstandings.


Thanks,
pq


pgpky2yiHsf5C.pgp
Description: OpenPGP digital signature


Re: [PATCH v4 03/10] clk: Use clamp instead of open-coding our own

2022-02-25 Thread Maxime Ripard
On Thu, Feb 24, 2022 at 02:44:20PM -0800, Stephen Boyd wrote:
> Quoting Maxime Ripard (2022-02-21 08:30:01)
> > On Fri, Feb 18, 2022 at 02:34:20PM -0800, Stephen Boyd wrote:
> > > Quoting Maxime Ripard (2022-01-25 06:15:42)
> > > > The code in clk_set_rate_range() will, if the current rate is outside of
> > > > the new range, will force it to the minimum or maximum. This is
> > > > equivalent to using clamp, while being less readable. Let's switch to
> > > > using clamp instead.
> > > > 
> > > > Signed-off-by: Maxime Ripard 
> > > > ---
> > > >  drivers/clk/clk.c | 6 +-
> > > >  1 file changed, 1 insertion(+), 5 deletions(-)
> > > > 
> > > > diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> > > > index 7bb5ae0fb688..150d1bc0985b 100644
> > > > --- a/drivers/clk/clk.c
> > > > +++ b/drivers/clk/clk.c
> > > > @@ -2365,11 +2365,7 @@ int clk_set_rate_range(struct clk *clk, unsigned 
> > > > long min, unsigned long max)
> > > >  *   this corner case when determining the rate
> > > >  */
> > > >  
> > > > -   if (rate < min)
> > > > -   rate = min;
> > > > -   else
> > > > -   rate = max;
> > > > -
> > > > +   rate = clamp(clk->core->req_rate, min, max);
> > > 
> > > This isn't equivalent. The else arm is taken if rate >= min and rate is
> > > set to max, whereas clamp() will leave the rate unchanged if rate >= min
> > > && rate < max.
> > 
> > This can't happen, since we're in an if block that is (rate < min ||
> > rate > max), so at this point if rate is not less than min, it is
> > greater than rate. Thus, it's equivalent to clamp.
> > 
> > Still, the commit message could be better, I'll rephrase it.
> 
> Perfect! Should probably add a comment above the clamp as well just in
> case someone decides to move it out of that if block.

The last version has a better commit message. We're actually moving that
out of the if in the next patch.

I'm not sure we really need a comment for this though:

The existing code does:

if (rate < min || rate > max)
if (rate < min)
rate = min;
else
rate = max;

So if the rate is below min, it's set to min, if it's between min and
max, it's unaffected, and if it's above max, it's set to max.

With this patch, the code does:

if (rate < min || rate > max)
rate = clamp(rate, min, max)

So if the rate is below min, it's set to min, if it's between min and
max, it's unaffected, and if it's above max, it's set to max. It's
equivalent.

After the next patch, the code will do:
rate = clamp(rate, min, max)

So if the rate is below min, it's set to min, if it's between min and
max, it's unaffected, and if it's above max, it's set to max. They are
all equivalent.

Maxime


signature.asc
Description: PGP signature


Re: [PATCH v4 7/9] drm: vkms: Refactor the plane composer to accept new formats

2022-02-25 Thread Pekka Paalanen
On Thu, 24 Feb 2022 21:43:01 -0300
Igor Torrente  wrote:

> Hi Pekka,
> 
> On 2/10/22 06:37, Pekka Paalanen wrote:
> > On Fri, 21 Jan 2022 18:38:29 -0300
> > Igor Torrente  wrote:
> >  
> >> Currently the blend function only accepts XRGB_ and ARGB_
> >> as a color input.
> >>
> >> This patch refactors all the functions related to the plane composition
> >> to overcome this limitation.
> >>
> >> A new internal format(`struct pixel`) is introduced to deal with all
> >> possible inputs. It consists of 16 bits fields that represent each of
> >> the channels.
> >>
> >> The pixels blend is done using this internal format. And new handlers
> >> are being added to convert a specific format to/from this internal format.
> >>
> >> So the blend operation depends on these handlers to convert to this common
> >> format. The blended result, if necessary, is converted to the writeback
> >> buffer format.
> >>
> >> This patch introduces three major differences to the blend function.
> >> 1 - All the planes are blended at once.
> >> 2 - The blend calculus is done as per line instead of per pixel.
> >> 3 - It is responsible to calculates the CRC and writing the writeback
> >>  buffer(if necessary).
> >>
> >> These changes allow us to allocate way less memory in the intermediate
> >> buffer to compute these operations. Because now we don't need to
> >> have the entire intermediate image lines at once, just one line is
> >> enough.
> >>
> >> | Memory consumption (output dimensions) |
> >> |:--:|
> >> |   Current  | This patch|
> >> |:--:|:-:|
> >> |   Width * Heigth   | 2 * Width |
> >>
> >> Beyond memory, we also have a minor performance benefit from all
> >> these changes. Results running the IGT tests `*kms_cursor_crc*`:
> >>
> >> | Frametime  |
> >> |:--:|
> >> |  Implementation |  Current  |  This commit |
> >> |:---:|:-:|::|
> >> | frametime range |  8~22 ms  |5~18 ms   |
> >> | Average |  10.0 ms  |7.3 ms|
> >>
> >> Reported-by: kernel test robot 
> >> Signed-off-by: Igor Torrente 
> >> ---
> >> V2: Improves the performance drastically, by perfoming the operations
> >>  per-line and not per-pixel(Pekka Paalanen).
> >>  Minor improvements(Pekka Paalanen).
> >>
> >> V3: Changes the code to blend the planes all at once. This improves
> >>  performance, memory consumption, and removes much of the weirdness
> >>  of the V2(Pekka Paalanen and me).
> >>  Minor improvements(Pekka Paalanen and me).
> >>
> >> V4: Rebase the code and adapt it to the new NUM_OVERLAY_PLANES constant.
> >> ---
> >>   drivers/gpu/drm/vkms/Makefile|   1 +
> >>   drivers/gpu/drm/vkms/vkms_composer.c | 335 +--
> >>   drivers/gpu/drm/vkms/vkms_formats.c  | 138 +++
> >>   drivers/gpu/drm/vkms/vkms_formats.h  |  31 +++
> >>   4 files changed, 333 insertions(+), 172 deletions(-)
> >>   create mode 100644 drivers/gpu/drm/vkms/vkms_formats.c
> >>   create mode 100644 drivers/gpu/drm/vkms/vkms_formats.h  
> >
> > Hi Igor,
> >
> > I'm really happy to see this, thanks!
> >
> > I still have some security/robustness and other comments below.
> >
> > I've deleted all the minus lines from the patch to make the new code
> > more clear.
> >  
> >>
> >> diff --git a/drivers/gpu/drm/vkms/Makefile b/drivers/gpu/drm/vkms/Makefile
> >> index 72f779cbfedd..1b28a6a32948 100644
> >> --- a/drivers/gpu/drm/vkms/Makefile
> >> +++ b/drivers/gpu/drm/vkms/Makefile
> >> @@ -3,6 +3,7 @@ vkms-y := \
> >>  vkms_drv.o \
> >>  vkms_plane.o \
> >>  vkms_output.o \
> >> +vkms_formats.o \
> >>  vkms_crtc.o \
> >>  vkms_composer.o \
> >>  vkms_writeback.o
> >> diff --git a/drivers/gpu/drm/vkms/vkms_composer.c 
> >> b/drivers/gpu/drm/vkms/vkms_composer.c
> >> index 95029d2ebcac..9f70fcf84fb9 100644
> >> --- a/drivers/gpu/drm/vkms/vkms_composer.c
> >> +++ b/drivers/gpu/drm/vkms/vkms_composer.c
> >> @@ -9,202 +9,210 @@
> >>   #include 
> >>
> >>   #include "vkms_drv.h"
> >> +#include "vkms_formats.h"
> >>
> >> +static u16 pre_mul_blend_channel(u16 src, u16 dst, u16 alpha)
> >>   {
> >> +u32 new_color;
> >>
> >> +new_color = (src * 0x + dst * (0x - alpha));
> >>
> >> +return DIV_ROUND_UP(new_color, 0x);  
> >
> > Why round-up rather than the usual mathematical rounding?  
> 
> AFAIK, this is the only round that's present in the kernel. And if I
> understood correctly it is the round toward positive infinity that we are
> all used to use.

Should be pretty easy to round-up from 0.5 and round-down otherwise.
Just add a different offset than DIV_ROUND_UP does.

Not having a ready-made macro and habits are not good
justifications. The justification needs to be mathematical.

The problem with DIV_ROUND_UP that I see, is that 0x0001 gets
rounded to 0x0001, and 

Re: [PATCH v4 02/10] clk: Always clamp the rounded rate

2022-02-25 Thread Maxime Ripard
Hi,

On Thu, Feb 24, 2022 at 02:39:20PM -0800, Stephen Boyd wrote:
> Quoting Maxime Ripard (2022-02-21 08:43:23)
> > Hi again,
> > 
> > On Mon, Feb 21, 2022 at 05:18:21PM +0100, Maxime Ripard wrote:
> > > On Fri, Feb 18, 2022 at 03:15:06PM -0800, Stephen Boyd wrote:
> > > > Quoting Maxime Ripard (2022-01-25 06:15:41)
> > > > > +/*
> > > > > + * Test that if our clock has some boundaries and we try to round a 
> > > > > rate
> > > > > + * lower than the minimum, the returned rate will be within range.
> > > > > + */
> > > > > +static void clk_range_test_set_range_round_rate_lower(struct kunit 
> > > > > *test)
> > > > > +{
> > > > > +   struct clk_dummy_context *ctx = test->priv;
> > > > > +   struct clk_hw *hw = >hw;
> > > > > +   struct clk *clk = hw->clk;
> > > > > +   long rate;
> > > > > +
> > > > > +   KUNIT_ASSERT_EQ(test,
> > > > > +   clk_set_rate_range(clk,
> > > > > +  DUMMY_CLOCK_RATE_1,
> > > > > +  DUMMY_CLOCK_RATE_2),
> > > > > +   0);
> > > > > +
> > > > > +   rate = clk_round_rate(clk, DUMMY_CLOCK_RATE_1 - 1000);
> > > > > +   KUNIT_ASSERT_GT(test, rate, 0);
> > > > > +   KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_1);
> > > > 
> > > > The comment says within range but this test says exactly the minimum
> > > > rate. Please change it to test that the rate is within rate 1 and rate
> > > > 2. Also, we should call clk_get_rate() here to make sure the rate is
> > > > within the boundaries and matches what clk_round_rate() returned.
> > > 
> > > Ok
> > 
> > Actually, that doesn't work. Calling clk_round_rate() won't affect the
> > clock rate, so the rate returned by clk_get_rate() won't match what
> > clk_round_rate() will return.
> 
> Huh? This is asking "what rate will I get if I call clk_set_rate() with
> DUMMY_CLOCK_RATE_1 - 1000 after setting the range to be rate 1 and rate
> 2. It should round that up to some value (and we should enforce that it
> is inclusive or exclusive). I think I missed that this is
> clk_round_rate().
> 
> Either way, the clk provider implementation could say that if you call
> clk_set_rate() with a frequency below the minimum that it lies somewhere
> between the rate 1 and rate 2. The expectation should only check that it
> is within the range and not exactly the minimum because we're not
> testing the clk provider implementation of the rounding here, just that
> the constraints are satisfied and the rate is within range. That's my
> understanding of the comment above the function and the function name.

You're right, that has been addressed in the last version I sent already

Maxime


signature.asc
Description: PGP signature


Re: [PATCH v3 0/2] drm/dp: Fix out-of-bounds reads

2022-02-25 Thread Thierry Reding
On Thu, Feb 24, 2022 at 07:56:08PM -0800, Kees Cook wrote:
> Hi,
> 
> I'm sending these again, as they still need fixing. They have been
> rebased due to the drm_dp_helper code being moved into a subdirectory.

Yeah, I noticed the other day that this had been partially reverted by
the DP code move. I've applied this now, though it didn't apply cleanly,
so I'll do a couple of test builds to make sure my resolution is correct
and will push this out later on.

Thanks,
Thierry


signature.asc
Description: PGP signature


Re: [PATCH v7, 11/15] media: mtk-vcodec: record capture queue format type

2022-02-25 Thread AngeloGioacchino Del Regno

Il 23/02/22 04:40, Yunfei Dong ha scritto:

Capture queue format type is difference for different platform,
need to calculate capture buffer size according to capture queue
format type in scp.

Signed-off-by: Yunfei Dong 



This change is ok, but the commit message should be changed to advertise
that this is preparation for the new stateless H264 decoding driver.
Besides, I suggest to reorder the commits sequence, so that this commit
goes in between "Extract H264 common code" and
"support stateless H.264 decoding for mt8192", as this last one is
the actual real user of this change.


Anyway, this is my commit message proposal:

The capture queue format type may be differ depending on platform:
for stateless decoder drivers, we need to calculate the capture buffer
size according to the capture queue format type in SCP.

As a preparation for introducing drivers for stateless decoding, save
the current capture queue type on a per vcodec context basis.

After fixing,
Reviewed-by: AngeloGioacchino Del Regno 



Re: [PATCH v7, 08/15] media: mtk-vcodec: Add format to support MT21C

2022-02-25 Thread AngeloGioacchino Del Regno

Il 23/02/22 04:40, Yunfei Dong ha scritto:

Needs to use mediatek compressed mode for mt8192 decoder.

Signed-off-by: Yunfei Dong 


Reviewed-by: AngeloGioacchino Del Regno 




Re: [PATCH v7, 07/15] media: mtk-vcodec: Refactor supported vdec formats and framesizes

2022-02-25 Thread AngeloGioacchino Del Regno

Il 23/02/22 04:40, Yunfei Dong ha scritto:

Supported output and capture format types for mt8192 are different
with mt8183. Needs to get format types according to decoder capability.

Signed-off-by: Yunfei Dong 


Reviewed-by: AngeloGioacchino Del Regno 




Re: [PATCH v7, 04/15] media: mtk-vcodec: Read max resolution from dec_capability

2022-02-25 Thread AngeloGioacchino Del Regno

Il 23/02/22 04:39, Yunfei Dong ha scritto:

Supported max resolution for different platforms are not the same: 2K
or 4K, getting it according to dec_capability.

Signed-off-by: Yunfei Dong 
Reviewed-by: Tzung-Bi Shih


Reviewed-by: AngeloGioacchino Del Regno 



Re: [PATCH v7, 01/15] media: mtk-vcodec: Add vdec enable/disable hardware helpers

2022-02-25 Thread AngeloGioacchino Del Regno

Il 23/02/22 04:39, Yunfei Dong ha scritto:

Lock, power and clock are highly coupled operations. Adds vdec
enable/disable hardware helpers and uses them.

Signed-off-by: Yunfei Dong 
Reviewed-by: Tzung-Bi Shih


Reviewed-by: AngeloGioacchino Del Regno 



Re: [PATCH v6 1/2] drm/vrr: Set VRR capable prop only if it is attached to connector

2022-02-25 Thread Ville Syrjälä
On Thu, Feb 24, 2022 at 05:30:54PM -0800, Manasi Navare wrote:
> VRR capable property is not attached by default to the connector
> It is attached only if VRR is supported.
> So if the driver tries to call drm core set prop function without
> it being attached that causes NULL dereference.
> 
> Cc: Jani Nikula 
> Cc: Ville Syrjälä 
> Cc: dri-devel@lists.freedesktop.org
> Signed-off-by: Manasi Navare 

Reviewed-by: Ville Syrjälä 

> ---
>  drivers/gpu/drm/drm_connector.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index a50c82bc2b2f..76a8c707c34b 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -2330,6 +2330,9 @@ EXPORT_SYMBOL(drm_connector_atomic_hdr_metadata_equal);
>  void drm_connector_set_vrr_capable_property(
>   struct drm_connector *connector, bool capable)
>  {
> + if (!connector->vrr_capable_property)
> + return;
> +
>   drm_object_property_set_value(>base,
> connector->vrr_capable_property,
> capable);
> -- 
> 2.19.1

-- 
Ville Syrjälä
Intel


Re: [Freedreno] [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment

2022-02-25 Thread Dmitry Baryshkov
On Fri, 25 Feb 2022 at 07:45, Abhinav Kumar  wrote:
>
>
>
> On 2/24/2022 8:22 PM, Dmitry Baryshkov wrote:
> > On Fri, 25 Feb 2022 at 05:01, Abhinav Kumar  
> > wrote:
> >>
> >>
> >>
> >> On 2/24/2022 12:41 PM, Dmitry Baryshkov wrote:
> >>> On Thu, 24 Feb 2022 at 21:25, Abhinav Kumar  
> >>> wrote:
> 
> 
> 
>  On 2/18/2022 6:26 PM, Dmitry Baryshkov wrote:
> > On 19/02/2022 02:56, Stephen Boyd wrote:
> >> Quoting Dmitry Baryshkov (2022-02-11 14:40:02)
> >>> In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for 
> >>> display
> >>> enable and disable") the DP driver received a drm_bridge instance, 
> >>> which
> >>> is always attached to the encoder as a root bridge. However it 
> >>> conflicts
> >>> with the panel_bridge support for eDP panels. The panel bridge 
> >>> attaches
> >>> to the encoder before the "dp" bridge has a chace to do so. Change
> >>
> >> s/chace/chance/
> >>
> >>> panel_bridge attachment to come after dp_bridge attachment.
> >>
> >> s/panel_bridge/panel bridge/ possibly? And maybe clarify that dp_bridge
> >> is the "DP driver's drm_bridge instance created in
> >> msm_dp_bridge_init()"?
> >>
> >> My understanding is that we want to pass the bridge created in
> >> msm_dp_bridge_init() as the 'previous' bridge so that it attaches the
> >> panel bridge to the output of the DP bridge that's attached to the
> >> encoder.
> >
> > Thanks! I'll update the commit log when pushing the patches.
> 
>  Please correct if i am missing something here.
> 
>  You are right that the eDP panel's panel bridge attaches to the encoder
>  in dp_drm_connector_init() which happens before msm_dp_bridge_init() and
>  hence it will attach directly to the encoder.
> 
>  But we are talking about different encoders here. DP's dp_display has a
>  different encoder compared to the EDP's dp_display.
> >>>
> >>> The encoders are different. However both encoders use the same
> >>> codepath, which includes dp_bridge. It controls dp_display by calling
> >>> msm_dp_display_foo() functions.
> >>>
> >
>  So DP's bridge will still be attached to its encoder's root.
> >>>
> >>> There is one dp_bridge per each encoder. Consider sc8180x which has 3
> >>> DP controllers (and thus 3 dp_bridges).
> >>>
> >>
> >> Sorry, but I still didnt follow this.
> >>
> >> So for eDP, dp_drm_connector_init() will attach the panel_bridge
> >> and then msm_dp_bridge_init() will add a drm_bridge.
> >>
> >> And yes in that case, the drm_bridge will be after the panel_bridge
> >>
> >> But since panel_bridge is at the root for eDP it should be okay.
> >
> > No. It is not.
> > For both DP and eDP the chain should be:
> > dpu_encoder -> dp_bridge -> external (panel) bridge, optional for DP
> > -> [other bridges] -> connector
> >
> > Otherwise drm_bridge_chain_foo() functions would be called in the
> > incorrect order.
>
> Agreed. For drm_bridge_chain_foo() ordering to be correct, for eDP chain
> the order should be what you mentioned and panel_bridge should be at the
> end ( should be the last one ).
>
> For the above reason,
>
> Reviewed-by: Abhinav Kumar 
>
> I still didnt understand what gets affected by this for the
> msm_dp_display_foo() functions you mentioned earlier and wanted to get
> some clarity on that.

They should be called at the correct time.

> >
> > Thus the dp_bridge should be attached directly to the encoder
> > (drm_encoder) and panel_bridge should use dp_bridge as the 'previous'
> > bridge.
> >
>
> Agreed.
>
> > For example, for the DP port one can use a display-connector (which
> > actually implements drm_bridge) as an external bridge to provide hpd
> > or dp power GPIOs.
> >
> > Note, that the current dp_connector breaks layering. It makes calls
> > directly into dp_display, not allowing external bridge (and other
> > bridges) to override get_modes/mode_valid and other callbacks.
> > Thus one of the next patches in series (the one that Kuogee had issues
> > with) tries to replace the chain with the following one:
> > dpu_encoder -> dp_bridge -> external (panel) bridge -> [other bridges]
> > -> drm_bridge_connector.
> >
> >>
>
> So originally the plan was always that the DP connector layer intercepts
> the call because panel-eDP file did not support reading of the EDID ( we
> have not provided the aux bus ). So it was intended that we did not want
> to goto the eDP panel to get the modes. Not an error but something which
> we wanted to cleanup later when we moved to panel-eDP completely.

panel_edp_get_modes() correctly handles this case and returns modes
specified in the panel description. So the code should work even with
panel-eDP and w/o the AUX bus.

>
> Till then we wanted the dp_connector to read the EDID and get the modes.
>
> So this was actually intended to happen till the point where we moved to
> panel-eDP to get the modes.
>
> Hence what you have 

Re: Regression from 3c196f056666 ("drm/amdgpu: always reset the asic in suspend (v2)") on suspend?

2022-02-25 Thread Éric Valette
On 2/21/22 15:16, Alex Deucher wrote:

 Is this system S0i3 or regular S3?
>> 
>> For me it is real S3.
>> 
>> The proposed patch is intended for INTEl + intel gpu + amdgpu but I have
>> dual amd GPU.
> It doesn't really matter what the platform is, it could still
> potentially help on your system, it depends on the bios implementation
> for your platform and how it handles suspend. You can try the patch,
> but I don't think you are hitting the same issue.  I bisect would be
> helpful in your case.

Trying to add the pach on top of 5.15.24, I got a already applied message and 
indeed the patch is already there. So this particular patch it does not fix my 
problem.

Saw new modif in 5.15.25. Will try and check if I can find time to bissect.

-- eric


Re: [PATCH v6 21/23] drm: rockchip: Add VOP2 driver

2022-02-25 Thread Dmitry Osipenko
On 2/24/22 10:47, Sascha Hauer wrote:
> On Thu, Feb 17, 2022 at 04:24:29PM +0300, Dmitry Osipenko wrote:
>> 17.02.2022 11:29, Sascha Hauer пишет:
>>> @@ -28,6 +28,12 @@ config ROCKCHIP_VOP
>>>   This selects support for the VOP driver. You should enable it
>>>   on all older SoCs up to RK3399.
>>>  
>>> +config ROCKCHIP_VOP2
>>> +   bool "Rockchip VOP2 driver"
>>> +   help
>>> + This selects support for the VOP2 driver. You should enable it
>>> + on all newer SoCs beginning form RK3568.
>>
>> s/form/from/
>>
>> The ROCKCHIP_VOP option is "default y". Do you really want "default n"
>> for the VOP2?
> 
> ROCKCHIP_VOP is only default y to keep the VOP driver enabled for
> existing defconfig that were generated before the introduction of
> that symbol.
> We don't have this problem for VOP2, so no need to make it default y.

To me it will be more consistent of you'll have both defaulting to y,
since both options are behind DRM_ROCKCHIP.


Re: [PATCH] drm/exynos: fimd: add BGR support for exynos4/5

2022-02-25 Thread Martin Jücker
Hello Inki,

On Thu, Feb 24, 2022 at 10:41:04AM +0900, Inki Dae wrote:
> Hi Martin.
> 
> I found that exynos4 and 5 data sheet include documented same register.
> RGB_ORDER_E field of VIDCONx registers will do same thing.

If I read the manual correctly, this register combined with the
RGB_ORDER_O makes it possible to map the whole RGB interface output to a
different order. What my patch provides is a way to configure each
hardware plane separately while maintaining a consistent output on the
RGB interface.

Implementing the RGB_ORDER_O and E would need some logic to make sure
that all planes are always using the same RGB order.

> 
> I'm not sure whether the use of undocumented register is safe or not - maybe 
> some HW bug exists.

I see, that makes sense. Would it be possible then to introduce a new
compatible, e.g. samsung,exynos4210-fimd-ext which can be used on tested
devices? I know that some other Galaxy Note and S devices with the
exynos4 chip have the same problem (and solution).

> 
> Anyway, I'd like to recommend you to use documented register only.
> 
> Sorry for late and thanks,
> Inki Dae

Kind Regards
Martin

> 
> 22. 1. 30. 07:01에 Martin Jücker 이(가) 쓴 글:
> > In the downstream kernels for exynos4 and exynos5 devices, there is an
> > undocumented register that controls the order of the RGB output. It can
> > be set to either normal order or reversed, which enables BGR support for
> > those SoCs.
> > 
> > This patch enables the BGR support for all the SoCs that were found to
> > have at least one device with this logic in the corresponding downstream
> > kernels.
> > 
> > Signed-off-by: Martin Jücker 
> > ---
> >  drivers/gpu/drm/exynos/exynos_drm_fimd.c | 42 ++--
> >  include/video/samsung_fimd.h |  4 +++
> >  2 files changed, 44 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c 
> > b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> > index c735e53939d8..cb632360c968 100644
> > --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> > +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> > @@ -109,6 +109,7 @@ struct fimd_driver_data {
> > unsigned int has_dp_clk:1;
> > unsigned int has_hw_trigger:1;
> > unsigned int has_trigger_per_te:1;
> > +   unsigned int has_bgr_support:1;
> >  };
> >  
> >  static struct fimd_driver_data s3c64xx_fimd_driver_data = {
> > @@ -138,6 +139,7 @@ static struct fimd_driver_data exynos4_fimd_driver_data 
> > = {
> > .lcdblk_bypass_shift = 1,
> > .has_shadowcon = 1,
> > .has_vtsel = 1,
> > +   .has_bgr_support = 1,
> >  };
> >  
> >  static struct fimd_driver_data exynos5_fimd_driver_data = {
> > @@ -149,6 +151,7 @@ static struct fimd_driver_data exynos5_fimd_driver_data 
> > = {
> > .has_vidoutcon = 1,
> > .has_vtsel = 1,
> > .has_dp_clk = 1,
> > +   .has_bgr_support = 1,
> >  };
> >  
> >  static struct fimd_driver_data exynos5420_fimd_driver_data = {
> > @@ -162,6 +165,7 @@ static struct fimd_driver_data 
> > exynos5420_fimd_driver_data = {
> > .has_vtsel = 1,
> > .has_mic_bypass = 1,
> > .has_dp_clk = 1,
> > +   .has_bgr_support = 1,
> >  };
> >  
> >  struct fimd_context {
> > @@ -226,6 +230,18 @@ static const uint32_t fimd_formats[] = {
> > DRM_FORMAT_ARGB,
> >  };
> >  
> > +static const uint32_t fimd_extended_formats[] = {
> > +   DRM_FORMAT_C8,
> > +   DRM_FORMAT_XRGB1555,
> > +   DRM_FORMAT_XBGR1555,
> > +   DRM_FORMAT_RGB565,
> > +   DRM_FORMAT_BGR565,
> > +   DRM_FORMAT_XRGB,
> > +   DRM_FORMAT_XBGR,
> > +   DRM_FORMAT_ARGB,
> > +   DRM_FORMAT_ABGR,
> > +};
> > +
> >  static const unsigned int capabilities[WINDOWS_NR] = {
> > 0,
> > EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND,
> > @@ -673,21 +689,25 @@ static void fimd_win_set_pixfmt(struct fimd_context 
> > *ctx, unsigned int win,
> > val |= WINCONx_BYTSWP;
> > break;
> > case DRM_FORMAT_XRGB1555:
> > +   case DRM_FORMAT_XBGR1555:
> > val |= WINCON0_BPPMODE_16BPP_1555;
> > val |= WINCONx_HAWSWP;
> > val |= WINCONx_BURSTLEN_16WORD;
> > break;
> > case DRM_FORMAT_RGB565:
> > +   case DRM_FORMAT_BGR565:
> > val |= WINCON0_BPPMODE_16BPP_565;
> > val |= WINCONx_HAWSWP;
> > val |= WINCONx_BURSTLEN_16WORD;
> > break;
> > case DRM_FORMAT_XRGB:
> > +   case DRM_FORMAT_XBGR:
> > val |= WINCON0_BPPMODE_24BPP_888;
> > val |= WINCONx_WSWP;
> > val |= WINCONx_BURSTLEN_16WORD;
> > break;
> > case DRM_FORMAT_ARGB:
> > +   case DRM_FORMAT_ABGR:
> > default:
> > val |= WINCON1_BPPMODE_25BPP_A1888;
> > val |= WINCONx_WSWP;
> > @@ -695,6 +715,18 @@ static void fimd_win_set_pixfmt(struct fimd_context 
> > *ctx, unsigned int win,
> > break;
> > }
> >  
> > +   switch (pixel_format) {
> > +   case DRM_FORMAT_XBGR1555:
> > +   

<    1   2   3   >