Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0
2
3#include <linux/clk.h>
4#include <linux/delay.h>
5#include <linux/device.h>
6#include <linux/err.h>
7#include <linux/kernel.h>
8#include <linux/module.h>
9#include <linux/mod_devicetable.h>
10#include <linux/mutex.h>
11#include <linux/of.h>
12#include <linux/regulator/consumer.h>
13#include <linux/spi/spi.h>
14#include <linux/units.h>
15
16#include <drm/drm_atomic_helper.h>
17#include <drm/drm_bridge.h>
18#include <drm/drm_drv.h>
19#include <drm/drm_mipi_dsi.h>
20#include <drm/drm_of.h>
21#include <drm/drm_panel.h>
22#include <video/mipi_display.h>
23
24#define SSD2825_DEVICE_ID_REG 0xb0
25#define SSD2825_RGB_INTERFACE_CTRL_REG_1 0xb1
26#define SSD2825_RGB_INTERFACE_CTRL_REG_2 0xb2
27#define SSD2825_RGB_INTERFACE_CTRL_REG_3 0xb3
28#define SSD2825_RGB_INTERFACE_CTRL_REG_4 0xb4
29#define SSD2825_RGB_INTERFACE_CTRL_REG_5 0xb5
30#define SSD2825_RGB_INTERFACE_CTRL_REG_6 0xb6
31#define SSD2825_NON_BURST_EV BIT(2)
32#define SSD2825_BURST BIT(3)
33#define SSD2825_PCKL_HIGH BIT(13)
34#define SSD2825_HSYNC_HIGH BIT(14)
35#define SSD2825_VSYNC_HIGH BIT(15)
36#define SSD2825_CONFIGURATION_REG 0xb7
37#define SSD2825_CONF_REG_HS BIT(0)
38#define SSD2825_CONF_REG_CKE BIT(1)
39#define SSD2825_CONF_REG_SLP BIT(2)
40#define SSD2825_CONF_REG_VEN BIT(3)
41#define SSD2825_CONF_REG_HCLK BIT(4)
42#define SSD2825_CONF_REG_CSS BIT(5)
43#define SSD2825_CONF_REG_DCS BIT(6)
44#define SSD2825_CONF_REG_REN BIT(7)
45#define SSD2825_CONF_REG_ECD BIT(8)
46#define SSD2825_CONF_REG_EOT BIT(9)
47#define SSD2825_CONF_REG_LPE BIT(10)
48#define SSD2825_VC_CTRL_REG 0xb8
49#define SSD2825_PLL_CTRL_REG 0xb9
50#define SSD2825_PLL_CONFIGURATION_REG 0xba
51#define SSD2825_CLOCK_CTRL_REG 0xbb
52#define SSD2825_PACKET_SIZE_CTRL_REG_1 0xbc
53#define SSD2825_PACKET_SIZE_CTRL_REG_2 0xbd
54#define SSD2825_PACKET_SIZE_CTRL_REG_3 0xbe
55#define SSD2825_PACKET_DROP_REG 0xbf
56#define SSD2825_OPERATION_CTRL_REG 0xc0
57#define SSD2825_MAX_RETURN_SIZE_REG 0xc1
58#define SSD2825_RETURN_DATA_COUNT_REG 0xc2
59#define SSD2825_ACK_RESPONSE_REG 0xc3
60#define SSD2825_LINE_CTRL_REG 0xc4
61#define SSD2825_INTERRUPT_CTRL_REG 0xc5
62#define SSD2825_INTERRUPT_STATUS_REG 0xc6
63#define SSD2825_ERROR_STATUS_REG 0xc7
64#define SSD2825_DATA_FORMAT_REG 0xc8
65#define SSD2825_DELAY_ADJ_REG_1 0xc9
66#define SSD2825_DELAY_ADJ_REG_2 0xca
67#define SSD2825_DELAY_ADJ_REG_3 0xcb
68#define SSD2825_DELAY_ADJ_REG_4 0xcc
69#define SSD2825_DELAY_ADJ_REG_5 0xcd
70#define SSD2825_DELAY_ADJ_REG_6 0xce
71#define SSD2825_HS_TX_TIMER_REG_1 0xcf
72#define SSD2825_HS_TX_TIMER_REG_2 0xd0
73#define SSD2825_LP_RX_TIMER_REG_1 0xd1
74#define SSD2825_LP_RX_TIMER_REG_2 0xd2
75#define SSD2825_TE_STATUS_REG 0xd3
76#define SSD2825_SPI_READ_REG 0xd4
77#define SSD2825_SPI_READ_REG_RESET 0xfa
78#define SSD2825_PLL_LOCK_REG 0xd5
79#define SSD2825_TEST_REG 0xd6
80#define SSD2825_TE_COUNT_REG 0xd7
81#define SSD2825_ANALOG_CTRL_REG_1 0xd8
82#define SSD2825_ANALOG_CTRL_REG_2 0xd9
83#define SSD2825_ANALOG_CTRL_REG_3 0xda
84#define SSD2825_ANALOG_CTRL_REG_4 0xdb
85#define SSD2825_INTERRUPT_OUT_CTRL_REG 0xdc
86#define SSD2825_RGB_INTERFACE_CTRL_REG_7 0xdd
87#define SSD2825_LANE_CONFIGURATION_REG 0xde
88#define SSD2825_DELAY_ADJ_REG_7 0xdf
89#define SSD2825_INPUT_PIN_CTRL_REG_1 0xe0
90#define SSD2825_INPUT_PIN_CTRL_REG_2 0xe1
91#define SSD2825_BIDIR_PIN_CTRL_REG_1 0xe2
92#define SSD2825_BIDIR_PIN_CTRL_REG_2 0xe3
93#define SSD2825_BIDIR_PIN_CTRL_REG_3 0xe4
94#define SSD2825_BIDIR_PIN_CTRL_REG_4 0xe5
95#define SSD2825_BIDIR_PIN_CTRL_REG_5 0xe6
96#define SSD2825_BIDIR_PIN_CTRL_REG_6 0xe7
97#define SSD2825_BIDIR_PIN_CTRL_REG_7 0xe8
98#define SSD2825_CABC_BRIGHTNESS_CTRL_REG_1 0xe9
99#define SSD2825_CABC_BRIGHTNESS_CTRL_REG_2 0xea
100#define SSD2825_CABC_BRIGHTNESS_STATUS_REG 0xeb
101#define SSD2825_READ_REG 0xff
102
103#define SSD2825_COM_BYTE 0x00
104#define SSD2825_DAT_BYTE 0x01
105
106#define SSD2828_LP_CLOCK_DIVIDER(n) (((n) - 1) & 0x3f)
107#define SSD2825_LP_MIN_CLK 5000 /* KHz */
108#define SSD2825_REF_MIN_CLK 2000 /* KHz */
109
110static const struct regulator_bulk_data ssd2825_supplies[] = {
111 { .supply = "dvdd" },
112 { .supply = "avdd" },
113 { .supply = "vddio" },
114};
115
116struct ssd2825_dsi_output {
117 struct mipi_dsi_device *dev;
118 struct drm_panel *panel;
119 struct drm_bridge *bridge;
120};
121
122struct ssd2825_priv {
123 struct spi_device *spi;
124 struct device *dev;
125
126 struct gpio_desc *reset_gpio;
127 struct regulator_bulk_data *supplies;
128
129 struct clk *tx_clk;
130
131 struct mipi_dsi_host dsi_host;
132 struct drm_bridge bridge;
133 struct ssd2825_dsi_output output;
134
135 struct mutex mlock; /* for host transfer operations */
136
137 u32 pd_lines; /* number of Parallel Port Input Data Lines */
138 u32 dsi_lanes; /* number of DSI Lanes */
139
140 /* Parameters for PLL programming */
141 u32 pll_freq_kbps; /* PLL in kbps */
142 u32 nibble_freq_khz; /* PLL div by 4 */
143
144 u32 hzd; /* HS Zero Delay in ns*/
145 u32 hpd; /* HS Prepare Delay is ns */
146};
147
148static inline struct ssd2825_priv *dsi_host_to_ssd2825(struct mipi_dsi_host *host)
149{
150 return container_of(host, struct ssd2825_priv, dsi_host);
151}
152
153static inline struct ssd2825_priv *bridge_to_ssd2825(struct drm_bridge *bridge)
154{
155 return container_of(bridge, struct ssd2825_priv, bridge);
156}
157
158static int ssd2825_write_raw(struct ssd2825_priv *priv, u8 high_byte, u8 low_byte)
159{
160 struct spi_device *spi = priv->spi;
161 u8 tx_buf[2];
162
163 /*
164 * Low byte is the value, high byte defines type of
165 * write cycle, 0 for command and 1 for data.
166 */
167 tx_buf[0] = low_byte;
168 tx_buf[1] = high_byte;
169
170 return spi_write(spi, tx_buf, 2);
171}
172
173static int ssd2825_write_reg(struct ssd2825_priv *priv, u8 reg, u16 command)
174{
175 u8 datal = (command & 0x00FF);
176 u8 datah = (command & 0xFF00) >> 8;
177 int ret;
178
179 /* Command write cycle */
180 ret = ssd2825_write_raw(priv, SSD2825_COM_BYTE, reg);
181 if (ret)
182 return ret;
183
184 /* Data write cycle bits 7-0 */
185 ret = ssd2825_write_raw(priv, SSD2825_DAT_BYTE, datal);
186 if (ret)
187 return ret;
188
189 /* Data write cycle bits 15-8 */
190 ret = ssd2825_write_raw(priv, SSD2825_DAT_BYTE, datah);
191 if (ret)
192 return ret;
193
194 return 0;
195}
196
197static int ssd2825_write_dsi(struct ssd2825_priv *priv, const u8 *command, int len)
198{
199 int ret, i;
200
201 ret = ssd2825_write_reg(priv, SSD2825_PACKET_SIZE_CTRL_REG_1, len);
202 if (ret)
203 return ret;
204
205 ret = ssd2825_write_raw(priv, SSD2825_COM_BYTE, SSD2825_PACKET_DROP_REG);
206 if (ret)
207 return ret;
208
209 for (i = 0; i < len; i++) {
210 ret = ssd2825_write_raw(priv, SSD2825_DAT_BYTE, command[i]);
211 if (ret)
212 return ret;
213 }
214
215 return 0;
216}
217
218static int ssd2825_read_raw(struct ssd2825_priv *priv, u8 cmd, u16 *data)
219{
220 struct spi_device *spi = priv->spi;
221 struct spi_message msg;
222 struct spi_transfer xfer[2];
223 u8 tx_buf[2];
224 u8 rx_buf[2];
225 int ret;
226
227 memset(&xfer, 0, sizeof(xfer));
228
229 tx_buf[1] = (cmd & 0xFF00) >> 8;
230 tx_buf[0] = (cmd & 0x00FF);
231
232 xfer[0].tx_buf = tx_buf;
233 xfer[0].bits_per_word = 9;
234 xfer[0].len = 2;
235
236 xfer[1].rx_buf = rx_buf;
237 xfer[1].bits_per_word = 16;
238 xfer[1].len = 2;
239
240 spi_message_init(&msg);
241 spi_message_add_tail(&xfer[0], &msg);
242 spi_message_add_tail(&xfer[1], &msg);
243
244 ret = spi_sync(spi, &msg);
245 if (ret) {
246 dev_err(&spi->dev, "ssd2825 read raw failed %d\n", ret);
247 return ret;
248 }
249
250 *data = rx_buf[1] | (rx_buf[0] << 8);
251
252 return 0;
253}
254
255static int ssd2825_read_reg(struct ssd2825_priv *priv, u8 reg, u16 *data)
256{
257 int ret;
258
259 /* Reset the read register */
260 ret = ssd2825_write_reg(priv, SSD2825_SPI_READ_REG, SSD2825_SPI_READ_REG_RESET);
261 if (ret)
262 return ret;
263
264 /* Push the address to read */
265 ret = ssd2825_write_raw(priv, SSD2825_COM_BYTE, reg);
266 if (ret)
267 return ret;
268
269 /* Perform a reading cycle */
270 ret = ssd2825_read_raw(priv, SSD2825_SPI_READ_REG_RESET, data);
271 if (ret)
272 return ret;
273
274 return 0;
275}
276
277static int ssd2825_dsi_host_attach(struct mipi_dsi_host *host, struct mipi_dsi_device *dev)
278{
279 struct ssd2825_priv *priv = dsi_host_to_ssd2825(host);
280 struct drm_bridge *bridge;
281 struct drm_panel *panel;
282 struct device_node *ep;
283 int ret;
284
285 if (dev->lanes > 4) {
286 dev_err(priv->dev, "unsupported number of data lanes(%u)\n", dev->lanes);
287 return -EINVAL;
288 }
289
290 /*
291 * ssd2825 supports both Video and Pulse mode, but the driver only
292 * implements Video (event) mode currently
293 */
294 if (!(dev->mode_flags & MIPI_DSI_MODE_VIDEO)) {
295 dev_err(priv->dev, "Only MIPI_DSI_MODE_VIDEO is supported\n");
296 return -EOPNOTSUPP;
297 }
298
299 ret = drm_of_find_panel_or_bridge(host->dev->of_node, 1, 0, &panel, &bridge);
300 if (ret)
301 return ret;
302
303 if (panel) {
304 bridge = drm_panel_bridge_add_typed(panel, DRM_MODE_CONNECTOR_DSI);
305 if (IS_ERR(bridge))
306 return PTR_ERR(bridge);
307 }
308
309 priv->output.dev = dev;
310 priv->output.bridge = bridge;
311 priv->output.panel = panel;
312
313 priv->dsi_lanes = dev->lanes;
314
315 /* get input ep (port0/endpoint0) */
316 ret = -EINVAL;
317 ep = of_graph_get_endpoint_by_regs(host->dev->of_node, 0, 0);
318 if (ep) {
319 ret = of_property_read_u32(ep, "bus-width", &priv->pd_lines);
320 of_node_put(ep);
321 }
322
323 if (ret)
324 priv->pd_lines = mipi_dsi_pixel_format_to_bpp(dev->format);
325
326 drm_bridge_add(&priv->bridge);
327
328 return 0;
329}
330
331static int ssd2825_dsi_host_detach(struct mipi_dsi_host *host, struct mipi_dsi_device *dev)
332{
333 struct ssd2825_priv *priv = dsi_host_to_ssd2825(host);
334
335 drm_bridge_remove(&priv->bridge);
336 if (priv->output.panel)
337 drm_panel_bridge_remove(priv->output.bridge);
338
339 return 0;
340}
341
342static ssize_t ssd2825_dsi_host_transfer(struct mipi_dsi_host *host,
343 const struct mipi_dsi_msg *msg)
344{
345 struct ssd2825_priv *priv = dsi_host_to_ssd2825(host);
346 u16 config;
347 int ret;
348
349 if (msg->rx_len) {
350 dev_warn(priv->dev, "MIPI rx is not supported\n");
351 return -EOPNOTSUPP;
352 }
353
354 guard(mutex)(&priv->mlock);
355
356 ret = ssd2825_read_reg(priv, SSD2825_CONFIGURATION_REG, &config);
357 if (ret)
358 return ret;
359
360 switch (msg->type) {
361 case MIPI_DSI_DCS_SHORT_WRITE:
362 case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
363 case MIPI_DSI_DCS_LONG_WRITE:
364 config |= SSD2825_CONF_REG_DCS;
365 break;
366 case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
367 case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
368 case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
369 case MIPI_DSI_GENERIC_LONG_WRITE:
370 config &= ~SSD2825_CONF_REG_DCS;
371 break;
372 case MIPI_DSI_DCS_READ:
373 case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
374 case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
375 case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
376 default:
377 return 0;
378 }
379
380 ret = ssd2825_write_reg(priv, SSD2825_CONFIGURATION_REG, config);
381 if (ret)
382 return ret;
383
384 ret = ssd2825_write_reg(priv, SSD2825_VC_CTRL_REG, 0x0000);
385 if (ret)
386 return ret;
387
388 ret = ssd2825_write_dsi(priv, msg->tx_buf, msg->tx_len);
389 if (ret)
390 return ret;
391
392 return 0;
393}
394
395static const struct mipi_dsi_host_ops ssd2825_dsi_host_ops = {
396 .attach = ssd2825_dsi_host_attach,
397 .detach = ssd2825_dsi_host_detach,
398 .transfer = ssd2825_dsi_host_transfer,
399};
400
401static void ssd2825_hw_reset(struct ssd2825_priv *priv)
402{
403 gpiod_set_value_cansleep(priv->reset_gpio, 1);
404 usleep_range(5000, 6000);
405 gpiod_set_value_cansleep(priv->reset_gpio, 0);
406 usleep_range(5000, 6000);
407}
408
409/*
410 * PLL configuration register settings.
411 *
412 * See the "PLL Configuration Register Description" in the SSD2825 datasheet.
413 */
414static u16 construct_pll_config(struct ssd2825_priv *priv,
415 u32 desired_pll_freq_kbps, u32 reference_freq_khz)
416{
417 u32 div_factor = 1, mul_factor, fr = 0;
418
419 while (reference_freq_khz / (div_factor + 1) >= SSD2825_REF_MIN_CLK)
420 div_factor++;
421 if (div_factor > 31)
422 div_factor = 31;
423
424 mul_factor = DIV_ROUND_UP(desired_pll_freq_kbps * div_factor,
425 reference_freq_khz);
426
427 priv->pll_freq_kbps = reference_freq_khz * mul_factor / div_factor;
428 priv->nibble_freq_khz = priv->pll_freq_kbps / 4;
429
430 if (priv->pll_freq_kbps >= 501000)
431 fr = 3;
432 else if (priv->pll_freq_kbps >= 251000)
433 fr = 2;
434 else if (priv->pll_freq_kbps >= 126000)
435 fr = 1;
436
437 return (fr << 14) | (div_factor << 8) | mul_factor;
438}
439
440static int ssd2825_setup_pll(struct ssd2825_priv *priv,
441 const struct drm_display_mode *mode)
442{
443 u16 pll_config, lp_div;
444 u32 nibble_delay, pclk_mult, tx_freq_khz;
445 u8 hzd, hpd;
446
447 tx_freq_khz = clk_get_rate(priv->tx_clk) / KILO;
448 if (!tx_freq_khz)
449 tx_freq_khz = SSD2825_REF_MIN_CLK;
450
451 pclk_mult = priv->pd_lines / priv->dsi_lanes + 1;
452 pll_config = construct_pll_config(priv, pclk_mult * mode->clock,
453 tx_freq_khz);
454
455 lp_div = priv->pll_freq_kbps / (SSD2825_LP_MIN_CLK * 8);
456
457 /* nibble_delay in nanoseconds */
458 nibble_delay = MICRO / priv->nibble_freq_khz;
459
460 hzd = priv->hzd / nibble_delay;
461 hpd = (priv->hpd - 4 * nibble_delay) / nibble_delay;
462
463 /* Disable PLL */
464 ssd2825_write_reg(priv, SSD2825_PLL_CTRL_REG, 0x0000);
465 ssd2825_write_reg(priv, SSD2825_LINE_CTRL_REG, 0x0001);
466
467 /* Set delays */
468 ssd2825_write_reg(priv, SSD2825_DELAY_ADJ_REG_1, (hzd << 8) | hpd);
469
470 /* Set PLL coefficients */
471 ssd2825_write_reg(priv, SSD2825_PLL_CONFIGURATION_REG, pll_config);
472
473 /* Clock Control Register */
474 ssd2825_write_reg(priv, SSD2825_CLOCK_CTRL_REG,
475 SSD2828_LP_CLOCK_DIVIDER(lp_div));
476
477 /* Enable PLL */
478 ssd2825_write_reg(priv, SSD2825_PLL_CTRL_REG, 0x0001);
479 ssd2825_write_reg(priv, SSD2825_VC_CTRL_REG, 0);
480
481 return 0;
482}
483
484static void ssd2825_bridge_atomic_pre_enable(struct drm_bridge *bridge,
485 struct drm_atomic_state *state)
486{
487 struct ssd2825_priv *priv = bridge_to_ssd2825(bridge);
488 struct mipi_dsi_device *dsi_dev = priv->output.dev;
489 const struct drm_crtc_state *crtc_state;
490 const struct drm_display_mode *mode;
491 struct drm_connector *connector;
492 struct drm_crtc *crtc;
493 u32 input_bus_flags = bridge->timings->input_bus_flags;
494 u16 flags = 0, config;
495 u8 pixel_format;
496 int ret;
497
498 /* Power Sequence */
499 ret = clk_prepare_enable(priv->tx_clk);
500 if (ret)
501 dev_err(priv->dev, "error enabling tx_clk (%d)\n", ret);
502
503 ret = regulator_bulk_enable(ARRAY_SIZE(ssd2825_supplies), priv->supplies);
504 if (ret)
505 dev_err(priv->dev, "error enabling regulators (%d)\n", ret);
506
507 usleep_range(1000, 2000);
508
509 ssd2825_hw_reset(priv);
510
511 /* Perform SW reset */
512 ssd2825_write_reg(priv, SSD2825_OPERATION_CTRL_REG, 0x0100);
513
514 /* Set pixel format */
515 switch (dsi_dev->format) {
516 case MIPI_DSI_FMT_RGB565:
517 pixel_format = 0x00;
518 break;
519 case MIPI_DSI_FMT_RGB666_PACKED:
520 pixel_format = 0x01;
521 break;
522 case MIPI_DSI_FMT_RGB666:
523 pixel_format = 0x02;
524 break;
525 case MIPI_DSI_FMT_RGB888:
526 default:
527 pixel_format = 0x03;
528 break;
529 }
530
531 connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
532 crtc = drm_atomic_get_new_connector_state(state, connector)->crtc;
533 crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
534 mode = &crtc_state->adjusted_mode;
535
536 /* Set panel timings */
537 ssd2825_write_reg(priv, SSD2825_RGB_INTERFACE_CTRL_REG_1,
538 ((mode->vtotal - mode->vsync_end) << 8) |
539 (mode->htotal - mode->hsync_end));
540 ssd2825_write_reg(priv, SSD2825_RGB_INTERFACE_CTRL_REG_2,
541 ((mode->vtotal - mode->vsync_start) << 8) |
542 (mode->htotal - mode->hsync_start));
543 ssd2825_write_reg(priv, SSD2825_RGB_INTERFACE_CTRL_REG_3,
544 ((mode->vsync_start - mode->vdisplay) << 8) |
545 (mode->hsync_start - mode->hdisplay));
546 ssd2825_write_reg(priv, SSD2825_RGB_INTERFACE_CTRL_REG_4, mode->hdisplay);
547 ssd2825_write_reg(priv, SSD2825_RGB_INTERFACE_CTRL_REG_5, mode->vdisplay);
548
549 if (mode->flags & DRM_MODE_FLAG_PHSYNC)
550 flags |= SSD2825_HSYNC_HIGH;
551
552 if (mode->flags & DRM_MODE_FLAG_PVSYNC)
553 flags |= SSD2825_VSYNC_HIGH;
554
555 if (dsi_dev->mode_flags & MIPI_DSI_MODE_VIDEO)
556 flags |= SSD2825_NON_BURST_EV;
557
558 if (input_bus_flags & DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE)
559 flags |= SSD2825_PCKL_HIGH;
560
561 ssd2825_write_reg(priv, SSD2825_RGB_INTERFACE_CTRL_REG_6, flags | pixel_format);
562 ssd2825_write_reg(priv, SSD2825_LANE_CONFIGURATION_REG, dsi_dev->lanes - 1);
563 ssd2825_write_reg(priv, SSD2825_TEST_REG, 0x0004);
564
565 /* Call PLL configuration */
566 ssd2825_setup_pll(priv, mode);
567
568 usleep_range(10000, 11000);
569
570 config = SSD2825_CONF_REG_HS | SSD2825_CONF_REG_CKE | SSD2825_CONF_REG_DCS |
571 SSD2825_CONF_REG_ECD | SSD2825_CONF_REG_EOT;
572
573 if (dsi_dev->mode_flags & MIPI_DSI_MODE_LPM)
574 config &= ~SSD2825_CONF_REG_HS;
575
576 if (dsi_dev->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET)
577 config &= ~SSD2825_CONF_REG_EOT;
578
579 /* Initial DSI configuration register set */
580 ssd2825_write_reg(priv, SSD2825_CONFIGURATION_REG, config);
581 ssd2825_write_reg(priv, SSD2825_VC_CTRL_REG, 0);
582
583 if (priv->output.panel)
584 drm_panel_enable(priv->output.panel);
585}
586
587static void ssd2825_bridge_atomic_enable(struct drm_bridge *bridge,
588 struct drm_atomic_state *state)
589{
590 struct ssd2825_priv *priv = bridge_to_ssd2825(bridge);
591 struct mipi_dsi_device *dsi_dev = priv->output.dev;
592 u16 config;
593
594 config = SSD2825_CONF_REG_HS | SSD2825_CONF_REG_DCS |
595 SSD2825_CONF_REG_ECD | SSD2825_CONF_REG_EOT;
596
597 if (dsi_dev->mode_flags & MIPI_DSI_MODE_VIDEO)
598 config |= SSD2825_CONF_REG_VEN;
599
600 if (dsi_dev->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET)
601 config &= ~SSD2825_CONF_REG_EOT;
602
603 /* Complete configuration after DSI commands were sent */
604 ssd2825_write_reg(priv, SSD2825_CONFIGURATION_REG, config);
605 ssd2825_write_reg(priv, SSD2825_PLL_CTRL_REG, 0x0001);
606 ssd2825_write_reg(priv, SSD2825_VC_CTRL_REG, 0x0000);
607}
608
609static void ssd2825_bridge_atomic_disable(struct drm_bridge *bridge,
610 struct drm_atomic_state *state)
611{
612 struct ssd2825_priv *priv = bridge_to_ssd2825(bridge);
613 int ret;
614
615 msleep(100);
616
617 /* Exit DSI configuration register set */
618 ssd2825_write_reg(priv, SSD2825_CONFIGURATION_REG,
619 SSD2825_CONF_REG_ECD | SSD2825_CONF_REG_EOT);
620 ssd2825_write_reg(priv, SSD2825_VC_CTRL_REG, 0);
621
622 /* HW disable */
623 gpiod_set_value_cansleep(priv->reset_gpio, 1);
624 usleep_range(5000, 6000);
625
626 ret = regulator_bulk_disable(ARRAY_SIZE(ssd2825_supplies),
627 priv->supplies);
628 if (ret < 0)
629 dev_err(priv->dev, "error disabling regulators (%d)\n", ret);
630
631 clk_disable_unprepare(priv->tx_clk);
632}
633
634static int ssd2825_bridge_attach(struct drm_bridge *bridge, struct drm_encoder *encoder,
635 enum drm_bridge_attach_flags flags)
636{
637 struct ssd2825_priv *priv = bridge_to_ssd2825(bridge);
638
639 return drm_bridge_attach(bridge->encoder, priv->output.bridge, bridge,
640 flags);
641}
642
643static enum drm_mode_status
644ssd2825_bridge_mode_valid(struct drm_bridge *bridge,
645 const struct drm_display_info *info,
646 const struct drm_display_mode *mode)
647{
648 if (mode->hdisplay > 1366)
649 return MODE_H_ILLEGAL;
650
651 if (mode->vdisplay > 1366)
652 return MODE_V_ILLEGAL;
653
654 return MODE_OK;
655}
656
657static bool ssd2825_mode_fixup(struct drm_bridge *bridge,
658 const struct drm_display_mode *mode,
659 struct drm_display_mode *adjusted_mode)
660{
661 /* Default to positive sync */
662
663 if (!(adjusted_mode->flags &
664 (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC)))
665 adjusted_mode->flags |= DRM_MODE_FLAG_PHSYNC;
666
667 if (!(adjusted_mode->flags &
668 (DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC)))
669 adjusted_mode->flags |= DRM_MODE_FLAG_PVSYNC;
670
671 return true;
672}
673
674static const struct drm_bridge_funcs ssd2825_bridge_funcs = {
675 .attach = ssd2825_bridge_attach,
676 .mode_valid = ssd2825_bridge_mode_valid,
677 .mode_fixup = ssd2825_mode_fixup,
678
679 .atomic_pre_enable = ssd2825_bridge_atomic_pre_enable,
680 .atomic_enable = ssd2825_bridge_atomic_enable,
681 .atomic_disable = ssd2825_bridge_atomic_disable,
682
683 .atomic_reset = drm_atomic_helper_bridge_reset,
684 .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
685 .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
686};
687
688static const struct drm_bridge_timings default_ssd2825_timings = {
689 .input_bus_flags = DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE
690 | DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE
691 | DRM_BUS_FLAG_DE_HIGH,
692};
693
694static int ssd2825_probe(struct spi_device *spi)
695{
696 struct ssd2825_priv *priv;
697 struct device *dev = &spi->dev;
698 struct device_node *np = dev->of_node;
699 int ret;
700
701 /* Driver supports only 8 bit 3 Wire mode */
702 spi->bits_per_word = 9;
703
704 ret = spi_setup(spi);
705 if (ret)
706 return ret;
707
708 priv = devm_drm_bridge_alloc(dev, struct ssd2825_priv, bridge, &ssd2825_bridge_funcs);
709 if (IS_ERR(priv))
710 return PTR_ERR(priv);
711
712 spi_set_drvdata(spi, priv);
713
714 priv->spi = spi;
715 priv->dev = dev;
716
717 mutex_init(&priv->mlock);
718
719 priv->tx_clk = devm_clk_get_optional(dev, NULL);
720 if (IS_ERR(priv->tx_clk))
721 return dev_err_probe(dev, PTR_ERR(priv->tx_clk),
722 "can't retrieve bridge tx_clk\n");
723
724 priv->reset_gpio = devm_gpiod_get_optional(dev, "reset",
725 GPIOD_OUT_HIGH);
726 if (IS_ERR(priv->reset_gpio))
727 return dev_err_probe(dev, PTR_ERR(priv->reset_gpio),
728 "failed to get reset GPIO\n");
729
730 ret = devm_regulator_bulk_get_const(dev, ARRAY_SIZE(ssd2825_supplies),
731 ssd2825_supplies, &priv->supplies);
732 if (ret)
733 return dev_err_probe(dev, ret, "failed to get regulators\n");
734
735 priv->hzd = 133; /* ns */
736 device_property_read_u32(dev, "solomon,hs-zero-delay-ns", &priv->hzd);
737
738 priv->hpd = 40; /* ns */
739 device_property_read_u32(dev, "solomon,hs-prep-delay-ns", &priv->hpd);
740
741 priv->dsi_host.dev = dev;
742 priv->dsi_host.ops = &ssd2825_dsi_host_ops;
743
744 priv->bridge.timings = &default_ssd2825_timings;
745 priv->bridge.of_node = np;
746
747 return mipi_dsi_host_register(&priv->dsi_host);
748}
749
750static void ssd2825_remove(struct spi_device *spi)
751{
752 struct ssd2825_priv *priv = spi_get_drvdata(spi);
753
754 mipi_dsi_host_unregister(&priv->dsi_host);
755}
756
757static const struct of_device_id ssd2825_of_match[] = {
758 { .compatible = "solomon,ssd2825" },
759 { /* sentinel */ }
760};
761MODULE_DEVICE_TABLE(of, ssd2825_of_match);
762
763static struct spi_driver ssd2825_driver = {
764 .driver = {
765 .name = "ssd2825",
766 .of_match_table = ssd2825_of_match,
767 },
768 .probe = ssd2825_probe,
769 .remove = ssd2825_remove,
770};
771module_spi_driver(ssd2825_driver);
772
773MODULE_AUTHOR("Svyatoslav Ryhel <clamor95@gmail.com>");
774MODULE_DESCRIPTION("Solomon SSD2825 RGB to MIPI-DSI bridge driver SPI");
775MODULE_LICENSE("GPL");