...
...
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