Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/gpu/drm/bridge/ssd2825.c
29281 views
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
110
static const struct regulator_bulk_data ssd2825_supplies[] = {
111
{ .supply = "dvdd" },
112
{ .supply = "avdd" },
113
{ .supply = "vddio" },
114
};
115
116
struct ssd2825_dsi_output {
117
struct mipi_dsi_device *dev;
118
struct drm_panel *panel;
119
struct drm_bridge *bridge;
120
};
121
122
struct 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
148
static 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
153
static inline struct ssd2825_priv *bridge_to_ssd2825(struct drm_bridge *bridge)
154
{
155
return container_of(bridge, struct ssd2825_priv, bridge);
156
}
157
158
static 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
173
static 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
197
static 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
218
static 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
255
static 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
277
static 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
331
static 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
342
static 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
395
static 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
401
static 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
*/
414
static 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
440
static 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
484
static 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
587
static 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
609
static 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
634
static 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
643
static enum drm_mode_status
644
ssd2825_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
657
static 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
674
static 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
688
static 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
694
static 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
750
static 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
757
static const struct of_device_id ssd2825_of_match[] = {
758
{ .compatible = "solomon,ssd2825" },
759
{ /* sentinel */ }
760
};
761
MODULE_DEVICE_TABLE(of, ssd2825_of_match);
762
763
static 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
};
771
module_spi_driver(ssd2825_driver);
772
773
MODULE_AUTHOR("Svyatoslav Ryhel <[email protected]>");
774
MODULE_DESCRIPTION("Solomon SSD2825 RGB to MIPI-DSI bridge driver SPI");
775
MODULE_LICENSE("GPL");
776
777