Merge tag 'gpio-v5.3-rc7-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kerne...
[sfrench/cifs-2.6.git] / drivers / gpu / drm / ingenic / ingenic-drm.c
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // Ingenic JZ47xx KMS driver
4 //
5 // Copyright (C) 2019, Paul Cercueil <paul@crapouillou.net>
6
7 #include <linux/clk.h>
8 #include <linux/dma-mapping.h>
9 #include <linux/module.h>
10 #include <linux/of_device.h>
11 #include <linux/platform_device.h>
12 #include <linux/regmap.h>
13
14 #include <drm/drm_atomic.h>
15 #include <drm/drm_atomic_helper.h>
16 #include <drm/drm_crtc.h>
17 #include <drm/drm_crtc_helper.h>
18 #include <drm/drm_drv.h>
19 #include <drm/drm_gem_cma_helper.h>
20 #include <drm/drm_fb_cma_helper.h>
21 #include <drm/drm_fb_helper.h>
22 #include <drm/drm_fourcc.h>
23 #include <drm/drm_gem_framebuffer_helper.h>
24 #include <drm/drm_irq.h>
25 #include <drm/drm_of.h>
26 #include <drm/drm_panel.h>
27 #include <drm/drm_plane.h>
28 #include <drm/drm_plane_helper.h>
29 #include <drm/drm_probe_helper.h>
30 #include <drm/drm_vblank.h>
31
32 #define JZ_REG_LCD_CFG                          0x00
33 #define JZ_REG_LCD_VSYNC                        0x04
34 #define JZ_REG_LCD_HSYNC                        0x08
35 #define JZ_REG_LCD_VAT                          0x0C
36 #define JZ_REG_LCD_DAH                          0x10
37 #define JZ_REG_LCD_DAV                          0x14
38 #define JZ_REG_LCD_PS                           0x18
39 #define JZ_REG_LCD_CLS                          0x1C
40 #define JZ_REG_LCD_SPL                          0x20
41 #define JZ_REG_LCD_REV                          0x24
42 #define JZ_REG_LCD_CTRL                         0x30
43 #define JZ_REG_LCD_STATE                        0x34
44 #define JZ_REG_LCD_IID                          0x38
45 #define JZ_REG_LCD_DA0                          0x40
46 #define JZ_REG_LCD_SA0                          0x44
47 #define JZ_REG_LCD_FID0                         0x48
48 #define JZ_REG_LCD_CMD0                         0x4C
49 #define JZ_REG_LCD_DA1                          0x50
50 #define JZ_REG_LCD_SA1                          0x54
51 #define JZ_REG_LCD_FID1                         0x58
52 #define JZ_REG_LCD_CMD1                         0x5C
53
54 #define JZ_LCD_CFG_SLCD                         BIT(31)
55 #define JZ_LCD_CFG_PS_DISABLE                   BIT(23)
56 #define JZ_LCD_CFG_CLS_DISABLE                  BIT(22)
57 #define JZ_LCD_CFG_SPL_DISABLE                  BIT(21)
58 #define JZ_LCD_CFG_REV_DISABLE                  BIT(20)
59 #define JZ_LCD_CFG_HSYNCM                       BIT(19)
60 #define JZ_LCD_CFG_PCLKM                        BIT(18)
61 #define JZ_LCD_CFG_INV                          BIT(17)
62 #define JZ_LCD_CFG_SYNC_DIR                     BIT(16)
63 #define JZ_LCD_CFG_PS_POLARITY                  BIT(15)
64 #define JZ_LCD_CFG_CLS_POLARITY                 BIT(14)
65 #define JZ_LCD_CFG_SPL_POLARITY                 BIT(13)
66 #define JZ_LCD_CFG_REV_POLARITY                 BIT(12)
67 #define JZ_LCD_CFG_HSYNC_ACTIVE_LOW             BIT(11)
68 #define JZ_LCD_CFG_PCLK_FALLING_EDGE            BIT(10)
69 #define JZ_LCD_CFG_DE_ACTIVE_LOW                BIT(9)
70 #define JZ_LCD_CFG_VSYNC_ACTIVE_LOW             BIT(8)
71 #define JZ_LCD_CFG_18_BIT                       BIT(7)
72 #define JZ_LCD_CFG_PDW                          (BIT(5) | BIT(4))
73
74 #define JZ_LCD_CFG_MODE_GENERIC_16BIT           0
75 #define JZ_LCD_CFG_MODE_GENERIC_18BIT           BIT(7)
76 #define JZ_LCD_CFG_MODE_GENERIC_24BIT           BIT(6)
77
78 #define JZ_LCD_CFG_MODE_SPECIAL_TFT_1           1
79 #define JZ_LCD_CFG_MODE_SPECIAL_TFT_2           2
80 #define JZ_LCD_CFG_MODE_SPECIAL_TFT_3           3
81
82 #define JZ_LCD_CFG_MODE_TV_OUT_P                4
83 #define JZ_LCD_CFG_MODE_TV_OUT_I                6
84
85 #define JZ_LCD_CFG_MODE_SINGLE_COLOR_STN        8
86 #define JZ_LCD_CFG_MODE_SINGLE_MONOCHROME_STN   9
87 #define JZ_LCD_CFG_MODE_DUAL_COLOR_STN          10
88 #define JZ_LCD_CFG_MODE_DUAL_MONOCHROME_STN     11
89
90 #define JZ_LCD_CFG_MODE_8BIT_SERIAL             12
91 #define JZ_LCD_CFG_MODE_LCM                     13
92
93 #define JZ_LCD_VSYNC_VPS_OFFSET                 16
94 #define JZ_LCD_VSYNC_VPE_OFFSET                 0
95
96 #define JZ_LCD_HSYNC_HPS_OFFSET                 16
97 #define JZ_LCD_HSYNC_HPE_OFFSET                 0
98
99 #define JZ_LCD_VAT_HT_OFFSET                    16
100 #define JZ_LCD_VAT_VT_OFFSET                    0
101
102 #define JZ_LCD_DAH_HDS_OFFSET                   16
103 #define JZ_LCD_DAH_HDE_OFFSET                   0
104
105 #define JZ_LCD_DAV_VDS_OFFSET                   16
106 #define JZ_LCD_DAV_VDE_OFFSET                   0
107
108 #define JZ_LCD_CTRL_BURST_4                     (0x0 << 28)
109 #define JZ_LCD_CTRL_BURST_8                     (0x1 << 28)
110 #define JZ_LCD_CTRL_BURST_16                    (0x2 << 28)
111 #define JZ_LCD_CTRL_RGB555                      BIT(27)
112 #define JZ_LCD_CTRL_OFUP                        BIT(26)
113 #define JZ_LCD_CTRL_FRC_GRAYSCALE_16            (0x0 << 24)
114 #define JZ_LCD_CTRL_FRC_GRAYSCALE_4             (0x1 << 24)
115 #define JZ_LCD_CTRL_FRC_GRAYSCALE_2             (0x2 << 24)
116 #define JZ_LCD_CTRL_PDD_MASK                    (0xff << 16)
117 #define JZ_LCD_CTRL_EOF_IRQ                     BIT(13)
118 #define JZ_LCD_CTRL_SOF_IRQ                     BIT(12)
119 #define JZ_LCD_CTRL_OFU_IRQ                     BIT(11)
120 #define JZ_LCD_CTRL_IFU0_IRQ                    BIT(10)
121 #define JZ_LCD_CTRL_IFU1_IRQ                    BIT(9)
122 #define JZ_LCD_CTRL_DD_IRQ                      BIT(8)
123 #define JZ_LCD_CTRL_QDD_IRQ                     BIT(7)
124 #define JZ_LCD_CTRL_REVERSE_ENDIAN              BIT(6)
125 #define JZ_LCD_CTRL_LSB_FISRT                   BIT(5)
126 #define JZ_LCD_CTRL_DISABLE                     BIT(4)
127 #define JZ_LCD_CTRL_ENABLE                      BIT(3)
128 #define JZ_LCD_CTRL_BPP_1                       0x0
129 #define JZ_LCD_CTRL_BPP_2                       0x1
130 #define JZ_LCD_CTRL_BPP_4                       0x2
131 #define JZ_LCD_CTRL_BPP_8                       0x3
132 #define JZ_LCD_CTRL_BPP_15_16                   0x4
133 #define JZ_LCD_CTRL_BPP_18_24                   0x5
134 #define JZ_LCD_CTRL_BPP_MASK                    (JZ_LCD_CTRL_RGB555 | (0x7 << 0))
135
136 #define JZ_LCD_CMD_SOF_IRQ                      BIT(31)
137 #define JZ_LCD_CMD_EOF_IRQ                      BIT(30)
138 #define JZ_LCD_CMD_ENABLE_PAL                   BIT(28)
139
140 #define JZ_LCD_SYNC_MASK                        0x3ff
141
142 #define JZ_LCD_STATE_EOF_IRQ                    BIT(5)
143 #define JZ_LCD_STATE_SOF_IRQ                    BIT(4)
144 #define JZ_LCD_STATE_DISABLED                   BIT(0)
145
146 struct ingenic_dma_hwdesc {
147         u32 next;
148         u32 addr;
149         u32 id;
150         u32 cmd;
151 } __packed;
152
153 struct jz_soc_info {
154         bool needs_dev_clk;
155 };
156
157 struct ingenic_drm {
158         struct drm_device drm;
159         struct drm_plane primary;
160         struct drm_crtc crtc;
161         struct drm_encoder encoder;
162
163         struct device *dev;
164         struct regmap *map;
165         struct clk *lcd_clk, *pix_clk;
166
167         struct ingenic_dma_hwdesc *dma_hwdesc;
168         dma_addr_t dma_hwdesc_phys;
169 };
170
171 static const u32 ingenic_drm_primary_formats[] = {
172         DRM_FORMAT_XRGB1555,
173         DRM_FORMAT_RGB565,
174         DRM_FORMAT_XRGB8888,
175 };
176
177 static bool ingenic_drm_writeable_reg(struct device *dev, unsigned int reg)
178 {
179         switch (reg) {
180         case JZ_REG_LCD_IID:
181         case JZ_REG_LCD_SA0:
182         case JZ_REG_LCD_FID0:
183         case JZ_REG_LCD_CMD0:
184         case JZ_REG_LCD_SA1:
185         case JZ_REG_LCD_FID1:
186         case JZ_REG_LCD_CMD1:
187                 return false;
188         default:
189                 return true;
190         }
191 }
192
193 static const struct regmap_config ingenic_drm_regmap_config = {
194         .reg_bits = 32,
195         .val_bits = 32,
196         .reg_stride = 4,
197
198         .max_register = JZ_REG_LCD_CMD1,
199         .writeable_reg = ingenic_drm_writeable_reg,
200 };
201
202 static inline struct ingenic_drm *drm_device_get_priv(struct drm_device *drm)
203 {
204         return container_of(drm, struct ingenic_drm, drm);
205 }
206
207 static inline struct ingenic_drm *drm_crtc_get_priv(struct drm_crtc *crtc)
208 {
209         return container_of(crtc, struct ingenic_drm, crtc);
210 }
211
212 static inline struct ingenic_drm *
213 drm_encoder_get_priv(struct drm_encoder *encoder)
214 {
215         return container_of(encoder, struct ingenic_drm, encoder);
216 }
217
218 static inline struct ingenic_drm *drm_plane_get_priv(struct drm_plane *plane)
219 {
220         return container_of(plane, struct ingenic_drm, primary);
221 }
222
223 static void ingenic_drm_crtc_atomic_enable(struct drm_crtc *crtc,
224                                            struct drm_crtc_state *state)
225 {
226         struct ingenic_drm *priv = drm_crtc_get_priv(crtc);
227
228         regmap_write(priv->map, JZ_REG_LCD_STATE, 0);
229
230         regmap_update_bits(priv->map, JZ_REG_LCD_CTRL,
231                            JZ_LCD_CTRL_ENABLE | JZ_LCD_CTRL_DISABLE,
232                            JZ_LCD_CTRL_ENABLE);
233
234         drm_crtc_vblank_on(crtc);
235 }
236
237 static void ingenic_drm_crtc_atomic_disable(struct drm_crtc *crtc,
238                                             struct drm_crtc_state *state)
239 {
240         struct ingenic_drm *priv = drm_crtc_get_priv(crtc);
241         unsigned int var;
242
243         drm_crtc_vblank_off(crtc);
244
245         regmap_update_bits(priv->map, JZ_REG_LCD_CTRL,
246                            JZ_LCD_CTRL_DISABLE, JZ_LCD_CTRL_DISABLE);
247
248         regmap_read_poll_timeout(priv->map, JZ_REG_LCD_STATE, var,
249                                  var & JZ_LCD_STATE_DISABLED,
250                                  1000, 0);
251 }
252
253 static void ingenic_drm_crtc_update_timings(struct ingenic_drm *priv,
254                                             struct drm_display_mode *mode)
255 {
256         unsigned int vpe, vds, vde, vt, hpe, hds, hde, ht;
257
258         vpe = mode->vsync_end - mode->vsync_start;
259         vds = mode->vtotal - mode->vsync_start;
260         vde = vds + mode->vdisplay;
261         vt = vde + mode->vsync_start - mode->vdisplay;
262
263         hpe = mode->hsync_end - mode->hsync_start;
264         hds = mode->htotal - mode->hsync_start;
265         hde = hds + mode->hdisplay;
266         ht = hde + mode->hsync_start - mode->hdisplay;
267
268         regmap_write(priv->map, JZ_REG_LCD_VSYNC,
269                      0 << JZ_LCD_VSYNC_VPS_OFFSET |
270                      vpe << JZ_LCD_VSYNC_VPE_OFFSET);
271
272         regmap_write(priv->map, JZ_REG_LCD_HSYNC,
273                      0 << JZ_LCD_HSYNC_HPS_OFFSET |
274                      hpe << JZ_LCD_HSYNC_HPE_OFFSET);
275
276         regmap_write(priv->map, JZ_REG_LCD_VAT,
277                      ht << JZ_LCD_VAT_HT_OFFSET |
278                      vt << JZ_LCD_VAT_VT_OFFSET);
279
280         regmap_write(priv->map, JZ_REG_LCD_DAH,
281                      hds << JZ_LCD_DAH_HDS_OFFSET |
282                      hde << JZ_LCD_DAH_HDE_OFFSET);
283         regmap_write(priv->map, JZ_REG_LCD_DAV,
284                      vds << JZ_LCD_DAV_VDS_OFFSET |
285                      vde << JZ_LCD_DAV_VDE_OFFSET);
286 }
287
288 static void ingenic_drm_crtc_update_ctrl(struct ingenic_drm *priv,
289                                          const struct drm_format_info *finfo)
290 {
291         unsigned int ctrl = JZ_LCD_CTRL_OFUP | JZ_LCD_CTRL_BURST_16;
292
293         switch (finfo->format) {
294         case DRM_FORMAT_XRGB1555:
295                 ctrl |= JZ_LCD_CTRL_RGB555;
296                 /* fall-through */
297         case DRM_FORMAT_RGB565:
298                 ctrl |= JZ_LCD_CTRL_BPP_15_16;
299                 break;
300         case DRM_FORMAT_XRGB8888:
301                 ctrl |= JZ_LCD_CTRL_BPP_18_24;
302                 break;
303         }
304
305         regmap_update_bits(priv->map, JZ_REG_LCD_CTRL,
306                            JZ_LCD_CTRL_OFUP | JZ_LCD_CTRL_BURST_16 |
307                            JZ_LCD_CTRL_BPP_MASK, ctrl);
308 }
309
310 static int ingenic_drm_crtc_atomic_check(struct drm_crtc *crtc,
311                                          struct drm_crtc_state *state)
312 {
313         struct ingenic_drm *priv = drm_crtc_get_priv(crtc);
314         long rate;
315
316         if (!drm_atomic_crtc_needs_modeset(state))
317                 return 0;
318
319         rate = clk_round_rate(priv->pix_clk,
320                               state->adjusted_mode.clock * 1000);
321         if (rate < 0)
322                 return rate;
323
324         return 0;
325 }
326
327 static void ingenic_drm_crtc_atomic_flush(struct drm_crtc *crtc,
328                                           struct drm_crtc_state *oldstate)
329 {
330         struct ingenic_drm *priv = drm_crtc_get_priv(crtc);
331         struct drm_crtc_state *state = crtc->state;
332         struct drm_pending_vblank_event *event = state->event;
333         struct drm_framebuffer *drm_fb = crtc->primary->state->fb;
334         const struct drm_format_info *finfo;
335
336         if (drm_atomic_crtc_needs_modeset(state)) {
337                 finfo = drm_format_info(drm_fb->format->format);
338
339                 ingenic_drm_crtc_update_timings(priv, &state->mode);
340                 ingenic_drm_crtc_update_ctrl(priv, finfo);
341
342                 clk_set_rate(priv->pix_clk, state->adjusted_mode.clock * 1000);
343
344                 regmap_write(priv->map, JZ_REG_LCD_DA0, priv->dma_hwdesc->next);
345         }
346
347         if (event) {
348                 state->event = NULL;
349
350                 spin_lock_irq(&crtc->dev->event_lock);
351                 if (drm_crtc_vblank_get(crtc) == 0)
352                         drm_crtc_arm_vblank_event(crtc, event);
353                 else
354                         drm_crtc_send_vblank_event(crtc, event);
355                 spin_unlock_irq(&crtc->dev->event_lock);
356         }
357 }
358
359 static void ingenic_drm_plane_atomic_update(struct drm_plane *plane,
360                                             struct drm_plane_state *oldstate)
361 {
362         struct ingenic_drm *priv = drm_plane_get_priv(plane);
363         struct drm_plane_state *state = plane->state;
364         unsigned int width, height, cpp;
365
366         width = state->crtc->state->adjusted_mode.hdisplay;
367         height = state->crtc->state->adjusted_mode.vdisplay;
368         cpp = state->fb->format->cpp[plane->index];
369
370         priv->dma_hwdesc->addr = drm_fb_cma_get_gem_addr(state->fb, state, 0);
371         priv->dma_hwdesc->cmd = width * height * cpp / 4;
372         priv->dma_hwdesc->cmd |= JZ_LCD_CMD_EOF_IRQ;
373 }
374
375 static void ingenic_drm_encoder_atomic_mode_set(struct drm_encoder *encoder,
376                                                 struct drm_crtc_state *crtc_state,
377                                                 struct drm_connector_state *conn_state)
378 {
379         struct ingenic_drm *priv = drm_encoder_get_priv(encoder);
380         struct drm_display_mode *mode = &crtc_state->adjusted_mode;
381         struct drm_display_info *info = &conn_state->connector->display_info;
382         unsigned int cfg = JZ_LCD_CFG_PS_DISABLE
383                          | JZ_LCD_CFG_CLS_DISABLE
384                          | JZ_LCD_CFG_SPL_DISABLE
385                          | JZ_LCD_CFG_REV_DISABLE;
386
387         if (mode->flags & DRM_MODE_FLAG_NHSYNC)
388                 cfg |= JZ_LCD_CFG_HSYNC_ACTIVE_LOW;
389         if (mode->flags & DRM_MODE_FLAG_NVSYNC)
390                 cfg |= JZ_LCD_CFG_VSYNC_ACTIVE_LOW;
391         if (info->bus_flags & DRM_BUS_FLAG_DE_LOW)
392                 cfg |= JZ_LCD_CFG_DE_ACTIVE_LOW;
393         if (info->bus_flags & DRM_BUS_FLAG_PIXDATA_NEGEDGE)
394                 cfg |= JZ_LCD_CFG_PCLK_FALLING_EDGE;
395
396         if (conn_state->connector->connector_type == DRM_MODE_CONNECTOR_TV) {
397                 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
398                         cfg |= JZ_LCD_CFG_MODE_TV_OUT_I;
399                 else
400                         cfg |= JZ_LCD_CFG_MODE_TV_OUT_P;
401         } else {
402                 switch (*info->bus_formats) {
403                 case MEDIA_BUS_FMT_RGB565_1X16:
404                         cfg |= JZ_LCD_CFG_MODE_GENERIC_16BIT;
405                         break;
406                 case MEDIA_BUS_FMT_RGB666_1X18:
407                         cfg |= JZ_LCD_CFG_MODE_GENERIC_18BIT;
408                         break;
409                 case MEDIA_BUS_FMT_RGB888_1X24:
410                         cfg |= JZ_LCD_CFG_MODE_GENERIC_24BIT;
411                         break;
412                 default:
413                         break;
414                 }
415         }
416
417         regmap_write(priv->map, JZ_REG_LCD_CFG, cfg);
418 }
419
420 static int ingenic_drm_encoder_atomic_check(struct drm_encoder *encoder,
421                                             struct drm_crtc_state *crtc_state,
422                                             struct drm_connector_state *conn_state)
423 {
424         struct drm_display_info *info = &conn_state->connector->display_info;
425
426         if (info->num_bus_formats != 1)
427                 return -EINVAL;
428
429         if (conn_state->connector->connector_type == DRM_MODE_CONNECTOR_TV)
430                 return 0;
431
432         switch (*info->bus_formats) {
433         case MEDIA_BUS_FMT_RGB565_1X16:
434         case MEDIA_BUS_FMT_RGB666_1X18:
435         case MEDIA_BUS_FMT_RGB888_1X24:
436                 return 0;
437         default:
438                 return -EINVAL;
439         }
440 }
441
442 static irqreturn_t ingenic_drm_irq_handler(int irq, void *arg)
443 {
444         struct ingenic_drm *priv = arg;
445         unsigned int state;
446
447         regmap_read(priv->map, JZ_REG_LCD_STATE, &state);
448
449         regmap_update_bits(priv->map, JZ_REG_LCD_STATE,
450                            JZ_LCD_STATE_EOF_IRQ, 0);
451
452         if (state & JZ_LCD_STATE_EOF_IRQ)
453                 drm_crtc_handle_vblank(&priv->crtc);
454
455         return IRQ_HANDLED;
456 }
457
458 static void ingenic_drm_release(struct drm_device *drm)
459 {
460         struct ingenic_drm *priv = drm_device_get_priv(drm);
461
462         drm_mode_config_cleanup(drm);
463         drm_dev_fini(drm);
464         kfree(priv);
465 }
466
467 static int ingenic_drm_enable_vblank(struct drm_crtc *crtc)
468 {
469         struct ingenic_drm *priv = drm_crtc_get_priv(crtc);
470
471         regmap_update_bits(priv->map, JZ_REG_LCD_CTRL,
472                            JZ_LCD_CTRL_EOF_IRQ, JZ_LCD_CTRL_EOF_IRQ);
473
474         return 0;
475 }
476
477 static void ingenic_drm_disable_vblank(struct drm_crtc *crtc)
478 {
479         struct ingenic_drm *priv = drm_crtc_get_priv(crtc);
480
481         regmap_update_bits(priv->map, JZ_REG_LCD_CTRL, JZ_LCD_CTRL_EOF_IRQ, 0);
482 }
483
484 DEFINE_DRM_GEM_CMA_FOPS(ingenic_drm_fops);
485
486 static struct drm_driver ingenic_drm_driver_data = {
487         .driver_features        = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME
488                                 | DRIVER_ATOMIC,
489         .name                   = "ingenic-drm",
490         .desc                   = "DRM module for Ingenic SoCs",
491         .date                   = "20190422",
492         .major                  = 1,
493         .minor                  = 0,
494         .patchlevel             = 0,
495
496         .fops                   = &ingenic_drm_fops,
497
498         .dumb_create            = drm_gem_cma_dumb_create,
499         .gem_free_object_unlocked = drm_gem_cma_free_object,
500         .gem_vm_ops             = &drm_gem_cma_vm_ops,
501
502         .prime_handle_to_fd     = drm_gem_prime_handle_to_fd,
503         .prime_fd_to_handle     = drm_gem_prime_fd_to_handle,
504         .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table,
505         .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
506         .gem_prime_vmap         = drm_gem_cma_prime_vmap,
507         .gem_prime_vunmap       = drm_gem_cma_prime_vunmap,
508         .gem_prime_mmap         = drm_gem_cma_prime_mmap,
509
510         .irq_handler            = ingenic_drm_irq_handler,
511         .release                = ingenic_drm_release,
512 };
513
514 static const struct drm_plane_funcs ingenic_drm_primary_plane_funcs = {
515         .update_plane           = drm_atomic_helper_update_plane,
516         .disable_plane          = drm_atomic_helper_disable_plane,
517         .reset                  = drm_atomic_helper_plane_reset,
518         .destroy                = drm_plane_cleanup,
519
520         .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
521         .atomic_destroy_state   = drm_atomic_helper_plane_destroy_state,
522 };
523
524 static const struct drm_crtc_funcs ingenic_drm_crtc_funcs = {
525         .set_config             = drm_atomic_helper_set_config,
526         .page_flip              = drm_atomic_helper_page_flip,
527         .reset                  = drm_atomic_helper_crtc_reset,
528         .destroy                = drm_crtc_cleanup,
529
530         .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
531         .atomic_destroy_state   = drm_atomic_helper_crtc_destroy_state,
532
533         .enable_vblank          = ingenic_drm_enable_vblank,
534         .disable_vblank         = ingenic_drm_disable_vblank,
535
536         .gamma_set              = drm_atomic_helper_legacy_gamma_set,
537 };
538
539 static const struct drm_plane_helper_funcs ingenic_drm_plane_helper_funcs = {
540         .atomic_update          = ingenic_drm_plane_atomic_update,
541         .prepare_fb             = drm_gem_fb_prepare_fb,
542 };
543
544 static const struct drm_crtc_helper_funcs ingenic_drm_crtc_helper_funcs = {
545         .atomic_enable          = ingenic_drm_crtc_atomic_enable,
546         .atomic_disable         = ingenic_drm_crtc_atomic_disable,
547         .atomic_flush           = ingenic_drm_crtc_atomic_flush,
548         .atomic_check           = ingenic_drm_crtc_atomic_check,
549 };
550
551 static const struct drm_encoder_helper_funcs ingenic_drm_encoder_helper_funcs = {
552         .atomic_mode_set        = ingenic_drm_encoder_atomic_mode_set,
553         .atomic_check           = ingenic_drm_encoder_atomic_check,
554 };
555
556 static const struct drm_mode_config_funcs ingenic_drm_mode_config_funcs = {
557         .fb_create              = drm_gem_fb_create,
558         .output_poll_changed    = drm_fb_helper_output_poll_changed,
559         .atomic_check           = drm_atomic_helper_check,
560         .atomic_commit          = drm_atomic_helper_commit,
561 };
562
563 static const struct drm_encoder_funcs ingenic_drm_encoder_funcs = {
564         .destroy                = drm_encoder_cleanup,
565 };
566
567 static void ingenic_drm_free_dma_hwdesc(void *d)
568 {
569         struct ingenic_drm *priv = d;
570
571         dma_free_coherent(priv->dev, sizeof(*priv->dma_hwdesc),
572                           priv->dma_hwdesc, priv->dma_hwdesc_phys);
573 }
574
575 static int ingenic_drm_probe(struct platform_device *pdev)
576 {
577         const struct jz_soc_info *soc_info;
578         struct device *dev = &pdev->dev;
579         struct ingenic_drm *priv;
580         struct clk *parent_clk;
581         struct drm_bridge *bridge;
582         struct drm_panel *panel;
583         struct drm_device *drm;
584         struct resource *mem;
585         void __iomem *base;
586         long parent_rate;
587         int ret, irq;
588
589         soc_info = of_device_get_match_data(dev);
590         if (!soc_info) {
591                 dev_err(dev, "Missing platform data\n");
592                 return -EINVAL;
593         }
594
595         priv = kzalloc(sizeof(*priv), GFP_KERNEL);
596         if (!priv)
597                 return -ENOMEM;
598
599         priv->dev = dev;
600         drm = &priv->drm;
601         drm->dev_private = priv;
602
603         platform_set_drvdata(pdev, priv);
604
605         ret = devm_drm_dev_init(dev, drm, &ingenic_drm_driver_data);
606         if (ret) {
607                 kfree(priv);
608                 return ret;
609         }
610
611         drm_mode_config_init(drm);
612         drm->mode_config.min_width = 0;
613         drm->mode_config.min_height = 0;
614         drm->mode_config.max_width = 800;
615         drm->mode_config.max_height = 600;
616         drm->mode_config.funcs = &ingenic_drm_mode_config_funcs;
617
618         mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
619         base = devm_ioremap_resource(dev, mem);
620         if (IS_ERR(base)) {
621                 dev_err(dev, "Failed to get memory resource");
622                 return PTR_ERR(base);
623         }
624
625         priv->map = devm_regmap_init_mmio(dev, base,
626                                           &ingenic_drm_regmap_config);
627         if (IS_ERR(priv->map)) {
628                 dev_err(dev, "Failed to create regmap");
629                 return PTR_ERR(priv->map);
630         }
631
632         irq = platform_get_irq(pdev, 0);
633         if (irq < 0) {
634                 dev_err(dev, "Failed to get platform irq");
635                 return irq;
636         }
637
638         if (soc_info->needs_dev_clk) {
639                 priv->lcd_clk = devm_clk_get(dev, "lcd");
640                 if (IS_ERR(priv->lcd_clk)) {
641                         dev_err(dev, "Failed to get lcd clock");
642                         return PTR_ERR(priv->lcd_clk);
643                 }
644         }
645
646         priv->pix_clk = devm_clk_get(dev, "lcd_pclk");
647         if (IS_ERR(priv->pix_clk)) {
648                 dev_err(dev, "Failed to get pixel clock");
649                 return PTR_ERR(priv->pix_clk);
650         }
651
652         ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0, &panel, &bridge);
653         if (ret) {
654                 if (ret != -EPROBE_DEFER)
655                         dev_err(dev, "Failed to get panel handle");
656                 return ret;
657         }
658
659         if (panel) {
660                 bridge = devm_drm_panel_bridge_add(dev, panel,
661                                                    DRM_MODE_CONNECTOR_Unknown);
662         }
663
664         priv->dma_hwdesc = dma_alloc_coherent(dev, sizeof(*priv->dma_hwdesc),
665                                               &priv->dma_hwdesc_phys,
666                                               GFP_KERNEL);
667         if (!priv->dma_hwdesc)
668                 return -ENOMEM;
669
670         ret = devm_add_action_or_reset(dev, ingenic_drm_free_dma_hwdesc, priv);
671         if (ret)
672                 return ret;
673
674         priv->dma_hwdesc->next = priv->dma_hwdesc_phys;
675         priv->dma_hwdesc->id = 0xdeafbead;
676
677         drm_plane_helper_add(&priv->primary, &ingenic_drm_plane_helper_funcs);
678
679         ret = drm_universal_plane_init(drm, &priv->primary,
680                                        0, &ingenic_drm_primary_plane_funcs,
681                                        ingenic_drm_primary_formats,
682                                        ARRAY_SIZE(ingenic_drm_primary_formats),
683                                        NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
684         if (ret) {
685                 dev_err(dev, "Failed to register primary plane: %i", ret);
686                 return ret;
687         }
688
689         drm_crtc_helper_add(&priv->crtc, &ingenic_drm_crtc_helper_funcs);
690
691         ret = drm_crtc_init_with_planes(drm, &priv->crtc, &priv->primary,
692                                         NULL, &ingenic_drm_crtc_funcs, NULL);
693         if (ret) {
694                 dev_err(dev, "Failed to init CRTC: %i", ret);
695                 return ret;
696         }
697
698         priv->encoder.possible_crtcs = 1;
699
700         drm_encoder_helper_add(&priv->encoder,
701                                &ingenic_drm_encoder_helper_funcs);
702
703         ret = drm_encoder_init(drm, &priv->encoder, &ingenic_drm_encoder_funcs,
704                                DRM_MODE_ENCODER_DPI, NULL);
705         if (ret) {
706                 dev_err(dev, "Failed to init encoder: %i", ret);
707                 return ret;
708         }
709
710         ret = drm_bridge_attach(&priv->encoder, bridge, NULL);
711         if (ret) {
712                 dev_err(dev, "Unable to attach bridge");
713                 return ret;
714         }
715
716         ret = drm_irq_install(drm, irq);
717         if (ret) {
718                 dev_err(dev, "Unable to install IRQ handler");
719                 return ret;
720         }
721
722         ret = drm_vblank_init(drm, 1);
723         if (ret) {
724                 dev_err(dev, "Failed calling drm_vblank_init()");
725                 return ret;
726         }
727
728         drm_mode_config_reset(drm);
729
730         ret = clk_prepare_enable(priv->pix_clk);
731         if (ret) {
732                 dev_err(dev, "Unable to start pixel clock");
733                 return ret;
734         }
735
736         if (priv->lcd_clk) {
737                 parent_clk = clk_get_parent(priv->lcd_clk);
738                 parent_rate = clk_get_rate(parent_clk);
739
740                 /* LCD Device clock must be 3x the pixel clock for STN panels,
741                  * or 1.5x the pixel clock for TFT panels. To avoid having to
742                  * check for the LCD device clock everytime we do a mode change,
743                  * we set the LCD device clock to the highest rate possible.
744                  */
745                 ret = clk_set_rate(priv->lcd_clk, parent_rate);
746                 if (ret) {
747                         dev_err(dev, "Unable to set LCD clock rate");
748                         goto err_pixclk_disable;
749                 }
750
751                 ret = clk_prepare_enable(priv->lcd_clk);
752                 if (ret) {
753                         dev_err(dev, "Unable to start lcd clock");
754                         goto err_pixclk_disable;
755                 }
756         }
757
758         ret = drm_dev_register(drm, 0);
759         if (ret) {
760                 dev_err(dev, "Failed to register DRM driver");
761                 goto err_devclk_disable;
762         }
763
764         ret = drm_fbdev_generic_setup(drm, 32);
765         if (ret)
766                 dev_warn(dev, "Unable to start fbdev emulation: %i", ret);
767
768         return 0;
769
770 err_devclk_disable:
771         if (priv->lcd_clk)
772                 clk_disable_unprepare(priv->lcd_clk);
773 err_pixclk_disable:
774         clk_disable_unprepare(priv->pix_clk);
775         return ret;
776 }
777
778 static int ingenic_drm_remove(struct platform_device *pdev)
779 {
780         struct ingenic_drm *priv = platform_get_drvdata(pdev);
781
782         if (priv->lcd_clk)
783                 clk_disable_unprepare(priv->lcd_clk);
784         clk_disable_unprepare(priv->pix_clk);
785
786         drm_dev_unregister(&priv->drm);
787         drm_atomic_helper_shutdown(&priv->drm);
788
789         return 0;
790 }
791
792 static const struct jz_soc_info jz4740_soc_info = {
793         .needs_dev_clk = true,
794 };
795
796 static const struct jz_soc_info jz4725b_soc_info = {
797         .needs_dev_clk = false,
798 };
799
800 static const struct of_device_id ingenic_drm_of_match[] = {
801         { .compatible = "ingenic,jz4740-lcd", .data = &jz4740_soc_info },
802         { .compatible = "ingenic,jz4725b-lcd", .data = &jz4725b_soc_info },
803         { /* sentinel */ },
804 };
805
806 static struct platform_driver ingenic_drm_driver = {
807         .driver = {
808                 .name = "ingenic-drm",
809                 .of_match_table = of_match_ptr(ingenic_drm_of_match),
810         },
811         .probe = ingenic_drm_probe,
812         .remove = ingenic_drm_remove,
813 };
814 module_platform_driver(ingenic_drm_driver);
815
816 MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
817 MODULE_DESCRIPTION("DRM driver for the Ingenic SoCs\n");
818 MODULE_LICENSE("GPL v2");