Граф коммитов

1257 Коммитов

Автор SHA1 Сообщение Дата
Liang He a5ce83e85d drm/omap: dss: Fix refcount leak bugs
[ Upstream commit 8b42057e62 ]

In dss_init_ports() and __dss_uninit_ports(), we should call
of_node_put() for the reference returned by of_graph_get_port_by_id()
in fail path or when it is not used anymore.

Fixes: 09bffa6e51 ("drm: omap: use common OF graph helpers")
Signed-off-by: Liang He <windhl@126.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220722144348.1306569-1-windhl@126.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
2022-10-26 12:34:54 +02:00
Laurent Pinchart fb8d617f8f drm/bridge: Centralize error message when bridge attach fails
Being informed of a failure to attach a bridge is useful, and many
drivers prints an error message in that case. Move the message to
drm_bridge_attach() to avoid code duplication.

Suggested-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Reviewed-by: Jyri Sarha <jyri.sarha@iki.fi>
2021-07-28 16:33:12 +03:00
Thomas Zimmermann 311ac6f3e5 drm/omapdrm: Remove outdated comment
The comment refers to drm_irq_install() et al, which are not used by
omapdrm. The functions are part of the DRM IRQ midlayer and shouldn't
be used any longer. Remove the comment.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20210706073125.7689-1-tzimmermann@suse.de
2021-07-15 11:24:53 +02:00
Thomas Zimmermann daea75017c drm/omapdrm: Track IRQ state in local device state
Replace usage of struct drm_device.irq_enabled with the driver's
own state field struct omap_drm_device.irq_enabled. The field in
the DRM device structure is considered legacy and should not be
used by KMS drivers.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20210625082222.3845-16-tzimmermann@suse.de
2021-06-29 11:08:43 +02:00
Daniel Vetter 942d8344d5 drm/omap: Follow implicit fencing in prepare_fb
I guess no one ever tried running omap together with lima or panfrost,
not even sure that's possible. Anyway for consistency, fix this.

Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Tomi Valkeinen <tomba@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20210622165511.3169559-12-daniel.vetter@ffwll.ch
2021-06-24 15:39:37 +02:00
Daniel Vetter 213cc929cb Merge drm/drm-fixes into drm-next
msm-next pull request has a baseline with stuff from -fixes, roll
forward first.

Some simple conflicts in amdgpu, ttm and one in i915 where git gets
confused and tries to add the same function twice.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2021-04-13 23:15:09 +02:00
Wan Jiabing 309f81e81d drm/omap: Remove duplicate declaration
struct dss_device has been declared. Remove the duplicate.
And sort these forward declarations alphabetically.

Signed-off-by: Wan Jiabing <wanjiabing@vivo.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210325111028.864628-1-wanjiabing@vivo.com
2021-03-26 09:23:25 +02:00
Yang Li 0cafc8d88e drm/omap: dsi: Add missing IRQF_ONESHOT
fixed the following coccicheck:
./drivers/gpu/drm/omapdrm/dss/dsi.c:4329:7-27: ERROR: Threaded IRQ with
no primary handler requested without IRQF_ONESHOT

Reported-by: Abaci Robot <abaci@linux.alibaba.com>
Signed-off-by: Yang Li <yang.lee@linux.alibaba.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Fixes: 4c1b935fea ("drm/omap: dsi: move TE GPIO handling into core")
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1616492093-68237-1-git-send-email-yang.lee@linux.alibaba.com
2021-03-26 09:23:13 +02:00
Arnd Bergmann 417fc6123b drm/omap: fix misleading indentation in pixinc()
An old patch added a 'return' statement after each BUG() in this driver,
which was necessary at the time, but has become redundant after the BUG()
definition was updated to handle this properly.

gcc-11 now warns about one such instance, where the 'return' statement
was incorrectly indented:

drivers/gpu/drm/omapdrm/dss/dispc.c: In function ‘pixinc’:
drivers/gpu/drm/omapdrm/dss/dispc.c:2093:9: error: this ‘else’ clause does not guard... [-Werror=misleading-indentation]
 2093 |         else
      |         ^~~~
drivers/gpu/drm/omapdrm/dss/dispc.c:2095:17: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘else’
 2095 |                 return 0;
      |                 ^~~~~~

Address this by removing the return again and changing the BUG()
to be unconditional to make this more intuitive.

Fixes: c6eee968d4 ("OMAPDSS: remove compiler warnings when CONFIG_BUG=n")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210322164203.827324-1-arnd@kernel.org
2021-03-26 09:13:37 +02:00
Junlin Yang 6909115442 drm/omap: dsi: fix unsigned expression compared with zero
r is "u32" always >= 0,mipi_dsi_create_packet may return little than zero.
so r < 0 condition is never accessible.

Fixes coccicheck warnings:
./drivers/gpu/drm/omapdrm/dss/dsi.c:2155:5-6:
WARNING: Unsigned expression compared with zero: r < 0

Signed-off-by: Junlin Yang <yangjunlin@yulong.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210312071445.1721-1-angkery@163.com
2021-03-17 13:59:23 +02:00
Maxime Ripard 37418bf14c
drm: Use state helper instead of the plane state pointer
Many drivers reference the plane->state pointer in order to get the
current plane state in their atomic_update or atomic_disable hooks,
which would be the new plane state in the global atomic state since
_swap_state happened when those hooks are run.

Use the drm_atomic_get_new_plane_state helper to get that state to make it
more obvious.

This was made using the coccinelle script below:

@ plane_atomic_func @
identifier helpers;
identifier func;
@@

(
 static const struct drm_plane_helper_funcs helpers = {
 	...,
 	.atomic_disable = func,
	...,
 };
|
 static const struct drm_plane_helper_funcs helpers = {
 	...,
 	.atomic_update = func,
	...,
 };
)

@ adds_new_state @
identifier plane_atomic_func.func;
identifier plane, state;
identifier new_state;
@@

 func(struct drm_plane *plane, struct drm_atomic_state *state)
 {
 	...
-	struct drm_plane_state *new_state = plane->state;
+	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, plane);
	...
 }

@ include depends on adds_new_state @
@@

 #include <drm/drm_atomic.h>

@ no_include depends on !include && adds_new_state @
@@

+ #include <drm/drm_atomic.h>
  #include <drm/...>

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://lore.kernel.org/r/20210219120032.260676-1-maxime@cerno.tech
2021-02-25 08:05:28 +01:00
Maxime Ripard 977697e20b
drm/atomic: Pass the full state to planes atomic disable and update
The current atomic helpers have either their object state being passed as
an argument or the full atomic state.

The former is the pattern that was done at first, before switching to the
latter for new hooks or when it was needed.

Let's convert the remaining helpers to provide a consistent interface,
this time with the planes atomic_update and atomic_disable.

The conversion was done using the coccinelle script below, built tested on
all the drivers.

@@
identifier plane, plane_state;
symbol state;
@@

 struct drm_plane_helper_funcs {
 	...
	void (*atomic_update)(struct drm_plane *plane,
-			      struct drm_plane_state *plane_state);
+			      struct drm_atomic_state *state);
 	...
 }

@@
identifier plane, plane_state;
symbol state;
@@

 struct drm_plane_helper_funcs {
	...
	void (*atomic_disable)(struct drm_plane *plane,
-			       struct drm_plane_state *plane_state);
+			       struct drm_atomic_state *state);
	...
 }

@ plane_atomic_func @
identifier helpers;
identifier func;
@@

(
 static const struct drm_plane_helper_funcs helpers = {
 	...,
 	.atomic_update = func,
	...,
 };
|
 static const struct drm_plane_helper_funcs helpers = {
 	...,
 	.atomic_disable = func,
	...,
 };
)

@@
struct drm_plane_helper_funcs *FUNCS;
identifier f;
identifier crtc_state;
identifier plane, plane_state, state;
expression e;
@@

 f(struct drm_crtc_state *crtc_state)
 {
 	...
 	struct drm_atomic_state *state = e;
 	<+...
(
-	FUNCS->atomic_disable(plane, plane_state)
+	FUNCS->atomic_disable(plane, state)
|
-	FUNCS->atomic_update(plane, plane_state)
+	FUNCS->atomic_update(plane, state)
)
 	...+>
 }

@@
identifier plane_atomic_func.func;
identifier plane;
symbol state;
@@

 func(struct drm_plane *plane,
-    struct drm_plane_state *state)
+    struct drm_plane_state *old_plane_state)
 {
	<...
-	state
+	old_plane_state
	...>
 }

@ ignores_old_state @
identifier plane_atomic_func.func;
identifier plane, old_state;
@@

 func(struct drm_plane *plane, struct drm_plane_state *old_state)
 {
	... when != old_state
 }

@ adds_old_state depends on plane_atomic_func && !ignores_old_state @
identifier plane_atomic_func.func;
identifier plane, plane_state;
@@

 func(struct drm_plane *plane, struct drm_plane_state *plane_state)
 {
+	struct drm_plane_state *plane_state = drm_atomic_get_old_plane_state(state, plane);
 	...
 }

@ depends on plane_atomic_func @
identifier plane_atomic_func.func;
identifier plane, plane_state;
@@

 func(struct drm_plane *plane,
-     struct drm_plane_state *plane_state
+     struct drm_atomic_state *state
     )
 { ... }

@ include depends on adds_old_state @
@@

 #include <drm/drm_atomic.h>

@ no_include depends on !include && adds_old_state @
@@

+ #include <drm/drm_atomic.h>
  #include <drm/...>

@@
identifier plane_atomic_func.func;
identifier plane, state;
identifier plane_state;
@@

 func(struct drm_plane *plane, struct drm_atomic_state *state) {
 	...
 	struct drm_plane_state *plane_state = drm_atomic_get_old_plane_state(state, plane);
 	<+...
-	plane_state->state
+	state
 	...+>
 }

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20210219120032.260676-9-maxime@cerno.tech
2021-02-25 08:05:28 +01:00
Maxime Ripard 41016fe102
drm: Rename plane->state variables in atomic update and disable
Some drivers are storing the plane->state pointer in atomic_update and
atomic_disable in a variable simply called state, while the state passed
as an argument is called old_state.

In order to ease subsequent reworks and to avoid confusing or
inconsistent names, let's rename those variables to new_state.

This was done using the following coccinelle script, plus some manual
changes for mtk and tegra.

@ plane_atomic_func @
identifier helpers;
identifier func;
@@

(
 static const struct drm_plane_helper_funcs helpers = {
 	...,
 	.atomic_disable = func,
	...,
 };
|
 static const struct drm_plane_helper_funcs helpers = {
 	...,
 	.atomic_update = func,
	...,
 };
)

@ moves_new_state_old_state @
identifier plane_atomic_func.func;
identifier plane;
symbol old_state;
symbol state;
@@

 func(struct drm_plane *plane, struct drm_plane_state *old_state)
 {
 	...
-	struct drm_plane_state *state = plane->state;
+	struct drm_plane_state *new_state = plane->state;
	...
 }

@ depends on moves_new_state_old_state @
identifier plane_atomic_func.func;
identifier plane;
identifier old_state;
symbol state;
@@

 func(struct drm_plane *plane, struct drm_plane_state *old_state)
 {
 	<...
-	state
+	new_state
	...>
 }

@ moves_new_state_oldstate @
identifier plane_atomic_func.func;
identifier plane;
symbol oldstate;
symbol state;
@@

 func(struct drm_plane *plane, struct drm_plane_state *oldstate)
 {
 	...
-	struct drm_plane_state *state = plane->state;
+	struct drm_plane_state *newstate = plane->state;
	...
 }

@ depends on moves_new_state_oldstate @
identifier plane_atomic_func.func;
identifier plane;
identifier old_state;
symbol state;
@@

 func(struct drm_plane *plane, struct drm_plane_state *old_state)
 {
 	<...
-	state
+	newstate
	...>
 }

@ moves_new_state_old_pstate @
identifier plane_atomic_func.func;
identifier plane;
symbol old_pstate;
symbol state;
@@

 func(struct drm_plane *plane, struct drm_plane_state *old_pstate)
 {
 	...
-	struct drm_plane_state *state = plane->state;
+	struct drm_plane_state *new_pstate = plane->state;
	...
 }

@ depends on moves_new_state_old_pstate @
identifier plane_atomic_func.func;
identifier plane;
identifier old_pstate;
symbol state;
@@

 func(struct drm_plane *plane, struct drm_plane_state *old_pstate)
 {
 	<...
-	state
+	new_pstate
	...>
 }

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20210219120032.260676-8-maxime@cerno.tech
2021-02-24 20:27:12 +01:00
Maxime Ripard e05162c017
drm: Store new plane state in a variable for atomic_update and disable
In order to store the new plane state in a subsequent helper, let's move
the plane->state dereferences into a variable.

This was done using the following coccinelle script, plus some hand
changes for vmwgfx:

@ plane_atomic_func @
identifier helpers;
identifier func;
@@

(
 static const struct drm_plane_helper_funcs helpers = {
 	...,
 	.atomic_disable = func,
	...,
 };
|
 static const struct drm_plane_helper_funcs helpers = {
 	...,
 	.atomic_update = func,
	...,
 };
)

@ has_new_state_old_state @
identifier plane_atomic_func.func;
identifier plane;
identifier new_state;
symbol old_state;
@@

 func(struct drm_plane *plane, struct drm_plane_state *old_state)
 {
 	...
 	struct drm_plane_state *new_state = plane->state;
	...
 }

@ depends on !has_new_state_old_state @
identifier plane_atomic_func.func;
identifier plane;
symbol old_state;
@@

 func(struct drm_plane *plane, struct drm_plane_state *old_state)
 {
+	struct drm_plane_state *new_state = plane->state;
 	<+...
-	plane->state
+	new_state
	...+>
 }

@ has_new_state_state @
identifier plane_atomic_func.func;
identifier plane;
identifier new_state;
symbol state;
@@

 func(struct drm_plane *plane, struct drm_plane_state *state)
 {
 	...
 	struct drm_plane_state *new_state = plane->state;
	...
 }

@ depends on !has_new_state_state @
identifier plane_atomic_func.func;
identifier plane;
symbol state;
@@

 func(struct drm_plane *plane, struct drm_plane_state *state)
 {
+	struct drm_plane_state *new_plane_state = plane->state;
 	<+...
-	plane->state
+	new_plane_state
	...+>
 }

@ has_new_state_old_s @
identifier plane_atomic_func.func;
identifier plane;
identifier new_state;
symbol old_s;
@@

 func(struct drm_plane *plane, struct drm_plane_state *old_s)
 {
 	...
 	struct drm_plane_state *new_state = plane->state;
	...
 }

@ depends on !has_new_state_old_s @
identifier plane_atomic_func.func;
identifier plane;
symbol old_s;
@@

 func(struct drm_plane *plane, struct drm_plane_state *old_s)
 {
+	struct drm_plane_state *new_s = plane->state;
 	<+...
-	plane->state
+	new_s
	...+>
 }

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://lore.kernel.org/r/20210219120032.260676-1-maxime@cerno.tech
2021-02-24 20:27:09 +01:00
Maxime Ripard dec9202067
drm: Use the state pointer directly in planes atomic_check
Now that atomic_check takes the global atomic state as a parameter, we
don't need to go through the pointer in the plane state.

This was done using the following coccinelle script:

@ plane_atomic_func @
identifier helpers;
identifier func;
@@

static struct drm_plane_helper_funcs helpers = {
	...,
	.atomic_check = func,
	...,
};

@@
identifier plane_atomic_func.func;
identifier plane, state;
identifier plane_state;
@@

  func(struct drm_plane *plane, struct drm_atomic_state *state) {
  ...
- struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
  <... when != plane_state
- plane_state->state
+ state
  ...>
 }

@@
identifier plane_atomic_func.func;
identifier plane, state;
identifier plane_state;
@@

  func(struct drm_plane *plane, struct drm_atomic_state *state) {
  ...
  struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
  <...
- plane_state->state
+ state
  ...>
 }

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20210219120032.260676-5-maxime@cerno.tech
2021-02-24 20:27:03 +01:00
Maxime Ripard 7c11b99a8e
drm/atomic: Pass the full state to planes atomic_check
The current atomic helpers have either their object state being passed as
an argument or the full atomic state.

The former is the pattern that was done at first, before switching to the
latter for new hooks or when it was needed.

Let's convert all the remaining helpers to provide a consistent
interface, starting with the planes atomic_check.

The conversion was done using the coccinelle script below plus some
manual changes for vmwgfx, built tested on all the drivers.

@@
identifier plane, plane_state;
symbol state;
@@

 struct drm_plane_helper_funcs {
 	...
	int (*atomic_check)(struct drm_plane *plane,
-			    struct drm_plane_state *plane_state);
+			    struct drm_atomic_state *state);
	...
}

@ plane_atomic_func @
identifier helpers;
identifier func;
@@

static const struct drm_plane_helper_funcs helpers = {
	...,
 	.atomic_check = func,
	...,
};

@@
struct drm_plane_helper_funcs *FUNCS;
identifier f;
identifier dev;
identifier plane, plane_state, state;
@@

 f(struct drm_device *dev, struct drm_atomic_state *state)
 {
 	<+...
-	FUNCS->atomic_check(plane, plane_state)
+	FUNCS->atomic_check(plane, state)
 	...+>
 }

@ ignores_new_state @
identifier plane_atomic_func.func;
identifier plane, new_plane_state;
@@

 func(struct drm_plane *plane, struct drm_plane_state *new_plane_state)
 {
	... when != new_plane_state
 }

@ adds_new_state depends on plane_atomic_func && !ignores_new_state @
identifier plane_atomic_func.func;
identifier plane, new_plane_state;
@@

 func(struct drm_plane *plane, struct drm_plane_state *new_plane_state)
 {
+	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane);
 	...
 }

@ depends on plane_atomic_func @
identifier plane_atomic_func.func;
identifier plane, new_plane_state;
@@

 func(struct drm_plane *plane,
-     struct drm_plane_state *new_plane_state
+     struct drm_atomic_state *state
     )
 { ... }

@ include depends on adds_new_state @
@@

 #include <drm/drm_atomic.h>

@ no_include depends on !include && adds_new_state @
@@

+ #include <drm/drm_atomic.h>
  #include <drm/...>

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20210219120032.260676-4-maxime@cerno.tech
2021-02-24 20:27:00 +01:00
Maxime Ripard ba5c164946
drm: Rename plane atomic_check state names
Most drivers call the argument to the plane atomic_check hook simply
state, which is going to conflict with the global atomic state in a
later rework. Let's rename it to new_plane_state (or new_state depending
on the convention used in the driver).

This was done using the coccinelle script below, and built tested:

@ plane_atomic_func @
identifier helpers;
identifier func;
@@

 static const struct drm_plane_helper_funcs helpers = {
 	.atomic_check = func,
 };

@ has_old_state @
identifier plane_atomic_func.func;
identifier plane;
expression e;
symbol old_state;
symbol state;
@@

 func(struct drm_plane *plane, struct drm_plane_state *state)
 {
 	...
 	struct drm_plane_state *old_state = e;
 	...
 }

@ depends on has_old_state @
identifier plane_atomic_func.func;
identifier plane;
symbol old_state;
@@

 func(struct drm_plane *plane,
-	struct drm_plane_state *state
+	struct drm_plane_state *new_state
     )
 {
 	<+...
-	state
+	new_state
	...+>
 }

@ has_state @
identifier plane_atomic_func.func;
identifier plane;
symbol state;
@@

 func(struct drm_plane *plane, struct drm_plane_state *state)
 {
 	...
 }

@ depends on has_state @
identifier plane_atomic_func.func;
identifier plane;
symbol old_state;
@@

 func(struct drm_plane *plane,
-	struct drm_plane_state *state
+	struct drm_plane_state *new_plane_state
     )
 {
 	<+...
-	state
+	new_plane_state
	...+>
 }

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20210219120032.260676-2-maxime@cerno.tech
2021-02-24 20:26:55 +01:00
Daniel Vetter 250aa22920 drm/omapdrm: Annotate dma-fence critical section in commit path
Nothing special, just put the end right after hw_done(). Note that in
one path there's a wait for the flip/update to complete. But as far as
I understand from comments and code that's only relevant for modesets,
and skipped if there wasn't a modeset done on a given crtc.

For a bit more clarity pull the hw_done() call out of the if/else,
that way it's a bit clearer flow. But happy to shuffle this around as
is seen fit.

Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210121152959.1725404-9-daniel.vetter@ffwll.ch
2021-02-23 12:54:19 +01:00
Menglong Dong bbd13d6a7b drm/omap: dsi: fix unreachable code in dsi_vc_send_short()
The 'r' in dsi_vc_send_short() is of type 'unsigned int', so the
'r < 0' can't be true.

Fix this by introducing a 'err' of type 'int' insteaded.

Fixes: 1ed6253856 ("drm/omap: dsi: switch dsi_vc_send_long/short to mipi_dsi_msg")

Signed-off-by: Menglong Dong <dong.menglong@zte.com.cn>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210127015117.23267-1-dong.menglong@zte.com.cn
2021-01-27 16:21:36 +02:00
Zheng Yongjun 010dbfbe7b drm/omap: Delete useless kfree code
The parameter of kfree function is NULL, so kfree code is useless, delete it.

Signed-off-by: Zheng Yongjun <zhengyongjun3@huawei.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201214134628.4937-1-zhengyongjun3@huawei.com
2020-12-15 17:19:54 +02:00
Tomi Valkeinen dfd2edccfd drm/omap: dsi: allow DSI commands to be sent early
Panel drivers can send DSI commands in panel's prepare(), which happens
before the bridge's enable() is called. The OMAP DSI driver currently
only sets up the DSI interface at bridge's enable(), so prepare() cannot
be used to send DSI commands.

This patch fixes the issue by making it possible to enable the DSI
interface any time a command is about to be sent. Disabling the
interface is be done via delayed work.

Clarifications for the delayed disable work and the panel doing DSI
transactions:

bridge_enable: If the disable callback is called just before
bridge_enable takes the dsi_bus_lock, no problem, bridge_enable just
enables the interface again. If the callback is ran just after
bridge_enable's dsi_bus_unlock, no problem, dsi->video_enabled == true
so the callback does nothing.

bridge_disable: similar to bridge-enable, the callback won't do anything
if video_enabled == true, and after bridge-disable has turned the video
and the interface off, there's nothing to do for the callback.

omap_dsi_host_detach: this is called when the panel does
mipi_dsi_detach(), and we expect the panel to _not_ do any DSI
transactions after (or during) mipi_dsi_detatch(), so there are no
race conditions.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-85-tomi.valkeinen@ti.com
2020-12-15 16:17:32 +02:00
Tomi Valkeinen 92bb0eabc8 drm/omap: dsi: fix DCS_CMD_ENABLE
We only need to set VC_CTRL:DCS_CMD_ENABLE for command mode panels when
the HW has DSI_QUIRK_DCS_CMD_CONFIG_VC quirk. The old code did this
right by accident, but now we set DCS_CMD_ENABLE for video mode panels
too.

Fix this by skipping the set for video mode.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-84-tomi.valkeinen@ti.com
2020-12-15 16:17:32 +02:00
Tomi Valkeinen c832078944 drm/omap: dsi: remove ulps support
ULPS is a niche power-saving feature which only really affects command
mode panels showing a static picture. I know the ULPS code used to work
very long time ago, but I could not get it working with the current
driver. As the ULPS code is not trivial and includes delayed work (so
lots of chances for race issues), and just keeping DSI video and command
mode panels working has been challenging enough even without ULPS, lets
remove ULPS support.

When the DSI driver works reliably for command and video mode displays,
someone interested can work on ULPS and add it back if the power saving
is substantial enough.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-83-tomi.valkeinen@ti.com
2020-12-15 16:17:32 +02:00
Tomi Valkeinen 9a521118cb drm/omap: dsi: fix and cleanup ddr_clk_always_on
The driver ignores MIPI_DSI_CLOCK_NON_CONTINUOUS, and always uses
non-continuous clock.

Fix this by using MIPI_DSI_CLOCK_NON_CONTINUOUS and at the same time,
drop ddr_clk_always_on field which seems pretty useless.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-82-tomi.valkeinen@ti.com
2020-12-15 16:17:32 +02:00
Tomi Valkeinen b6c1048cc7 drm/omap: dsi: split video mode enable/disable into separate func
Clean up the code by separating video-mode enable/disable code into
functions of their own.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-81-tomi.valkeinen@ti.com
2020-12-15 16:17:32 +02:00
Tomi Valkeinen 7b93de9899 drm/omap: dsi: cleanup initial vc setup
As we now have a fixed setup for VCs (VC0 for video stream, VC1 for
commands), we can simplify the VC setup.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-80-tomi.valkeinen@ti.com
2020-12-15 16:17:32 +02:00
Tomi Valkeinen a4a29d1d34 drm/omap: dsi: rename dsi_display_* functions
The function names have evolved to be very confusing, and bunch of them
have "display" in them even if the function doesn't deal with display as
such (e.g. dsi_display_enable which just enables the DSI interface).
Rename them by dropping the "display".

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-79-tomi.valkeinen@ti.com
2020-12-15 16:17:32 +02:00
Tomi Valkeinen ead05b53a9 drm/omap: dsi: display_disable cleanup
We can drop dsi_display_disable() which just calls
_dsi_display_disable(), and rename _dsi_display_disable() to
dsi_display_disable().

The WARN_ON(!dsi_bus_is_locked(dsi)) in dsi_display_disable is extra and
can be dropped, as _dsi_display_disable() has the same WARN_ON().

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-78-tomi.valkeinen@ti.com
2020-12-15 16:17:32 +02:00
Tomi Valkeinen 1f05605379 drm/omap: dsi: display_enable cleanup
We can drop dsi_display_enable(), which just calls
_dsi_display_enable(), and rename _dsi_display_enable() to
dsi_display_enable().

The WARN_ON(!dsi_bus_is_locked(dsi)) in dsi_display_enable is extra and
can be dropped, as _dsi_display_enable() has the same WARN_ON().

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-77-tomi.valkeinen@ti.com
2020-12-15 16:17:32 +02:00
Tomi Valkeinen 5d676b6f27 drm/omap: dsi: move enable/disable to bridge enable/disable
Clean up the code by inlining dsi_enable_video_outputs and
dsi_disable_video_outputs functions.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-76-tomi.valkeinen@ti.com
2020-12-15 16:17:31 +02:00
Tomi Valkeinen 7aa5234623 drm/omap: dsi: move structs & defines to dsi.h
Move structs and defines to a private dsi.h header file to make dsi.c a
bit easier to navigate. Also move the (now) private structs and defines
from omapdss.h to dsi.h.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-75-tomi.valkeinen@ti.com
2020-12-15 16:17:31 +02:00
Tomi Valkeinen 4029b16b13 drm/omap: dsi: use separate VCs for cmd and video
For command mode panels we can use a single VC for sending command and
video data, even if we have to change the data source for that VC when
going from command to video or vice versa.

However, with video mode panels we want to keep the pixel data VC
enabled, and use another VC for command data, and the commands will get
interleaved into the pixel data.

This patch makes the driver use VC0 for commands and VC1 for video.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-71-tomi.valkeinen@ti.com
2020-12-15 16:17:31 +02:00
Tomi Valkeinen eb40e2f448 drm/omap: dsi: enable HS before sending the frame
We currently use a single VC for sending commands and pixel data. The
LP/HS mode for pixel data is correctly set to HS by accident, as we have
set the VC to HS already earlier.

However, if we use a different VC for video data, the VC is in LP mode.
Fix this by always enabling HS mode before starting a frame update.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-70-tomi.valkeinen@ti.com
2020-12-15 16:17:31 +02:00
Tomi Valkeinen 83d74642b0 drm/omap: dsi: skip dsi_vc_enable_hs when already in correct mode
Simplify and optimize dsi_vc_enable_hs() so that it can be called
without checking the current HS/LP mode. Make dsi_vc_enable_hs() return
if the VC is already in the correct mode.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-69-tomi.valkeinen@ti.com
2020-12-15 16:17:31 +02:00
Tomi Valkeinen d58eb31f50 drm/omap: dsi: untangle vc & channel
DSI virtual channel and hardware VC blocks have gotten tangled as
described in the previous commits. This has not caused any issues, as
the value for both is 0, so it happens to work.

To fix the issue, change the code to use the correct one of the two.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-68-tomi.valkeinen@ti.com
2020-12-15 16:17:31 +02:00
Tomi Valkeinen 5e43075429 drm/omap: dsi: pass vc and channel to various functions
To start fixing the issues related to channels and vcs described in the
previous commit, pass vc and/or channel to various functions which will
need it do properly handle different DSI channels and VCs.

No functional changes.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-67-tomi.valkeinen@ti.com
2020-12-15 16:17:31 +02:00
Tomi Valkeinen d81711458e drm/omap: dsi: rename 'channel' to 'vc'
The "channel" usage in omap dsi driver is confusing. We have three
different "channels":

1) DSI virtual channel ID. This is a number from 0 to 3, included in the
packet payload.

2) VC. This is a register block in the DSI IP. There are four of those
blocks. A VC is a DSI "pipeline", with defined fifo settings, data
source (cpu or dispc), and some other settings. It has no relation to
the 1).

3) dispc channel. It's the "pipeline" number dispc uses to send pixel
data.

The previous patch handled the third case.

 To start fixing 1) and 2), we first rename all uses of 'channel' to
'vc', as in most of the cases that is the correct thing to use.

However, in some places 1) and 2) have gotten mixed up (i.e. the code
uses msg->channel when it should use vc), which will be fixed in the
following patch.

Note that mixing 1) and 2) currently is "fine", as at the moment we only
support DSI peripherals with DSI virtual channel 0, and we always use
VC0 to send data. So both 1) and 2) are always 0.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-66-tomi.valkeinen@ti.com
2020-12-15 16:17:31 +02:00
Tomi Valkeinen f408600f06 drm/omap: dsi: cleanup dispc channel usage
The "channel" usage in omap dsi driver is confusing. As the first step,
change "channel" to "dispc_channel" when dealing with the dispc channel.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-65-tomi.valkeinen@ti.com
2020-12-15 16:17:30 +02:00
Tomi Valkeinen 442cbc86b9 drm/omap: dsi: drop useless channel checks
A DSI peripheral can have virtual channel ID of 0-3. This should be
always the case, and there's no need in the driver to validate the
channel.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-64-tomi.valkeinen@ti.com
2020-12-15 16:17:30 +02:00
Tomi Valkeinen d843314e48 drm/omap: dsi: simplify VC handling
The VC handling has gotten quite tangled up. As the first step to clean
it up, lets define that we only support a single DSI peripheral (which
was really already the case), and we always use VC0 (define VC_DEFAULT
0) register block to send data to the peripheral.

We can thus have a single mipi_dsi_device pointer and remove the
for-loops which made passes over all the four VCs (just the first one
was ever used).

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-63-tomi.valkeinen@ti.com
2020-12-15 16:17:30 +02:00
Tomi Valkeinen 8350ac8e11 drm/omap: dsi: send nop instead of page & column
The OMAP DSI command mode panel driver used to send page & column
address before each frame update, and this code was moved into the DSI
host driver when converting it to the DRM bridge model.

However, it's not really required to send the page & column address
before each frame. It's also something that doesn't really belong to the
DSI host driver, so we should drop the code.

That said, frame updates break if we don't send _something_ between the
frames. A NOP command does the trick.

It is not clear if this behavior is as expected from a DSI command mode
frame transfer, or is it a feature/issue with OMAP DSI driver, or a
feature/issue in the command mode panel used.

Most likely this is related to the following from the DSI spec:

"To enable PHY synchronization the host processor should periodically
end HS transmission and drive the Data Lanes to the LP state. This
transition should take place at least once per frame."

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-62-tomi.valkeinen@ti.com
2020-12-15 16:17:30 +02:00
Tomi Valkeinen 443dae0958 drm/omap: dsi: set trans_mode according to client mode_flags
The DSI host driver currently ignores the video mode flags in
client->mode_flags. Add the code to take the transfer mode from client's
mode_flags.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-60-tomi.valkeinen@ti.com
2020-12-15 16:17:30 +02:00
Tomi Valkeinen 4119bd55e4 drm/omap: pll: fix iteration loop check
If the PLL calc function is given bad parameters, n_start/m_start may be
higher than n_stop/m_stop, which leads to the loops iterating through
the whole u32 number space.

Fix this by failing early on such cases.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-59-tomi.valkeinen@ti.com
2020-12-15 16:17:30 +02:00
Tomi Valkeinen 05ec612893 drm/omap: remove dss_mgr_ops
dss_mgr_ops was needed with the multi-module architecture, but is no
longer needed. We can thus remove it and use direct calls.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-55-tomi.valkeinen@ti.com
2020-12-15 16:17:30 +02:00
Tomi Valkeinen dac62bcafe drm/omap: remove dispc_ops
dispc_ops was created to help with the multi-module architecture and
giving us the possibility of multiple dispc implementations. Neither of
these is valid anymore, and we can remove dispc_ops and use direct
calls to dispc.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-54-tomi.valkeinen@ti.com
2020-12-15 16:15:06 +02:00
Tomi Valkeinen 96f4418505 drm/omap: drop unused owner field
dssdev->owner is set, but never used. We can drop the field.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-53-tomi.valkeinen@ti.com
2020-12-15 16:08:27 +02:00
Tomi Valkeinen 3201509a15 drm/omap: remove unused display.c
The functions in display.c are not used, so drop the file.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-52-tomi.valkeinen@ti.com
2020-12-15 16:08:27 +02:00
Tomi Valkeinen 55b68fb856 drm/omap: squash omapdrm sub-modules into one
At the moment we have three different modules: omapdss-base, omapdss,
omapdrm. This setup is finally obsolete, as the last omapdrm specific
panel has been converted to DRM panel.

We can thus remove omapdss-base and omapdss, and just compile everything
into omapdrm.ko.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-51-tomi.valkeinen@ti.com
2020-12-15 16:08:27 +02:00
Sebastian Reichel 578739e86f drm/omap: dsi: simplify pin config
Simplify DSI pin config, which always originates from DT
nowadays. With the code being fully contained in the DSI
encoder, we can drop the public structure.

Since the function is no longer exposed, it now directly
takes the private DSI data pointer. This drops a pointless
conversion and means the pins can be configured earlier.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-49-tomi.valkeinen@ti.com
2020-12-15 16:08:27 +02:00
Sebastian Reichel 94d7332979 drm/omap: simplify DSI manual update code
Move dsi_ops into the main structure, since all other ops
are gone. Instead of checking the device type we can simply
check if dsi_ops are set.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-48-tomi.valkeinen@ti.com
2020-12-15 16:08:26 +02:00