1 From 008c93b47b9b965368eb5bbfbef60b816931e0ab Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.com>
3 Date: Wed, 20 Nov 2024 13:58:08 +0000
4 Subject: [PATCH] drm: vc4: dsi: Handle the different command FIFO widths
6 DSI0 and DSI1 have different widths for the command FIFO (24bit
7 vs 32bit), but the driver was assuming the 32bit width of DSI1
9 DSI0 also wants the data packed as 24bit big endian, so the
10 formatting code needs updating.
12 Handle the difference via the variant structure.
14 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
16 drivers/gpu/drm/vc4/vc4_dsi.c | 64 ++++++++++++++++++++++++-----------
17 1 file changed, 44 insertions(+), 20 deletions(-)
19 --- a/drivers/gpu/drm/vc4/vc4_dsi.c
20 +++ b/drivers/gpu/drm/vc4/vc4_dsi.c
23 #define DSI_CMD_FIFO_DEPTH 16
24 #define DSI_PIX_FIFO_DEPTH 256
25 -#define DSI_PIX_FIFO_WIDTH 4
27 #define DSI0_CTRL 0x00
30 #define DSI1_DISP1_CTRL 0x2c
31 /* Format of the data written to TXPKT_PIX_FIFO. */
32 # define DSI_DISP1_PFORMAT_MASK VC4_MASK(2, 1)
33 -# define DSI_DISP1_PFORMAT_SHIFT 1
34 -# define DSI_DISP1_PFORMAT_16BIT 0
35 -# define DSI_DISP1_PFORMAT_24BIT 1
36 -# define DSI_DISP1_PFORMAT_32BIT_LE 2
37 -# define DSI_DISP1_PFORMAT_32BIT_BE 3
38 +# define DSI1_DISP1_PFORMAT_SHIFT 1
39 +# define DSI0_DISP1_PFORMAT_16BIT 0
40 +# define DSI0_DISP1_PFORMAT_16BIT_ADJ 1
41 +# define DSI0_DISP1_PFORMAT_24BIT 2
42 +# define DSI0_DISP1_PFORMAT_32BIT_LE 3 /* NB Invalid, but required for macros to work */
43 +# define DSI1_DISP1_PFORMAT_16BIT 0
44 +# define DSI1_DISP1_PFORMAT_24BIT 1
45 +# define DSI1_DISP1_PFORMAT_32BIT_LE 2
46 +# define DSI1_DISP1_PFORMAT_32BIT_BE 3
48 /* DISP1 is always command mode. */
49 # define DSI_DISP1_ENABLE BIT(0)
50 @@ -553,6 +556,7 @@ struct vc4_dsi_variant {
53 bool broken_axi_workaround;
54 + unsigned int cmd_fifo_width;
56 const char *debugfs_name;
57 const struct debugfs_reg32 *regs;
58 @@ -1151,10 +1155,16 @@ static void vc4_dsi_bridge_pre_enable(st
59 /* Set up DISP1 for transferring long command payloads through
62 - DSI_PORT_WRITE(DISP1_CTRL,
63 - VC4_SET_FIELD(DSI_DISP1_PFORMAT_32BIT_LE,
64 - DSI_DISP1_PFORMAT) |
66 + if (dsi->variant->cmd_fifo_width == 4)
67 + DSI_PORT_WRITE(DISP1_CTRL,
68 + VC4_SET_FIELD(DSI_PORT_BIT(DISP1_PFORMAT_32BIT_LE),
69 + DSI_DISP1_PFORMAT) |
72 + DSI_PORT_WRITE(DISP1_CTRL,
73 + VC4_SET_FIELD(DSI_PORT_BIT(DISP1_PFORMAT_24BIT),
74 + DSI_DISP1_PFORMAT) |
77 /* Bring AFE out of reset. */
78 DSI_PORT_WRITE(PHY_AFEC0,
79 @@ -1235,9 +1245,9 @@ static ssize_t vc4_dsi_transfer(struct v
82 cmd_fifo_len = (packet.payload_length %
83 - DSI_PIX_FIFO_WIDTH);
84 + dsi->variant->cmd_fifo_width);
85 pix_fifo_len = ((packet.payload_length - cmd_fifo_len) /
86 - DSI_PIX_FIFO_WIDTH);
87 + dsi->variant->cmd_fifo_width);
90 WARN_ON_ONCE(pix_fifo_len >= DSI_PIX_FIFO_DEPTH);
91 @@ -1255,14 +1265,25 @@ static ssize_t vc4_dsi_transfer(struct v
93 for (i = 0; i < cmd_fifo_len; i++)
94 DSI_PORT_WRITE(TXPKT_CMD_FIFO, packet.payload[i]);
95 - for (i = 0; i < pix_fifo_len; i++) {
96 - const u8 *pix = packet.payload + cmd_fifo_len + i * 4;
97 + if (dsi->variant->cmd_fifo_width == 4) {
98 + for (i = 0; i < pix_fifo_len; i++) {
99 + const u8 *pix = packet.payload + cmd_fifo_len + i * 4;
101 + DSI_PORT_WRITE(TXPKT_PIX_FIFO,
108 + for (i = 0; i < pix_fifo_len; i++) {
109 + const u8 *pix = packet.payload + cmd_fifo_len + i * 3;
111 - DSI_PORT_WRITE(TXPKT_PIX_FIFO,
116 + DSI_PORT_WRITE(TXPKT_PIX_FIFO,
123 if (msg->flags & MIPI_DSI_MSG_USE_LPM)
124 @@ -1516,6 +1537,7 @@ static const struct drm_encoder_funcs vc
126 static const struct vc4_dsi_variant bcm2711_dsi1_variant = {
128 + .cmd_fifo_width = 4,
129 .debugfs_name = "dsi1_regs",
131 .nregs = ARRAY_SIZE(dsi1_regs),
132 @@ -1523,6 +1545,7 @@ static const struct vc4_dsi_variant bcm2
134 static const struct vc4_dsi_variant bcm2835_dsi0_variant = {
136 + .cmd_fifo_width = 3,
137 .debugfs_name = "dsi0_regs",
139 .nregs = ARRAY_SIZE(dsi0_regs),
140 @@ -1530,6 +1553,7 @@ static const struct vc4_dsi_variant bcm2
142 static const struct vc4_dsi_variant bcm2835_dsi1_variant = {
144 + .cmd_fifo_width = 4,
145 .broken_axi_workaround = true,
146 .debugfs_name = "dsi1_regs",