01a8077954b341046087ae0d8c6230e10ff18707
[sfrench/cifs-2.6.git] / drivers / gpu / drm / tinydrm / st7586.c
1 /*
2  * DRM driver for Sitronix ST7586 panels
3  *
4  * Copyright 2017 David Lechner <david@lechnology.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  */
11
12 #include <linux/delay.h>
13 #include <linux/dma-buf.h>
14 #include <linux/gpio/consumer.h>
15 #include <linux/module.h>
16 #include <linux/property.h>
17 #include <linux/spi/spi.h>
18 #include <video/mipi_display.h>
19
20 #include <drm/drm_damage_helper.h>
21 #include <drm/drm_drv.h>
22 #include <drm/drm_fb_cma_helper.h>
23 #include <drm/drm_gem_cma_helper.h>
24 #include <drm/drm_gem_framebuffer_helper.h>
25 #include <drm/drm_rect.h>
26 #include <drm/drm_vblank.h>
27 #include <drm/tinydrm/mipi-dbi.h>
28 #include <drm/tinydrm/tinydrm-helpers.h>
29
30 /* controller-specific commands */
31 #define ST7586_DISP_MODE_GRAY   0x38
32 #define ST7586_DISP_MODE_MONO   0x39
33 #define ST7586_ENABLE_DDRAM     0x3a
34 #define ST7586_SET_DISP_DUTY    0xb0
35 #define ST7586_SET_PART_DISP    0xb4
36 #define ST7586_SET_NLINE_INV    0xb5
37 #define ST7586_SET_VOP          0xc0
38 #define ST7586_SET_BIAS_SYSTEM  0xc3
39 #define ST7586_SET_BOOST_LEVEL  0xc4
40 #define ST7586_SET_VOP_OFFSET   0xc7
41 #define ST7586_ENABLE_ANALOG    0xd0
42 #define ST7586_AUTO_READ_CTRL   0xd7
43 #define ST7586_OTP_RW_CTRL      0xe0
44 #define ST7586_OTP_CTRL_OUT     0xe1
45 #define ST7586_OTP_READ         0xe3
46
47 #define ST7586_DISP_CTRL_MX     BIT(6)
48 #define ST7586_DISP_CTRL_MY     BIT(7)
49
50 /*
51  * The ST7586 controller has an unusual pixel format where 2bpp grayscale is
52  * packed 3 pixels per byte with the first two pixels using 3 bits and the 3rd
53  * pixel using only 2 bits.
54  *
55  * |  D7  |  D6  |  D5  ||      |      || 2bpp |
56  * | (D4) | (D3) | (D2) ||  D1  |  D0  || GRAY |
57  * +------+------+------++------+------++------+
58  * |  1   |  1   |  1   ||  1   |  1   || 0  0 | black
59  * |  1   |  0   |  0   ||  1   |  0   || 0  1 | dark gray
60  * |  0   |  1   |  0   ||  0   |  1   || 1  0 | light gray
61  * |  0   |  0   |  0   ||  0   |  0   || 1  1 | white
62  */
63
64 static const u8 st7586_lookup[] = { 0x7, 0x4, 0x2, 0x0 };
65
66 static void st7586_xrgb8888_to_gray332(u8 *dst, void *vaddr,
67                                        struct drm_framebuffer *fb,
68                                        struct drm_rect *clip)
69 {
70         size_t len = (clip->x2 - clip->x1) * (clip->y2 - clip->y1);
71         unsigned int x, y;
72         u8 *src, *buf, val;
73
74         buf = kmalloc(len, GFP_KERNEL);
75         if (!buf)
76                 return;
77
78         tinydrm_xrgb8888_to_gray8(buf, vaddr, fb, clip);
79         src = buf;
80
81         for (y = clip->y1; y < clip->y2; y++) {
82                 for (x = clip->x1; x < clip->x2; x += 3) {
83                         val = st7586_lookup[*src++ >> 6] << 5;
84                         val |= st7586_lookup[*src++ >> 6] << 2;
85                         val |= st7586_lookup[*src++ >> 6] >> 1;
86                         *dst++ = val;
87                 }
88         }
89
90         kfree(buf);
91 }
92
93 static int st7586_buf_copy(void *dst, struct drm_framebuffer *fb,
94                            struct drm_rect *clip)
95 {
96         struct drm_gem_cma_object *cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
97         struct dma_buf_attachment *import_attach = cma_obj->base.import_attach;
98         void *src = cma_obj->vaddr;
99         int ret = 0;
100
101         if (import_attach) {
102                 ret = dma_buf_begin_cpu_access(import_attach->dmabuf,
103                                                DMA_FROM_DEVICE);
104                 if (ret)
105                         return ret;
106         }
107
108         st7586_xrgb8888_to_gray332(dst, src, fb, clip);
109
110         if (import_attach)
111                 ret = dma_buf_end_cpu_access(import_attach->dmabuf,
112                                              DMA_FROM_DEVICE);
113
114         return ret;
115 }
116
117 static void st7586_fb_dirty(struct drm_framebuffer *fb, struct drm_rect *rect)
118 {
119         struct tinydrm_device *tdev = fb->dev->dev_private;
120         struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
121         int start, end;
122         int ret = 0;
123
124         if (!mipi->enabled)
125                 return;
126
127         /* 3 pixels per byte, so grow clip to nearest multiple of 3 */
128         rect->x1 = rounddown(rect->x1, 3);
129         rect->x2 = roundup(rect->x2, 3);
130
131         DRM_DEBUG_KMS("Flushing [FB:%d] " DRM_RECT_FMT "\n", fb->base.id, DRM_RECT_ARG(rect));
132
133         ret = st7586_buf_copy(mipi->tx_buf, fb, rect);
134         if (ret)
135                 goto err_msg;
136
137         /* Pixels are packed 3 per byte */
138         start = rect->x1 / 3;
139         end = rect->x2 / 3;
140
141         mipi_dbi_command(mipi, MIPI_DCS_SET_COLUMN_ADDRESS,
142                          (start >> 8) & 0xFF, start & 0xFF,
143                          (end >> 8) & 0xFF, (end - 1) & 0xFF);
144         mipi_dbi_command(mipi, MIPI_DCS_SET_PAGE_ADDRESS,
145                          (rect->y1 >> 8) & 0xFF, rect->y1 & 0xFF,
146                          (rect->y2 >> 8) & 0xFF, (rect->y2 - 1) & 0xFF);
147
148         ret = mipi_dbi_command_buf(mipi, MIPI_DCS_WRITE_MEMORY_START,
149                                    (u8 *)mipi->tx_buf,
150                                    (end - start) * (rect->y2 - rect->y1));
151 err_msg:
152         if (ret)
153                 dev_err_once(fb->dev->dev, "Failed to update display %d\n", ret);
154 }
155
156 static void st7586_pipe_update(struct drm_simple_display_pipe *pipe,
157                                struct drm_plane_state *old_state)
158 {
159         struct drm_plane_state *state = pipe->plane.state;
160         struct drm_crtc *crtc = &pipe->crtc;
161         struct drm_rect rect;
162
163         if (drm_atomic_helper_damage_merged(old_state, state, &rect))
164                 st7586_fb_dirty(state->fb, &rect);
165
166         if (crtc->state->event) {
167                 spin_lock_irq(&crtc->dev->event_lock);
168                 drm_crtc_send_vblank_event(crtc, crtc->state->event);
169                 spin_unlock_irq(&crtc->dev->event_lock);
170                 crtc->state->event = NULL;
171         }
172 }
173
174 static void st7586_pipe_enable(struct drm_simple_display_pipe *pipe,
175                                struct drm_crtc_state *crtc_state,
176                                struct drm_plane_state *plane_state)
177 {
178         struct tinydrm_device *tdev = pipe_to_tinydrm(pipe);
179         struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
180         struct drm_framebuffer *fb = plane_state->fb;
181         struct drm_rect rect = {
182                 .x1 = 0,
183                 .x2 = fb->width,
184                 .y1 = 0,
185                 .y2 = fb->height,
186         };
187         int ret;
188         u8 addr_mode;
189
190         DRM_DEBUG_KMS("\n");
191
192         ret = mipi_dbi_poweron_reset(mipi);
193         if (ret)
194                 return;
195
196         mipi_dbi_command(mipi, ST7586_AUTO_READ_CTRL, 0x9f);
197         mipi_dbi_command(mipi, ST7586_OTP_RW_CTRL, 0x00);
198
199         msleep(10);
200
201         mipi_dbi_command(mipi, ST7586_OTP_READ);
202
203         msleep(20);
204
205         mipi_dbi_command(mipi, ST7586_OTP_CTRL_OUT);
206         mipi_dbi_command(mipi, MIPI_DCS_EXIT_SLEEP_MODE);
207         mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_OFF);
208
209         msleep(50);
210
211         mipi_dbi_command(mipi, ST7586_SET_VOP_OFFSET, 0x00);
212         mipi_dbi_command(mipi, ST7586_SET_VOP, 0xe3, 0x00);
213         mipi_dbi_command(mipi, ST7586_SET_BIAS_SYSTEM, 0x02);
214         mipi_dbi_command(mipi, ST7586_SET_BOOST_LEVEL, 0x04);
215         mipi_dbi_command(mipi, ST7586_ENABLE_ANALOG, 0x1d);
216         mipi_dbi_command(mipi, ST7586_SET_NLINE_INV, 0x00);
217         mipi_dbi_command(mipi, ST7586_DISP_MODE_GRAY);
218         mipi_dbi_command(mipi, ST7586_ENABLE_DDRAM, 0x02);
219
220         switch (mipi->rotation) {
221         default:
222                 addr_mode = 0x00;
223                 break;
224         case 90:
225                 addr_mode = ST7586_DISP_CTRL_MY;
226                 break;
227         case 180:
228                 addr_mode = ST7586_DISP_CTRL_MX | ST7586_DISP_CTRL_MY;
229                 break;
230         case 270:
231                 addr_mode = ST7586_DISP_CTRL_MX;
232                 break;
233         }
234         mipi_dbi_command(mipi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
235
236         mipi_dbi_command(mipi, ST7586_SET_DISP_DUTY, 0x7f);
237         mipi_dbi_command(mipi, ST7586_SET_PART_DISP, 0xa0);
238         mipi_dbi_command(mipi, MIPI_DCS_SET_PARTIAL_AREA, 0x00, 0x00, 0x00, 0x77);
239         mipi_dbi_command(mipi, MIPI_DCS_EXIT_INVERT_MODE);
240
241         msleep(100);
242
243         mipi->enabled = true;
244         st7586_fb_dirty(fb, &rect);
245
246         mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_ON);
247 }
248
249 static void st7586_pipe_disable(struct drm_simple_display_pipe *pipe)
250 {
251         struct tinydrm_device *tdev = pipe_to_tinydrm(pipe);
252         struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
253
254         DRM_DEBUG_KMS("\n");
255
256         if (!mipi->enabled)
257                 return;
258
259         mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_OFF);
260         mipi->enabled = false;
261 }
262
263 static const u32 st7586_formats[] = {
264         DRM_FORMAT_XRGB8888,
265 };
266
267 static int st7586_init(struct device *dev, struct mipi_dbi *mipi,
268                 const struct drm_simple_display_pipe_funcs *pipe_funcs,
269                 struct drm_driver *driver, const struct drm_display_mode *mode,
270                 unsigned int rotation)
271 {
272         size_t bufsize = (mode->vdisplay + 2) / 3 * mode->hdisplay;
273         struct tinydrm_device *tdev = &mipi->tinydrm;
274         int ret;
275
276         mutex_init(&mipi->cmdlock);
277
278         mipi->tx_buf = devm_kmalloc(dev, bufsize, GFP_KERNEL);
279         if (!mipi->tx_buf)
280                 return -ENOMEM;
281
282         ret = devm_tinydrm_init(dev, tdev, driver);
283         if (ret)
284                 return ret;
285
286         ret = tinydrm_display_pipe_init(tdev, pipe_funcs,
287                                         DRM_MODE_CONNECTOR_VIRTUAL,
288                                         st7586_formats,
289                                         ARRAY_SIZE(st7586_formats),
290                                         mode, rotation);
291         if (ret)
292                 return ret;
293
294         drm_plane_enable_fb_damage_clips(&tdev->pipe.plane);
295
296         tdev->drm->mode_config.preferred_depth = 32;
297         mipi->rotation = rotation;
298
299         drm_mode_config_reset(tdev->drm);
300
301         DRM_DEBUG_KMS("preferred_depth=%u, rotation = %u\n",
302                       tdev->drm->mode_config.preferred_depth, rotation);
303
304         return 0;
305 }
306
307 static const struct drm_simple_display_pipe_funcs st7586_pipe_funcs = {
308         .enable         = st7586_pipe_enable,
309         .disable        = st7586_pipe_disable,
310         .update         = st7586_pipe_update,
311         .prepare_fb     = drm_gem_fb_simple_display_pipe_prepare_fb,
312 };
313
314 static const struct drm_display_mode st7586_mode = {
315         TINYDRM_MODE(178, 128, 37, 27),
316 };
317
318 DEFINE_DRM_GEM_CMA_FOPS(st7586_fops);
319
320 static struct drm_driver st7586_driver = {
321         .driver_features        = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME |
322                                   DRIVER_ATOMIC,
323         .fops                   = &st7586_fops,
324         DRM_GEM_CMA_VMAP_DRIVER_OPS,
325         .debugfs_init           = mipi_dbi_debugfs_init,
326         .name                   = "st7586",
327         .desc                   = "Sitronix ST7586",
328         .date                   = "20170801",
329         .major                  = 1,
330         .minor                  = 0,
331 };
332
333 static const struct of_device_id st7586_of_match[] = {
334         { .compatible = "lego,ev3-lcd" },
335         {},
336 };
337 MODULE_DEVICE_TABLE(of, st7586_of_match);
338
339 static const struct spi_device_id st7586_id[] = {
340         { "ev3-lcd", 0 },
341         { },
342 };
343 MODULE_DEVICE_TABLE(spi, st7586_id);
344
345 static int st7586_probe(struct spi_device *spi)
346 {
347         struct device *dev = &spi->dev;
348         struct mipi_dbi *mipi;
349         struct gpio_desc *a0;
350         u32 rotation = 0;
351         int ret;
352
353         mipi = devm_kzalloc(dev, sizeof(*mipi), GFP_KERNEL);
354         if (!mipi)
355                 return -ENOMEM;
356
357         mipi->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
358         if (IS_ERR(mipi->reset)) {
359                 DRM_DEV_ERROR(dev, "Failed to get gpio 'reset'\n");
360                 return PTR_ERR(mipi->reset);
361         }
362
363         a0 = devm_gpiod_get(dev, "a0", GPIOD_OUT_LOW);
364         if (IS_ERR(a0)) {
365                 DRM_DEV_ERROR(dev, "Failed to get gpio 'a0'\n");
366                 return PTR_ERR(a0);
367         }
368
369         device_property_read_u32(dev, "rotation", &rotation);
370
371         ret = mipi_dbi_spi_init(spi, mipi, a0);
372         if (ret)
373                 return ret;
374
375         /* Cannot read from this controller via SPI */
376         mipi->read_commands = NULL;
377
378         /*
379          * we are using 8-bit data, so we are not actually swapping anything,
380          * but setting mipi->swap_bytes makes mipi_dbi_typec3_command() do the
381          * right thing and not use 16-bit transfers (which results in swapped
382          * bytes on little-endian systems and causes out of order data to be
383          * sent to the display).
384          */
385         mipi->swap_bytes = true;
386
387         ret = st7586_init(&spi->dev, mipi, &st7586_pipe_funcs, &st7586_driver,
388                           &st7586_mode, rotation);
389         if (ret)
390                 return ret;
391
392         spi_set_drvdata(spi, mipi);
393
394         return devm_tinydrm_register(&mipi->tinydrm);
395 }
396
397 static void st7586_shutdown(struct spi_device *spi)
398 {
399         struct mipi_dbi *mipi = spi_get_drvdata(spi);
400
401         tinydrm_shutdown(&mipi->tinydrm);
402 }
403
404 static struct spi_driver st7586_spi_driver = {
405         .driver = {
406                 .name = "st7586",
407                 .owner = THIS_MODULE,
408                 .of_match_table = st7586_of_match,
409         },
410         .id_table = st7586_id,
411         .probe = st7586_probe,
412         .shutdown = st7586_shutdown,
413 };
414 module_spi_driver(st7586_spi_driver);
415
416 MODULE_DESCRIPTION("Sitronix ST7586 DRM driver");
417 MODULE_AUTHOR("David Lechner <david@lechnology.com>");
418 MODULE_LICENSE("GPL");