... | ... | ||
---|---|---|---|
16 | 16 | ||
17 | Tomi | 17 | Tomi |
18 | 18 | ||
19 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> | 19 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> |
20 | --- | 20 | --- |
21 | Changes in v2: | ||
22 | - Change the tidss clock adjustment from mode_fixup() to atomic_check() | ||
23 | - Link to v1: https://lore.kernel.org/r/20250320-cdns-dsi-impro-v1-0-725277c5f43b@ideasonboard.com | ||
24 | |||
25 | --- | ||
21 | Tomi Valkeinen (18): | 26 | Tomi Valkeinen (18): |
22 | drm/tidss: Fix missing includes and struct decls | 27 | drm/tidss: Fix missing includes and struct decls |
23 | drm/tidss: Use the crtc_* timings when programming the HW | 28 | drm/tidss: Use the crtc_* timings when programming the HW |
24 | drm/tidss: Add mode_fixup to adjust the clock based on HW | 29 | drm/tidss: Adjust the pclk based on the HW capabilities |
25 | phy: cdns-dphy: Store hs_clk_rate and return it | 30 | phy: cdns-dphy: Store hs_clk_rate and return it |
26 | phy: cdns-dphy: Remove leftover code | 31 | phy: cdns-dphy: Remove leftover code |
27 | drm/bridge: cdns-dsi: Adjust mode to negative syncs | 32 | drm/bridge: cdns-dsi: Adjust mode to negative syncs |
28 | drm/bridge: cdns-dsi: Fail if HS rate changed when validating PHY config | 33 | drm/bridge: cdns-dsi: Fail if HS rate changed when validating PHY config |
29 | drm/bridge: cdns-dsi: Clean up cdns_dsi_mode2cfg() | 34 | drm/bridge: cdns-dsi: Clean up cdns_dsi_mode2cfg() |
... | ... | ||
37 | drm/bridge: cdns-dsi: Update htotal in cdns_dsi_mode2cfg() | 42 | drm/bridge: cdns-dsi: Update htotal in cdns_dsi_mode2cfg() |
38 | drm/bridge: cdns-dsi: Drop cdns_dsi_adjust_phy_config() | 43 | drm/bridge: cdns-dsi: Drop cdns_dsi_adjust_phy_config() |
39 | drm/bridge: cdns-dsi: Don't fail on MIPI_DSI_MODE_VIDEO_BURST | 44 | drm/bridge: cdns-dsi: Don't fail on MIPI_DSI_MODE_VIDEO_BURST |
40 | 45 | ||
41 | drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 224 +++++++++++-------------- | 46 | drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 224 +++++++++++-------------- |
42 | drivers/gpu/drm/tidss/tidss_crtc.c | 24 ++- | 47 | drivers/gpu/drm/tidss/tidss_crtc.c | 25 ++- |
43 | drivers/gpu/drm/tidss/tidss_dispc.c | 22 ++- | 48 | drivers/gpu/drm/tidss/tidss_dispc.c | 22 ++- |
44 | drivers/gpu/drm/tidss/tidss_dispc.h | 5 + | 49 | drivers/gpu/drm/tidss/tidss_dispc.h | 5 + |
45 | drivers/gpu/drm/tidss/tidss_drv.h | 2 + | 50 | drivers/gpu/drm/tidss/tidss_drv.h | 2 + |
46 | drivers/gpu/drm/tidss/tidss_plane.h | 2 + | 51 | drivers/gpu/drm/tidss/tidss_plane.h | 2 + |
47 | drivers/gpu/drm/tidss/tidss_scale_coefs.h | 2 + | 52 | drivers/gpu/drm/tidss/tidss_scale_coefs.h | 2 + |
48 | drivers/phy/cadence/cdns-dphy.c | 24 +-- | 53 | drivers/phy/cadence/cdns-dphy.c | 24 +-- |
49 | 8 files changed, 158 insertions(+), 147 deletions(-) | 54 | 8 files changed, 155 insertions(+), 151 deletions(-) |
50 | --- | 55 | --- |
51 | base-commit: 10646ddac2917b31c985ceff0e4982c42a9c924b | 56 | base-commit: 10646ddac2917b31c985ceff0e4982c42a9c924b |
52 | change-id: 20250320-cdns-dsi-impro-3d8fbd7848d1 | 57 | change-id: 20250320-cdns-dsi-impro-3d8fbd7848d1 |
53 | prerequisite-message-id: 20250226155228.564289-1-aradhya.bhatia@linux.dev | 58 | prerequisite-message-id: 20250226155228.564289-1-aradhya.bhatia@linux.dev |
54 | prerequisite-patch-id: 46845a8d15042dd343a29a17fc0b9d0eec2605f5 | 59 | prerequisite-patch-id: 46845a8d15042dd343a29a17fc0b9d0eec2605f5 |
... | ... | diff view generated by jsdifflib |
1 | Fix missing includes and struct declarations. Even if these don't cause | 1 | Fix missing includes and struct declarations. Even if these don't cause |
---|---|---|---|
2 | any compile issues at the moment, it's good to have them correct. | 2 | any compile issues at the moment, it's good to have them correct. |
3 | 3 | ||
4 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> | 4 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> |
5 | --- | 5 | --- |
6 | drivers/gpu/drm/tidss/tidss_dispc.h | 3 +++ | 6 | drivers/gpu/drm/tidss/tidss_dispc.h | 3 +++ |
7 | drivers/gpu/drm/tidss/tidss_drv.h | 2 ++ | 7 | drivers/gpu/drm/tidss/tidss_drv.h | 2 ++ |
8 | drivers/gpu/drm/tidss/tidss_plane.h | 2 ++ | 8 | drivers/gpu/drm/tidss/tidss_plane.h | 2 ++ |
9 | drivers/gpu/drm/tidss/tidss_scale_coefs.h | 2 ++ | 9 | drivers/gpu/drm/tidss/tidss_scale_coefs.h | 2 ++ |
10 | 4 files changed, 9 insertions(+) | 10 | 4 files changed, 9 insertions(+) |
11 | 11 | ||
12 | diff --git a/drivers/gpu/drm/tidss/tidss_dispc.h b/drivers/gpu/drm/tidss/tidss_dispc.h | 12 | diff --git a/drivers/gpu/drm/tidss/tidss_dispc.h b/drivers/gpu/drm/tidss/tidss_dispc.h |
13 | index XXXXXXX..XXXXXXX 100644 | 13 | index XXXXXXX..XXXXXXX 100644 |
14 | --- a/drivers/gpu/drm/tidss/tidss_dispc.h | 14 | --- a/drivers/gpu/drm/tidss/tidss_dispc.h |
15 | +++ b/drivers/gpu/drm/tidss/tidss_dispc.h | 15 | +++ b/drivers/gpu/drm/tidss/tidss_dispc.h |
16 | @@ -XXX,XX +XXX,XX @@ | 16 | @@ -XXX,XX +XXX,XX @@ |
17 | #ifndef __TIDSS_DISPC_H__ | 17 | #ifndef __TIDSS_DISPC_H__ |
18 | #define __TIDSS_DISPC_H__ | 18 | #define __TIDSS_DISPC_H__ |
19 | 19 | ||
20 | +#include <drm/drm_color_mgmt.h> | 20 | +#include <drm/drm_color_mgmt.h> |
21 | + | 21 | + |
22 | #include "tidss_drv.h" | 22 | #include "tidss_drv.h" |
23 | 23 | ||
24 | struct dispc_device; | 24 | struct dispc_device; |
25 | 25 | ||
26 | struct drm_crtc_state; | 26 | struct drm_crtc_state; |
27 | +struct drm_plane_state; | 27 | +struct drm_plane_state; |
28 | 28 | ||
29 | enum tidss_gamma_type { TIDSS_GAMMA_8BIT, TIDSS_GAMMA_10BIT }; | 29 | enum tidss_gamma_type { TIDSS_GAMMA_8BIT, TIDSS_GAMMA_10BIT }; |
30 | 30 | ||
31 | diff --git a/drivers/gpu/drm/tidss/tidss_drv.h b/drivers/gpu/drm/tidss/tidss_drv.h | 31 | diff --git a/drivers/gpu/drm/tidss/tidss_drv.h b/drivers/gpu/drm/tidss/tidss_drv.h |
32 | index XXXXXXX..XXXXXXX 100644 | 32 | index XXXXXXX..XXXXXXX 100644 |
33 | --- a/drivers/gpu/drm/tidss/tidss_drv.h | 33 | --- a/drivers/gpu/drm/tidss/tidss_drv.h |
34 | +++ b/drivers/gpu/drm/tidss/tidss_drv.h | 34 | +++ b/drivers/gpu/drm/tidss/tidss_drv.h |
35 | @@ -XXX,XX +XXX,XX @@ | 35 | @@ -XXX,XX +XXX,XX @@ |
36 | 36 | ||
37 | #include <linux/spinlock.h> | 37 | #include <linux/spinlock.h> |
38 | 38 | ||
39 | +#include <drm/drm_device.h> | 39 | +#include <drm/drm_device.h> |
40 | + | 40 | + |
41 | #define TIDSS_MAX_PORTS 4 | 41 | #define TIDSS_MAX_PORTS 4 |
42 | #define TIDSS_MAX_PLANES 4 | 42 | #define TIDSS_MAX_PLANES 4 |
43 | 43 | ||
44 | diff --git a/drivers/gpu/drm/tidss/tidss_plane.h b/drivers/gpu/drm/tidss/tidss_plane.h | 44 | diff --git a/drivers/gpu/drm/tidss/tidss_plane.h b/drivers/gpu/drm/tidss/tidss_plane.h |
45 | index XXXXXXX..XXXXXXX 100644 | 45 | index XXXXXXX..XXXXXXX 100644 |
46 | --- a/drivers/gpu/drm/tidss/tidss_plane.h | 46 | --- a/drivers/gpu/drm/tidss/tidss_plane.h |
47 | +++ b/drivers/gpu/drm/tidss/tidss_plane.h | 47 | +++ b/drivers/gpu/drm/tidss/tidss_plane.h |
48 | @@ -XXX,XX +XXX,XX @@ | 48 | @@ -XXX,XX +XXX,XX @@ |
49 | #ifndef __TIDSS_PLANE_H__ | 49 | #ifndef __TIDSS_PLANE_H__ |
50 | #define __TIDSS_PLANE_H__ | 50 | #define __TIDSS_PLANE_H__ |
51 | 51 | ||
52 | +#include <drm/drm_plane.h> | 52 | +#include <drm/drm_plane.h> |
53 | + | 53 | + |
54 | #define to_tidss_plane(p) container_of((p), struct tidss_plane, plane) | 54 | #define to_tidss_plane(p) container_of((p), struct tidss_plane, plane) |
55 | 55 | ||
56 | struct tidss_device; | 56 | struct tidss_device; |
57 | diff --git a/drivers/gpu/drm/tidss/tidss_scale_coefs.h b/drivers/gpu/drm/tidss/tidss_scale_coefs.h | 57 | diff --git a/drivers/gpu/drm/tidss/tidss_scale_coefs.h b/drivers/gpu/drm/tidss/tidss_scale_coefs.h |
58 | index XXXXXXX..XXXXXXX 100644 | 58 | index XXXXXXX..XXXXXXX 100644 |
59 | --- a/drivers/gpu/drm/tidss/tidss_scale_coefs.h | 59 | --- a/drivers/gpu/drm/tidss/tidss_scale_coefs.h |
60 | +++ b/drivers/gpu/drm/tidss/tidss_scale_coefs.h | 60 | +++ b/drivers/gpu/drm/tidss/tidss_scale_coefs.h |
61 | @@ -XXX,XX +XXX,XX @@ | 61 | @@ -XXX,XX +XXX,XX @@ |
62 | 62 | ||
63 | #include <linux/types.h> | 63 | #include <linux/types.h> |
64 | 64 | ||
65 | +struct device; | 65 | +struct device; |
66 | + | 66 | + |
67 | struct tidss_scale_coefs { | 67 | struct tidss_scale_coefs { |
68 | s16 c2[16]; | 68 | s16 c2[16]; |
69 | s16 c1[16]; | 69 | s16 c1[16]; |
70 | 70 | ||
71 | -- | 71 | -- |
72 | 2.43.0 | 72 | 2.43.0 | diff view generated by jsdifflib |
1 | Use the crtc_* fields from drm_display_mode, instead of the "logical" | 1 | Use the crtc_* fields from drm_display_mode, instead of the "logical" |
---|---|---|---|
2 | fields. This shouldn't change anything in practice, but afaiu the crtc_* | 2 | fields. This shouldn't change anything in practice, but afaiu the crtc_* |
3 | fields are the correct ones to use here. | 3 | fields are the correct ones to use here. |
4 | 4 | ||
5 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> | 5 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> |
6 | --- | 6 | --- |
7 | drivers/gpu/drm/tidss/tidss_crtc.c | 2 +- | 7 | drivers/gpu/drm/tidss/tidss_crtc.c | 2 +- |
8 | drivers/gpu/drm/tidss/tidss_dispc.c | 16 ++++++++-------- | 8 | drivers/gpu/drm/tidss/tidss_dispc.c | 16 ++++++++-------- |
9 | 2 files changed, 9 insertions(+), 9 deletions(-) | 9 | 2 files changed, 9 insertions(+), 9 deletions(-) |
10 | 10 | ||
11 | diff --git a/drivers/gpu/drm/tidss/tidss_crtc.c b/drivers/gpu/drm/tidss/tidss_crtc.c | 11 | diff --git a/drivers/gpu/drm/tidss/tidss_crtc.c b/drivers/gpu/drm/tidss/tidss_crtc.c |
12 | index XXXXXXX..XXXXXXX 100644 | 12 | index XXXXXXX..XXXXXXX 100644 |
13 | --- a/drivers/gpu/drm/tidss/tidss_crtc.c | 13 | --- a/drivers/gpu/drm/tidss/tidss_crtc.c |
14 | +++ b/drivers/gpu/drm/tidss/tidss_crtc.c | 14 | +++ b/drivers/gpu/drm/tidss/tidss_crtc.c |
15 | @@ -XXX,XX +XXX,XX @@ static void tidss_crtc_atomic_enable(struct drm_crtc *crtc, | 15 | @@ -XXX,XX +XXX,XX @@ static void tidss_crtc_atomic_enable(struct drm_crtc *crtc, |
16 | tidss_runtime_get(tidss); | 16 | tidss_runtime_get(tidss); |
17 | 17 | ||
18 | r = dispc_vp_set_clk_rate(tidss->dispc, tcrtc->hw_videoport, | 18 | r = dispc_vp_set_clk_rate(tidss->dispc, tcrtc->hw_videoport, |
19 | - mode->clock * 1000); | 19 | - mode->clock * 1000); |
20 | + mode->crtc_clock * 1000); | 20 | + mode->crtc_clock * 1000); |
21 | if (r != 0) | 21 | if (r != 0) |
22 | return; | 22 | return; |
23 | 23 | ||
24 | diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c | 24 | diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c |
25 | index XXXXXXX..XXXXXXX 100644 | 25 | index XXXXXXX..XXXXXXX 100644 |
26 | --- a/drivers/gpu/drm/tidss/tidss_dispc.c | 26 | --- a/drivers/gpu/drm/tidss/tidss_dispc.c |
27 | +++ b/drivers/gpu/drm/tidss/tidss_dispc.c | 27 | +++ b/drivers/gpu/drm/tidss/tidss_dispc.c |
28 | @@ -XXX,XX +XXX,XX @@ void dispc_vp_enable(struct dispc_device *dispc, u32 hw_videoport, | 28 | @@ -XXX,XX +XXX,XX @@ void dispc_vp_enable(struct dispc_device *dispc, u32 hw_videoport, |
29 | 29 | ||
30 | dispc_set_num_datalines(dispc, hw_videoport, fmt->data_width); | 30 | dispc_set_num_datalines(dispc, hw_videoport, fmt->data_width); |
31 | 31 | ||
32 | - hfp = mode->hsync_start - mode->hdisplay; | 32 | - hfp = mode->hsync_start - mode->hdisplay; |
33 | - hsw = mode->hsync_end - mode->hsync_start; | 33 | - hsw = mode->hsync_end - mode->hsync_start; |
34 | - hbp = mode->htotal - mode->hsync_end; | 34 | - hbp = mode->htotal - mode->hsync_end; |
35 | + hfp = mode->crtc_hsync_start - mode->crtc_hdisplay; | 35 | + hfp = mode->crtc_hsync_start - mode->crtc_hdisplay; |
36 | + hsw = mode->crtc_hsync_end - mode->crtc_hsync_start; | 36 | + hsw = mode->crtc_hsync_end - mode->crtc_hsync_start; |
37 | + hbp = mode->crtc_htotal - mode->crtc_hsync_end; | 37 | + hbp = mode->crtc_htotal - mode->crtc_hsync_end; |
38 | 38 | ||
39 | - vfp = mode->vsync_start - mode->vdisplay; | 39 | - vfp = mode->vsync_start - mode->vdisplay; |
40 | - vsw = mode->vsync_end - mode->vsync_start; | 40 | - vsw = mode->vsync_end - mode->vsync_start; |
41 | - vbp = mode->vtotal - mode->vsync_end; | 41 | - vbp = mode->vtotal - mode->vsync_end; |
42 | + vfp = mode->crtc_vsync_start - mode->crtc_vdisplay; | 42 | + vfp = mode->crtc_vsync_start - mode->crtc_vdisplay; |
43 | + vsw = mode->crtc_vsync_end - mode->crtc_vsync_start; | 43 | + vsw = mode->crtc_vsync_end - mode->crtc_vsync_start; |
44 | + vbp = mode->crtc_vtotal - mode->crtc_vsync_end; | 44 | + vbp = mode->crtc_vtotal - mode->crtc_vsync_end; |
45 | 45 | ||
46 | dispc_vp_write(dispc, hw_videoport, DISPC_VP_TIMING_H, | 46 | dispc_vp_write(dispc, hw_videoport, DISPC_VP_TIMING_H, |
47 | FLD_VAL(hsw - 1, 7, 0) | | 47 | FLD_VAL(hsw - 1, 7, 0) | |
48 | @@ -XXX,XX +XXX,XX @@ void dispc_vp_enable(struct dispc_device *dispc, u32 hw_videoport, | 48 | @@ -XXX,XX +XXX,XX @@ void dispc_vp_enable(struct dispc_device *dispc, u32 hw_videoport, |
49 | FLD_VAL(ivs, 12, 12)); | 49 | FLD_VAL(ivs, 12, 12)); |
50 | 50 | ||
51 | dispc_vp_write(dispc, hw_videoport, DISPC_VP_SIZE_SCREEN, | 51 | dispc_vp_write(dispc, hw_videoport, DISPC_VP_SIZE_SCREEN, |
52 | - FLD_VAL(mode->hdisplay - 1, 11, 0) | | 52 | - FLD_VAL(mode->hdisplay - 1, 11, 0) | |
53 | - FLD_VAL(mode->vdisplay - 1, 27, 16)); | 53 | - FLD_VAL(mode->vdisplay - 1, 27, 16)); |
54 | + FLD_VAL(mode->crtc_hdisplay - 1, 11, 0) | | 54 | + FLD_VAL(mode->crtc_hdisplay - 1, 11, 0) | |
55 | + FLD_VAL(mode->crtc_vdisplay - 1, 27, 16)); | 55 | + FLD_VAL(mode->crtc_vdisplay - 1, 27, 16)); |
56 | 56 | ||
57 | VP_REG_FLD_MOD(dispc, hw_videoport, DISPC_VP_CONTROL, 1, 0, 0); | 57 | VP_REG_FLD_MOD(dispc, hw_videoport, DISPC_VP_CONTROL, 1, 0, 0); |
58 | } | 58 | } |
59 | 59 | ||
60 | -- | 60 | -- |
61 | 2.43.0 | 61 | 2.43.0 | diff view generated by jsdifflib |
1 | At the moment the driver just sets the clock rate with clk_set_rate(), | 1 | At the moment the driver just sets the clock rate with clk_set_rate(), |
---|---|---|---|
2 | and if the resulting rate is not the same as requested, prints a debug | 2 | and if the resulting rate is not the same as requested, prints a debug |
3 | print, but nothing else. | 3 | print, but nothing else. |
4 | 4 | ||
5 | Add mode_fixup(), in which the clk_round_rate() is used to get the | 5 | Add functionality to atomic_check(), in which the clk_round_rate() is |
6 | "rounded" rate, and set that to the adjusted_mode. | 6 | used to get the "rounded" rate, and set that to the adjusted_mode. |
7 | 7 | ||
8 | In practice, with the current K3 SoCs, the display PLL is capable of | 8 | In practice, with the current K3 SoCs, the display PLL is capable of |
9 | producing very exact clocks, so most likely the rounded rate is the same | 9 | producing very exact clocks, so most likely the rounded rate is the same |
10 | as the original one. | 10 | as the original one. |
11 | 11 | ||
12 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> | 12 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> |
13 | --- | 13 | --- |
14 | drivers/gpu/drm/tidss/tidss_crtc.c | 22 ++++++++++++++++++++++ | 14 | drivers/gpu/drm/tidss/tidss_crtc.c | 23 +++++++++++++++++++---- |
15 | drivers/gpu/drm/tidss/tidss_dispc.c | 6 ++++++ | 15 | drivers/gpu/drm/tidss/tidss_dispc.c | 6 ++++++ |
16 | drivers/gpu/drm/tidss/tidss_dispc.h | 2 ++ | 16 | drivers/gpu/drm/tidss/tidss_dispc.h | 2 ++ |
17 | 3 files changed, 30 insertions(+) | 17 | 3 files changed, 27 insertions(+), 4 deletions(-) |
18 | 18 | ||
19 | diff --git a/drivers/gpu/drm/tidss/tidss_crtc.c b/drivers/gpu/drm/tidss/tidss_crtc.c | 19 | diff --git a/drivers/gpu/drm/tidss/tidss_crtc.c b/drivers/gpu/drm/tidss/tidss_crtc.c |
20 | index XXXXXXX..XXXXXXX 100644 | 20 | index XXXXXXX..XXXXXXX 100644 |
21 | --- a/drivers/gpu/drm/tidss/tidss_crtc.c | 21 | --- a/drivers/gpu/drm/tidss/tidss_crtc.c |
22 | +++ b/drivers/gpu/drm/tidss/tidss_crtc.c | 22 | +++ b/drivers/gpu/drm/tidss/tidss_crtc.c |
23 | @@ -XXX,XX +XXX,XX @@ enum drm_mode_status tidss_crtc_mode_valid(struct drm_crtc *crtc, | 23 | @@ -XXX,XX +XXX,XX @@ static int tidss_crtc_atomic_check(struct drm_crtc *crtc, |
24 | return dispc_vp_mode_valid(tidss->dispc, tcrtc->hw_videoport, mode); | 24 | struct dispc_device *dispc = tidss->dispc; |
25 | } | 25 | struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); |
26 | 26 | u32 hw_videoport = tcrtc->hw_videoport; | |
27 | +static bool tidss_crtc_mode_fixup(struct drm_crtc *crtc, | 27 | - const struct drm_display_mode *mode; |
28 | + const struct drm_display_mode *mode, | 28 | + struct drm_display_mode *adjusted_mode; |
29 | + struct drm_display_mode *adjusted_mode) | 29 | enum drm_mode_status ok; |
30 | +{ | 30 | |
31 | + struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); | 31 | dev_dbg(ddev->dev, "%s\n", __func__); |
32 | + struct drm_device *ddev = crtc->dev; | 32 | @@ -XXX,XX +XXX,XX @@ static int tidss_crtc_atomic_check(struct drm_crtc *crtc, |
33 | + struct tidss_device *tidss = to_tidss(ddev); | 33 | if (!crtc_state->enable) |
34 | + long rate; | 34 | return 0; |
35 | |||
36 | - mode = &crtc_state->adjusted_mode; | ||
37 | + adjusted_mode = &crtc_state->adjusted_mode; | ||
38 | |||
39 | - ok = dispc_vp_mode_valid(dispc, hw_videoport, mode); | ||
40 | + if (drm_atomic_crtc_needs_modeset(crtc_state)) { | ||
41 | + long rate; | ||
35 | + | 42 | + |
36 | + rate = dispc_vp_round_clk_rate(tidss->dispc, tcrtc->hw_videoport, | 43 | + rate = dispc_vp_round_clk_rate(tidss->dispc, |
37 | + adjusted_mode->clock * 1000); | 44 | + tcrtc->hw_videoport, |
38 | + if (rate < 0) | 45 | + adjusted_mode->clock * 1000); |
39 | + return false; | 46 | + if (rate < 0) |
47 | + return -EINVAL; | ||
40 | + | 48 | + |
41 | + adjusted_mode->clock = rate / 1000; | 49 | + adjusted_mode->clock = rate / 1000; |
42 | + | 50 | + |
43 | + drm_mode_set_crtcinfo(adjusted_mode, 0); | 51 | + drm_mode_set_crtcinfo(adjusted_mode, 0); |
52 | + } | ||
44 | + | 53 | + |
45 | + return true; | 54 | + ok = dispc_vp_mode_valid(dispc, hw_videoport, adjusted_mode); |
46 | +} | 55 | if (ok != MODE_OK) { |
47 | + | 56 | dev_dbg(ddev->dev, "%s: bad mode: %ux%u pclk %u kHz\n", |
48 | static const struct drm_crtc_helper_funcs tidss_crtc_helper_funcs = { | 57 | - __func__, mode->hdisplay, mode->vdisplay, mode->clock); |
49 | + .mode_fixup = tidss_crtc_mode_fixup, | 58 | + __func__, adjusted_mode->hdisplay, |
50 | .atomic_check = tidss_crtc_atomic_check, | 59 | + adjusted_mode->vdisplay, adjusted_mode->clock); |
51 | .atomic_flush = tidss_crtc_atomic_flush, | 60 | return -EINVAL; |
52 | .atomic_enable = tidss_crtc_atomic_enable, | 61 | } |
62 | |||
53 | diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c | 63 | diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c |
54 | index XXXXXXX..XXXXXXX 100644 | 64 | index XXXXXXX..XXXXXXX 100644 |
55 | --- a/drivers/gpu/drm/tidss/tidss_dispc.c | 65 | --- a/drivers/gpu/drm/tidss/tidss_dispc.c |
56 | +++ b/drivers/gpu/drm/tidss/tidss_dispc.c | 66 | +++ b/drivers/gpu/drm/tidss/tidss_dispc.c |
57 | @@ -XXX,XX +XXX,XX @@ unsigned int dispc_pclk_diff(unsigned long rate, unsigned long real_rate) | 67 | @@ -XXX,XX +XXX,XX @@ unsigned int dispc_pclk_diff(unsigned long rate, unsigned long real_rate) |
... | ... | diff view generated by jsdifflib |
1 | The DPHY driver does not return the actual hs_clk_rate, so the DSI | 1 | The DPHY driver does not return the actual hs_clk_rate, so the DSI |
---|---|---|---|
2 | driver has no idea what clock was actually achieved. Set the realized | 2 | driver has no idea what clock was actually achieved. Set the realized |
3 | hs_clk_rate to the opts struct, so that the DSI driver gets it back. | 3 | hs_clk_rate to the opts struct, so that the DSI driver gets it back. |
4 | 4 | ||
5 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> | 5 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> |
6 | --- | 6 | --- |
7 | drivers/phy/cadence/cdns-dphy.c | 5 +++++ | 7 | drivers/phy/cadence/cdns-dphy.c | 5 +++++ |
8 | 1 file changed, 5 insertions(+) | 8 | 1 file changed, 5 insertions(+) |
9 | 9 | ||
10 | diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c | 10 | diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c |
11 | index XXXXXXX..XXXXXXX 100644 | 11 | index XXXXXXX..XXXXXXX 100644 |
12 | --- a/drivers/phy/cadence/cdns-dphy.c | 12 | --- a/drivers/phy/cadence/cdns-dphy.c |
13 | +++ b/drivers/phy/cadence/cdns-dphy.c | 13 | +++ b/drivers/phy/cadence/cdns-dphy.c |
14 | @@ -XXX,XX +XXX,XX @@ struct cdns_dphy_cfg { | 14 | @@ -XXX,XX +XXX,XX @@ struct cdns_dphy_cfg { |
15 | u8 pll_ipdiv; | 15 | u8 pll_ipdiv; |
16 | u8 pll_opdiv; | 16 | u8 pll_opdiv; |
17 | u16 pll_fbdiv; | 17 | u16 pll_fbdiv; |
18 | + u32 hs_clk_rate; | 18 | + u32 hs_clk_rate; |
19 | unsigned int nlanes; | 19 | unsigned int nlanes; |
20 | }; | 20 | }; |
21 | 21 | ||
22 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy, | 22 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy, |
23 | cfg->pll_ipdiv, | 23 | cfg->pll_ipdiv, |
24 | pll_ref_hz); | 24 | pll_ref_hz); |
25 | 25 | ||
26 | + cfg->hs_clk_rate = div_u64((u64)pll_ref_hz * cfg->pll_fbdiv, | 26 | + cfg->hs_clk_rate = div_u64((u64)pll_ref_hz * cfg->pll_fbdiv, |
27 | + 2 * cfg->pll_opdiv * cfg->pll_ipdiv); | 27 | + 2 * cfg->pll_opdiv * cfg->pll_ipdiv); |
28 | + | 28 | + |
29 | return 0; | 29 | return 0; |
30 | } | 30 | } |
31 | 31 | ||
32 | @@ -XXX,XX +XXX,XX @@ static int cdns_dphy_config_from_opts(struct phy *phy, | 32 | @@ -XXX,XX +XXX,XX @@ static int cdns_dphy_config_from_opts(struct phy *phy, |
33 | if (ret) | 33 | if (ret) |
34 | return ret; | 34 | return ret; |
35 | 35 | ||
36 | + opts->hs_clk_rate = cfg->hs_clk_rate; | 36 | + opts->hs_clk_rate = cfg->hs_clk_rate; |
37 | opts->wakeup = cdns_dphy_get_wakeup_time_ns(dphy) / 1000; | 37 | opts->wakeup = cdns_dphy_get_wakeup_time_ns(dphy) / 1000; |
38 | 38 | ||
39 | return 0; | 39 | return 0; |
40 | 40 | ||
41 | -- | 41 | -- |
42 | 2.43.0 | 42 | 2.43.0 | diff view generated by jsdifflib |
1 | The code in cdns-dphy has probably been part of a DSI driver in the | 1 | The code in cdns-dphy has probably been part of a DSI driver in the |
---|---|---|---|
2 | past. Remove DSI defines and variables which are not used or do not | 2 | past. Remove DSI defines and variables which are not used or do not |
3 | actually do anything. Also rename cdns_dsi_get_dphy_pll_cfg() to | 3 | actually do anything. Also rename cdns_dsi_get_dphy_pll_cfg() to |
4 | cdns_get_dphy_pll_cfg(), i.e. drop the "dsi", as it's not relevant here. | 4 | cdns_get_dphy_pll_cfg(), i.e. drop the "dsi", as it's not relevant here. |
5 | 5 | ||
6 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> | 6 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> |
7 | --- | 7 | --- |
8 | drivers/phy/cadence/cdns-dphy.c | 19 ++++--------------- | 8 | drivers/phy/cadence/cdns-dphy.c | 19 ++++--------------- |
9 | 1 file changed, 4 insertions(+), 15 deletions(-) | 9 | 1 file changed, 4 insertions(+), 15 deletions(-) |
10 | 10 | ||
11 | diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c | 11 | diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c |
12 | index XXXXXXX..XXXXXXX 100644 | 12 | index XXXXXXX..XXXXXXX 100644 |
13 | --- a/drivers/phy/cadence/cdns-dphy.c | 13 | --- a/drivers/phy/cadence/cdns-dphy.c |
14 | +++ b/drivers/phy/cadence/cdns-dphy.c | 14 | +++ b/drivers/phy/cadence/cdns-dphy.c |
15 | @@ -XXX,XX +XXX,XX @@ | 15 | @@ -XXX,XX +XXX,XX @@ |
16 | #define DPHY_PSM_CFG_FROM_REG BIT(0) | 16 | #define DPHY_PSM_CFG_FROM_REG BIT(0) |
17 | #define DPHY_PSM_CLK_DIV(x) ((x) << 1) | 17 | #define DPHY_PSM_CLK_DIV(x) ((x) << 1) |
18 | 18 | ||
19 | -#define DSI_HBP_FRAME_OVERHEAD 12 | 19 | -#define DSI_HBP_FRAME_OVERHEAD 12 |
20 | -#define DSI_HSA_FRAME_OVERHEAD 14 | 20 | -#define DSI_HSA_FRAME_OVERHEAD 14 |
21 | -#define DSI_HFP_FRAME_OVERHEAD 6 | 21 | -#define DSI_HFP_FRAME_OVERHEAD 6 |
22 | -#define DSI_HSS_VSS_VSE_FRAME_OVERHEAD 4 | 22 | -#define DSI_HSS_VSS_VSE_FRAME_OVERHEAD 4 |
23 | -#define DSI_BLANKING_FRAME_OVERHEAD 6 | 23 | -#define DSI_BLANKING_FRAME_OVERHEAD 6 |
24 | -#define DSI_NULL_FRAME_OVERHEAD 6 | 24 | -#define DSI_NULL_FRAME_OVERHEAD 6 |
25 | -#define DSI_EOT_PKT_SIZE 4 | 25 | -#define DSI_EOT_PKT_SIZE 4 |
26 | - | 26 | - |
27 | #define DPHY_TX_J721E_WIZ_PLL_CTRL 0xF04 | 27 | #define DPHY_TX_J721E_WIZ_PLL_CTRL 0xF04 |
28 | #define DPHY_TX_J721E_WIZ_STATUS 0xF08 | 28 | #define DPHY_TX_J721E_WIZ_STATUS 0xF08 |
29 | #define DPHY_TX_J721E_WIZ_RST_CTRL 0xF0C | 29 | #define DPHY_TX_J721E_WIZ_RST_CTRL 0xF0C |
30 | @@ -XXX,XX +XXX,XX @@ static const unsigned int tx_bands[] = { | 30 | @@ -XXX,XX +XXX,XX @@ static const unsigned int tx_bands[] = { |
31 | 870, 950, 1000, 1200, 1400, 1600, 1800, 2000, 2200, 2500 | 31 | 870, 950, 1000, 1200, 1400, 1600, 1800, 2000, 2200, 2500 |
32 | }; | 32 | }; |
33 | 33 | ||
34 | -static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy, | 34 | -static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy, |
35 | - struct cdns_dphy_cfg *cfg, | 35 | - struct cdns_dphy_cfg *cfg, |
36 | - struct phy_configure_opts_mipi_dphy *opts, | 36 | - struct phy_configure_opts_mipi_dphy *opts, |
37 | - unsigned int *dsi_hfp_ext) | 37 | - unsigned int *dsi_hfp_ext) |
38 | +static int cdns_get_dphy_pll_cfg(struct cdns_dphy *dphy, | 38 | +static int cdns_get_dphy_pll_cfg(struct cdns_dphy *dphy, |
39 | + struct cdns_dphy_cfg *cfg, | 39 | + struct cdns_dphy_cfg *cfg, |
40 | + struct phy_configure_opts_mipi_dphy *opts) | 40 | + struct phy_configure_opts_mipi_dphy *opts) |
41 | { | 41 | { |
42 | unsigned long pll_ref_hz = clk_get_rate(dphy->pll_ref_clk); | 42 | unsigned long pll_ref_hz = clk_get_rate(dphy->pll_ref_clk); |
43 | u64 dlane_bps; | 43 | u64 dlane_bps; |
44 | @@ -XXX,XX +XXX,XX @@ static int cdns_dphy_config_from_opts(struct phy *phy, | 44 | @@ -XXX,XX +XXX,XX @@ static int cdns_dphy_config_from_opts(struct phy *phy, |
45 | struct cdns_dphy_cfg *cfg) | 45 | struct cdns_dphy_cfg *cfg) |
46 | { | 46 | { |
47 | struct cdns_dphy *dphy = phy_get_drvdata(phy); | 47 | struct cdns_dphy *dphy = phy_get_drvdata(phy); |
48 | - unsigned int dsi_hfp_ext = 0; | 48 | - unsigned int dsi_hfp_ext = 0; |
49 | int ret; | 49 | int ret; |
50 | 50 | ||
51 | ret = phy_mipi_dphy_config_validate(opts); | 51 | ret = phy_mipi_dphy_config_validate(opts); |
52 | if (ret) | 52 | if (ret) |
53 | return ret; | 53 | return ret; |
54 | 54 | ||
55 | - ret = cdns_dsi_get_dphy_pll_cfg(dphy, cfg, | 55 | - ret = cdns_dsi_get_dphy_pll_cfg(dphy, cfg, |
56 | - opts, &dsi_hfp_ext); | 56 | - opts, &dsi_hfp_ext); |
57 | + ret = cdns_get_dphy_pll_cfg(dphy, cfg, opts); | 57 | + ret = cdns_get_dphy_pll_cfg(dphy, cfg, opts); |
58 | if (ret) | 58 | if (ret) |
59 | return ret; | 59 | return ret; |
60 | 60 | ||
61 | 61 | ||
62 | -- | 62 | -- |
63 | 2.43.0 | 63 | 2.43.0 | diff view generated by jsdifflib |
1 | The Cadence DSI requires negative syncs from the incoming video signal, | 1 | The Cadence DSI requires negative syncs from the incoming video signal, |
---|---|---|---|
2 | but at the moment that requirement is not expressed in any way. If the | 2 | but at the moment that requirement is not expressed in any way. If the |
3 | crtc decides to use positive syncs, things break down. | 3 | crtc decides to use positive syncs, things break down. |
4 | 4 | ||
5 | Use the adjusted_mode in atomic_check to set the sync flags to negative | 5 | Use the adjusted_mode in atomic_check to set the sync flags to negative |
6 | ones. | 6 | ones. |
7 | 7 | ||
8 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> | 8 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> |
9 | --- | 9 | --- |
10 | drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 5 +++++ | 10 | drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 5 +++++ |
11 | 1 file changed, 5 insertions(+) | 11 | 1 file changed, 5 insertions(+) |
12 | 12 | ||
13 | diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 13 | diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
14 | index XXXXXXX..XXXXXXX 100644 | 14 | index XXXXXXX..XXXXXXX 100644 |
15 | --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 15 | --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
16 | +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 16 | +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
17 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_bridge_atomic_check(struct drm_bridge *bridge, | 17 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_bridge_atomic_check(struct drm_bridge *bridge, |
18 | struct cdns_dsi_bridge_state *dsi_state = to_cdns_dsi_bridge_state(bridge_state); | 18 | struct cdns_dsi_bridge_state *dsi_state = to_cdns_dsi_bridge_state(bridge_state); |
19 | const struct drm_display_mode *mode = &crtc_state->mode; | 19 | const struct drm_display_mode *mode = &crtc_state->mode; |
20 | struct cdns_dsi_cfg *dsi_cfg = &dsi_state->dsi_cfg; | 20 | struct cdns_dsi_cfg *dsi_cfg = &dsi_state->dsi_cfg; |
21 | + struct drm_display_mode *adjusted_crtc_mode = &crtc_state->adjusted_mode; | 21 | + struct drm_display_mode *adjusted_crtc_mode = &crtc_state->adjusted_mode; |
22 | + | 22 | + |
23 | + /* cdns-dsi requires negative syncs */ | 23 | + /* cdns-dsi requires negative syncs */ |
24 | + adjusted_crtc_mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); | 24 | + adjusted_crtc_mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); |
25 | + adjusted_crtc_mode->flags |= DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC; | 25 | + adjusted_crtc_mode->flags |= DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC; |
26 | 26 | ||
27 | return cdns_dsi_check_conf(dsi, mode, dsi_cfg, false); | 27 | return cdns_dsi_check_conf(dsi, mode, dsi_cfg, false); |
28 | } | 28 | } |
29 | 29 | ||
30 | -- | 30 | -- |
31 | 2.43.0 | 31 | 2.43.0 | diff view generated by jsdifflib |
1 | The phy_validate() can change the HS clock rate we passed to it in the | 1 | The phy_validate() can change the HS clock rate we passed to it in the |
---|---|---|---|
2 | PHY config, depending on what the HW can actually do. The driver just | 2 | PHY config, depending on what the HW can actually do. The driver just |
3 | ignores this at the moment, but if the actual HS clock rate is different | 3 | ignores this at the moment, but if the actual HS clock rate is different |
4 | than the requested one, the pipeline will fail as all the DSI timing | 4 | than the requested one, the pipeline will fail as all the DSI timing |
5 | calculations will be incorrect. | 5 | calculations will be incorrect. |
6 | 6 | ||
7 | There are ways to improve DSI operation for various clock rates, but for | 7 | There are ways to improve DSI operation for various clock rates, but for |
8 | now, just add a check to see if the rate changed, and return an error if | 8 | now, just add a check to see if the rate changed, and return an error if |
9 | that happens. | 9 | that happens. |
10 | 10 | ||
11 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> | 11 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> |
12 | --- | 12 | --- |
13 | drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 11 +++++++++++ | 13 | drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 11 +++++++++++ |
14 | 1 file changed, 11 insertions(+) | 14 | 1 file changed, 11 insertions(+) |
15 | 15 | ||
16 | diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 16 | diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
17 | index XXXXXXX..XXXXXXX 100644 | 17 | index XXXXXXX..XXXXXXX 100644 |
18 | --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 18 | --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
19 | +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 19 | +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
20 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_check_conf(struct cdns_dsi *dsi, | 20 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_check_conf(struct cdns_dsi *dsi, |
21 | unsigned long dsi_hss_hsa_hse_hbp; | 21 | unsigned long dsi_hss_hsa_hse_hbp; |
22 | unsigned int nlanes = output->dev->lanes; | 22 | unsigned int nlanes = output->dev->lanes; |
23 | int mode_clock = (mode_valid_check ? mode->clock : mode->crtc_clock); | 23 | int mode_clock = (mode_valid_check ? mode->clock : mode->crtc_clock); |
24 | + unsigned long req_hs_clk_rate; | 24 | + unsigned long req_hs_clk_rate; |
25 | int ret; | 25 | int ret; |
26 | 26 | ||
27 | ret = cdns_dsi_mode2cfg(dsi, mode, dsi_cfg, mode_valid_check); | 27 | ret = cdns_dsi_mode2cfg(dsi, mode, dsi_cfg, mode_valid_check); |
28 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_check_conf(struct cdns_dsi *dsi, | 28 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_check_conf(struct cdns_dsi *dsi, |
29 | if (ret) | 29 | if (ret) |
30 | return ret; | 30 | return ret; |
31 | 31 | ||
32 | + req_hs_clk_rate = output->phy_opts.mipi_dphy.hs_clk_rate; | 32 | + req_hs_clk_rate = output->phy_opts.mipi_dphy.hs_clk_rate; |
33 | ret = phy_validate(dsi->dphy, PHY_MODE_MIPI_DPHY, 0, &output->phy_opts); | 33 | ret = phy_validate(dsi->dphy, PHY_MODE_MIPI_DPHY, 0, &output->phy_opts); |
34 | if (ret) | 34 | if (ret) |
35 | return ret; | 35 | return ret; |
36 | 36 | ||
37 | + if (req_hs_clk_rate != output->phy_opts.mipi_dphy.hs_clk_rate) { | 37 | + if (req_hs_clk_rate != output->phy_opts.mipi_dphy.hs_clk_rate) { |
38 | + dev_err(&dsi->dphy->dev, | 38 | + dev_err(&dsi->dphy->dev, |
39 | + "validation changed hs_clk_rate from %lu to %lu, diff %lu\n", | 39 | + "validation changed hs_clk_rate from %lu to %lu, diff %lu\n", |
40 | + req_hs_clk_rate, output->phy_opts.mipi_dphy.hs_clk_rate, | 40 | + req_hs_clk_rate, output->phy_opts.mipi_dphy.hs_clk_rate, |
41 | + output->phy_opts.mipi_dphy.hs_clk_rate - | 41 | + output->phy_opts.mipi_dphy.hs_clk_rate - |
42 | + req_hs_clk_rate); | 42 | + req_hs_clk_rate); |
43 | + return -EINVAL; | 43 | + return -EINVAL; |
44 | + } | 44 | + } |
45 | + | 45 | + |
46 | dsi_hss_hsa_hse_hbp = dsi_cfg->hbp + DSI_HBP_FRAME_OVERHEAD; | 46 | dsi_hss_hsa_hse_hbp = dsi_cfg->hbp + DSI_HBP_FRAME_OVERHEAD; |
47 | if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) | 47 | if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) |
48 | dsi_hss_hsa_hse_hbp += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD; | 48 | dsi_hss_hsa_hse_hbp += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD; |
49 | 49 | ||
50 | -- | 50 | -- |
51 | 2.43.0 | 51 | 2.43.0 | diff view generated by jsdifflib |
1 | Clean up the function a bit, mainly by doing the mode_valid_check dance | 1 | Clean up the function a bit, mainly by doing the mode_valid_check dance |
---|---|---|---|
2 | once in the beginning of the function, and grouping the calculations | 2 | once in the beginning of the function, and grouping the calculations |
3 | wrt. sync/event mode a bit better. | 3 | wrt. sync/event mode a bit better. |
4 | 4 | ||
5 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> | 5 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> |
6 | --- | 6 | --- |
7 | drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 48 ++++++++++++-------------- | 7 | drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 48 ++++++++++++-------------- |
8 | 1 file changed, 22 insertions(+), 26 deletions(-) | 8 | 1 file changed, 22 insertions(+), 26 deletions(-) |
9 | 9 | ||
10 | diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 10 | diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
11 | index XXXXXXX..XXXXXXX 100644 | 11 | index XXXXXXX..XXXXXXX 100644 |
12 | --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 12 | --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
13 | +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 13 | +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
14 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi, | 14 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi, |
15 | bool mode_valid_check) | 15 | bool mode_valid_check) |
16 | { | 16 | { |
17 | struct cdns_dsi_output *output = &dsi->output; | 17 | struct cdns_dsi_output *output = &dsi->output; |
18 | - unsigned int tmp; | 18 | - unsigned int tmp; |
19 | - bool sync_pulse = false; | 19 | - bool sync_pulse = false; |
20 | + u32 dpi_hsa, dpi_hbp, dpi_hfp, dpi_hact; | 20 | + u32 dpi_hsa, dpi_hbp, dpi_hfp, dpi_hact; |
21 | + bool sync_pulse; | 21 | + bool sync_pulse; |
22 | int bpp; | 22 | int bpp; |
23 | 23 | ||
24 | + if (mode_valid_check) { | 24 | + if (mode_valid_check) { |
25 | + dpi_hsa = mode->hsync_end - mode->hsync_start; | 25 | + dpi_hsa = mode->hsync_end - mode->hsync_start; |
26 | + dpi_hbp = mode->htotal - mode->hsync_end; | 26 | + dpi_hbp = mode->htotal - mode->hsync_end; |
27 | + dpi_hfp = mode->hsync_start - mode->hdisplay; | 27 | + dpi_hfp = mode->hsync_start - mode->hdisplay; |
28 | + dpi_hact = mode->hdisplay; | 28 | + dpi_hact = mode->hdisplay; |
29 | + } else { | 29 | + } else { |
30 | + dpi_hsa = mode->crtc_hsync_end - mode->crtc_hsync_start; | 30 | + dpi_hsa = mode->crtc_hsync_end - mode->crtc_hsync_start; |
31 | + dpi_hbp = mode->crtc_htotal - mode->crtc_hsync_end; | 31 | + dpi_hbp = mode->crtc_htotal - mode->crtc_hsync_end; |
32 | + dpi_hfp = mode->crtc_hsync_start - mode->crtc_hdisplay; | 32 | + dpi_hfp = mode->crtc_hsync_start - mode->crtc_hdisplay; |
33 | + dpi_hact = mode->crtc_hdisplay; | 33 | + dpi_hact = mode->crtc_hdisplay; |
34 | + } | 34 | + } |
35 | + | 35 | + |
36 | memset(dsi_cfg, 0, sizeof(*dsi_cfg)); | 36 | memset(dsi_cfg, 0, sizeof(*dsi_cfg)); |
37 | 37 | ||
38 | - if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) | 38 | - if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) |
39 | - sync_pulse = true; | 39 | - sync_pulse = true; |
40 | + sync_pulse = output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE; | 40 | + sync_pulse = output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE; |
41 | 41 | ||
42 | bpp = mipi_dsi_pixel_format_to_bpp(output->dev->format); | 42 | bpp = mipi_dsi_pixel_format_to_bpp(output->dev->format); |
43 | 43 | ||
44 | - if (mode_valid_check) | 44 | - if (mode_valid_check) |
45 | - tmp = mode->htotal - | 45 | - tmp = mode->htotal - |
46 | - (sync_pulse ? mode->hsync_end : mode->hsync_start); | 46 | - (sync_pulse ? mode->hsync_end : mode->hsync_start); |
47 | - else | 47 | - else |
48 | - tmp = mode->crtc_htotal - | 48 | - tmp = mode->crtc_htotal - |
49 | - (sync_pulse ? | 49 | - (sync_pulse ? |
50 | - mode->crtc_hsync_end : mode->crtc_hsync_start); | 50 | - mode->crtc_hsync_end : mode->crtc_hsync_start); |
51 | - | 51 | - |
52 | - dsi_cfg->hbp = dpi_to_dsi_timing(tmp, bpp, DSI_HBP_FRAME_OVERHEAD); | 52 | - dsi_cfg->hbp = dpi_to_dsi_timing(tmp, bpp, DSI_HBP_FRAME_OVERHEAD); |
53 | + dsi_cfg->hbp = dpi_to_dsi_timing(dpi_hbp + (sync_pulse ? 0 : dpi_hsa), | 53 | + dsi_cfg->hbp = dpi_to_dsi_timing(dpi_hbp + (sync_pulse ? 0 : dpi_hsa), |
54 | + bpp, DSI_HBP_FRAME_OVERHEAD); | 54 | + bpp, DSI_HBP_FRAME_OVERHEAD); |
55 | 55 | ||
56 | - if (sync_pulse) { | 56 | - if (sync_pulse) { |
57 | - if (mode_valid_check) | 57 | - if (mode_valid_check) |
58 | - tmp = mode->hsync_end - mode->hsync_start; | 58 | - tmp = mode->hsync_end - mode->hsync_start; |
59 | - else | 59 | - else |
60 | - tmp = mode->crtc_hsync_end - mode->crtc_hsync_start; | 60 | - tmp = mode->crtc_hsync_end - mode->crtc_hsync_start; |
61 | + if (sync_pulse) | 61 | + if (sync_pulse) |
62 | + dsi_cfg->hsa = | 62 | + dsi_cfg->hsa = |
63 | + dpi_to_dsi_timing(dpi_hsa, bpp, DSI_HSA_FRAME_OVERHEAD); | 63 | + dpi_to_dsi_timing(dpi_hsa, bpp, DSI_HSA_FRAME_OVERHEAD); |
64 | 64 | ||
65 | - dsi_cfg->hsa = dpi_to_dsi_timing(tmp, bpp, | 65 | - dsi_cfg->hsa = dpi_to_dsi_timing(tmp, bpp, |
66 | - DSI_HSA_FRAME_OVERHEAD); | 66 | - DSI_HSA_FRAME_OVERHEAD); |
67 | - } | 67 | - } |
68 | + dsi_cfg->hact = dpi_to_dsi_timing(dpi_hact, bpp, 0); | 68 | + dsi_cfg->hact = dpi_to_dsi_timing(dpi_hact, bpp, 0); |
69 | 69 | ||
70 | - dsi_cfg->hact = dpi_to_dsi_timing(mode_valid_check ? | 70 | - dsi_cfg->hact = dpi_to_dsi_timing(mode_valid_check ? |
71 | - mode->hdisplay : mode->crtc_hdisplay, | 71 | - mode->hdisplay : mode->crtc_hdisplay, |
72 | - bpp, 0); | 72 | - bpp, 0); |
73 | - dsi_cfg->hfp = dpi_to_dsi_timing(mode_to_dpi_hfp(mode, mode_valid_check), | 73 | - dsi_cfg->hfp = dpi_to_dsi_timing(mode_to_dpi_hfp(mode, mode_valid_check), |
74 | - bpp, DSI_HFP_FRAME_OVERHEAD); | 74 | - bpp, DSI_HFP_FRAME_OVERHEAD); |
75 | + dsi_cfg->hfp = dpi_to_dsi_timing(dpi_hfp, bpp, DSI_HFP_FRAME_OVERHEAD); | 75 | + dsi_cfg->hfp = dpi_to_dsi_timing(dpi_hfp, bpp, DSI_HFP_FRAME_OVERHEAD); |
76 | 76 | ||
77 | return 0; | 77 | return 0; |
78 | } | 78 | } |
79 | 79 | ||
80 | -- | 80 | -- |
81 | 2.43.0 | 81 | 2.43.0 | diff view generated by jsdifflib |
1 | The driver tries to calculate the value for REG_WAKEUP_TIME. However, | 1 | The driver tries to calculate the value for REG_WAKEUP_TIME. However, |
---|---|---|---|
2 | the calculation itself is not correct, and to add on it, the resulting | 2 | the calculation itself is not correct, and to add on it, the resulting |
3 | value is almost always larger than the field's size, so the actual | 3 | value is almost always larger than the field's size, so the actual |
4 | result is more or less random. | 4 | result is more or less random. |
5 | 5 | ||
6 | According to the docs, figuring out the value for REG_WAKEUP_TIME | 6 | According to the docs, figuring out the value for REG_WAKEUP_TIME |
7 | requires HW characterization and there's no way to have a generic | 7 | requires HW characterization and there's no way to have a generic |
8 | algorithm to come up with the value. That doesn't help at all... | 8 | algorithm to come up with the value. That doesn't help at all... |
9 | 9 | ||
10 | However, we know that the value must be smaller than the line time, and, | 10 | However, we know that the value must be smaller than the line time, and, |
11 | at least in my understanding, the proper value for it is quite small. | 11 | at least in my understanding, the proper value for it is quite small. |
12 | Testing shows that setting it to 1/10 of the line time seems to work | 12 | Testing shows that setting it to 1/10 of the line time seems to work |
13 | well. All video modes from my HDMI monitor work with this algorithm. | 13 | well. All video modes from my HDMI monitor work with this algorithm. |
14 | 14 | ||
15 | Hopefully we'll get more information on how to calculate the value, and | 15 | Hopefully we'll get more information on how to calculate the value, and |
16 | we can then update this. | 16 | we can then update this. |
17 | 17 | ||
18 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> | 18 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> |
19 | --- | 19 | --- |
20 | drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 8 +++++++- | 20 | drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 8 +++++++- |
21 | 1 file changed, 7 insertions(+), 1 deletion(-) | 21 | 1 file changed, 7 insertions(+), 1 deletion(-) |
22 | 22 | ||
23 | diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 23 | diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
24 | index XXXXXXX..XXXXXXX 100644 | 24 | index XXXXXXX..XXXXXXX 100644 |
25 | --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 25 | --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
26 | +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 26 | +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
27 | @@ -XXX,XX +XXX,XX @@ static void cdns_dsi_bridge_atomic_pre_enable(struct drm_bridge *bridge, | 27 | @@ -XXX,XX +XXX,XX @@ static void cdns_dsi_bridge_atomic_pre_enable(struct drm_bridge *bridge, |
28 | 28 | ||
29 | tx_byte_period = DIV_ROUND_DOWN_ULL((u64)NSEC_PER_SEC * 8, | 29 | tx_byte_period = DIV_ROUND_DOWN_ULL((u64)NSEC_PER_SEC * 8, |
30 | phy_cfg->hs_clk_rate); | 30 | phy_cfg->hs_clk_rate); |
31 | - reg_wakeup = (phy_cfg->hs_prepare + phy_cfg->hs_zero) / tx_byte_period; | 31 | - reg_wakeup = (phy_cfg->hs_prepare + phy_cfg->hs_zero) / tx_byte_period; |
32 | + | 32 | + |
33 | + /* | 33 | + /* |
34 | + * Estimated time [in clock cycles] to perform LP->HS on D-PHY. | 34 | + * Estimated time [in clock cycles] to perform LP->HS on D-PHY. |
35 | + * It is not clear how to calculate this, so for now, | 35 | + * It is not clear how to calculate this, so for now, |
36 | + * set it to 1/10 of the total number of clocks in a line. | 36 | + * set it to 1/10 of the total number of clocks in a line. |
37 | + */ | 37 | + */ |
38 | + reg_wakeup = dsi_cfg.htotal / nlanes / 10; | 38 | + reg_wakeup = dsi_cfg.htotal / nlanes / 10; |
39 | writel(REG_WAKEUP_TIME(reg_wakeup) | REG_LINE_DURATION(tmp), | 39 | writel(REG_WAKEUP_TIME(reg_wakeup) | REG_LINE_DURATION(tmp), |
40 | dsi->regs + VID_DPHY_TIME); | 40 | dsi->regs + VID_DPHY_TIME); |
41 | 41 | ||
42 | 42 | ||
43 | -- | 43 | -- |
44 | 2.43.0 | 44 | 2.43.0 | diff view generated by jsdifflib |
1 | The timings calculation gets it wrong for DSI event mode, resulting in | 1 | The timings calculation gets it wrong for DSI event mode, resulting in |
---|---|---|---|
2 | too large hbp value. Fix the issue by taking into account the | 2 | too large hbp value. Fix the issue by taking into account the |
3 | pulse/event mode difference. | 3 | pulse/event mode difference. |
4 | 4 | ||
5 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> | 5 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> |
6 | --- | 6 | --- |
7 | drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 33 ++++++++++++++++++-------- | 7 | drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 33 ++++++++++++++++++-------- |
8 | 1 file changed, 23 insertions(+), 10 deletions(-) | 8 | 1 file changed, 23 insertions(+), 10 deletions(-) |
9 | 9 | ||
10 | diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 10 | diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
11 | index XXXXXXX..XXXXXXX 100644 | 11 | index XXXXXXX..XXXXXXX 100644 |
12 | --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 12 | --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
13 | +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 13 | +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
14 | @@ -XXX,XX +XXX,XX @@ | 14 | @@ -XXX,XX +XXX,XX @@ |
15 | #define DSI_OUTPUT_PORT 0 | 15 | #define DSI_OUTPUT_PORT 0 |
16 | #define DSI_INPUT_PORT(inputid) (1 + (inputid)) | 16 | #define DSI_INPUT_PORT(inputid) (1 + (inputid)) |
17 | 17 | ||
18 | -#define DSI_HBP_FRAME_OVERHEAD 12 | 18 | -#define DSI_HBP_FRAME_OVERHEAD 12 |
19 | +#define DSI_HBP_FRAME_PULSE_OVERHEAD 12 | 19 | +#define DSI_HBP_FRAME_PULSE_OVERHEAD 12 |
20 | +#define DSI_HBP_FRAME_EVENT_OVERHEAD 16 | 20 | +#define DSI_HBP_FRAME_EVENT_OVERHEAD 16 |
21 | #define DSI_HSA_FRAME_OVERHEAD 14 | 21 | #define DSI_HSA_FRAME_OVERHEAD 14 |
22 | #define DSI_HFP_FRAME_OVERHEAD 6 | 22 | #define DSI_HFP_FRAME_OVERHEAD 6 |
23 | #define DSI_HSS_VSS_VSE_FRAME_OVERHEAD 4 | 23 | #define DSI_HSS_VSS_VSE_FRAME_OVERHEAD 4 |
24 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi, | 24 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi, |
25 | 25 | ||
26 | bpp = mipi_dsi_pixel_format_to_bpp(output->dev->format); | 26 | bpp = mipi_dsi_pixel_format_to_bpp(output->dev->format); |
27 | 27 | ||
28 | - dsi_cfg->hbp = dpi_to_dsi_timing(dpi_hbp + (sync_pulse ? 0 : dpi_hsa), | 28 | - dsi_cfg->hbp = dpi_to_dsi_timing(dpi_hbp + (sync_pulse ? 0 : dpi_hsa), |
29 | - bpp, DSI_HBP_FRAME_OVERHEAD); | 29 | - bpp, DSI_HBP_FRAME_OVERHEAD); |
30 | + if (sync_pulse) { | 30 | + if (sync_pulse) { |
31 | + dsi_cfg->hbp = dpi_to_dsi_timing(dpi_hbp, bpp, | 31 | + dsi_cfg->hbp = dpi_to_dsi_timing(dpi_hbp, bpp, |
32 | + DSI_HBP_FRAME_PULSE_OVERHEAD); | 32 | + DSI_HBP_FRAME_PULSE_OVERHEAD); |
33 | 33 | ||
34 | - if (sync_pulse) | 34 | - if (sync_pulse) |
35 | - dsi_cfg->hsa = | 35 | - dsi_cfg->hsa = |
36 | - dpi_to_dsi_timing(dpi_hsa, bpp, DSI_HSA_FRAME_OVERHEAD); | 36 | - dpi_to_dsi_timing(dpi_hsa, bpp, DSI_HSA_FRAME_OVERHEAD); |
37 | + dsi_cfg->hsa = dpi_to_dsi_timing(dpi_hsa, bpp, | 37 | + dsi_cfg->hsa = dpi_to_dsi_timing(dpi_hsa, bpp, |
38 | + DSI_HSA_FRAME_OVERHEAD); | 38 | + DSI_HSA_FRAME_OVERHEAD); |
39 | + } else { | 39 | + } else { |
40 | + dsi_cfg->hbp = dpi_to_dsi_timing(dpi_hbp + dpi_hsa, bpp, | 40 | + dsi_cfg->hbp = dpi_to_dsi_timing(dpi_hbp + dpi_hsa, bpp, |
41 | + DSI_HBP_FRAME_EVENT_OVERHEAD); | 41 | + DSI_HBP_FRAME_EVENT_OVERHEAD); |
42 | + | 42 | + |
43 | + dsi_cfg->hsa = 0; | 43 | + dsi_cfg->hsa = 0; |
44 | + } | 44 | + } |
45 | 45 | ||
46 | dsi_cfg->hact = dpi_to_dsi_timing(dpi_hact, bpp, 0); | 46 | dsi_cfg->hact = dpi_to_dsi_timing(dpi_hact, bpp, 0); |
47 | 47 | ||
48 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_adjust_phy_config(struct cdns_dsi *dsi, | 48 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_adjust_phy_config(struct cdns_dsi *dsi, |
49 | unsigned int dsi_hfp_ext; | 49 | unsigned int dsi_hfp_ext; |
50 | unsigned int lanes = output->dev->lanes; | 50 | unsigned int lanes = output->dev->lanes; |
51 | 51 | ||
52 | - dsi_htotal = dsi_cfg->hbp + DSI_HBP_FRAME_OVERHEAD; | 52 | - dsi_htotal = dsi_cfg->hbp + DSI_HBP_FRAME_OVERHEAD; |
53 | - if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) | 53 | - if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) |
54 | + if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) { | 54 | + if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) { |
55 | + dsi_htotal = dsi_cfg->hbp + DSI_HBP_FRAME_PULSE_OVERHEAD; | 55 | + dsi_htotal = dsi_cfg->hbp + DSI_HBP_FRAME_PULSE_OVERHEAD; |
56 | dsi_htotal += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD; | 56 | dsi_htotal += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD; |
57 | + } else { | 57 | + } else { |
58 | + dsi_htotal = dsi_cfg->hbp + DSI_HBP_FRAME_EVENT_OVERHEAD; | 58 | + dsi_htotal = dsi_cfg->hbp + DSI_HBP_FRAME_EVENT_OVERHEAD; |
59 | + } | 59 | + } |
60 | 60 | ||
61 | dsi_htotal += dsi_cfg->hact; | 61 | dsi_htotal += dsi_cfg->hact; |
62 | dsi_htotal += dsi_cfg->hfp + DSI_HFP_FRAME_OVERHEAD; | 62 | dsi_htotal += dsi_cfg->hfp + DSI_HFP_FRAME_OVERHEAD; |
63 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_check_conf(struct cdns_dsi *dsi, | 63 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_check_conf(struct cdns_dsi *dsi, |
64 | return -EINVAL; | 64 | return -EINVAL; |
65 | } | 65 | } |
66 | 66 | ||
67 | - dsi_hss_hsa_hse_hbp = dsi_cfg->hbp + DSI_HBP_FRAME_OVERHEAD; | 67 | - dsi_hss_hsa_hse_hbp = dsi_cfg->hbp + DSI_HBP_FRAME_OVERHEAD; |
68 | - if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) | 68 | - if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) |
69 | + if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) { | 69 | + if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) { |
70 | + dsi_hss_hsa_hse_hbp = dsi_cfg->hbp + DSI_HBP_FRAME_PULSE_OVERHEAD; | 70 | + dsi_hss_hsa_hse_hbp = dsi_cfg->hbp + DSI_HBP_FRAME_PULSE_OVERHEAD; |
71 | dsi_hss_hsa_hse_hbp += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD; | 71 | dsi_hss_hsa_hse_hbp += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD; |
72 | + } else { | 72 | + } else { |
73 | + dsi_hss_hsa_hse_hbp = dsi_cfg->hbp + DSI_HBP_FRAME_EVENT_OVERHEAD; | 73 | + dsi_hss_hsa_hse_hbp = dsi_cfg->hbp + DSI_HBP_FRAME_EVENT_OVERHEAD; |
74 | + } | 74 | + } |
75 | 75 | ||
76 | /* | 76 | /* |
77 | * Make sure DPI(HFP) > DSI(HSS+HSA+HSE+HBP) to guarantee that the FIFO | 77 | * Make sure DPI(HFP) > DSI(HSS+HSA+HSE+HBP) to guarantee that the FIFO |
78 | 78 | ||
79 | -- | 79 | -- |
80 | 2.43.0 | 80 | 2.43.0 | diff view generated by jsdifflib |
1 | The driver check if "DPI(HFP) > DSI(HSS+HSA+HSE+HBP)", and rejects the | 1 | The driver check if "DPI(HFP) > DSI(HSS+HSA+HSE+HBP)", and rejects the |
---|---|---|---|
2 | mode if not. | 2 | mode if not. |
3 | 3 | ||
4 | However, testing shows that this doesn't hold at all. I can set the hfp | 4 | However, testing shows that this doesn't hold at all. I can set the hfp |
5 | to very small values, with no errors. The feedback from the HW team also | 5 | to very small values, with no errors. The feedback from the HW team also |
6 | was that the check is not right, although it's not clear if there's a | 6 | was that the check is not right, although it's not clear if there's a |
7 | way to validate the FIFO emptying. | 7 | way to validate the FIFO emptying. |
8 | 8 | ||
9 | The check rejects quite a lot of modes, apparently for no good reason, | 9 | The check rejects quite a lot of modes, apparently for no good reason, |
10 | so drop the check. | 10 | so drop the check. |
11 | 11 | ||
12 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> | 12 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> |
13 | --- | 13 | --- |
14 | drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 28 -------------------------- | 14 | drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 28 -------------------------- |
15 | 1 file changed, 28 deletions(-) | 15 | 1 file changed, 28 deletions(-) |
16 | 16 | ||
17 | diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 17 | diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
18 | index XXXXXXX..XXXXXXX 100644 | 18 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 19 | --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
20 | +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 20 | +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
21 | @@ -XXX,XX +XXX,XX @@ bridge_to_cdns_dsi_input(struct drm_bridge *bridge) | 21 | @@ -XXX,XX +XXX,XX @@ bridge_to_cdns_dsi_input(struct drm_bridge *bridge) |
22 | return container_of(bridge, struct cdns_dsi_input, bridge); | 22 | return container_of(bridge, struct cdns_dsi_input, bridge); |
23 | } | 23 | } |
24 | 24 | ||
25 | -static unsigned int mode_to_dpi_hfp(const struct drm_display_mode *mode, | 25 | -static unsigned int mode_to_dpi_hfp(const struct drm_display_mode *mode, |
26 | - bool mode_valid_check) | 26 | - bool mode_valid_check) |
27 | -{ | 27 | -{ |
28 | - if (mode_valid_check) | 28 | - if (mode_valid_check) |
29 | - return mode->hsync_start - mode->hdisplay; | 29 | - return mode->hsync_start - mode->hdisplay; |
30 | - | 30 | - |
31 | - return mode->crtc_hsync_start - mode->crtc_hdisplay; | 31 | - return mode->crtc_hsync_start - mode->crtc_hdisplay; |
32 | -} | 32 | -} |
33 | - | 33 | - |
34 | static unsigned int dpi_to_dsi_timing(unsigned int dpi_timing, | 34 | static unsigned int dpi_to_dsi_timing(unsigned int dpi_timing, |
35 | unsigned int dpi_bpp, | 35 | unsigned int dpi_bpp, |
36 | unsigned int dsi_pkt_overhead) | 36 | unsigned int dsi_pkt_overhead) |
37 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_check_conf(struct cdns_dsi *dsi, | 37 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_check_conf(struct cdns_dsi *dsi, |
38 | { | 38 | { |
39 | struct cdns_dsi_output *output = &dsi->output; | 39 | struct cdns_dsi_output *output = &dsi->output; |
40 | struct phy_configure_opts_mipi_dphy *phy_cfg = &output->phy_opts.mipi_dphy; | 40 | struct phy_configure_opts_mipi_dphy *phy_cfg = &output->phy_opts.mipi_dphy; |
41 | - unsigned long dsi_hss_hsa_hse_hbp; | 41 | - unsigned long dsi_hss_hsa_hse_hbp; |
42 | unsigned int nlanes = output->dev->lanes; | 42 | unsigned int nlanes = output->dev->lanes; |
43 | int mode_clock = (mode_valid_check ? mode->clock : mode->crtc_clock); | 43 | int mode_clock = (mode_valid_check ? mode->clock : mode->crtc_clock); |
44 | unsigned long req_hs_clk_rate; | 44 | unsigned long req_hs_clk_rate; |
45 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_check_conf(struct cdns_dsi *dsi, | 45 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_check_conf(struct cdns_dsi *dsi, |
46 | return -EINVAL; | 46 | return -EINVAL; |
47 | } | 47 | } |
48 | 48 | ||
49 | - if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) { | 49 | - if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) { |
50 | - dsi_hss_hsa_hse_hbp = dsi_cfg->hbp + DSI_HBP_FRAME_PULSE_OVERHEAD; | 50 | - dsi_hss_hsa_hse_hbp = dsi_cfg->hbp + DSI_HBP_FRAME_PULSE_OVERHEAD; |
51 | - dsi_hss_hsa_hse_hbp += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD; | 51 | - dsi_hss_hsa_hse_hbp += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD; |
52 | - } else { | 52 | - } else { |
53 | - dsi_hss_hsa_hse_hbp = dsi_cfg->hbp + DSI_HBP_FRAME_EVENT_OVERHEAD; | 53 | - dsi_hss_hsa_hse_hbp = dsi_cfg->hbp + DSI_HBP_FRAME_EVENT_OVERHEAD; |
54 | - } | 54 | - } |
55 | - | 55 | - |
56 | - /* | 56 | - /* |
57 | - * Make sure DPI(HFP) > DSI(HSS+HSA+HSE+HBP) to guarantee that the FIFO | 57 | - * Make sure DPI(HFP) > DSI(HSS+HSA+HSE+HBP) to guarantee that the FIFO |
58 | - * is empty before we start a receiving a new line on the DPI | 58 | - * is empty before we start a receiving a new line on the DPI |
59 | - * interface. | 59 | - * interface. |
60 | - */ | 60 | - */ |
61 | - if ((u64)phy_cfg->hs_clk_rate * | 61 | - if ((u64)phy_cfg->hs_clk_rate * |
62 | - mode_to_dpi_hfp(mode, mode_valid_check) * nlanes < | 62 | - mode_to_dpi_hfp(mode, mode_valid_check) * nlanes < |
63 | - (u64)dsi_hss_hsa_hse_hbp * | 63 | - (u64)dsi_hss_hsa_hse_hbp * |
64 | - (mode_valid_check ? mode->clock : mode->crtc_clock) * 1000) | 64 | - (mode_valid_check ? mode->clock : mode->crtc_clock) * 1000) |
65 | - return -EINVAL; | 65 | - return -EINVAL; |
66 | - | 66 | - |
67 | return 0; | 67 | return 0; |
68 | } | 68 | } |
69 | 69 | ||
70 | 70 | ||
71 | -- | 71 | -- |
72 | 2.43.0 | 72 | 2.43.0 | diff view generated by jsdifflib |
1 | The docs say about mode_valid(): | 1 | The docs say about mode_valid(): |
---|---|---|---|
2 | 2 | ||
3 | "it is not allowed to look at anything else but the passed-in mode, and | 3 | "it is not allowed to look at anything else but the passed-in mode, and |
4 | validate it against configuration-invariant hardware constraints" | 4 | validate it against configuration-invariant hardware constraints" |
5 | 5 | ||
6 | We're doing a lot more than just looking at the mode. The main issue | 6 | We're doing a lot more than just looking at the mode. The main issue |
7 | here is that we're doing checks based on the pixel clock, before we know | 7 | here is that we're doing checks based on the pixel clock, before we know |
8 | what the pixel clock from the crtc actually is. | 8 | what the pixel clock from the crtc actually is. |
9 | 9 | ||
10 | So, drop the checks from .mode_valid(). This also allows us to remove | 10 | So, drop the checks from .mode_valid(). This also allows us to remove |
11 | the 'mode_valid_check' parameter from internal functions, and the | 11 | the 'mode_valid_check' parameter from internal functions, and the |
12 | related code. | 12 | related code. |
13 | 13 | ||
14 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> | 14 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> |
15 | --- | 15 | --- |
16 | drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 44 ++++++++------------------ | 16 | drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 44 ++++++++------------------ |
17 | 1 file changed, 14 insertions(+), 30 deletions(-) | 17 | 1 file changed, 14 insertions(+), 30 deletions(-) |
18 | 18 | ||
19 | diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 19 | diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
20 | index XXXXXXX..XXXXXXX 100644 | 20 | index XXXXXXX..XXXXXXX 100644 |
21 | --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 21 | --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
22 | +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 22 | +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
23 | @@ -XXX,XX +XXX,XX @@ static unsigned int dpi_to_dsi_timing(unsigned int dpi_timing, | 23 | @@ -XXX,XX +XXX,XX @@ static unsigned int dpi_to_dsi_timing(unsigned int dpi_timing, |
24 | 24 | ||
25 | static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi, | 25 | static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi, |
26 | const struct drm_display_mode *mode, | 26 | const struct drm_display_mode *mode, |
27 | - struct cdns_dsi_cfg *dsi_cfg, | 27 | - struct cdns_dsi_cfg *dsi_cfg, |
28 | - bool mode_valid_check) | 28 | - bool mode_valid_check) |
29 | + struct cdns_dsi_cfg *dsi_cfg) | 29 | + struct cdns_dsi_cfg *dsi_cfg) |
30 | { | 30 | { |
31 | struct cdns_dsi_output *output = &dsi->output; | 31 | struct cdns_dsi_output *output = &dsi->output; |
32 | u32 dpi_hsa, dpi_hbp, dpi_hfp, dpi_hact; | 32 | u32 dpi_hsa, dpi_hbp, dpi_hfp, dpi_hact; |
33 | bool sync_pulse; | 33 | bool sync_pulse; |
34 | int bpp; | 34 | int bpp; |
35 | 35 | ||
36 | - if (mode_valid_check) { | 36 | - if (mode_valid_check) { |
37 | - dpi_hsa = mode->hsync_end - mode->hsync_start; | 37 | - dpi_hsa = mode->hsync_end - mode->hsync_start; |
38 | - dpi_hbp = mode->htotal - mode->hsync_end; | 38 | - dpi_hbp = mode->htotal - mode->hsync_end; |
39 | - dpi_hfp = mode->hsync_start - mode->hdisplay; | 39 | - dpi_hfp = mode->hsync_start - mode->hdisplay; |
40 | - dpi_hact = mode->hdisplay; | 40 | - dpi_hact = mode->hdisplay; |
41 | - } else { | 41 | - } else { |
42 | - dpi_hsa = mode->crtc_hsync_end - mode->crtc_hsync_start; | 42 | - dpi_hsa = mode->crtc_hsync_end - mode->crtc_hsync_start; |
43 | - dpi_hbp = mode->crtc_htotal - mode->crtc_hsync_end; | 43 | - dpi_hbp = mode->crtc_htotal - mode->crtc_hsync_end; |
44 | - dpi_hfp = mode->crtc_hsync_start - mode->crtc_hdisplay; | 44 | - dpi_hfp = mode->crtc_hsync_start - mode->crtc_hdisplay; |
45 | - dpi_hact = mode->crtc_hdisplay; | 45 | - dpi_hact = mode->crtc_hdisplay; |
46 | - } | 46 | - } |
47 | + dpi_hsa = mode->crtc_hsync_end - mode->crtc_hsync_start; | 47 | + dpi_hsa = mode->crtc_hsync_end - mode->crtc_hsync_start; |
48 | + dpi_hbp = mode->crtc_htotal - mode->crtc_hsync_end; | 48 | + dpi_hbp = mode->crtc_htotal - mode->crtc_hsync_end; |
49 | + dpi_hfp = mode->crtc_hsync_start - mode->crtc_hdisplay; | 49 | + dpi_hfp = mode->crtc_hsync_start - mode->crtc_hdisplay; |
50 | + dpi_hact = mode->crtc_hdisplay; | 50 | + dpi_hact = mode->crtc_hdisplay; |
51 | 51 | ||
52 | memset(dsi_cfg, 0, sizeof(*dsi_cfg)); | 52 | memset(dsi_cfg, 0, sizeof(*dsi_cfg)); |
53 | 53 | ||
54 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi, | 54 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi, |
55 | static int cdns_dsi_adjust_phy_config(struct cdns_dsi *dsi, | 55 | static int cdns_dsi_adjust_phy_config(struct cdns_dsi *dsi, |
56 | struct cdns_dsi_cfg *dsi_cfg, | 56 | struct cdns_dsi_cfg *dsi_cfg, |
57 | struct phy_configure_opts_mipi_dphy *phy_cfg, | 57 | struct phy_configure_opts_mipi_dphy *phy_cfg, |
58 | - const struct drm_display_mode *mode, | 58 | - const struct drm_display_mode *mode, |
59 | - bool mode_valid_check) | 59 | - bool mode_valid_check) |
60 | + const struct drm_display_mode *mode) | 60 | + const struct drm_display_mode *mode) |
61 | { | 61 | { |
62 | struct cdns_dsi_output *output = &dsi->output; | 62 | struct cdns_dsi_output *output = &dsi->output; |
63 | unsigned long long dlane_bps; | 63 | unsigned long long dlane_bps; |
64 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_adjust_phy_config(struct cdns_dsi *dsi, | 64 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_adjust_phy_config(struct cdns_dsi *dsi, |
65 | if (dsi_htotal % lanes) | 65 | if (dsi_htotal % lanes) |
66 | adj_dsi_htotal += lanes - (dsi_htotal % lanes); | 66 | adj_dsi_htotal += lanes - (dsi_htotal % lanes); |
67 | 67 | ||
68 | - dpi_hz = (mode_valid_check ? mode->clock : mode->crtc_clock) * 1000; | 68 | - dpi_hz = (mode_valid_check ? mode->clock : mode->crtc_clock) * 1000; |
69 | + dpi_hz = mode->crtc_clock * 1000; | 69 | + dpi_hz = mode->crtc_clock * 1000; |
70 | dlane_bps = (unsigned long long)dpi_hz * adj_dsi_htotal; | 70 | dlane_bps = (unsigned long long)dpi_hz * adj_dsi_htotal; |
71 | 71 | ||
72 | /* data rate in bytes/sec is not an integer, refuse the mode. */ | 72 | /* data rate in bytes/sec is not an integer, refuse the mode. */ |
73 | - dpi_htotal = mode_valid_check ? mode->htotal : mode->crtc_htotal; | 73 | - dpi_htotal = mode_valid_check ? mode->htotal : mode->crtc_htotal; |
74 | + dpi_htotal = mode->crtc_htotal; | 74 | + dpi_htotal = mode->crtc_htotal; |
75 | if (do_div(dlane_bps, lanes * dpi_htotal)) | 75 | if (do_div(dlane_bps, lanes * dpi_htotal)) |
76 | return -EINVAL; | 76 | return -EINVAL; |
77 | 77 | ||
78 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_adjust_phy_config(struct cdns_dsi *dsi, | 78 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_adjust_phy_config(struct cdns_dsi *dsi, |
79 | 79 | ||
80 | static int cdns_dsi_check_conf(struct cdns_dsi *dsi, | 80 | static int cdns_dsi_check_conf(struct cdns_dsi *dsi, |
81 | const struct drm_display_mode *mode, | 81 | const struct drm_display_mode *mode, |
82 | - struct cdns_dsi_cfg *dsi_cfg, | 82 | - struct cdns_dsi_cfg *dsi_cfg, |
83 | - bool mode_valid_check) | 83 | - bool mode_valid_check) |
84 | + struct cdns_dsi_cfg *dsi_cfg) | 84 | + struct cdns_dsi_cfg *dsi_cfg) |
85 | { | 85 | { |
86 | struct cdns_dsi_output *output = &dsi->output; | 86 | struct cdns_dsi_output *output = &dsi->output; |
87 | struct phy_configure_opts_mipi_dphy *phy_cfg = &output->phy_opts.mipi_dphy; | 87 | struct phy_configure_opts_mipi_dphy *phy_cfg = &output->phy_opts.mipi_dphy; |
88 | unsigned int nlanes = output->dev->lanes; | 88 | unsigned int nlanes = output->dev->lanes; |
89 | - int mode_clock = (mode_valid_check ? mode->clock : mode->crtc_clock); | 89 | - int mode_clock = (mode_valid_check ? mode->clock : mode->crtc_clock); |
90 | unsigned long req_hs_clk_rate; | 90 | unsigned long req_hs_clk_rate; |
91 | int ret; | 91 | int ret; |
92 | 92 | ||
93 | - ret = cdns_dsi_mode2cfg(dsi, mode, dsi_cfg, mode_valid_check); | 93 | - ret = cdns_dsi_mode2cfg(dsi, mode, dsi_cfg, mode_valid_check); |
94 | + ret = cdns_dsi_mode2cfg(dsi, mode, dsi_cfg); | 94 | + ret = cdns_dsi_mode2cfg(dsi, mode, dsi_cfg); |
95 | if (ret) | 95 | if (ret) |
96 | return ret; | 96 | return ret; |
97 | 97 | ||
98 | - ret = phy_mipi_dphy_get_default_config(mode_clock * 1000, | 98 | - ret = phy_mipi_dphy_get_default_config(mode_clock * 1000, |
99 | + ret = phy_mipi_dphy_get_default_config(mode->crtc_clock * 1000, | 99 | + ret = phy_mipi_dphy_get_default_config(mode->crtc_clock * 1000, |
100 | mipi_dsi_pixel_format_to_bpp(output->dev->format), | 100 | mipi_dsi_pixel_format_to_bpp(output->dev->format), |
101 | nlanes, phy_cfg); | 101 | nlanes, phy_cfg); |
102 | if (ret) | 102 | if (ret) |
103 | return ret; | 103 | return ret; |
104 | 104 | ||
105 | - ret = cdns_dsi_adjust_phy_config(dsi, dsi_cfg, phy_cfg, mode, mode_valid_check); | 105 | - ret = cdns_dsi_adjust_phy_config(dsi, dsi_cfg, phy_cfg, mode, mode_valid_check); |
106 | + ret = cdns_dsi_adjust_phy_config(dsi, dsi_cfg, phy_cfg, mode); | 106 | + ret = cdns_dsi_adjust_phy_config(dsi, dsi_cfg, phy_cfg, mode); |
107 | if (ret) | 107 | if (ret) |
108 | return ret; | 108 | return ret; |
109 | 109 | ||
110 | @@ -XXX,XX +XXX,XX @@ cdns_dsi_bridge_mode_valid(struct drm_bridge *bridge, | 110 | @@ -XXX,XX +XXX,XX @@ cdns_dsi_bridge_mode_valid(struct drm_bridge *bridge, |
111 | struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge); | 111 | struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge); |
112 | struct cdns_dsi *dsi = input_to_dsi(input); | 112 | struct cdns_dsi *dsi = input_to_dsi(input); |
113 | struct cdns_dsi_output *output = &dsi->output; | 113 | struct cdns_dsi_output *output = &dsi->output; |
114 | - struct cdns_dsi_cfg dsi_cfg; | 114 | - struct cdns_dsi_cfg dsi_cfg; |
115 | - int bpp, ret; | 115 | - int bpp, ret; |
116 | + int bpp; | 116 | + int bpp; |
117 | 117 | ||
118 | /* | 118 | /* |
119 | * VFP_DSI should be less than VFP_DPI and VFP_DSI should be at | 119 | * VFP_DSI should be less than VFP_DPI and VFP_DSI should be at |
120 | @@ -XXX,XX +XXX,XX @@ cdns_dsi_bridge_mode_valid(struct drm_bridge *bridge, | 120 | @@ -XXX,XX +XXX,XX @@ cdns_dsi_bridge_mode_valid(struct drm_bridge *bridge, |
121 | if ((mode->hdisplay * bpp) % 32) | 121 | if ((mode->hdisplay * bpp) % 32) |
122 | return MODE_H_ILLEGAL; | 122 | return MODE_H_ILLEGAL; |
123 | 123 | ||
124 | - ret = cdns_dsi_check_conf(dsi, mode, &dsi_cfg, true); | 124 | - ret = cdns_dsi_check_conf(dsi, mode, &dsi_cfg, true); |
125 | - if (ret) | 125 | - if (ret) |
126 | - return MODE_BAD; | 126 | - return MODE_BAD; |
127 | - | 127 | - |
128 | return MODE_OK; | 128 | return MODE_OK; |
129 | } | 129 | } |
130 | 130 | ||
131 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_bridge_atomic_check(struct drm_bridge *bridge, | 131 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_bridge_atomic_check(struct drm_bridge *bridge, |
132 | adjusted_crtc_mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); | 132 | adjusted_crtc_mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); |
133 | adjusted_crtc_mode->flags |= DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC; | 133 | adjusted_crtc_mode->flags |= DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC; |
134 | 134 | ||
135 | - return cdns_dsi_check_conf(dsi, mode, dsi_cfg, false); | 135 | - return cdns_dsi_check_conf(dsi, mode, dsi_cfg, false); |
136 | + return cdns_dsi_check_conf(dsi, mode, dsi_cfg); | 136 | + return cdns_dsi_check_conf(dsi, mode, dsi_cfg); |
137 | } | 137 | } |
138 | 138 | ||
139 | static struct drm_bridge_state * | 139 | static struct drm_bridge_state * |
140 | 140 | ||
141 | -- | 141 | -- |
142 | 2.43.0 | 142 | 2.43.0 | diff view generated by jsdifflib |
1 | The driver uses crtc_* fields from the mode. While I think in the | 1 | The driver uses crtc_* fields from the mode. While I think in the |
---|---|---|---|
2 | enable-path this would be correct, I do not think it's correct in the | 2 | enable-path this would be correct, I do not think it's correct in the |
3 | check phase, as the crtc hasn't had a chance to update the crtc_* fields | 3 | check phase, as the crtc hasn't had a chance to update the crtc_* fields |
4 | yet. | 4 | yet. |
5 | 5 | ||
6 | Overall, my understanding is that the crtc_* fields are relevant only in | 6 | Overall, my understanding is that the crtc_* fields are relevant only in |
7 | cases where we have things like interlace or double pixel mode, where we | 7 | cases where we have things like interlace or double pixel mode, where we |
8 | have a logical and real timings. We never use those with DSI, so the | 8 | have a logical and real timings. We never use those with DSI, so the |
9 | crtc_* fields should just always match the normal values. | 9 | crtc_* fields should just always match the normal values. |
10 | 10 | ||
11 | So, drop the use of crtc_* values. | 11 | So, drop the use of crtc_* values. |
12 | 12 | ||
13 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> | 13 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> |
14 | --- | 14 | --- |
15 | drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 22 +++++++++++----------- | 15 | drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 22 +++++++++++----------- |
16 | 1 file changed, 11 insertions(+), 11 deletions(-) | 16 | 1 file changed, 11 insertions(+), 11 deletions(-) |
17 | 17 | ||
18 | diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 18 | diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
19 | index XXXXXXX..XXXXXXX 100644 | 19 | index XXXXXXX..XXXXXXX 100644 |
20 | --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 20 | --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
21 | +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 21 | +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
22 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi, | 22 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi, |
23 | bool sync_pulse; | 23 | bool sync_pulse; |
24 | int bpp; | 24 | int bpp; |
25 | 25 | ||
26 | - dpi_hsa = mode->crtc_hsync_end - mode->crtc_hsync_start; | 26 | - dpi_hsa = mode->crtc_hsync_end - mode->crtc_hsync_start; |
27 | - dpi_hbp = mode->crtc_htotal - mode->crtc_hsync_end; | 27 | - dpi_hbp = mode->crtc_htotal - mode->crtc_hsync_end; |
28 | - dpi_hfp = mode->crtc_hsync_start - mode->crtc_hdisplay; | 28 | - dpi_hfp = mode->crtc_hsync_start - mode->crtc_hdisplay; |
29 | - dpi_hact = mode->crtc_hdisplay; | 29 | - dpi_hact = mode->crtc_hdisplay; |
30 | + dpi_hsa = mode->hsync_end - mode->hsync_start; | 30 | + dpi_hsa = mode->hsync_end - mode->hsync_start; |
31 | + dpi_hbp = mode->htotal - mode->hsync_end; | 31 | + dpi_hbp = mode->htotal - mode->hsync_end; |
32 | + dpi_hfp = mode->hsync_start - mode->hdisplay; | 32 | + dpi_hfp = mode->hsync_start - mode->hdisplay; |
33 | + dpi_hact = mode->hdisplay; | 33 | + dpi_hact = mode->hdisplay; |
34 | 34 | ||
35 | memset(dsi_cfg, 0, sizeof(*dsi_cfg)); | 35 | memset(dsi_cfg, 0, sizeof(*dsi_cfg)); |
36 | 36 | ||
37 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_adjust_phy_config(struct cdns_dsi *dsi, | 37 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_adjust_phy_config(struct cdns_dsi *dsi, |
38 | if (dsi_htotal % lanes) | 38 | if (dsi_htotal % lanes) |
39 | adj_dsi_htotal += lanes - (dsi_htotal % lanes); | 39 | adj_dsi_htotal += lanes - (dsi_htotal % lanes); |
40 | 40 | ||
41 | - dpi_hz = mode->crtc_clock * 1000; | 41 | - dpi_hz = mode->crtc_clock * 1000; |
42 | + dpi_hz = mode->clock * 1000; | 42 | + dpi_hz = mode->clock * 1000; |
43 | dlane_bps = (unsigned long long)dpi_hz * adj_dsi_htotal; | 43 | dlane_bps = (unsigned long long)dpi_hz * adj_dsi_htotal; |
44 | 44 | ||
45 | /* data rate in bytes/sec is not an integer, refuse the mode. */ | 45 | /* data rate in bytes/sec is not an integer, refuse the mode. */ |
46 | - dpi_htotal = mode->crtc_htotal; | 46 | - dpi_htotal = mode->crtc_htotal; |
47 | + dpi_htotal = mode->htotal; | 47 | + dpi_htotal = mode->htotal; |
48 | if (do_div(dlane_bps, lanes * dpi_htotal)) | 48 | if (do_div(dlane_bps, lanes * dpi_htotal)) |
49 | return -EINVAL; | 49 | return -EINVAL; |
50 | 50 | ||
51 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_check_conf(struct cdns_dsi *dsi, | 51 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_check_conf(struct cdns_dsi *dsi, |
52 | if (ret) | 52 | if (ret) |
53 | return ret; | 53 | return ret; |
54 | 54 | ||
55 | - ret = phy_mipi_dphy_get_default_config(mode->crtc_clock * 1000, | 55 | - ret = phy_mipi_dphy_get_default_config(mode->crtc_clock * 1000, |
56 | + ret = phy_mipi_dphy_get_default_config(mode->clock * 1000, | 56 | + ret = phy_mipi_dphy_get_default_config(mode->clock * 1000, |
57 | mipi_dsi_pixel_format_to_bpp(output->dev->format), | 57 | mipi_dsi_pixel_format_to_bpp(output->dev->format), |
58 | nlanes, phy_cfg); | 58 | nlanes, phy_cfg); |
59 | if (ret) | 59 | if (ret) |
60 | @@ -XXX,XX +XXX,XX @@ static void cdns_dsi_bridge_atomic_pre_enable(struct drm_bridge *bridge, | 60 | @@ -XXX,XX +XXX,XX @@ static void cdns_dsi_bridge_atomic_pre_enable(struct drm_bridge *bridge, |
61 | writel(HFP_LEN(dsi_cfg.hfp) | HACT_LEN(dsi_cfg.hact), | 61 | writel(HFP_LEN(dsi_cfg.hfp) | HACT_LEN(dsi_cfg.hact), |
62 | dsi->regs + VID_HSIZE2); | 62 | dsi->regs + VID_HSIZE2); |
63 | 63 | ||
64 | - writel(VBP_LEN(mode->crtc_vtotal - mode->crtc_vsync_end - 1) | | 64 | - writel(VBP_LEN(mode->crtc_vtotal - mode->crtc_vsync_end - 1) | |
65 | - VFP_LEN(mode->crtc_vsync_start - mode->crtc_vdisplay) | | 65 | - VFP_LEN(mode->crtc_vsync_start - mode->crtc_vdisplay) | |
66 | - VSA_LEN(mode->crtc_vsync_end - mode->crtc_vsync_start + 1), | 66 | - VSA_LEN(mode->crtc_vsync_end - mode->crtc_vsync_start + 1), |
67 | + writel(VBP_LEN(mode->vtotal - mode->vsync_end - 1) | | 67 | + writel(VBP_LEN(mode->vtotal - mode->vsync_end - 1) | |
68 | + VFP_LEN(mode->vsync_start - mode->vdisplay) | | 68 | + VFP_LEN(mode->vsync_start - mode->vdisplay) | |
69 | + VSA_LEN(mode->vsync_end - mode->vsync_start + 1), | 69 | + VSA_LEN(mode->vsync_end - mode->vsync_start + 1), |
70 | dsi->regs + VID_VSIZE1); | 70 | dsi->regs + VID_VSIZE1); |
71 | - writel(mode->crtc_vdisplay, dsi->regs + VID_VSIZE2); | 71 | - writel(mode->crtc_vdisplay, dsi->regs + VID_VSIZE2); |
72 | + writel(mode->vdisplay, dsi->regs + VID_VSIZE2); | 72 | + writel(mode->vdisplay, dsi->regs + VID_VSIZE2); |
73 | 73 | ||
74 | tmp = dsi_cfg.htotal - | 74 | tmp = dsi_cfg.htotal - |
75 | (dsi_cfg.hsa + DSI_BLANKING_FRAME_OVERHEAD + | 75 | (dsi_cfg.hsa + DSI_BLANKING_FRAME_OVERHEAD + |
76 | 76 | ||
77 | -- | 77 | -- |
78 | 2.43.0 | 78 | 2.43.0 | diff view generated by jsdifflib |
1 | The drm_display_mode is a bit difficult one to use (we need hfp, hbp, | 1 | The drm_display_mode is a bit difficult one to use (we need hfp, hbp, |
---|---|---|---|
2 | ... instead of hsync_start, hsync_end, ...) and understand (when to use | 2 | ... instead of hsync_start, hsync_end, ...) and understand (when to use |
3 | crtc_* fields). | 3 | crtc_* fields). |
4 | 4 | ||
5 | To simplify the code, use struct videomode internally which cleans up | 5 | To simplify the code, use struct videomode internally which cleans up |
6 | the code. If in the future we want to use crtc_* fields in some code | 6 | the code. If in the future we want to use crtc_* fields in some code |
7 | patchs, that can be easily achieved by creating a videomode from the | 7 | patchs, that can be easily achieved by creating a videomode from the |
8 | crtc_* fields, and no change to the functions that do the work is | 8 | crtc_* fields, and no change to the functions that do the work is |
9 | needed. | 9 | needed. |
10 | 10 | ||
11 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> | 11 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> |
12 | --- | 12 | --- |
13 | drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 31 +++++++++++++++----------- | 13 | drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 31 +++++++++++++++----------- |
14 | 1 file changed, 18 insertions(+), 13 deletions(-) | 14 | 1 file changed, 18 insertions(+), 13 deletions(-) |
15 | 15 | ||
16 | diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 16 | diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
17 | index XXXXXXX..XXXXXXX 100644 | 17 | index XXXXXXX..XXXXXXX 100644 |
18 | --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 18 | --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
19 | +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 19 | +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
20 | @@ -XXX,XX +XXX,XX @@ | 20 | @@ -XXX,XX +XXX,XX @@ |
21 | #include <drm/drm_drv.h> | 21 | #include <drm/drm_drv.h> |
22 | #include <drm/drm_probe_helper.h> | 22 | #include <drm/drm_probe_helper.h> |
23 | #include <video/mipi_display.h> | 23 | #include <video/mipi_display.h> |
24 | +#include <video/videomode.h> | 24 | +#include <video/videomode.h> |
25 | 25 | ||
26 | #include <linux/clk.h> | 26 | #include <linux/clk.h> |
27 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
28 | @@ -XXX,XX +XXX,XX @@ static unsigned int dpi_to_dsi_timing(unsigned int dpi_timing, | 28 | @@ -XXX,XX +XXX,XX @@ static unsigned int dpi_to_dsi_timing(unsigned int dpi_timing, |
29 | } | 29 | } |
30 | 30 | ||
31 | static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi, | 31 | static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi, |
32 | - const struct drm_display_mode *mode, | 32 | - const struct drm_display_mode *mode, |
33 | + const struct videomode *vm, | 33 | + const struct videomode *vm, |
34 | struct cdns_dsi_cfg *dsi_cfg) | 34 | struct cdns_dsi_cfg *dsi_cfg) |
35 | { | 35 | { |
36 | struct cdns_dsi_output *output = &dsi->output; | 36 | struct cdns_dsi_output *output = &dsi->output; |
37 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi, | 37 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi, |
38 | bool sync_pulse; | 38 | bool sync_pulse; |
39 | int bpp; | 39 | int bpp; |
40 | 40 | ||
41 | - dpi_hsa = mode->hsync_end - mode->hsync_start; | 41 | - dpi_hsa = mode->hsync_end - mode->hsync_start; |
42 | - dpi_hbp = mode->htotal - mode->hsync_end; | 42 | - dpi_hbp = mode->htotal - mode->hsync_end; |
43 | - dpi_hfp = mode->hsync_start - mode->hdisplay; | 43 | - dpi_hfp = mode->hsync_start - mode->hdisplay; |
44 | - dpi_hact = mode->hdisplay; | 44 | - dpi_hact = mode->hdisplay; |
45 | + dpi_hsa = vm->hsync_len; | 45 | + dpi_hsa = vm->hsync_len; |
46 | + dpi_hbp = vm->hback_porch; | 46 | + dpi_hbp = vm->hback_porch; |
47 | + dpi_hfp = vm->hfront_porch; | 47 | + dpi_hfp = vm->hfront_porch; |
48 | + dpi_hact = vm->hactive; | 48 | + dpi_hact = vm->hactive; |
49 | 49 | ||
50 | memset(dsi_cfg, 0, sizeof(*dsi_cfg)); | 50 | memset(dsi_cfg, 0, sizeof(*dsi_cfg)); |
51 | 51 | ||
52 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi, | 52 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi, |
53 | static int cdns_dsi_adjust_phy_config(struct cdns_dsi *dsi, | 53 | static int cdns_dsi_adjust_phy_config(struct cdns_dsi *dsi, |
54 | struct cdns_dsi_cfg *dsi_cfg, | 54 | struct cdns_dsi_cfg *dsi_cfg, |
55 | struct phy_configure_opts_mipi_dphy *phy_cfg, | 55 | struct phy_configure_opts_mipi_dphy *phy_cfg, |
56 | - const struct drm_display_mode *mode) | 56 | - const struct drm_display_mode *mode) |
57 | + const struct videomode *vm) | 57 | + const struct videomode *vm) |
58 | { | 58 | { |
59 | struct cdns_dsi_output *output = &dsi->output; | 59 | struct cdns_dsi_output *output = &dsi->output; |
60 | unsigned long long dlane_bps; | 60 | unsigned long long dlane_bps; |
61 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_adjust_phy_config(struct cdns_dsi *dsi, | 61 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_adjust_phy_config(struct cdns_dsi *dsi, |
62 | if (dsi_htotal % lanes) | 62 | if (dsi_htotal % lanes) |
63 | adj_dsi_htotal += lanes - (dsi_htotal % lanes); | 63 | adj_dsi_htotal += lanes - (dsi_htotal % lanes); |
64 | 64 | ||
65 | - dpi_hz = mode->clock * 1000; | 65 | - dpi_hz = mode->clock * 1000; |
66 | + dpi_hz = vm->pixelclock; | 66 | + dpi_hz = vm->pixelclock; |
67 | dlane_bps = (unsigned long long)dpi_hz * adj_dsi_htotal; | 67 | dlane_bps = (unsigned long long)dpi_hz * adj_dsi_htotal; |
68 | 68 | ||
69 | /* data rate in bytes/sec is not an integer, refuse the mode. */ | 69 | /* data rate in bytes/sec is not an integer, refuse the mode. */ |
70 | - dpi_htotal = mode->htotal; | 70 | - dpi_htotal = mode->htotal; |
71 | + dpi_htotal = vm->hactive + vm->hfront_porch + vm->hback_porch + | 71 | + dpi_htotal = vm->hactive + vm->hfront_porch + vm->hback_porch + |
72 | + vm->hsync_len; | 72 | + vm->hsync_len; |
73 | if (do_div(dlane_bps, lanes * dpi_htotal)) | 73 | if (do_div(dlane_bps, lanes * dpi_htotal)) |
74 | return -EINVAL; | 74 | return -EINVAL; |
75 | 75 | ||
76 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_adjust_phy_config(struct cdns_dsi *dsi, | 76 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_adjust_phy_config(struct cdns_dsi *dsi, |
77 | } | 77 | } |
78 | 78 | ||
79 | static int cdns_dsi_check_conf(struct cdns_dsi *dsi, | 79 | static int cdns_dsi_check_conf(struct cdns_dsi *dsi, |
80 | - const struct drm_display_mode *mode, | 80 | - const struct drm_display_mode *mode, |
81 | + const struct videomode *vm, | 81 | + const struct videomode *vm, |
82 | struct cdns_dsi_cfg *dsi_cfg) | 82 | struct cdns_dsi_cfg *dsi_cfg) |
83 | { | 83 | { |
84 | struct cdns_dsi_output *output = &dsi->output; | 84 | struct cdns_dsi_output *output = &dsi->output; |
85 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_check_conf(struct cdns_dsi *dsi, | 85 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_check_conf(struct cdns_dsi *dsi, |
86 | unsigned long req_hs_clk_rate; | 86 | unsigned long req_hs_clk_rate; |
87 | int ret; | 87 | int ret; |
88 | 88 | ||
89 | - ret = cdns_dsi_mode2cfg(dsi, mode, dsi_cfg); | 89 | - ret = cdns_dsi_mode2cfg(dsi, mode, dsi_cfg); |
90 | + ret = cdns_dsi_mode2cfg(dsi, vm, dsi_cfg); | 90 | + ret = cdns_dsi_mode2cfg(dsi, vm, dsi_cfg); |
91 | if (ret) | 91 | if (ret) |
92 | return ret; | 92 | return ret; |
93 | 93 | ||
94 | - ret = phy_mipi_dphy_get_default_config(mode->clock * 1000, | 94 | - ret = phy_mipi_dphy_get_default_config(mode->clock * 1000, |
95 | + ret = phy_mipi_dphy_get_default_config(vm->pixelclock, | 95 | + ret = phy_mipi_dphy_get_default_config(vm->pixelclock, |
96 | mipi_dsi_pixel_format_to_bpp(output->dev->format), | 96 | mipi_dsi_pixel_format_to_bpp(output->dev->format), |
97 | nlanes, phy_cfg); | 97 | nlanes, phy_cfg); |
98 | if (ret) | 98 | if (ret) |
99 | return ret; | 99 | return ret; |
100 | 100 | ||
101 | - ret = cdns_dsi_adjust_phy_config(dsi, dsi_cfg, phy_cfg, mode); | 101 | - ret = cdns_dsi_adjust_phy_config(dsi, dsi_cfg, phy_cfg, mode); |
102 | + ret = cdns_dsi_adjust_phy_config(dsi, dsi_cfg, phy_cfg, vm); | 102 | + ret = cdns_dsi_adjust_phy_config(dsi, dsi_cfg, phy_cfg, vm); |
103 | if (ret) | 103 | if (ret) |
104 | return ret; | 104 | return ret; |
105 | 105 | ||
106 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_bridge_atomic_check(struct drm_bridge *bridge, | 106 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_bridge_atomic_check(struct drm_bridge *bridge, |
107 | const struct drm_display_mode *mode = &crtc_state->mode; | 107 | const struct drm_display_mode *mode = &crtc_state->mode; |
108 | struct cdns_dsi_cfg *dsi_cfg = &dsi_state->dsi_cfg; | 108 | struct cdns_dsi_cfg *dsi_cfg = &dsi_state->dsi_cfg; |
109 | struct drm_display_mode *adjusted_crtc_mode = &crtc_state->adjusted_mode; | 109 | struct drm_display_mode *adjusted_crtc_mode = &crtc_state->adjusted_mode; |
110 | + struct videomode vm; | 110 | + struct videomode vm; |
111 | 111 | ||
112 | /* cdns-dsi requires negative syncs */ | 112 | /* cdns-dsi requires negative syncs */ |
113 | adjusted_crtc_mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); | 113 | adjusted_crtc_mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); |
114 | adjusted_crtc_mode->flags |= DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC; | 114 | adjusted_crtc_mode->flags |= DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC; |
115 | 115 | ||
116 | - return cdns_dsi_check_conf(dsi, mode, dsi_cfg); | 116 | - return cdns_dsi_check_conf(dsi, mode, dsi_cfg); |
117 | + drm_display_mode_to_videomode(mode, &vm); | 117 | + drm_display_mode_to_videomode(mode, &vm); |
118 | + | 118 | + |
119 | + return cdns_dsi_check_conf(dsi, &vm, dsi_cfg); | 119 | + return cdns_dsi_check_conf(dsi, &vm, dsi_cfg); |
120 | } | 120 | } |
121 | 121 | ||
122 | static struct drm_bridge_state * | 122 | static struct drm_bridge_state * |
123 | 123 | ||
124 | -- | 124 | -- |
125 | 2.43.0 | 125 | 2.43.0 | diff view generated by jsdifflib |
1 | The driver currently expects the pixel clock and the HS clock to be | 1 | The driver currently expects the pixel clock and the HS clock to be |
---|---|---|---|
2 | compatible, but the DPHY PLL doesn't give very finely grained rates. | 2 | compatible, but the DPHY PLL doesn't give very finely grained rates. |
3 | This often leads to the situation where the pipeline just fails, as the | 3 | This often leads to the situation where the pipeline just fails, as the |
4 | resulting HS clock is just too off. | 4 | resulting HS clock is just too off. |
5 | 5 | ||
6 | We could change the driver to do a better job on adjusting the DSI | 6 | We could change the driver to do a better job on adjusting the DSI |
7 | blanking values, hopefully getting a working pipeline even if the pclk | 7 | blanking values, hopefully getting a working pipeline even if the pclk |
8 | and HS clocks are not exactly compatible. But that is a bigger work. | 8 | and HS clocks are not exactly compatible. But that is a bigger work. |
9 | 9 | ||
10 | What we can do easily is to see in .atomic_check() what HS clock rate we | 10 | What we can do easily is to see in .atomic_check() what HS clock rate we |
11 | can get, based on the pixel clock rate, and then convert the HS clock | 11 | can get, based on the pixel clock rate, and then convert the HS clock |
12 | rate back to pixel clock rate and ask that rate from the crtc. If the | 12 | rate back to pixel clock rate and ask that rate from the crtc. If the |
13 | crtc has a good PLL (which is the case for TI K3 SoCs), this will fix | 13 | crtc has a good PLL (which is the case for TI K3 SoCs), this will fix |
14 | any issues wrt. the clock rates. | 14 | any issues wrt. the clock rates. |
15 | 15 | ||
16 | If the crtc cannot provide the requested clock, well, we're no worse off | 16 | If the crtc cannot provide the requested clock, well, we're no worse off |
17 | with this patch than what we have at the moment. | 17 | with this patch than what we have at the moment. |
18 | 18 | ||
19 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> | 19 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> |
20 | --- | 20 | --- |
21 | drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 39 +++++++++++++++++++++++++- | 21 | drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 39 +++++++++++++++++++++++++- |
22 | 1 file changed, 38 insertions(+), 1 deletion(-) | 22 | 1 file changed, 38 insertions(+), 1 deletion(-) |
23 | 23 | ||
24 | diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 24 | diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
25 | index XXXXXXX..XXXXXXX 100644 | 25 | index XXXXXXX..XXXXXXX 100644 |
26 | --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 26 | --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
27 | +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 27 | +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
28 | @@ -XXX,XX +XXX,XX @@ static u32 *cdns_dsi_bridge_get_input_bus_fmts(struct drm_bridge *bridge, | 28 | @@ -XXX,XX +XXX,XX @@ static u32 *cdns_dsi_bridge_get_input_bus_fmts(struct drm_bridge *bridge, |
29 | return input_fmts; | 29 | return input_fmts; |
30 | } | 30 | } |
31 | 31 | ||
32 | +static long cdns_dsi_round_pclk(struct cdns_dsi *dsi, unsigned long pclk) | 32 | +static long cdns_dsi_round_pclk(struct cdns_dsi *dsi, unsigned long pclk) |
33 | +{ | 33 | +{ |
34 | + struct cdns_dsi_output *output = &dsi->output; | 34 | + struct cdns_dsi_output *output = &dsi->output; |
35 | + unsigned int nlanes = output->dev->lanes; | 35 | + unsigned int nlanes = output->dev->lanes; |
36 | + union phy_configure_opts phy_opts = { 0 }; | 36 | + union phy_configure_opts phy_opts = { 0 }; |
37 | + u32 bitspp; | 37 | + u32 bitspp; |
38 | + int ret; | 38 | + int ret; |
39 | + | 39 | + |
40 | + bitspp = mipi_dsi_pixel_format_to_bpp(output->dev->format); | 40 | + bitspp = mipi_dsi_pixel_format_to_bpp(output->dev->format); |
41 | + | 41 | + |
42 | + ret = phy_mipi_dphy_get_default_config(pclk, bitspp, nlanes, | 42 | + ret = phy_mipi_dphy_get_default_config(pclk, bitspp, nlanes, |
43 | + &phy_opts.mipi_dphy); | 43 | + &phy_opts.mipi_dphy); |
44 | + if (ret) | 44 | + if (ret) |
45 | + return ret; | 45 | + return ret; |
46 | + | 46 | + |
47 | + ret = phy_validate(dsi->dphy, PHY_MODE_MIPI_DPHY, 0, &phy_opts); | 47 | + ret = phy_validate(dsi->dphy, PHY_MODE_MIPI_DPHY, 0, &phy_opts); |
48 | + if (ret) | 48 | + if (ret) |
49 | + return ret; | 49 | + return ret; |
50 | + | 50 | + |
51 | + return div64_u64((u64)phy_opts.mipi_dphy.hs_clk_rate * nlanes, bitspp); | 51 | + return div64_u64((u64)phy_opts.mipi_dphy.hs_clk_rate * nlanes, bitspp); |
52 | +} | 52 | +} |
53 | + | 53 | + |
54 | static int cdns_dsi_bridge_atomic_check(struct drm_bridge *bridge, | 54 | static int cdns_dsi_bridge_atomic_check(struct drm_bridge *bridge, |
55 | struct drm_bridge_state *bridge_state, | 55 | struct drm_bridge_state *bridge_state, |
56 | struct drm_crtc_state *crtc_state, | 56 | struct drm_crtc_state *crtc_state, |
57 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_bridge_atomic_check(struct drm_bridge *bridge, | 57 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_bridge_atomic_check(struct drm_bridge *bridge, |
58 | struct cdns_dsi_cfg *dsi_cfg = &dsi_state->dsi_cfg; | 58 | struct cdns_dsi_cfg *dsi_cfg = &dsi_state->dsi_cfg; |
59 | struct drm_display_mode *adjusted_crtc_mode = &crtc_state->adjusted_mode; | 59 | struct drm_display_mode *adjusted_crtc_mode = &crtc_state->adjusted_mode; |
60 | struct videomode vm; | 60 | struct videomode vm; |
61 | + long pclk; | 61 | + long pclk; |
62 | 62 | ||
63 | /* cdns-dsi requires negative syncs */ | 63 | /* cdns-dsi requires negative syncs */ |
64 | adjusted_crtc_mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); | 64 | adjusted_crtc_mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); |
65 | adjusted_crtc_mode->flags |= DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC; | 65 | adjusted_crtc_mode->flags |= DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC; |
66 | 66 | ||
67 | - drm_display_mode_to_videomode(mode, &vm); | 67 | - drm_display_mode_to_videomode(mode, &vm); |
68 | + /* | 68 | + /* |
69 | + * The DPHY PLL has quite a coarsely grained clock rate options. See | 69 | + * The DPHY PLL has quite a coarsely grained clock rate options. See |
70 | + * what hsclk rate we can achieve based on the pixel clock, convert it | 70 | + * what hsclk rate we can achieve based on the pixel clock, convert it |
71 | + * back to pixel clock, set that to the adjusted_mode->clock. This is | 71 | + * back to pixel clock, set that to the adjusted_mode->clock. This is |
72 | + * all in hopes that the CRTC will be able to provide us the requested | 72 | + * all in hopes that the CRTC will be able to provide us the requested |
73 | + * clock, as otherwise the DPI and DSI clocks will be out of sync. | 73 | + * clock, as otherwise the DPI and DSI clocks will be out of sync. |
74 | + */ | 74 | + */ |
75 | + | 75 | + |
76 | + pclk = cdns_dsi_round_pclk(dsi, mode->clock * 1000); | 76 | + pclk = cdns_dsi_round_pclk(dsi, mode->clock * 1000); |
77 | + if (pclk < 0) | 77 | + if (pclk < 0) |
78 | + return (int)pclk; | 78 | + return (int)pclk; |
79 | + | 79 | + |
80 | + adjusted_crtc_mode->clock = pclk / 1000; | 80 | + adjusted_crtc_mode->clock = pclk / 1000; |
81 | + | 81 | + |
82 | + drm_display_mode_to_videomode(adjusted_crtc_mode, &vm); | 82 | + drm_display_mode_to_videomode(adjusted_crtc_mode, &vm); |
83 | 83 | ||
84 | return cdns_dsi_check_conf(dsi, &vm, dsi_cfg); | 84 | return cdns_dsi_check_conf(dsi, &vm, dsi_cfg); |
85 | } | 85 | } |
86 | 86 | ||
87 | -- | 87 | -- |
88 | 2.43.0 | 88 | 2.43.0 | diff view generated by jsdifflib |
1 | cdns_dsi_mode2cfg() calculates the dsi timings, but for some reason | 1 | cdns_dsi_mode2cfg() calculates the dsi timings, but for some reason |
---|---|---|---|
2 | doesn't set the htotal based on those timings. It is set only later, in | 2 | doesn't set the htotal based on those timings. It is set only later, in |
3 | cdns_dsi_adjust_phy_config(). | 3 | cdns_dsi_adjust_phy_config(). |
4 | 4 | ||
5 | As cdns_dsi_mode2cfg() is the logical place to calculate it, let's move | 5 | As cdns_dsi_mode2cfg() is the logical place to calculate it, let's move |
6 | it there. Especially as the following patch will remove | 6 | it there. Especially as the following patch will remove |
7 | cdns_dsi_adjust_phy_config(). | 7 | cdns_dsi_adjust_phy_config(). |
8 | 8 | ||
9 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> | 9 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> |
10 | --- | 10 | --- |
11 | drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 19 ++++++++++--------- | 11 | drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 19 ++++++++++--------- |
12 | 1 file changed, 10 insertions(+), 9 deletions(-) | 12 | 1 file changed, 10 insertions(+), 9 deletions(-) |
13 | 13 | ||
14 | diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 14 | diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
15 | index XXXXXXX..XXXXXXX 100644 | 15 | index XXXXXXX..XXXXXXX 100644 |
16 | --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 16 | --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
17 | +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 17 | +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
18 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi, | 18 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi, |
19 | 19 | ||
20 | dsi_cfg->hfp = dpi_to_dsi_timing(dpi_hfp, bpp, DSI_HFP_FRAME_OVERHEAD); | 20 | dsi_cfg->hfp = dpi_to_dsi_timing(dpi_hfp, bpp, DSI_HFP_FRAME_OVERHEAD); |
21 | 21 | ||
22 | + dsi_cfg->htotal = dsi_cfg->hact + dsi_cfg->hfp + DSI_HFP_FRAME_OVERHEAD; | 22 | + dsi_cfg->htotal = dsi_cfg->hact + dsi_cfg->hfp + DSI_HFP_FRAME_OVERHEAD; |
23 | + | 23 | + |
24 | + if (sync_pulse) { | 24 | + if (sync_pulse) { |
25 | + dsi_cfg->htotal += dsi_cfg->hbp + DSI_HBP_FRAME_PULSE_OVERHEAD; | 25 | + dsi_cfg->htotal += dsi_cfg->hbp + DSI_HBP_FRAME_PULSE_OVERHEAD; |
26 | + dsi_cfg->htotal += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD; | 26 | + dsi_cfg->htotal += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD; |
27 | + } else { | 27 | + } else { |
28 | + dsi_cfg->htotal += dsi_cfg->hbp + DSI_HBP_FRAME_EVENT_OVERHEAD; | 28 | + dsi_cfg->htotal += dsi_cfg->hbp + DSI_HBP_FRAME_EVENT_OVERHEAD; |
29 | + } | 29 | + } |
30 | + | 30 | + |
31 | return 0; | 31 | return 0; |
32 | } | 32 | } |
33 | 33 | ||
34 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_adjust_phy_config(struct cdns_dsi *dsi, | 34 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_adjust_phy_config(struct cdns_dsi *dsi, |
35 | unsigned int dsi_hfp_ext; | 35 | unsigned int dsi_hfp_ext; |
36 | unsigned int lanes = output->dev->lanes; | 36 | unsigned int lanes = output->dev->lanes; |
37 | 37 | ||
38 | - if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) { | 38 | - if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) { |
39 | - dsi_htotal = dsi_cfg->hbp + DSI_HBP_FRAME_PULSE_OVERHEAD; | 39 | - dsi_htotal = dsi_cfg->hbp + DSI_HBP_FRAME_PULSE_OVERHEAD; |
40 | - dsi_htotal += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD; | 40 | - dsi_htotal += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD; |
41 | - } else { | 41 | - } else { |
42 | - dsi_htotal = dsi_cfg->hbp + DSI_HBP_FRAME_EVENT_OVERHEAD; | 42 | - dsi_htotal = dsi_cfg->hbp + DSI_HBP_FRAME_EVENT_OVERHEAD; |
43 | - } | 43 | - } |
44 | - | 44 | - |
45 | - dsi_htotal += dsi_cfg->hact; | 45 | - dsi_htotal += dsi_cfg->hact; |
46 | - dsi_htotal += dsi_cfg->hfp + DSI_HFP_FRAME_OVERHEAD; | 46 | - dsi_htotal += dsi_cfg->hfp + DSI_HFP_FRAME_OVERHEAD; |
47 | + dsi_htotal = dsi_cfg->htotal; | 47 | + dsi_htotal = dsi_cfg->htotal; |
48 | 48 | ||
49 | /* | 49 | /* |
50 | * Make sure DSI htotal is aligned on a lane boundary when calculating | 50 | * Make sure DSI htotal is aligned on a lane boundary when calculating |
51 | 51 | ||
52 | -- | 52 | -- |
53 | 2.43.0 | 53 | 2.43.0 | diff view generated by jsdifflib |
1 | cdns_dsi_adjust_phy_config() is called from | 1 | cdns_dsi_adjust_phy_config() is called from |
---|---|---|---|
2 | cdns_dsi_adjust_phy_config(), which is called from .atomic_check(). It | 2 | cdns_dsi_adjust_phy_config(), which is called from .atomic_check(). It |
3 | checks the DSI htotal and adjusts it to align on the DSI lane boundary | 3 | checks the DSI htotal and adjusts it to align on the DSI lane boundary |
4 | by changing hfp and then recalculating htotal and HS clock rate. | 4 | by changing hfp and then recalculating htotal and HS clock rate. |
5 | 5 | ||
6 | This has a few problems. | 6 | This has a few problems. |
7 | 7 | ||
8 | First is the fact that the whole thing is not needed: we do not need to | 8 | First is the fact that the whole thing is not needed: we do not need to |
9 | align on the lane boundary. The whole frame is sent in HS mode, and it | 9 | align on the lane boundary. The whole frame is sent in HS mode, and it |
10 | is fine if the line's last byte clock tick fills, say, only 2 of the 4 | 10 | is fine if the line's last byte clock tick fills, say, only 2 of the 4 |
11 | lanes. The next line will just continue from there. Assuming the | 11 | lanes. The next line will just continue from there. Assuming the |
12 | DSI timing values have been calculated to match the incoming DPI stream, | 12 | DSI timing values have been calculated to match the incoming DPI stream, |
13 | and the HS clock is compatible with the DPI pixel clock, the "uneven" | 13 | and the HS clock is compatible with the DPI pixel clock, the "uneven" |
14 | DSI lines will even out when multiple lines are being sent. | 14 | DSI lines will even out when multiple lines are being sent. |
15 | 15 | ||
16 | But we could do the align, aligning is not a problem as such. However, | 16 | But we could do the align, aligning is not a problem as such. However, |
17 | adding more bytes to the hfp, as the function currently does, makes the | 17 | adding more bytes to the hfp, as the function currently does, makes the |
18 | DSI line time longer, so the function then adjusts the HS clock rate. | 18 | DSI line time longer, so the function then adjusts the HS clock rate. |
19 | This is where things fail: we don't know what rates we can get from the | 19 | This is where things fail: we don't know what rates we can get from the |
20 | HS clock, and at least in TI K3 SoC case the rates are quite coarsely | 20 | HS clock, and at least in TI K3 SoC case the rates are quite coarsely |
21 | grained. Thus small adjustment to hfp will lead to a big change in HS | 21 | grained. Thus small adjustment to hfp will lead to a big change in HS |
22 | clock rate, and things break down. | 22 | clock rate, and things break down. |
23 | 23 | ||
24 | We could do a loop here, adjusting hfp, adjusting clock, checking clock | 24 | We could do a loop here, adjusting hfp, adjusting clock, checking clock |
25 | rate, adjusting hfp again, etc., but considering that the whole | 25 | rate, adjusting hfp again, etc., but considering that the whole |
26 | adjustment shouldn't be needed at all, it's easier to just remove the | 26 | adjustment shouldn't be needed at all, it's easier to just remove the |
27 | function. | 27 | function. |
28 | 28 | ||
29 | Something like this function should be added back later, when adding | 29 | Something like this function should be added back later, when adding |
30 | burst mode support, but that's a bigger change and I don't think this | 30 | burst mode support, but that's a bigger change and I don't think this |
31 | function would help that work in any way. | 31 | function would help that work in any way. |
32 | 32 | ||
33 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> | 33 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> |
34 | --- | 34 | --- |
35 | drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 48 -------------------------- | 35 | drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 48 -------------------------- |
36 | 1 file changed, 48 deletions(-) | 36 | 1 file changed, 48 deletions(-) |
37 | 37 | ||
38 | diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 38 | diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
39 | index XXXXXXX..XXXXXXX 100644 | 39 | index XXXXXXX..XXXXXXX 100644 |
40 | --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 40 | --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
41 | +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 41 | +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
42 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi, | 42 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi, |
43 | return 0; | 43 | return 0; |
44 | } | 44 | } |
45 | 45 | ||
46 | -static int cdns_dsi_adjust_phy_config(struct cdns_dsi *dsi, | 46 | -static int cdns_dsi_adjust_phy_config(struct cdns_dsi *dsi, |
47 | - struct cdns_dsi_cfg *dsi_cfg, | 47 | - struct cdns_dsi_cfg *dsi_cfg, |
48 | - struct phy_configure_opts_mipi_dphy *phy_cfg, | 48 | - struct phy_configure_opts_mipi_dphy *phy_cfg, |
49 | - const struct videomode *vm) | 49 | - const struct videomode *vm) |
50 | -{ | 50 | -{ |
51 | - struct cdns_dsi_output *output = &dsi->output; | 51 | - struct cdns_dsi_output *output = &dsi->output; |
52 | - unsigned long long dlane_bps; | 52 | - unsigned long long dlane_bps; |
53 | - unsigned long adj_dsi_htotal; | 53 | - unsigned long adj_dsi_htotal; |
54 | - unsigned long dsi_htotal; | 54 | - unsigned long dsi_htotal; |
55 | - unsigned long dpi_htotal; | 55 | - unsigned long dpi_htotal; |
56 | - unsigned long dpi_hz; | 56 | - unsigned long dpi_hz; |
57 | - unsigned int dsi_hfp_ext; | 57 | - unsigned int dsi_hfp_ext; |
58 | - unsigned int lanes = output->dev->lanes; | 58 | - unsigned int lanes = output->dev->lanes; |
59 | - | 59 | - |
60 | - dsi_htotal = dsi_cfg->htotal; | 60 | - dsi_htotal = dsi_cfg->htotal; |
61 | - | 61 | - |
62 | - /* | 62 | - /* |
63 | - * Make sure DSI htotal is aligned on a lane boundary when calculating | 63 | - * Make sure DSI htotal is aligned on a lane boundary when calculating |
64 | - * the expected data rate. This is done by extending HFP in case of | 64 | - * the expected data rate. This is done by extending HFP in case of |
65 | - * misalignment. | 65 | - * misalignment. |
66 | - */ | 66 | - */ |
67 | - adj_dsi_htotal = dsi_htotal; | 67 | - adj_dsi_htotal = dsi_htotal; |
68 | - if (dsi_htotal % lanes) | 68 | - if (dsi_htotal % lanes) |
69 | - adj_dsi_htotal += lanes - (dsi_htotal % lanes); | 69 | - adj_dsi_htotal += lanes - (dsi_htotal % lanes); |
70 | - | 70 | - |
71 | - dpi_hz = vm->pixelclock; | 71 | - dpi_hz = vm->pixelclock; |
72 | - dlane_bps = (unsigned long long)dpi_hz * adj_dsi_htotal; | 72 | - dlane_bps = (unsigned long long)dpi_hz * adj_dsi_htotal; |
73 | - | 73 | - |
74 | - /* data rate in bytes/sec is not an integer, refuse the mode. */ | 74 | - /* data rate in bytes/sec is not an integer, refuse the mode. */ |
75 | - dpi_htotal = vm->hactive + vm->hfront_porch + vm->hback_porch + | 75 | - dpi_htotal = vm->hactive + vm->hfront_porch + vm->hback_porch + |
76 | - vm->hsync_len; | 76 | - vm->hsync_len; |
77 | - if (do_div(dlane_bps, lanes * dpi_htotal)) | 77 | - if (do_div(dlane_bps, lanes * dpi_htotal)) |
78 | - return -EINVAL; | 78 | - return -EINVAL; |
79 | - | 79 | - |
80 | - /* data rate was in bytes/sec, convert to bits/sec. */ | 80 | - /* data rate was in bytes/sec, convert to bits/sec. */ |
81 | - phy_cfg->hs_clk_rate = dlane_bps * 8; | 81 | - phy_cfg->hs_clk_rate = dlane_bps * 8; |
82 | - | 82 | - |
83 | - dsi_hfp_ext = adj_dsi_htotal - dsi_htotal; | 83 | - dsi_hfp_ext = adj_dsi_htotal - dsi_htotal; |
84 | - dsi_cfg->hfp += dsi_hfp_ext; | 84 | - dsi_cfg->hfp += dsi_hfp_ext; |
85 | - dsi_cfg->htotal = dsi_htotal + dsi_hfp_ext; | 85 | - dsi_cfg->htotal = dsi_htotal + dsi_hfp_ext; |
86 | - | 86 | - |
87 | - return 0; | 87 | - return 0; |
88 | -} | 88 | -} |
89 | - | 89 | - |
90 | static int cdns_dsi_check_conf(struct cdns_dsi *dsi, | 90 | static int cdns_dsi_check_conf(struct cdns_dsi *dsi, |
91 | const struct videomode *vm, | 91 | const struct videomode *vm, |
92 | struct cdns_dsi_cfg *dsi_cfg) | 92 | struct cdns_dsi_cfg *dsi_cfg) |
93 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_check_conf(struct cdns_dsi *dsi, | 93 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_check_conf(struct cdns_dsi *dsi, |
94 | if (ret) | 94 | if (ret) |
95 | return ret; | 95 | return ret; |
96 | 96 | ||
97 | - ret = cdns_dsi_adjust_phy_config(dsi, dsi_cfg, phy_cfg, vm); | 97 | - ret = cdns_dsi_adjust_phy_config(dsi, dsi_cfg, phy_cfg, vm); |
98 | - if (ret) | 98 | - if (ret) |
99 | - return ret; | 99 | - return ret; |
100 | - | 100 | - |
101 | req_hs_clk_rate = output->phy_opts.mipi_dphy.hs_clk_rate; | 101 | req_hs_clk_rate = output->phy_opts.mipi_dphy.hs_clk_rate; |
102 | ret = phy_validate(dsi->dphy, PHY_MODE_MIPI_DPHY, 0, &output->phy_opts); | 102 | ret = phy_validate(dsi->dphy, PHY_MODE_MIPI_DPHY, 0, &output->phy_opts); |
103 | if (ret) | 103 | if (ret) |
104 | 104 | ||
105 | -- | 105 | -- |
106 | 2.43.0 | 106 | 2.43.0 | diff view generated by jsdifflib |
1 | While the cdns-dsi does not support DSI burst mode, the burst mode is | 1 | While the cdns-dsi does not support DSI burst mode, the burst mode is |
---|---|---|---|
2 | essentially DSI event mode with more versatile clocking and timings. | 2 | essentially DSI event mode with more versatile clocking and timings. |
3 | Thus cdns-dsi doesn't need to fail if the DSI peripheral driver requests | 3 | Thus cdns-dsi doesn't need to fail if the DSI peripheral driver requests |
4 | MIPI_DSI_MODE_VIDEO_BURST. | 4 | MIPI_DSI_MODE_VIDEO_BURST. |
5 | 5 | ||
6 | In my particular use case, this allows the use of ti-sn65dsi83 driver. | 6 | In my particular use case, this allows the use of ti-sn65dsi83 driver. |
7 | 7 | ||
8 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> | 8 | Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> |
9 | --- | 9 | --- |
10 | drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 4 ---- | 10 | drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 4 ---- |
11 | 1 file changed, 4 deletions(-) | 11 | 1 file changed, 4 deletions(-) |
12 | 12 | ||
13 | diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 13 | diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
14 | index XXXXXXX..XXXXXXX 100644 | 14 | index XXXXXXX..XXXXXXX 100644 |
15 | --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 15 | --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
16 | +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 16 | +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |
17 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_attach(struct mipi_dsi_host *host, | 17 | @@ -XXX,XX +XXX,XX @@ static int cdns_dsi_attach(struct mipi_dsi_host *host, |
18 | if (output->dev) | 18 | if (output->dev) |
19 | return -EBUSY; | 19 | return -EBUSY; |
20 | 20 | ||
21 | - /* We do not support burst mode yet. */ | 21 | - /* We do not support burst mode yet. */ |
22 | - if (dev->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) | 22 | - if (dev->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) |
23 | - return -ENOTSUPP; | 23 | - return -ENOTSUPP; |
24 | - | 24 | - |
25 | /* | 25 | /* |
26 | * The host <-> device link might be described using an OF-graph | 26 | * The host <-> device link might be described using an OF-graph |
27 | * representation, in this case we extract the device of_node from | 27 | * representation, in this case we extract the device of_node from |
28 | 28 | ||
29 | -- | 29 | -- |
30 | 2.43.0 | 30 | 2.43.0 | diff view generated by jsdifflib |