1
2
3
4
5
6
7
8
9
10
11
12
13#include <drm/drm_crtc_helper.h>
14#include <drm/drm_mipi_dsi.h>
15#include <drm/drm_panel.h>
16#include <drm/drmP.h>
17#include <linux/component.h>
18#include <linux/device.h>
19#include <linux/of_device.h>
20#include <linux/of_graph.h>
21#include <linux/phy/phy.h>
22#include <video/mipi_display.h>
23#include <video/videomode.h>
24
25
26#define XDSI_CCR 0x00
27#define XDSI_CCR_COREENB BIT(0)
28#define XDSI_CCR_CRREADY BIT(2)
29#define XDSI_PCR 0x04
30#define XDSI_PCR_VIDEOMODE(x) (((x) & 0x3) << 3)
31#define XDSI_PCR_VIDEOMODE_MASK (0x3 << 3)
32#define XDSI_PCR_VIDEOMODE_SHIFT 3
33#define XDSI_PCR_BLLPTYPE(x) ((x) << 5)
34#define XDSI_PCR_BLLPMODE(x) ((x) << 6)
35#define XDSI_PCR_EOTPENABLE(x) ((x) << 13)
36#define XDSI_GIER 0x20
37#define XDSI_ISR 0x24
38#define XDSI_IER 0x28
39#define XDSI_CMD 0x30
40#define XDSI_CMD_QUEUE_PACKET(x) (((x) & 0xffffff) << 0)
41#define XDSI_TIME1 0x50
42#define XDSI_TIME1_BLLP_BURST(x) (((x) & 0xffff) << 0)
43#define XDSI_TIME1_HSA(x) (((x) & 0xffff) << 16)
44#define XDSI_TIME2 0x54
45#define XDSI_TIME2_VACT(x) (((x) & 0xffff) << 0)
46#define XDSI_TIME2_HACT(x) (((x) & 0xffff) << 16)
47#define XDSI_TIME3 0x58
48#define XDSI_TIME3_HFP(x) (((x) & 0xffff) << 0)
49#define XDSI_TIME3_HBP(x) (((x) & 0xffff) << 16)
50#define XDSI_TIME4 0x5c
51#define XDSI_TIME4_VFP(x) (((x) & 0xff) << 0)
52#define XDSI_TIME4_VBP(x) (((x) & 0xff) << 8)
53#define XDSI_TIME4_VSA(x) (((x) & 0xff) << 16)
54#define XDSI_LTIME 0x60
55#define XDSI_BLLP_TIME 0x64
56#define XDSI_NUM_DATA_TYPES 5
57#define XDSI_NUM_PIXELS_PER_BEAT 3
58#define XDSI_VIDEO_MODE_SYNC_PULSE 0x0
59#define XDSI_VIDEO_MODE_SYNC_EVENT 0x1
60#define XDSI_VIDEO_MODE_BURST 0x2
61
62
63
64
65
66
67
68
69int xdsi_mul_factor[XDSI_NUM_DATA_TYPES][XDSI_NUM_PIXELS_PER_BEAT] = {
70 { 3, 6, 12 },
71 { 3, 5, 9 },
72 { 3, 5, 9 },
73 { 2, 4, 8 }
74};
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103struct xilinx_dsi {
104 struct drm_encoder encoder;
105 struct mipi_dsi_host dsi_host;
106 struct drm_connector connector;
107 struct device_node *panel_node;
108 struct drm_panel *panel;
109 struct device *dev;
110 void __iomem *iomem;
111 u32 lanes;
112 u32 mode_flags;
113 enum mipi_dsi_pixel_format format;
114 struct videomode vm;
115 u32 mul_factor;
116 struct drm_property *eotp_prop;
117 struct drm_property *bllp_mode_prop;
118 struct drm_property *bllp_type_prop;
119 struct drm_property *video_mode_prop;
120 struct drm_property *bllp_burst_time_prop;
121 struct drm_property *cmd_queue_prop;
122 bool eotp_prop_val;
123 bool bllp_mode_prop_val;
124 bool bllp_type_prop_val;
125 u32 video_mode_prop_val;
126 u32 bllp_burst_time_prop_val;
127 u32 cmd_queue_prop_val;
128};
129
130#define host_to_dsi(host) container_of(host, struct xilinx_dsi, dsi_host)
131#define connector_to_dsi(c) container_of(c, struct xilinx_dsi, connector)
132#define encoder_to_dsi(e) container_of(e, struct xilinx_dsi, encoder)
133
134static inline void xilinx_dsi_writel(void __iomem *base, int offset, u32 val)
135{
136 writel(val, base + offset);
137}
138
139static inline u32 xilinx_dsi_readl(void __iomem *base, int offset)
140{
141 return readl(base + offset);
142}
143
144
145
146
147
148
149static void
150xilinx_dsi_set_default_drm_properties(struct xilinx_dsi *dsi)
151{
152 drm_object_property_set_value(&dsi->connector.base, dsi->eotp_prop, 1);
153 drm_object_property_set_value(&dsi->connector.base,
154 dsi->bllp_mode_prop, 0);
155 drm_object_property_set_value(&dsi->connector.base,
156 dsi->bllp_type_prop, 0);
157 drm_object_property_set_value(&dsi->connector.base,
158 dsi->video_mode_prop, 0);
159 drm_object_property_set_value(&dsi->connector.base,
160 dsi->bllp_burst_time_prop, 0);
161 drm_object_property_set_value(&dsi->connector.base,
162 dsi->cmd_queue_prop, 0);
163}
164
165
166
167
168
169
170
171
172
173static void xilinx_dsi_set_config_parameters(struct xilinx_dsi *dsi)
174{
175 u32 reg = 0;
176
177 reg |= XDSI_PCR_EOTPENABLE(dsi->eotp_prop_val);
178 reg |= XDSI_PCR_VIDEOMODE(dsi->video_mode_prop_val);
179 reg |= XDSI_PCR_BLLPTYPE(dsi->bllp_type_prop_val);
180 reg |= XDSI_PCR_BLLPMODE(dsi->bllp_mode_prop_val);
181
182 xilinx_dsi_writel(dsi->iomem, XDSI_PCR, reg);
183
184
185
186
187 if (dsi->video_mode_prop_val == XDSI_VIDEO_MODE_BURST) {
188 reg = XDSI_TIME1_BLLP_BURST(dsi->bllp_burst_time_prop_val);
189 xilinx_dsi_writel(dsi->iomem, XDSI_TIME1, reg);
190 }
191
192 reg = XDSI_CMD_QUEUE_PACKET(dsi->cmd_queue_prop_val);
193 xilinx_dsi_writel(dsi->iomem, XDSI_CMD, reg);
194
195 dev_dbg(dsi->dev, "PCR register value is = %x\n",
196 xilinx_dsi_readl(dsi->iomem, XDSI_PCR));
197}
198
199
200
201
202
203
204
205
206static void xilinx_dsi_set_display_mode(struct xilinx_dsi *dsi)
207{
208 struct videomode *vm = &dsi->vm;
209 u32 reg, video_mode;
210
211 reg = xilinx_dsi_readl(dsi->iomem, XDSI_PCR);
212 video_mode = ((reg & XDSI_PCR_VIDEOMODE_MASK) >>
213 XDSI_PCR_VIDEOMODE_SHIFT);
214
215
216 if ((!video_mode) &
217 (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)) {
218 reg = XDSI_TIME1_HSA(vm->hsync_len);
219 xilinx_dsi_writel(dsi->iomem, XDSI_TIME1, reg);
220 }
221
222 reg = XDSI_TIME4_VFP(vm->vfront_porch) |
223 XDSI_TIME4_VBP(vm->vback_porch) |
224 XDSI_TIME4_VSA(vm->vsync_len);
225 xilinx_dsi_writel(dsi->iomem, XDSI_TIME4, reg);
226
227 reg = XDSI_TIME3_HFP(vm->hfront_porch) |
228 XDSI_TIME3_HBP(vm->hback_porch);
229 xilinx_dsi_writel(dsi->iomem, XDSI_TIME3, reg);
230
231 dev_dbg(dsi->dev, "mul factor for parsed datatype is = %d\n",
232 dsi->mul_factor);
233
234 reg = XDSI_TIME2_HACT((vm->hactive) * dsi->mul_factor) |
235 XDSI_TIME2_VACT(vm->vactive);
236 xilinx_dsi_writel(dsi->iomem, XDSI_TIME2, reg);
237
238 dev_dbg(dsi->dev, "LCD size = %dx%d\n", vm->hactive, vm->vactive);
239}
240
241
242
243
244
245
246
247
248
249static void xilinx_dsi_set_display_enable(struct xilinx_dsi *dsi)
250{
251 u32 reg;
252
253 reg = xilinx_dsi_readl(dsi->iomem, XDSI_CCR);
254 reg |= XDSI_CCR_COREENB;
255
256 xilinx_dsi_writel(dsi->iomem, XDSI_CCR, reg);
257 dev_dbg(dsi->dev, "MIPI DSI Tx controller is enabled.\n");
258}
259
260
261
262
263
264
265
266
267
268static void xilinx_dsi_set_display_disable(struct xilinx_dsi *dsi)
269{
270 u32 reg;
271
272 reg = xilinx_dsi_readl(dsi->iomem, XDSI_CCR);
273 reg &= ~XDSI_CCR_COREENB;
274
275 xilinx_dsi_writel(dsi->iomem, XDSI_CCR, reg);
276 dev_dbg(dsi->dev, "DSI Tx is disabled. reset regs to default values\n");
277}
278
279
280static void xilinx_dsi_encoder_dpms(struct drm_encoder *encoder,
281 int mode)
282{
283 struct xilinx_dsi *dsi = encoder_to_dsi(encoder);
284
285 dev_dbg(dsi->dev, "encoder dpms state: %d\n", mode);
286
287 switch (mode) {
288 case DRM_MODE_DPMS_ON:
289 xilinx_dsi_set_display_enable(dsi);
290 break;
291 default:
292 xilinx_dsi_set_display_disable(dsi);
293 xilinx_dsi_set_default_drm_properties(dsi);
294 break;
295 }
296}
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312static int
313xilinx_dsi_connector_set_property(struct drm_connector *base_connector,
314 struct drm_property *property,
315 u64 value)
316{
317 struct xilinx_dsi *dsi = connector_to_dsi(base_connector);
318
319 dev_dbg(dsi->dev, "property name = %s, value = %lld\n",
320 property->name, value);
321
322 if (property == dsi->eotp_prop)
323 dsi->eotp_prop_val = !!value;
324 else if (property == dsi->bllp_mode_prop)
325 dsi->bllp_mode_prop_val = !!value;
326 else if (property == dsi->bllp_type_prop)
327 dsi->bllp_type_prop_val = !!value;
328 else if (property == dsi->video_mode_prop)
329 dsi->video_mode_prop_val = (unsigned int)value;
330 else if (property == dsi->bllp_burst_time_prop)
331 dsi->bllp_burst_time_prop_val = (unsigned int)value;
332 else if (property == dsi->cmd_queue_prop)
333 dsi->cmd_queue_prop_val = (unsigned int)value;
334 else
335 return -EINVAL;
336
337 xilinx_dsi_set_config_parameters(dsi);
338
339 return 0;
340}
341
342static int xilinx_dsi_host_attach(struct mipi_dsi_host *host,
343 struct mipi_dsi_device *device)
344{
345 u32 panel_lanes;
346 struct xilinx_dsi *dsi = host_to_dsi(host);
347
348 panel_lanes = device->lanes;
349 dsi->mode_flags = device->mode_flags;
350 dsi->panel_node = device->dev.of_node;
351
352 if (panel_lanes != dsi->lanes) {
353 dev_err(dsi->dev, "Mismatch of lanes. panel = %d, DSI = %d\n",
354 panel_lanes, dsi->lanes);
355 return -EINVAL;
356 }
357
358 if ((dsi->lanes > 4) || (dsi->lanes < 1)) {
359 dev_err(dsi->dev, "%d lanes : invalid xlnx,dsi-num-lanes\n",
360 dsi->lanes);
361 return -EINVAL;
362 }
363
364 if (device->format != dsi->format) {
365 dev_err(dsi->dev, "Mismatch of format. panel = %d, DSI = %d\n",
366 device->format, dsi->format);
367 return -EINVAL;
368 }
369
370 if (dsi->connector.dev)
371 drm_helper_hpd_irq_event(dsi->connector.dev);
372
373 return 0;
374}
375
376static int xilinx_dsi_host_detach(struct mipi_dsi_host *host,
377 struct mipi_dsi_device *device)
378{
379 struct xilinx_dsi *dsi = host_to_dsi(host);
380
381 dsi->panel_node = NULL;
382
383 if (dsi->connector.dev)
384 drm_helper_hpd_irq_event(dsi->connector.dev);
385
386 return 0;
387}
388
389static const struct mipi_dsi_host_ops xilinx_dsi_ops = {
390 .attach = xilinx_dsi_host_attach,
391 .detach = xilinx_dsi_host_detach,
392};
393
394static int xilinx_dsi_connector_dpms(struct drm_connector *connector,
395 int mode)
396{
397 struct xilinx_dsi *dsi = connector_to_dsi(connector);
398 int ret;
399 bool panel_on = 0;
400
401 dev_dbg(dsi->dev, "connector dpms state: %d\n", mode);
402
403 switch (mode) {
404 case DRM_MODE_DPMS_ON:
405 ret = drm_panel_prepare(dsi->panel);
406 if (ret < 0)
407 return ret;
408
409 ret = drm_panel_enable(dsi->panel);
410 if (ret < 0) {
411 drm_panel_unprepare(dsi->panel);
412 dev_err(dsi->dev, "DRM panel not enabled. power off DSI\n");
413 return ret;
414 }
415 break;
416 default:
417 drm_panel_disable(dsi->panel);
418 drm_panel_unprepare(dsi->panel);
419 break;
420 }
421
422 return drm_helper_connector_dpms(connector, mode);
423}
424
425static enum drm_connector_status
426xilinx_dsi_detect(struct drm_connector *connector, bool force)
427{
428 struct xilinx_dsi *dsi = connector_to_dsi(connector);
429
430 if (!dsi->panel) {
431 dsi->panel = of_drm_find_panel(dsi->panel_node);
432 if (dsi->panel)
433 drm_panel_attach(dsi->panel, &dsi->connector);
434 } else if (!dsi->panel_node) {
435 xilinx_dsi_connector_dpms(connector, DRM_MODE_DPMS_OFF);
436 drm_panel_detach(dsi->panel);
437 dsi->panel = NULL;
438 }
439
440 if (dsi->panel)
441 return connector_status_connected;
442
443 return connector_status_disconnected;
444}
445
446static void xilinx_dsi_connector_destroy(struct drm_connector *connector)
447{
448 drm_connector_unregister(connector);
449 drm_connector_cleanup(connector);
450 connector->dev = NULL;
451}
452
453static struct drm_connector_funcs xilinx_dsi_connector_funcs = {
454 .dpms = xilinx_dsi_connector_dpms,
455 .detect = xilinx_dsi_detect,
456 .fill_modes = drm_helper_probe_single_connector_modes,
457 .destroy = xilinx_dsi_connector_destroy,
458 .set_property = xilinx_dsi_connector_set_property,
459};
460
461static int xilinx_dsi_get_modes(struct drm_connector *connector)
462{
463 struct xilinx_dsi *dsi = connector_to_dsi(connector);
464
465 if (dsi->panel)
466 return dsi->panel->funcs->get_modes(dsi->panel);
467
468 return 0;
469}
470
471static struct drm_encoder *
472xilinx_dsi_best_encoder(struct drm_connector *connector)
473{
474 return &(connector_to_dsi(connector)->encoder);
475}
476
477static struct drm_connector_helper_funcs xilinx_dsi_connector_helper_funcs = {
478 .get_modes = xilinx_dsi_get_modes,
479 .best_encoder = xilinx_dsi_best_encoder,
480};
481
482
483
484
485
486
487
488
489
490static void
491xilinx_drm_dsi_connector_create_property(struct drm_connector *base_connector)
492{
493 struct drm_device *dev = base_connector->dev;
494 struct xilinx_dsi *dsi = connector_to_dsi(base_connector);
495
496 dsi->eotp_prop = drm_property_create_bool(dev, 1, "eotp");
497 dsi->video_mode_prop = drm_property_create_range(dev, 0,
498 "video_mode", 0, 2);
499 dsi->bllp_mode_prop = drm_property_create_bool(dev, 0, "bllp_mode");
500 dsi->bllp_type_prop = drm_property_create_bool(dev, 0, "bllp_type");
501 dsi->bllp_burst_time_prop = drm_property_create_range(dev, 0,
502 "bllp_burst_time", 0, 0xFFFF);
503 dsi->cmd_queue_prop = drm_property_create_range(dev, 0,
504 "cmd_queue", 0, 0xFFFFFF);
505}
506
507
508
509
510
511
512
513static void
514xilinx_drm_dsi_connector_attach_property(struct drm_connector *base_connector)
515{
516 struct xilinx_dsi *dsi = connector_to_dsi(base_connector);
517 struct drm_mode_object *obj = &base_connector->base;
518
519 if (dsi->eotp_prop)
520 drm_object_attach_property(obj, dsi->eotp_prop, 1);
521
522 if (dsi->video_mode_prop)
523 drm_object_attach_property(obj, dsi->video_mode_prop, 0);
524
525 if (dsi->bllp_burst_time_prop)
526 drm_object_attach_property(&base_connector->base,
527 dsi->bllp_burst_time_prop, 0);
528
529 if (dsi->bllp_mode_prop)
530 drm_object_attach_property(&base_connector->base,
531 dsi->bllp_mode_prop, 0);
532
533 if (dsi->bllp_type_prop)
534 drm_object_attach_property(&base_connector->base,
535 dsi->bllp_type_prop, 0);
536
537 if (dsi->cmd_queue_prop)
538 drm_object_attach_property(&base_connector->base,
539 dsi->cmd_queue_prop, 0);
540}
541
542static int xilinx_dsi_create_connector(struct drm_encoder *encoder)
543{
544 struct xilinx_dsi *dsi = encoder_to_dsi(encoder);
545 struct drm_connector *connector = &dsi->connector;
546 int ret;
547
548 connector->polled = DRM_CONNECTOR_POLL_HPD;
549
550 ret = drm_connector_init(encoder->dev, connector,
551 &xilinx_dsi_connector_funcs,
552 DRM_MODE_CONNECTOR_DSI);
553 if (ret) {
554 dev_err(dsi->dev, "Failed to initialize connector with drm\n");
555 return ret;
556 }
557
558 drm_connector_helper_add(connector, &xilinx_dsi_connector_helper_funcs);
559 drm_connector_register(connector);
560 drm_mode_connector_attach_encoder(connector, encoder);
561 xilinx_drm_dsi_connector_create_property(connector);
562 xilinx_drm_dsi_connector_attach_property(connector);
563
564 return 0;
565}
566
567static bool xilinx_dsi_mode_fixup(struct drm_encoder *encoder,
568 const struct drm_display_mode *mode,
569 struct drm_display_mode *adjusted_mode)
570{
571 return true;
572}
573
574
575
576
577
578
579
580
581
582
583
584static void xilinx_dsi_mode_set(struct drm_encoder *encoder,
585 struct drm_display_mode *mode,
586 struct drm_display_mode *adjusted_mode)
587{
588 struct xilinx_dsi *dsi = encoder_to_dsi(encoder);
589 struct videomode *vm = &dsi->vm;
590 struct drm_display_mode *m = adjusted_mode;
591
592 vm->hactive = m->hdisplay;
593 vm->vactive = m->vdisplay;
594 vm->vfront_porch = m->vsync_start - m->vdisplay;
595 vm->vback_porch = m->vtotal - m->vsync_end;
596 vm->vsync_len = m->vsync_end - m->vsync_start;
597 vm->hfront_porch = m->hsync_start - m->hdisplay;
598 vm->hback_porch = m->htotal - m->hsync_end;
599 vm->hsync_len = m->hsync_end - m->hsync_start;
600 xilinx_dsi_set_display_mode(dsi);
601}
602
603static void xilinx_dsi_prepare(struct drm_encoder *encoder)
604{
605 struct xilinx_dsi *dsi = encoder_to_dsi(encoder);
606
607 dev_dbg(dsi->dev, "%s %d\n", __func__, __LINE__);
608 xilinx_dsi_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
609}
610
611static void xilinx_dsi_commit(struct drm_encoder *encoder)
612{
613 struct xilinx_dsi *dsi = encoder_to_dsi(encoder);
614
615 dev_dbg(dsi->dev, "config and enable the DSI: %s %d\n",
616 __func__, __LINE__);
617
618 xilinx_dsi_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
619}
620
621static struct drm_encoder_helper_funcs xilinx_dsi_encoder_helper_funcs = {
622 .dpms = xilinx_dsi_encoder_dpms,
623 .mode_fixup = xilinx_dsi_mode_fixup,
624 .mode_set = xilinx_dsi_mode_set,
625 .prepare = xilinx_dsi_prepare,
626 .commit = xilinx_dsi_commit,
627};
628
629static struct drm_encoder_funcs xilinx_dsi_encoder_funcs = {
630 .destroy = drm_encoder_cleanup,
631};
632
633static int xilinx_dsi_parse_dt(struct xilinx_dsi *dsi)
634{
635 struct device *dev = dsi->dev;
636 struct device_node *node = dev->of_node;
637 int ret;
638 u32 pixels_per_beat, datatype;
639
640 ret = of_property_read_u32(node, "xlnx,dsi-num-lanes",
641 &dsi->lanes);
642 if (ret < 0) {
643 dev_err(dsi->dev, "missing xlnx,dsi-num-lanes property\n");
644 return ret;
645 }
646
647 if ((dsi->lanes > 4) || (dsi->lanes < 1)) {
648 dev_err(dsi->dev, "%d lanes : invalid xlnx,dsi-num-lanes\n",
649 dsi->lanes);
650 return -EINVAL;
651 }
652
653 ret = of_property_read_u32(node, "xlnx,dsi-pixels-perbeat",
654 &pixels_per_beat);
655 if (ret < 0) {
656 dev_err(dsi->dev, "missing xlnx,dsi-pixels-perbeat property\n");
657 return ret;
658 }
659
660 if ((pixels_per_beat != 1) &&
661 (pixels_per_beat != 2) &&
662 (pixels_per_beat != 4)) {
663 dev_err(dsi->dev, "Wrong dts val xlnx,dsi-pixels-perbeat\n");
664 return -EINVAL;
665 }
666
667 ret = of_property_read_u32(node, "xlnx,dsi-data-type", &datatype);
668
669 if (ret < 0) {
670 dev_err(dsi->dev, "missing xlnx,dsi-data-type property\n");
671 return ret;
672 }
673
674 dsi->format = datatype;
675
676 if ((datatype > MIPI_DSI_FMT_RGB565) ||
677 (datatype < MIPI_DSI_FMT_RGB888)) {
678 dev_err(dsi->dev, "Invalid xlnx,dsi-data-type string\n");
679 return -EINVAL;
680 }
681
682 dsi->mul_factor = xdsi_mul_factor[datatype][pixels_per_beat >> 1];
683
684 dev_dbg(dsi->dev, "DSI controller num lanes = %d,pixels per beat = %d",
685 dsi->lanes, pixels_per_beat);
686
687 dev_dbg(dsi->dev, "DSI controller datatype = %d\n", datatype);
688
689 return 0;
690}
691
692static int xilinx_dsi_bind(struct device *dev, struct device *master,
693 void *data)
694{
695 struct xilinx_dsi *dsi = dev_get_drvdata(dev);
696 struct drm_encoder *encoder = &dsi->encoder;
697 struct drm_device *drm_dev = data;
698 int ret;
699
700
701
702
703
704
705 encoder->possible_crtcs = 1;
706
707 drm_encoder_init(drm_dev, encoder, &xilinx_dsi_encoder_funcs,
708 DRM_MODE_ENCODER_DSI, NULL);
709
710 drm_encoder_helper_add(encoder, &xilinx_dsi_encoder_helper_funcs);
711
712 ret = xilinx_dsi_create_connector(encoder);
713 if (ret) {
714 dev_err(dsi->dev, "fail creating connector, ret = %d\n", ret);
715 drm_encoder_cleanup(encoder);
716 return ret;
717 }
718
719 ret = mipi_dsi_host_register(&dsi->dsi_host);
720 if (ret) {
721 xilinx_dsi_connector_destroy(&dsi->connector);
722 drm_encoder_cleanup(encoder);
723 return ret;
724 }
725
726 return ret;
727}
728
729static void xilinx_dsi_unbind(struct device *dev, struct device *master,
730 void *data)
731{
732 struct xilinx_dsi *dsi = dev_get_drvdata(dev);
733
734 xilinx_dsi_encoder_dpms(&dsi->encoder, DRM_MODE_DPMS_OFF);
735 mipi_dsi_host_unregister(&dsi->dsi_host);
736}
737
738static const struct component_ops xilinx_dsi_component_ops = {
739 .bind = xilinx_dsi_bind,
740 .unbind = xilinx_dsi_unbind,
741};
742
743static int xilinx_dsi_probe(struct platform_device *pdev)
744{
745 struct device *dev = &pdev->dev;
746 struct resource *res;
747 struct xilinx_dsi *dsi;
748 int ret;
749
750 dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
751 if (!dsi)
752 return -ENOMEM;
753
754 dsi->dsi_host.ops = &xilinx_dsi_ops;
755 dsi->dsi_host.dev = dev;
756 dsi->dev = dev;
757
758 ret = xilinx_dsi_parse_dt(dsi);
759 if (ret)
760 return ret;
761
762 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
763 dsi->iomem = devm_ioremap_resource(dev, res);
764 dev_dbg(dsi->dev, "dsi virtual address = %p %s %d\n",
765 dsi->iomem, __func__, __LINE__);
766
767 if (IS_ERR(dsi->iomem)) {
768 dev_err(dev, "failed to remap io region\n");
769 return PTR_ERR(dsi->iomem);
770 }
771
772 platform_set_drvdata(pdev, dsi);
773
774 return component_add(dev, &xilinx_dsi_component_ops);
775}
776
777static int xilinx_dsi_remove(struct platform_device *pdev)
778{
779 component_del(&pdev->dev, &xilinx_dsi_component_ops);
780
781 return 0;
782}
783
784static const struct of_device_id xilinx_dsi_of_match[] = {
785 { .compatible = "xlnx,mipi-dsi-tx-subsystem"},
786 { }
787};
788MODULE_DEVICE_TABLE(of, xilinx_dsi_of_match);
789
790struct platform_driver dsi_driver = {
791 .probe = xilinx_dsi_probe,
792 .remove = xilinx_dsi_remove,
793 .driver = {
794 .name = "xilinx-mipi-dsi",
795 .owner = THIS_MODULE,
796 .of_match_table = xilinx_dsi_of_match,
797 },
798};
799
800module_platform_driver(dsi_driver);
801
802MODULE_AUTHOR("Siva Rajesh <sivaraj@xilinx.com>");
803MODULE_DESCRIPTION("Xilinx FPGA MIPI DSI Tx Driver");
804MODULE_LICENSE("GPL v2");
805