]> Git Repo - linux.git/blob - drivers/gpu/drm/solomon/ssd130x.c
Revert "drm/amdgpu: add param to specify fw bo location for front-door loading"
[linux.git] / drivers / gpu / drm / solomon / ssd130x.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * DRM driver for Solomon SSD13xx OLED displays
4  *
5  * Copyright 2022 Red Hat Inc.
6  * Author: Javier Martinez Canillas <[email protected]>
7  *
8  * Based on drivers/video/fbdev/ssd1307fb.c
9  * Copyright 2012 Free Electrons
10  */
11
12 #include <linux/backlight.h>
13 #include <linux/bitfield.h>
14 #include <linux/bits.h>
15 #include <linux/delay.h>
16 #include <linux/gpio/consumer.h>
17 #include <linux/property.h>
18 #include <linux/pwm.h>
19 #include <linux/regulator/consumer.h>
20
21 #include <drm/drm_atomic.h>
22 #include <drm/drm_atomic_helper.h>
23 #include <drm/drm_crtc_helper.h>
24 #include <drm/drm_damage_helper.h>
25 #include <drm/drm_edid.h>
26 #include <drm/drm_fbdev_generic.h>
27 #include <drm/drm_format_helper.h>
28 #include <drm/drm_framebuffer.h>
29 #include <drm/drm_gem_atomic_helper.h>
30 #include <drm/drm_gem_framebuffer_helper.h>
31 #include <drm/drm_gem_shmem_helper.h>
32 #include <drm/drm_managed.h>
33 #include <drm/drm_modes.h>
34 #include <drm/drm_rect.h>
35 #include <drm/drm_probe_helper.h>
36
37 #include "ssd130x.h"
38
39 #define DRIVER_NAME     "ssd130x"
40 #define DRIVER_DESC     "DRM driver for Solomon SSD13xx OLED displays"
41 #define DRIVER_DATE     "20220131"
42 #define DRIVER_MAJOR    1
43 #define DRIVER_MINOR    0
44
45 #define SSD130X_PAGE_HEIGHT 8
46
47 #define SSD132X_SEGMENT_WIDTH 2
48
49 /* ssd13xx commands */
50 #define SSD13XX_CONTRAST                        0x81
51 #define SSD13XX_SET_SEG_REMAP                   0xa0
52 #define SSD13XX_SET_MULTIPLEX_RATIO             0xa8
53 #define SSD13XX_DISPLAY_OFF                     0xae
54 #define SSD13XX_DISPLAY_ON                      0xaf
55
56 #define SSD13XX_SET_SEG_REMAP_MASK              GENMASK(0, 0)
57 #define SSD13XX_SET_SEG_REMAP_SET(val)          FIELD_PREP(SSD13XX_SET_SEG_REMAP_MASK, (val))
58
59 /* ssd130x commands */
60 #define SSD130X_PAGE_COL_START_LOW              0x00
61 #define SSD130X_PAGE_COL_START_HIGH             0x10
62 #define SSD130X_SET_ADDRESS_MODE                0x20
63 #define SSD130X_SET_COL_RANGE                   0x21
64 #define SSD130X_SET_PAGE_RANGE                  0x22
65 #define SSD130X_SET_LOOKUP_TABLE                0x91
66 #define SSD130X_CHARGE_PUMP                     0x8d
67 #define SSD130X_START_PAGE_ADDRESS              0xb0
68 #define SSD130X_SET_COM_SCAN_DIR                0xc0
69 #define SSD130X_SET_DISPLAY_OFFSET              0xd3
70 #define SSD130X_SET_CLOCK_FREQ                  0xd5
71 #define SSD130X_SET_AREA_COLOR_MODE             0xd8
72 #define SSD130X_SET_PRECHARGE_PERIOD            0xd9
73 #define SSD130X_SET_COM_PINS_CONFIG             0xda
74 #define SSD130X_SET_VCOMH                       0xdb
75
76 /* ssd130x commands accessors */
77 #define SSD130X_PAGE_COL_START_MASK             GENMASK(3, 0)
78 #define SSD130X_PAGE_COL_START_HIGH_SET(val)    FIELD_PREP(SSD130X_PAGE_COL_START_MASK, (val) >> 4)
79 #define SSD130X_PAGE_COL_START_LOW_SET(val)     FIELD_PREP(SSD130X_PAGE_COL_START_MASK, (val))
80 #define SSD130X_START_PAGE_ADDRESS_MASK         GENMASK(2, 0)
81 #define SSD130X_START_PAGE_ADDRESS_SET(val)     FIELD_PREP(SSD130X_START_PAGE_ADDRESS_MASK, (val))
82 #define SSD130X_SET_COM_SCAN_DIR_MASK           GENMASK(3, 3)
83 #define SSD130X_SET_COM_SCAN_DIR_SET(val)       FIELD_PREP(SSD130X_SET_COM_SCAN_DIR_MASK, (val))
84 #define SSD130X_SET_CLOCK_DIV_MASK              GENMASK(3, 0)
85 #define SSD130X_SET_CLOCK_DIV_SET(val)          FIELD_PREP(SSD130X_SET_CLOCK_DIV_MASK, (val))
86 #define SSD130X_SET_CLOCK_FREQ_MASK             GENMASK(7, 4)
87 #define SSD130X_SET_CLOCK_FREQ_SET(val)         FIELD_PREP(SSD130X_SET_CLOCK_FREQ_MASK, (val))
88 #define SSD130X_SET_PRECHARGE_PERIOD1_MASK      GENMASK(3, 0)
89 #define SSD130X_SET_PRECHARGE_PERIOD1_SET(val)  FIELD_PREP(SSD130X_SET_PRECHARGE_PERIOD1_MASK, (val))
90 #define SSD130X_SET_PRECHARGE_PERIOD2_MASK      GENMASK(7, 4)
91 #define SSD130X_SET_PRECHARGE_PERIOD2_SET(val)  FIELD_PREP(SSD130X_SET_PRECHARGE_PERIOD2_MASK, (val))
92 #define SSD130X_SET_COM_PINS_CONFIG1_MASK       GENMASK(4, 4)
93 #define SSD130X_SET_COM_PINS_CONFIG1_SET(val)   FIELD_PREP(SSD130X_SET_COM_PINS_CONFIG1_MASK, (val))
94 #define SSD130X_SET_COM_PINS_CONFIG2_MASK       GENMASK(5, 5)
95 #define SSD130X_SET_COM_PINS_CONFIG2_SET(val)   FIELD_PREP(SSD130X_SET_COM_PINS_CONFIG2_MASK, (val))
96
97 #define SSD130X_SET_ADDRESS_MODE_HORIZONTAL     0x00
98 #define SSD130X_SET_ADDRESS_MODE_VERTICAL       0x01
99 #define SSD130X_SET_ADDRESS_MODE_PAGE           0x02
100
101 #define SSD130X_SET_AREA_COLOR_MODE_ENABLE      0x1e
102 #define SSD130X_SET_AREA_COLOR_MODE_LOW_POWER   0x05
103
104 /* ssd132x commands */
105 #define SSD132X_SET_COL_RANGE                   0x15
106 #define SSD132X_SET_DEACTIVATE_SCROLL           0x2e
107 #define SSD132X_SET_ROW_RANGE                   0x75
108 #define SSD132X_SET_DISPLAY_START               0xa1
109 #define SSD132X_SET_DISPLAY_OFFSET              0xa2
110 #define SSD132X_SET_DISPLAY_NORMAL              0xa4
111 #define SSD132X_SET_FUNCTION_SELECT_A           0xab
112 #define SSD132X_SET_PHASE_LENGTH                0xb1
113 #define SSD132X_SET_CLOCK_FREQ                  0xb3
114 #define SSD132X_SET_GPIO                        0xb5
115 #define SSD132X_SET_PRECHARGE_PERIOD            0xb6
116 #define SSD132X_SET_GRAY_SCALE_TABLE            0xb8
117 #define SSD132X_SELECT_DEFAULT_TABLE            0xb9
118 #define SSD132X_SET_PRECHARGE_VOLTAGE           0xbc
119 #define SSD130X_SET_VCOMH_VOLTAGE               0xbe
120 #define SSD132X_SET_FUNCTION_SELECT_B           0xd5
121
122 #define MAX_CONTRAST 255
123
124 const struct ssd130x_deviceinfo ssd130x_variants[] = {
125         [SH1106_ID] = {
126                 .default_vcomh = 0x40,
127                 .default_dclk_div = 1,
128                 .default_dclk_frq = 5,
129                 .default_width = 132,
130                 .default_height = 64,
131                 .page_mode_only = 1,
132                 .family_id = SSD130X_FAMILY,
133         },
134         [SSD1305_ID] = {
135                 .default_vcomh = 0x34,
136                 .default_dclk_div = 1,
137                 .default_dclk_frq = 7,
138                 .default_width = 132,
139                 .default_height = 64,
140                 .family_id = SSD130X_FAMILY,
141         },
142         [SSD1306_ID] = {
143                 .default_vcomh = 0x20,
144                 .default_dclk_div = 1,
145                 .default_dclk_frq = 8,
146                 .need_chargepump = 1,
147                 .default_width = 128,
148                 .default_height = 64,
149                 .family_id = SSD130X_FAMILY,
150         },
151         [SSD1307_ID] = {
152                 .default_vcomh = 0x20,
153                 .default_dclk_div = 2,
154                 .default_dclk_frq = 12,
155                 .need_pwm = 1,
156                 .default_width = 128,
157                 .default_height = 39,
158                 .family_id = SSD130X_FAMILY,
159         },
160         [SSD1309_ID] = {
161                 .default_vcomh = 0x34,
162                 .default_dclk_div = 1,
163                 .default_dclk_frq = 10,
164                 .default_width = 128,
165                 .default_height = 64,
166                 .family_id = SSD130X_FAMILY,
167         },
168         /* ssd132x family */
169         [SSD1322_ID] = {
170                 .default_width = 480,
171                 .default_height = 128,
172                 .family_id = SSD132X_FAMILY,
173         },
174         [SSD1325_ID] = {
175                 .default_width = 128,
176                 .default_height = 80,
177                 .family_id = SSD132X_FAMILY,
178         },
179         [SSD1327_ID] = {
180                 .default_width = 128,
181                 .default_height = 128,
182                 .family_id = SSD132X_FAMILY,
183         }
184 };
185 EXPORT_SYMBOL_NS_GPL(ssd130x_variants, DRM_SSD130X);
186
187 struct ssd130x_crtc_state {
188         struct drm_crtc_state base;
189         /* Buffer to store pixels in HW format and written to the panel */
190         u8 *data_array;
191 };
192
193 struct ssd130x_plane_state {
194         struct drm_shadow_plane_state base;
195         /* Intermediate buffer to convert pixels from XRGB8888 to HW format */
196         u8 *buffer;
197 };
198
199 static inline struct ssd130x_crtc_state *to_ssd130x_crtc_state(struct drm_crtc_state *state)
200 {
201         return container_of(state, struct ssd130x_crtc_state, base);
202 }
203
204 static inline struct ssd130x_plane_state *to_ssd130x_plane_state(struct drm_plane_state *state)
205 {
206         return container_of(state, struct ssd130x_plane_state, base.base);
207 }
208
209 static inline struct ssd130x_device *drm_to_ssd130x(struct drm_device *drm)
210 {
211         return container_of(drm, struct ssd130x_device, drm);
212 }
213
214 /*
215  * Helper to write data (SSD13XX_DATA) to the device.
216  */
217 static int ssd130x_write_data(struct ssd130x_device *ssd130x, u8 *values, int count)
218 {
219         return regmap_bulk_write(ssd130x->regmap, SSD13XX_DATA, values, count);
220 }
221
222 /*
223  * Helper to write command (SSD13XX_COMMAND). The fist variadic argument
224  * is the command to write and the following are the command options.
225  *
226  * Note that the ssd13xx protocol requires each command and option to be
227  * written as a SSD13XX_COMMAND device register value. That is why a call
228  * to regmap_write(..., SSD13XX_COMMAND, ...) is done for each argument.
229  */
230 static int ssd130x_write_cmd(struct ssd130x_device *ssd130x, int count,
231                              /* u8 cmd, u8 option, ... */...)
232 {
233         va_list ap;
234         u8 value;
235         int ret;
236
237         va_start(ap, count);
238
239         do {
240                 value = va_arg(ap, int);
241                 ret = regmap_write(ssd130x->regmap, SSD13XX_COMMAND, value);
242                 if (ret)
243                         goto out_end;
244         } while (--count);
245
246 out_end:
247         va_end(ap);
248
249         return ret;
250 }
251
252 /* Set address range for horizontal/vertical addressing modes */
253 static int ssd130x_set_col_range(struct ssd130x_device *ssd130x,
254                                  u8 col_start, u8 cols)
255 {
256         u8 col_end = col_start + cols - 1;
257         int ret;
258
259         if (col_start == ssd130x->col_start && col_end == ssd130x->col_end)
260                 return 0;
261
262         ret = ssd130x_write_cmd(ssd130x, 3, SSD130X_SET_COL_RANGE, col_start, col_end);
263         if (ret < 0)
264                 return ret;
265
266         ssd130x->col_start = col_start;
267         ssd130x->col_end = col_end;
268         return 0;
269 }
270
271 static int ssd130x_set_page_range(struct ssd130x_device *ssd130x,
272                                   u8 page_start, u8 pages)
273 {
274         u8 page_end = page_start + pages - 1;
275         int ret;
276
277         if (page_start == ssd130x->page_start && page_end == ssd130x->page_end)
278                 return 0;
279
280         ret = ssd130x_write_cmd(ssd130x, 3, SSD130X_SET_PAGE_RANGE, page_start, page_end);
281         if (ret < 0)
282                 return ret;
283
284         ssd130x->page_start = page_start;
285         ssd130x->page_end = page_end;
286         return 0;
287 }
288
289 /* Set page and column start address for page addressing mode */
290 static int ssd130x_set_page_pos(struct ssd130x_device *ssd130x,
291                                 u8 page_start, u8 col_start)
292 {
293         int ret;
294         u32 page, col_low, col_high;
295
296         page = SSD130X_START_PAGE_ADDRESS |
297                SSD130X_START_PAGE_ADDRESS_SET(page_start);
298         col_low = SSD130X_PAGE_COL_START_LOW |
299                   SSD130X_PAGE_COL_START_LOW_SET(col_start);
300         col_high = SSD130X_PAGE_COL_START_HIGH |
301                    SSD130X_PAGE_COL_START_HIGH_SET(col_start);
302         ret = ssd130x_write_cmd(ssd130x, 3, page, col_low, col_high);
303         if (ret < 0)
304                 return ret;
305
306         return 0;
307 }
308
309 static int ssd130x_pwm_enable(struct ssd130x_device *ssd130x)
310 {
311         struct device *dev = ssd130x->dev;
312         struct pwm_state pwmstate;
313
314         ssd130x->pwm = pwm_get(dev, NULL);
315         if (IS_ERR(ssd130x->pwm)) {
316                 dev_err(dev, "Could not get PWM from firmware description!\n");
317                 return PTR_ERR(ssd130x->pwm);
318         }
319
320         pwm_init_state(ssd130x->pwm, &pwmstate);
321         pwm_set_relative_duty_cycle(&pwmstate, 50, 100);
322         pwm_apply_state(ssd130x->pwm, &pwmstate);
323
324         /* Enable the PWM */
325         pwm_enable(ssd130x->pwm);
326
327         dev_dbg(dev, "Using PWM %s with a %lluns period.\n",
328                 ssd130x->pwm->label, pwm_get_period(ssd130x->pwm));
329
330         return 0;
331 }
332
333 static void ssd130x_reset(struct ssd130x_device *ssd130x)
334 {
335         if (!ssd130x->reset)
336                 return;
337
338         /* Reset the screen */
339         gpiod_set_value_cansleep(ssd130x->reset, 1);
340         udelay(4);
341         gpiod_set_value_cansleep(ssd130x->reset, 0);
342         udelay(4);
343 }
344
345 static int ssd130x_power_on(struct ssd130x_device *ssd130x)
346 {
347         struct device *dev = ssd130x->dev;
348         int ret;
349
350         ssd130x_reset(ssd130x);
351
352         ret = regulator_enable(ssd130x->vcc_reg);
353         if (ret) {
354                 dev_err(dev, "Failed to enable VCC: %d\n", ret);
355                 return ret;
356         }
357
358         if (ssd130x->device_info->need_pwm) {
359                 ret = ssd130x_pwm_enable(ssd130x);
360                 if (ret) {
361                         dev_err(dev, "Failed to enable PWM: %d\n", ret);
362                         regulator_disable(ssd130x->vcc_reg);
363                         return ret;
364                 }
365         }
366
367         return 0;
368 }
369
370 static void ssd130x_power_off(struct ssd130x_device *ssd130x)
371 {
372         pwm_disable(ssd130x->pwm);
373         pwm_put(ssd130x->pwm);
374
375         regulator_disable(ssd130x->vcc_reg);
376 }
377
378 static int ssd130x_init(struct ssd130x_device *ssd130x)
379 {
380         u32 precharge, dclk, com_invdir, compins, chargepump, seg_remap;
381         bool scan_mode;
382         int ret;
383
384         /* Set initial contrast */
385         ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_CONTRAST, ssd130x->contrast);
386         if (ret < 0)
387                 return ret;
388
389         /* Set segment re-map */
390         seg_remap = (SSD13XX_SET_SEG_REMAP |
391                      SSD13XX_SET_SEG_REMAP_SET(ssd130x->seg_remap));
392         ret = ssd130x_write_cmd(ssd130x, 1, seg_remap);
393         if (ret < 0)
394                 return ret;
395
396         /* Set COM direction */
397         com_invdir = (SSD130X_SET_COM_SCAN_DIR |
398                       SSD130X_SET_COM_SCAN_DIR_SET(ssd130x->com_invdir));
399         ret = ssd130x_write_cmd(ssd130x,  1, com_invdir);
400         if (ret < 0)
401                 return ret;
402
403         /* Set multiplex ratio value */
404         ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_SET_MULTIPLEX_RATIO, ssd130x->height - 1);
405         if (ret < 0)
406                 return ret;
407
408         /* set display offset value */
409         ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_DISPLAY_OFFSET, ssd130x->com_offset);
410         if (ret < 0)
411                 return ret;
412
413         /* Set clock frequency */
414         dclk = (SSD130X_SET_CLOCK_DIV_SET(ssd130x->dclk_div - 1) |
415                 SSD130X_SET_CLOCK_FREQ_SET(ssd130x->dclk_frq));
416         ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_CLOCK_FREQ, dclk);
417         if (ret < 0)
418                 return ret;
419
420         /* Set Area Color Mode ON/OFF & Low Power Display Mode */
421         if (ssd130x->area_color_enable || ssd130x->low_power) {
422                 u32 mode = 0;
423
424                 if (ssd130x->area_color_enable)
425                         mode |= SSD130X_SET_AREA_COLOR_MODE_ENABLE;
426
427                 if (ssd130x->low_power)
428                         mode |= SSD130X_SET_AREA_COLOR_MODE_LOW_POWER;
429
430                 ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_AREA_COLOR_MODE, mode);
431                 if (ret < 0)
432                         return ret;
433         }
434
435         /* Set precharge period in number of ticks from the internal clock */
436         precharge = (SSD130X_SET_PRECHARGE_PERIOD1_SET(ssd130x->prechargep1) |
437                      SSD130X_SET_PRECHARGE_PERIOD2_SET(ssd130x->prechargep2));
438         ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_PRECHARGE_PERIOD, precharge);
439         if (ret < 0)
440                 return ret;
441
442         /* Set COM pins configuration */
443         compins = BIT(1);
444         /*
445          * The COM scan mode field values are the inverse of the boolean DT
446          * property "solomon,com-seq". The value 0b means scan from COM0 to
447          * COM[N - 1] while 1b means scan from COM[N - 1] to COM0.
448          */
449         scan_mode = !ssd130x->com_seq;
450         compins |= (SSD130X_SET_COM_PINS_CONFIG1_SET(scan_mode) |
451                     SSD130X_SET_COM_PINS_CONFIG2_SET(ssd130x->com_lrremap));
452         ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_COM_PINS_CONFIG, compins);
453         if (ret < 0)
454                 return ret;
455
456         /* Set VCOMH */
457         ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_VCOMH, ssd130x->vcomh);
458         if (ret < 0)
459                 return ret;
460
461         /* Turn on the DC-DC Charge Pump */
462         chargepump = BIT(4);
463
464         if (ssd130x->device_info->need_chargepump)
465                 chargepump |= BIT(2);
466
467         ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_CHARGE_PUMP, chargepump);
468         if (ret < 0)
469                 return ret;
470
471         /* Set lookup table */
472         if (ssd130x->lookup_table_set) {
473                 int i;
474
475                 ret = ssd130x_write_cmd(ssd130x, 1, SSD130X_SET_LOOKUP_TABLE);
476                 if (ret < 0)
477                         return ret;
478
479                 for (i = 0; i < ARRAY_SIZE(ssd130x->lookup_table); i++) {
480                         u8 val = ssd130x->lookup_table[i];
481
482                         if (val < 31 || val > 63)
483                                 dev_warn(ssd130x->dev,
484                                          "lookup table index %d value out of range 31 <= %d <= 63\n",
485                                          i, val);
486                         ret = ssd130x_write_cmd(ssd130x, 1, val);
487                         if (ret < 0)
488                                 return ret;
489                 }
490         }
491
492         /* Switch to page addressing mode */
493         if (ssd130x->page_address_mode)
494                 return ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_ADDRESS_MODE,
495                                          SSD130X_SET_ADDRESS_MODE_PAGE);
496
497         /* Switch to horizontal addressing mode */
498         return ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_ADDRESS_MODE,
499                                  SSD130X_SET_ADDRESS_MODE_HORIZONTAL);
500 }
501
502 static int ssd132x_init(struct ssd130x_device *ssd130x)
503 {
504         int ret;
505
506         /* Set initial contrast */
507         ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_CONTRAST, 0x80);
508         if (ret < 0)
509                 return ret;
510
511         /* Set column start and end */
512         ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_COL_RANGE, 0x00,
513                                 ssd130x->width / SSD132X_SEGMENT_WIDTH - 1);
514         if (ret < 0)
515                 return ret;
516
517         /* Set row start and end */
518         ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_ROW_RANGE, 0x00, ssd130x->height - 1);
519         if (ret < 0)
520                 return ret;
521         /*
522          * Horizontal Address Increment
523          * Re-map for Column Address, Nibble and COM
524          * COM Split Odd Even
525          */
526         ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_SET_SEG_REMAP, 0x53);
527         if (ret < 0)
528                 return ret;
529
530         /* Set display start and offset */
531         ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_DISPLAY_START, 0x00);
532         if (ret < 0)
533                 return ret;
534
535         ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_DISPLAY_OFFSET, 0x00);
536         if (ret < 0)
537                 return ret;
538
539         /* Set display mode normal */
540         ret = ssd130x_write_cmd(ssd130x, 1, SSD132X_SET_DISPLAY_NORMAL);
541         if (ret < 0)
542                 return ret;
543
544         /* Set multiplex ratio value */
545         ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_SET_MULTIPLEX_RATIO, ssd130x->height - 1);
546         if (ret < 0)
547                 return ret;
548
549         /* Set phase length */
550         ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_PHASE_LENGTH, 0x55);
551         if (ret < 0)
552                 return ret;
553
554         /* Select default linear gray scale table */
555         ret = ssd130x_write_cmd(ssd130x, 1, SSD132X_SELECT_DEFAULT_TABLE);
556         if (ret < 0)
557                 return ret;
558
559         /* Set clock frequency */
560         ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_CLOCK_FREQ, 0x01);
561         if (ret < 0)
562                 return ret;
563
564         /* Enable internal VDD regulator */
565         ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_FUNCTION_SELECT_A, 0x1);
566         if (ret < 0)
567                 return ret;
568
569         /* Set pre-charge period */
570         ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_PRECHARGE_PERIOD, 0x01);
571         if (ret < 0)
572                 return ret;
573
574         /* Set pre-charge voltage */
575         ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_PRECHARGE_VOLTAGE, 0x08);
576         if (ret < 0)
577                 return ret;
578
579         /* Set VCOMH voltage */
580         ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_VCOMH_VOLTAGE, 0x07);
581         if (ret < 0)
582                 return ret;
583
584         /* Enable second pre-charge and internal VSL */
585         ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_FUNCTION_SELECT_B, 0x62);
586         if (ret < 0)
587                 return ret;
588
589         return 0;
590 }
591
592 static int ssd130x_update_rect(struct ssd130x_device *ssd130x,
593                                struct drm_rect *rect, u8 *buf,
594                                u8 *data_array)
595 {
596         unsigned int x = rect->x1;
597         unsigned int y = rect->y1;
598         unsigned int width = drm_rect_width(rect);
599         unsigned int height = drm_rect_height(rect);
600         unsigned int line_length = DIV_ROUND_UP(width, 8);
601         unsigned int page_height = SSD130X_PAGE_HEIGHT;
602         unsigned int pages = DIV_ROUND_UP(height, page_height);
603         struct drm_device *drm = &ssd130x->drm;
604         u32 array_idx = 0;
605         int ret, i, j, k;
606
607         drm_WARN_ONCE(drm, y % page_height != 0, "y must be aligned to screen page\n");
608
609         /*
610          * The screen is divided in pages, each having a height of 8
611          * pixels, and the width of the screen. When sending a byte of
612          * data to the controller, it gives the 8 bits for the current
613          * column. I.e, the first byte are the 8 bits of the first
614          * column, then the 8 bits for the second column, etc.
615          *
616          *
617          * Representation of the screen, assuming it is 5 bits
618          * wide. Each letter-number combination is a bit that controls
619          * one pixel.
620          *
621          * A0 A1 A2 A3 A4
622          * B0 B1 B2 B3 B4
623          * C0 C1 C2 C3 C4
624          * D0 D1 D2 D3 D4
625          * E0 E1 E2 E3 E4
626          * F0 F1 F2 F3 F4
627          * G0 G1 G2 G3 G4
628          * H0 H1 H2 H3 H4
629          *
630          * If you want to update this screen, you need to send 5 bytes:
631          *  (1) A0 B0 C0 D0 E0 F0 G0 H0
632          *  (2) A1 B1 C1 D1 E1 F1 G1 H1
633          *  (3) A2 B2 C2 D2 E2 F2 G2 H2
634          *  (4) A3 B3 C3 D3 E3 F3 G3 H3
635          *  (5) A4 B4 C4 D4 E4 F4 G4 H4
636          */
637
638         if (!ssd130x->page_address_mode) {
639                 u8 page_start;
640
641                 /* Set address range for horizontal addressing mode */
642                 ret = ssd130x_set_col_range(ssd130x, ssd130x->col_offset + x, width);
643                 if (ret < 0)
644                         return ret;
645
646                 page_start = ssd130x->page_offset + y / page_height;
647                 ret = ssd130x_set_page_range(ssd130x, page_start, pages);
648                 if (ret < 0)
649                         return ret;
650         }
651
652         for (i = 0; i < pages; i++) {
653                 int m = page_height;
654
655                 /* Last page may be partial */
656                 if (page_height * (y / page_height + i + 1) > ssd130x->height)
657                         m = ssd130x->height % page_height;
658
659                 for (j = 0; j < width; j++) {
660                         u8 data = 0;
661
662                         for (k = 0; k < m; k++) {
663                                 u32 idx = (page_height * i + k) * line_length + j / 8;
664                                 u8 byte = buf[idx];
665                                 u8 bit = (byte >> (j % 8)) & 1;
666
667                                 data |= bit << k;
668                         }
669                         data_array[array_idx++] = data;
670                 }
671
672                 /*
673                  * In page addressing mode, the start address needs to be reset,
674                  * and each page then needs to be written out separately.
675                  */
676                 if (ssd130x->page_address_mode) {
677                         ret = ssd130x_set_page_pos(ssd130x,
678                                                    ssd130x->page_offset + i,
679                                                    ssd130x->col_offset + x);
680                         if (ret < 0)
681                                 return ret;
682
683                         ret = ssd130x_write_data(ssd130x, data_array, width);
684                         if (ret < 0)
685                                 return ret;
686
687                         array_idx = 0;
688                 }
689         }
690
691         /* Write out update in one go if we aren't using page addressing mode */
692         if (!ssd130x->page_address_mode)
693                 ret = ssd130x_write_data(ssd130x, data_array, width * pages);
694
695         return ret;
696 }
697
698 static int ssd132x_update_rect(struct ssd130x_device *ssd130x,
699                                struct drm_rect *rect, u8 *buf,
700                                u8 *data_array)
701 {
702         unsigned int x = rect->x1;
703         unsigned int y = rect->y1;
704         unsigned int segment_width = SSD132X_SEGMENT_WIDTH;
705         unsigned int width = drm_rect_width(rect);
706         unsigned int height = drm_rect_height(rect);
707         unsigned int columns = DIV_ROUND_UP(width, segment_width);
708         unsigned int rows = height;
709         struct drm_device *drm = &ssd130x->drm;
710         u32 array_idx = 0;
711         unsigned int i, j;
712         int ret;
713
714         drm_WARN_ONCE(drm, x % segment_width != 0, "x must be aligned to screen segment\n");
715
716         /*
717          * The screen is divided in Segment and Common outputs, where
718          * COM0 to COM[N - 1] are the rows and SEG0 to SEG[M - 1] are
719          * the columns.
720          *
721          * Each Segment has a 4-bit pixel and each Common output has a
722          * row of pixels. When using the (default) horizontal address
723          * increment mode, each byte of data sent to the controller has
724          * two Segments (e.g: SEG0 and SEG1) that are stored in the lower
725          * and higher nibbles of a single byte representing one column.
726          * That is, the first byte are SEG0 (D0[3:0]) and SEG1 (D0[7:4]),
727          * the second byte are SEG2 (D1[3:0]) and SEG3 (D1[7:4]) and so on.
728          */
729
730         /* Set column start and end */
731         ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_COL_RANGE, x / segment_width, columns - 1);
732         if (ret < 0)
733                 return ret;
734
735         /* Set row start and end */
736         ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_ROW_RANGE, y, rows - 1);
737         if (ret < 0)
738                 return ret;
739
740         for (i = 0; i < height; i++) {
741                 /* Process pair of pixels and combine them into a single byte */
742                 for (j = 0; j < width; j += segment_width) {
743                         u8 n1 = buf[i * width + j];
744                         u8 n2 = buf[i * width + j + 1];
745
746                         data_array[array_idx++] = (n2 << 4) | n1;
747                 }
748         }
749
750         /* Write out update in one go since horizontal addressing mode is used */
751         ret = ssd130x_write_data(ssd130x, data_array, columns * rows);
752
753         return ret;
754 }
755
756 static void ssd130x_clear_screen(struct ssd130x_device *ssd130x, u8 *data_array)
757 {
758         unsigned int pages = DIV_ROUND_UP(ssd130x->height, SSD130X_PAGE_HEIGHT);
759         unsigned int width = ssd130x->width;
760         int ret, i;
761
762         if (!ssd130x->page_address_mode) {
763                 memset(data_array, 0, width * pages);
764
765                 /* Set address range for horizontal addressing mode */
766                 ret = ssd130x_set_col_range(ssd130x, ssd130x->col_offset, width);
767                 if (ret < 0)
768                         return;
769
770                 ret = ssd130x_set_page_range(ssd130x, ssd130x->page_offset, pages);
771                 if (ret < 0)
772                         return;
773
774                 /* Write out update in one go if we aren't using page addressing mode */
775                 ssd130x_write_data(ssd130x, data_array, width * pages);
776         } else {
777                 /*
778                  * In page addressing mode, the start address needs to be reset,
779                  * and each page then needs to be written out separately.
780                  */
781                 memset(data_array, 0, width);
782
783                 for (i = 0; i < pages; i++) {
784                         ret = ssd130x_set_page_pos(ssd130x,
785                                                    ssd130x->page_offset + i,
786                                                    ssd130x->col_offset);
787                         if (ret < 0)
788                                 return;
789
790                         ret = ssd130x_write_data(ssd130x, data_array, width);
791                         if (ret < 0)
792                                 return;
793                 }
794         }
795 }
796
797 static void ssd132x_clear_screen(struct ssd130x_device *ssd130x, u8 *data_array)
798 {
799         unsigned int columns = DIV_ROUND_UP(ssd130x->height, SSD132X_SEGMENT_WIDTH);
800         unsigned int height = ssd130x->height;
801
802         memset(data_array, 0, columns * height);
803
804         /* Write out update in one go since horizontal addressing mode is used */
805         ssd130x_write_data(ssd130x, data_array, columns * height);
806 }
807
808 static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb,
809                                 const struct iosys_map *vmap,
810                                 struct drm_rect *rect,
811                                 u8 *buf, u8 *data_array,
812                                 struct drm_format_conv_state *fmtcnv_state)
813 {
814         struct ssd130x_device *ssd130x = drm_to_ssd130x(fb->dev);
815         struct iosys_map dst;
816         unsigned int dst_pitch;
817         int ret = 0;
818
819         /* Align y to display page boundaries */
820         rect->y1 = round_down(rect->y1, SSD130X_PAGE_HEIGHT);
821         rect->y2 = min_t(unsigned int, round_up(rect->y2, SSD130X_PAGE_HEIGHT), ssd130x->height);
822
823         dst_pitch = DIV_ROUND_UP(drm_rect_width(rect), 8);
824
825         ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);
826         if (ret)
827                 return ret;
828
829         iosys_map_set_vaddr(&dst, buf);
830         drm_fb_xrgb8888_to_mono(&dst, &dst_pitch, vmap, fb, rect, fmtcnv_state);
831
832         drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
833
834         ssd130x_update_rect(ssd130x, rect, buf, data_array);
835
836         return ret;
837 }
838
839 static int ssd132x_fb_blit_rect(struct drm_framebuffer *fb,
840                                 const struct iosys_map *vmap,
841                                 struct drm_rect *rect, u8 *buf,
842                                 u8 *data_array,
843                                 struct drm_format_conv_state *fmtcnv_state)
844 {
845         struct ssd130x_device *ssd130x = drm_to_ssd130x(fb->dev);
846         unsigned int dst_pitch = drm_rect_width(rect);
847         struct iosys_map dst;
848         int ret = 0;
849
850         /* Align x to display segment boundaries */
851         rect->x1 = round_down(rect->x1, SSD132X_SEGMENT_WIDTH);
852         rect->x2 = min_t(unsigned int, round_up(rect->x2, SSD132X_SEGMENT_WIDTH),
853                          ssd130x->width);
854
855         ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);
856         if (ret)
857                 return ret;
858
859         iosys_map_set_vaddr(&dst, buf);
860         drm_fb_xrgb8888_to_gray8(&dst, &dst_pitch, vmap, fb, rect, fmtcnv_state);
861
862         drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
863
864         ssd132x_update_rect(ssd130x, rect, buf, data_array);
865
866         return ret;
867 }
868
869 static int ssd130x_primary_plane_atomic_check(struct drm_plane *plane,
870                                               struct drm_atomic_state *state)
871 {
872         struct drm_device *drm = plane->dev;
873         struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
874         struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
875         struct ssd130x_plane_state *ssd130x_state = to_ssd130x_plane_state(plane_state);
876         struct drm_shadow_plane_state *shadow_plane_state = &ssd130x_state->base;
877         struct drm_crtc *crtc = plane_state->crtc;
878         struct drm_crtc_state *crtc_state = NULL;
879         const struct drm_format_info *fi;
880         unsigned int pitch;
881         int ret;
882
883         if (crtc)
884                 crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
885
886         ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state,
887                                                   DRM_PLANE_NO_SCALING,
888                                                   DRM_PLANE_NO_SCALING,
889                                                   false, false);
890         if (ret)
891                 return ret;
892         else if (!plane_state->visible)
893                 return 0;
894
895         fi = drm_format_info(DRM_FORMAT_R1);
896         if (!fi)
897                 return -EINVAL;
898
899         pitch = drm_format_info_min_pitch(fi, 0, ssd130x->width);
900
901         if (plane_state->fb->format != fi) {
902                 void *buf;
903
904                 /* format conversion necessary; reserve buffer */
905                 buf = drm_format_conv_state_reserve(&shadow_plane_state->fmtcnv_state,
906                                                     pitch, GFP_KERNEL);
907                 if (!buf)
908                         return -ENOMEM;
909         }
910
911         ssd130x_state->buffer = kcalloc(pitch, ssd130x->height, GFP_KERNEL);
912         if (!ssd130x_state->buffer)
913                 return -ENOMEM;
914
915         return 0;
916 }
917
918 static int ssd132x_primary_plane_atomic_check(struct drm_plane *plane,
919                                               struct drm_atomic_state *state)
920 {
921         struct drm_device *drm = plane->dev;
922         struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
923         struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
924         struct ssd130x_plane_state *ssd130x_state = to_ssd130x_plane_state(plane_state);
925         struct drm_shadow_plane_state *shadow_plane_state = &ssd130x_state->base;
926         struct drm_crtc *crtc = plane_state->crtc;
927         struct drm_crtc_state *crtc_state = NULL;
928         const struct drm_format_info *fi;
929         unsigned int pitch;
930         int ret;
931
932         if (crtc)
933                 crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
934
935         ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state,
936                                                   DRM_PLANE_NO_SCALING,
937                                                   DRM_PLANE_NO_SCALING,
938                                                   false, false);
939         if (ret)
940                 return ret;
941         else if (!plane_state->visible)
942                 return 0;
943
944         fi = drm_format_info(DRM_FORMAT_R8);
945         if (!fi)
946                 return -EINVAL;
947
948         pitch = drm_format_info_min_pitch(fi, 0, ssd130x->width);
949
950         if (plane_state->fb->format != fi) {
951                 void *buf;
952
953                 /* format conversion necessary; reserve buffer */
954                 buf = drm_format_conv_state_reserve(&shadow_plane_state->fmtcnv_state,
955                                                     pitch, GFP_KERNEL);
956                 if (!buf)
957                         return -ENOMEM;
958         }
959
960         ssd130x_state->buffer = kcalloc(pitch, ssd130x->height, GFP_KERNEL);
961         if (!ssd130x_state->buffer)
962                 return -ENOMEM;
963
964         return 0;
965 }
966
967 static void ssd130x_primary_plane_atomic_update(struct drm_plane *plane,
968                                                 struct drm_atomic_state *state)
969 {
970         struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
971         struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
972         struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
973         struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, plane_state->crtc);
974         struct ssd130x_crtc_state *ssd130x_crtc_state =  to_ssd130x_crtc_state(crtc_state);
975         struct ssd130x_plane_state *ssd130x_plane_state = to_ssd130x_plane_state(plane_state);
976         struct drm_framebuffer *fb = plane_state->fb;
977         struct drm_atomic_helper_damage_iter iter;
978         struct drm_device *drm = plane->dev;
979         struct drm_rect dst_clip;
980         struct drm_rect damage;
981         int idx;
982
983         if (!drm_dev_enter(drm, &idx))
984                 return;
985
986         drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state);
987         drm_atomic_for_each_plane_damage(&iter, &damage) {
988                 dst_clip = plane_state->dst;
989
990                 if (!drm_rect_intersect(&dst_clip, &damage))
991                         continue;
992
993                 ssd130x_fb_blit_rect(fb, &shadow_plane_state->data[0], &dst_clip,
994                                      ssd130x_plane_state->buffer,
995                                      ssd130x_crtc_state->data_array,
996                                      &shadow_plane_state->fmtcnv_state);
997         }
998
999         drm_dev_exit(idx);
1000 }
1001
1002 static void ssd132x_primary_plane_atomic_update(struct drm_plane *plane,
1003                                                 struct drm_atomic_state *state)
1004 {
1005         struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
1006         struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
1007         struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
1008         struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, plane_state->crtc);
1009         struct ssd130x_crtc_state *ssd130x_crtc_state =  to_ssd130x_crtc_state(crtc_state);
1010         struct ssd130x_plane_state *ssd130x_plane_state = to_ssd130x_plane_state(plane_state);
1011         struct drm_framebuffer *fb = plane_state->fb;
1012         struct drm_atomic_helper_damage_iter iter;
1013         struct drm_device *drm = plane->dev;
1014         struct drm_rect dst_clip;
1015         struct drm_rect damage;
1016         int idx;
1017
1018         if (!drm_dev_enter(drm, &idx))
1019                 return;
1020
1021         drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state);
1022         drm_atomic_for_each_plane_damage(&iter, &damage) {
1023                 dst_clip = plane_state->dst;
1024
1025                 if (!drm_rect_intersect(&dst_clip, &damage))
1026                         continue;
1027
1028                 ssd132x_fb_blit_rect(fb, &shadow_plane_state->data[0], &dst_clip,
1029                                      ssd130x_plane_state->buffer,
1030                                      ssd130x_crtc_state->data_array,
1031                                      &shadow_plane_state->fmtcnv_state);
1032         }
1033
1034         drm_dev_exit(idx);
1035 }
1036
1037 static void ssd130x_primary_plane_atomic_disable(struct drm_plane *plane,
1038                                                  struct drm_atomic_state *state)
1039 {
1040         struct drm_device *drm = plane->dev;
1041         struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
1042         struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
1043         struct drm_crtc_state *crtc_state;
1044         struct ssd130x_crtc_state *ssd130x_crtc_state;
1045         int idx;
1046
1047         if (!plane_state->crtc)
1048                 return;
1049
1050         crtc_state = drm_atomic_get_new_crtc_state(state, plane_state->crtc);
1051         ssd130x_crtc_state = to_ssd130x_crtc_state(crtc_state);
1052
1053         if (!drm_dev_enter(drm, &idx))
1054                 return;
1055
1056         ssd130x_clear_screen(ssd130x, ssd130x_crtc_state->data_array);
1057
1058         drm_dev_exit(idx);
1059 }
1060
1061 static void ssd132x_primary_plane_atomic_disable(struct drm_plane *plane,
1062                                                  struct drm_atomic_state *state)
1063 {
1064         struct drm_device *drm = plane->dev;
1065         struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
1066         struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
1067         struct drm_crtc_state *crtc_state;
1068         struct ssd130x_crtc_state *ssd130x_crtc_state;
1069         int idx;
1070
1071         if (!plane_state->crtc)
1072                 return;
1073
1074         crtc_state = drm_atomic_get_new_crtc_state(state, plane_state->crtc);
1075         ssd130x_crtc_state = to_ssd130x_crtc_state(crtc_state);
1076
1077         if (!drm_dev_enter(drm, &idx))
1078                 return;
1079
1080         ssd132x_clear_screen(ssd130x, ssd130x_crtc_state->data_array);
1081
1082         drm_dev_exit(idx);
1083 }
1084
1085 /* Called during init to allocate the plane's atomic state. */
1086 static void ssd130x_primary_plane_reset(struct drm_plane *plane)
1087 {
1088         struct ssd130x_plane_state *ssd130x_state;
1089
1090         WARN_ON(plane->state);
1091
1092         ssd130x_state = kzalloc(sizeof(*ssd130x_state), GFP_KERNEL);
1093         if (!ssd130x_state)
1094                 return;
1095
1096         __drm_gem_reset_shadow_plane(plane, &ssd130x_state->base);
1097 }
1098
1099 static struct drm_plane_state *ssd130x_primary_plane_duplicate_state(struct drm_plane *plane)
1100 {
1101         struct drm_shadow_plane_state *new_shadow_plane_state;
1102         struct ssd130x_plane_state *old_ssd130x_state;
1103         struct ssd130x_plane_state *ssd130x_state;
1104
1105         if (WARN_ON(!plane->state))
1106                 return NULL;
1107
1108         old_ssd130x_state = to_ssd130x_plane_state(plane->state);
1109         ssd130x_state = kmemdup(old_ssd130x_state, sizeof(*ssd130x_state), GFP_KERNEL);
1110         if (!ssd130x_state)
1111                 return NULL;
1112
1113         /* The buffer is not duplicated and is allocated in .atomic_check */
1114         ssd130x_state->buffer = NULL;
1115
1116         new_shadow_plane_state = &ssd130x_state->base;
1117
1118         __drm_gem_duplicate_shadow_plane_state(plane, new_shadow_plane_state);
1119
1120         return &new_shadow_plane_state->base;
1121 }
1122
1123 static void ssd130x_primary_plane_destroy_state(struct drm_plane *plane,
1124                                                 struct drm_plane_state *state)
1125 {
1126         struct ssd130x_plane_state *ssd130x_state = to_ssd130x_plane_state(state);
1127
1128         kfree(ssd130x_state->buffer);
1129
1130         __drm_gem_destroy_shadow_plane_state(&ssd130x_state->base);
1131
1132         kfree(ssd130x_state);
1133 }
1134
1135 static const struct drm_plane_helper_funcs ssd130x_primary_plane_helper_funcs[] = {
1136         [SSD130X_FAMILY] = {
1137                 DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
1138                 .atomic_check = ssd130x_primary_plane_atomic_check,
1139                 .atomic_update = ssd130x_primary_plane_atomic_update,
1140                 .atomic_disable = ssd130x_primary_plane_atomic_disable,
1141         },
1142         [SSD132X_FAMILY] = {
1143                 DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
1144                 .atomic_check = ssd132x_primary_plane_atomic_check,
1145                 .atomic_update = ssd132x_primary_plane_atomic_update,
1146                 .atomic_disable = ssd132x_primary_plane_atomic_disable,
1147         }
1148 };
1149
1150 static const struct drm_plane_funcs ssd130x_primary_plane_funcs = {
1151         .update_plane = drm_atomic_helper_update_plane,
1152         .disable_plane = drm_atomic_helper_disable_plane,
1153         .reset = ssd130x_primary_plane_reset,
1154         .atomic_duplicate_state = ssd130x_primary_plane_duplicate_state,
1155         .atomic_destroy_state = ssd130x_primary_plane_destroy_state,
1156         .destroy = drm_plane_cleanup,
1157 };
1158
1159 static enum drm_mode_status ssd130x_crtc_mode_valid(struct drm_crtc *crtc,
1160                                                     const struct drm_display_mode *mode)
1161 {
1162         struct ssd130x_device *ssd130x = drm_to_ssd130x(crtc->dev);
1163
1164         if (mode->hdisplay != ssd130x->mode.hdisplay &&
1165             mode->vdisplay != ssd130x->mode.vdisplay)
1166                 return MODE_ONE_SIZE;
1167         else if (mode->hdisplay != ssd130x->mode.hdisplay)
1168                 return MODE_ONE_WIDTH;
1169         else if (mode->vdisplay != ssd130x->mode.vdisplay)
1170                 return MODE_ONE_HEIGHT;
1171
1172         return MODE_OK;
1173 }
1174
1175 static int ssd130x_crtc_atomic_check(struct drm_crtc *crtc,
1176                                      struct drm_atomic_state *state)
1177 {
1178         struct drm_device *drm = crtc->dev;
1179         struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
1180         struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
1181         struct ssd130x_crtc_state *ssd130x_state = to_ssd130x_crtc_state(crtc_state);
1182         unsigned int pages = DIV_ROUND_UP(ssd130x->height, SSD130X_PAGE_HEIGHT);
1183         int ret;
1184
1185         ret = drm_crtc_helper_atomic_check(crtc, state);
1186         if (ret)
1187                 return ret;
1188
1189         ssd130x_state->data_array = kmalloc(ssd130x->width * pages, GFP_KERNEL);
1190         if (!ssd130x_state->data_array)
1191                 return -ENOMEM;
1192
1193         return 0;
1194 }
1195
1196 static int ssd132x_crtc_atomic_check(struct drm_crtc *crtc,
1197                                      struct drm_atomic_state *state)
1198 {
1199         struct drm_device *drm = crtc->dev;
1200         struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
1201         struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
1202         struct ssd130x_crtc_state *ssd130x_state = to_ssd130x_crtc_state(crtc_state);
1203         unsigned int columns = DIV_ROUND_UP(ssd130x->width, SSD132X_SEGMENT_WIDTH);
1204         int ret;
1205
1206         ret = drm_crtc_helper_atomic_check(crtc, state);
1207         if (ret)
1208                 return ret;
1209
1210         ssd130x_state->data_array = kmalloc(columns * ssd130x->height, GFP_KERNEL);
1211         if (!ssd130x_state->data_array)
1212                 return -ENOMEM;
1213
1214         return 0;
1215 }
1216
1217 /* Called during init to allocate the CRTC's atomic state. */
1218 static void ssd130x_crtc_reset(struct drm_crtc *crtc)
1219 {
1220         struct ssd130x_crtc_state *ssd130x_state;
1221
1222         WARN_ON(crtc->state);
1223
1224         ssd130x_state = kzalloc(sizeof(*ssd130x_state), GFP_KERNEL);
1225         if (!ssd130x_state)
1226                 return;
1227
1228         __drm_atomic_helper_crtc_reset(crtc, &ssd130x_state->base);
1229 }
1230
1231 static struct drm_crtc_state *ssd130x_crtc_duplicate_state(struct drm_crtc *crtc)
1232 {
1233         struct ssd130x_crtc_state *old_ssd130x_state;
1234         struct ssd130x_crtc_state *ssd130x_state;
1235
1236         if (WARN_ON(!crtc->state))
1237                 return NULL;
1238
1239         old_ssd130x_state = to_ssd130x_crtc_state(crtc->state);
1240         ssd130x_state = kmemdup(old_ssd130x_state, sizeof(*ssd130x_state), GFP_KERNEL);
1241         if (!ssd130x_state)
1242                 return NULL;
1243
1244         /* The buffer is not duplicated and is allocated in .atomic_check */
1245         ssd130x_state->data_array = NULL;
1246
1247         __drm_atomic_helper_crtc_duplicate_state(crtc, &ssd130x_state->base);
1248
1249         return &ssd130x_state->base;
1250 }
1251
1252 static void ssd130x_crtc_destroy_state(struct drm_crtc *crtc,
1253                                        struct drm_crtc_state *state)
1254 {
1255         struct ssd130x_crtc_state *ssd130x_state = to_ssd130x_crtc_state(state);
1256
1257         kfree(ssd130x_state->data_array);
1258
1259         __drm_atomic_helper_crtc_destroy_state(state);
1260
1261         kfree(ssd130x_state);
1262 }
1263
1264 /*
1265  * The CRTC is always enabled. Screen updates are performed by
1266  * the primary plane's atomic_update function. Disabling clears
1267  * the screen in the primary plane's atomic_disable function.
1268  */
1269 static const struct drm_crtc_helper_funcs ssd130x_crtc_helper_funcs[] = {
1270         [SSD130X_FAMILY] = {
1271                 .mode_valid = ssd130x_crtc_mode_valid,
1272                 .atomic_check = ssd130x_crtc_atomic_check,
1273         },
1274         [SSD132X_FAMILY] = {
1275                 .mode_valid = ssd130x_crtc_mode_valid,
1276                 .atomic_check = ssd132x_crtc_atomic_check,
1277         },
1278 };
1279
1280 static const struct drm_crtc_funcs ssd130x_crtc_funcs = {
1281         .reset = ssd130x_crtc_reset,
1282         .destroy = drm_crtc_cleanup,
1283         .set_config = drm_atomic_helper_set_config,
1284         .page_flip = drm_atomic_helper_page_flip,
1285         .atomic_duplicate_state = ssd130x_crtc_duplicate_state,
1286         .atomic_destroy_state = ssd130x_crtc_destroy_state,
1287 };
1288
1289 static void ssd130x_encoder_atomic_enable(struct drm_encoder *encoder,
1290                                           struct drm_atomic_state *state)
1291 {
1292         struct drm_device *drm = encoder->dev;
1293         struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
1294         int ret;
1295
1296         ret = ssd130x_power_on(ssd130x);
1297         if (ret)
1298                 return;
1299
1300         ret = ssd130x_init(ssd130x);
1301         if (ret)
1302                 goto power_off;
1303
1304         ssd130x_write_cmd(ssd130x, 1, SSD13XX_DISPLAY_ON);
1305
1306         backlight_enable(ssd130x->bl_dev);
1307
1308         return;
1309
1310 power_off:
1311         ssd130x_power_off(ssd130x);
1312         return;
1313 }
1314
1315 static void ssd132x_encoder_atomic_enable(struct drm_encoder *encoder,
1316                                           struct drm_atomic_state *state)
1317 {
1318         struct drm_device *drm = encoder->dev;
1319         struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
1320         int ret;
1321
1322         ret = ssd130x_power_on(ssd130x);
1323         if (ret)
1324                 return;
1325
1326         ret = ssd132x_init(ssd130x);
1327         if (ret)
1328                 goto power_off;
1329
1330         ssd130x_write_cmd(ssd130x, 1, SSD13XX_DISPLAY_ON);
1331
1332         backlight_enable(ssd130x->bl_dev);
1333
1334         return;
1335
1336 power_off:
1337         ssd130x_power_off(ssd130x);
1338 }
1339
1340 static void ssd130x_encoder_atomic_disable(struct drm_encoder *encoder,
1341                                            struct drm_atomic_state *state)
1342 {
1343         struct drm_device *drm = encoder->dev;
1344         struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
1345
1346         backlight_disable(ssd130x->bl_dev);
1347
1348         ssd130x_write_cmd(ssd130x, 1, SSD13XX_DISPLAY_OFF);
1349
1350         ssd130x_power_off(ssd130x);
1351 }
1352
1353 static const struct drm_encoder_helper_funcs ssd130x_encoder_helper_funcs[] = {
1354         [SSD130X_FAMILY] = {
1355                 .atomic_enable = ssd130x_encoder_atomic_enable,
1356                 .atomic_disable = ssd130x_encoder_atomic_disable,
1357         },
1358         [SSD132X_FAMILY] = {
1359                 .atomic_enable = ssd132x_encoder_atomic_enable,
1360                 .atomic_disable = ssd130x_encoder_atomic_disable,
1361         }
1362 };
1363
1364 static const struct drm_encoder_funcs ssd130x_encoder_funcs = {
1365         .destroy = drm_encoder_cleanup,
1366 };
1367
1368 static int ssd130x_connector_get_modes(struct drm_connector *connector)
1369 {
1370         struct ssd130x_device *ssd130x = drm_to_ssd130x(connector->dev);
1371         struct drm_display_mode *mode;
1372         struct device *dev = ssd130x->dev;
1373
1374         mode = drm_mode_duplicate(connector->dev, &ssd130x->mode);
1375         if (!mode) {
1376                 dev_err(dev, "Failed to duplicated mode\n");
1377                 return 0;
1378         }
1379
1380         drm_mode_probed_add(connector, mode);
1381         drm_set_preferred_mode(connector, mode->hdisplay, mode->vdisplay);
1382
1383         /* There is only a single mode */
1384         return 1;
1385 }
1386
1387 static const struct drm_connector_helper_funcs ssd130x_connector_helper_funcs = {
1388         .get_modes = ssd130x_connector_get_modes,
1389 };
1390
1391 static const struct drm_connector_funcs ssd130x_connector_funcs = {
1392         .reset = drm_atomic_helper_connector_reset,
1393         .fill_modes = drm_helper_probe_single_connector_modes,
1394         .destroy = drm_connector_cleanup,
1395         .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
1396         .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
1397 };
1398
1399 static const struct drm_mode_config_funcs ssd130x_mode_config_funcs = {
1400         .fb_create = drm_gem_fb_create_with_dirty,
1401         .atomic_check = drm_atomic_helper_check,
1402         .atomic_commit = drm_atomic_helper_commit,
1403 };
1404
1405 static const uint32_t ssd130x_formats[] = {
1406         DRM_FORMAT_XRGB8888,
1407 };
1408
1409 DEFINE_DRM_GEM_FOPS(ssd130x_fops);
1410
1411 static const struct drm_driver ssd130x_drm_driver = {
1412         DRM_GEM_SHMEM_DRIVER_OPS,
1413         .name                   = DRIVER_NAME,
1414         .desc                   = DRIVER_DESC,
1415         .date                   = DRIVER_DATE,
1416         .major                  = DRIVER_MAJOR,
1417         .minor                  = DRIVER_MINOR,
1418         .driver_features        = DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
1419         .fops                   = &ssd130x_fops,
1420 };
1421
1422 static int ssd130x_update_bl(struct backlight_device *bdev)
1423 {
1424         struct ssd130x_device *ssd130x = bl_get_data(bdev);
1425         int brightness = backlight_get_brightness(bdev);
1426         int ret;
1427
1428         ssd130x->contrast = brightness;
1429
1430         ret = ssd130x_write_cmd(ssd130x, 1, SSD13XX_CONTRAST);
1431         if (ret < 0)
1432                 return ret;
1433
1434         ret = ssd130x_write_cmd(ssd130x, 1, ssd130x->contrast);
1435         if (ret < 0)
1436                 return ret;
1437
1438         return 0;
1439 }
1440
1441 static const struct backlight_ops ssd130xfb_bl_ops = {
1442         .update_status  = ssd130x_update_bl,
1443 };
1444
1445 static void ssd130x_parse_properties(struct ssd130x_device *ssd130x)
1446 {
1447         struct device *dev = ssd130x->dev;
1448
1449         if (device_property_read_u32(dev, "solomon,width", &ssd130x->width))
1450                 ssd130x->width = ssd130x->device_info->default_width;
1451
1452         if (device_property_read_u32(dev, "solomon,height", &ssd130x->height))
1453                 ssd130x->height = ssd130x->device_info->default_height;
1454
1455         if (device_property_read_u32(dev, "solomon,page-offset", &ssd130x->page_offset))
1456                 ssd130x->page_offset = 1;
1457
1458         if (device_property_read_u32(dev, "solomon,col-offset", &ssd130x->col_offset))
1459                 ssd130x->col_offset = 0;
1460
1461         if (device_property_read_u32(dev, "solomon,com-offset", &ssd130x->com_offset))
1462                 ssd130x->com_offset = 0;
1463
1464         if (device_property_read_u32(dev, "solomon,prechargep1", &ssd130x->prechargep1))
1465                 ssd130x->prechargep1 = 2;
1466
1467         if (device_property_read_u32(dev, "solomon,prechargep2", &ssd130x->prechargep2))
1468                 ssd130x->prechargep2 = 2;
1469
1470         if (!device_property_read_u8_array(dev, "solomon,lookup-table",
1471                                            ssd130x->lookup_table,
1472                                            ARRAY_SIZE(ssd130x->lookup_table)))
1473                 ssd130x->lookup_table_set = 1;
1474
1475         ssd130x->seg_remap = !device_property_read_bool(dev, "solomon,segment-no-remap");
1476         ssd130x->com_seq = device_property_read_bool(dev, "solomon,com-seq");
1477         ssd130x->com_lrremap = device_property_read_bool(dev, "solomon,com-lrremap");
1478         ssd130x->com_invdir = device_property_read_bool(dev, "solomon,com-invdir");
1479         ssd130x->area_color_enable =
1480                 device_property_read_bool(dev, "solomon,area-color-enable");
1481         ssd130x->low_power = device_property_read_bool(dev, "solomon,low-power");
1482
1483         ssd130x->contrast = 127;
1484         ssd130x->vcomh = ssd130x->device_info->default_vcomh;
1485
1486         /* Setup display timing */
1487         if (device_property_read_u32(dev, "solomon,dclk-div", &ssd130x->dclk_div))
1488                 ssd130x->dclk_div = ssd130x->device_info->default_dclk_div;
1489         if (device_property_read_u32(dev, "solomon,dclk-frq", &ssd130x->dclk_frq))
1490                 ssd130x->dclk_frq = ssd130x->device_info->default_dclk_frq;
1491 }
1492
1493 static int ssd130x_init_modeset(struct ssd130x_device *ssd130x)
1494 {
1495         enum ssd130x_family_ids family_id = ssd130x->device_info->family_id;
1496         struct drm_display_mode *mode = &ssd130x->mode;
1497         struct device *dev = ssd130x->dev;
1498         struct drm_device *drm = &ssd130x->drm;
1499         unsigned long max_width, max_height;
1500         struct drm_plane *primary_plane;
1501         struct drm_crtc *crtc;
1502         struct drm_encoder *encoder;
1503         struct drm_connector *connector;
1504         int ret;
1505
1506         /*
1507          * Modesetting
1508          */
1509
1510         ret = drmm_mode_config_init(drm);
1511         if (ret) {
1512                 dev_err(dev, "DRM mode config init failed: %d\n", ret);
1513                 return ret;
1514         }
1515
1516         mode->type = DRM_MODE_TYPE_DRIVER;
1517         mode->clock = 1;
1518         mode->hdisplay = mode->htotal = ssd130x->width;
1519         mode->hsync_start = mode->hsync_end = ssd130x->width;
1520         mode->vdisplay = mode->vtotal = ssd130x->height;
1521         mode->vsync_start = mode->vsync_end = ssd130x->height;
1522         mode->width_mm = 27;
1523         mode->height_mm = 27;
1524
1525         max_width = max_t(unsigned long, mode->hdisplay, DRM_SHADOW_PLANE_MAX_WIDTH);
1526         max_height = max_t(unsigned long, mode->vdisplay, DRM_SHADOW_PLANE_MAX_HEIGHT);
1527
1528         drm->mode_config.min_width = mode->hdisplay;
1529         drm->mode_config.max_width = max_width;
1530         drm->mode_config.min_height = mode->vdisplay;
1531         drm->mode_config.max_height = max_height;
1532         drm->mode_config.preferred_depth = 24;
1533         drm->mode_config.funcs = &ssd130x_mode_config_funcs;
1534
1535         /* Primary plane */
1536
1537         primary_plane = &ssd130x->primary_plane;
1538         ret = drm_universal_plane_init(drm, primary_plane, 0, &ssd130x_primary_plane_funcs,
1539                                        ssd130x_formats, ARRAY_SIZE(ssd130x_formats),
1540                                        NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
1541         if (ret) {
1542                 dev_err(dev, "DRM primary plane init failed: %d\n", ret);
1543                 return ret;
1544         }
1545
1546         drm_plane_helper_add(primary_plane, &ssd130x_primary_plane_helper_funcs[family_id]);
1547
1548         drm_plane_enable_fb_damage_clips(primary_plane);
1549
1550         /* CRTC */
1551
1552         crtc = &ssd130x->crtc;
1553         ret = drm_crtc_init_with_planes(drm, crtc, primary_plane, NULL,
1554                                         &ssd130x_crtc_funcs, NULL);
1555         if (ret) {
1556                 dev_err(dev, "DRM crtc init failed: %d\n", ret);
1557                 return ret;
1558         }
1559
1560         drm_crtc_helper_add(crtc, &ssd130x_crtc_helper_funcs[family_id]);
1561
1562         /* Encoder */
1563
1564         encoder = &ssd130x->encoder;
1565         ret = drm_encoder_init(drm, encoder, &ssd130x_encoder_funcs,
1566                                DRM_MODE_ENCODER_NONE, NULL);
1567         if (ret) {
1568                 dev_err(dev, "DRM encoder init failed: %d\n", ret);
1569                 return ret;
1570         }
1571
1572         drm_encoder_helper_add(encoder, &ssd130x_encoder_helper_funcs[family_id]);
1573
1574         encoder->possible_crtcs = drm_crtc_mask(crtc);
1575
1576         /* Connector */
1577
1578         connector = &ssd130x->connector;
1579         ret = drm_connector_init(drm, connector, &ssd130x_connector_funcs,
1580                                  DRM_MODE_CONNECTOR_Unknown);
1581         if (ret) {
1582                 dev_err(dev, "DRM connector init failed: %d\n", ret);
1583                 return ret;
1584         }
1585
1586         drm_connector_helper_add(connector, &ssd130x_connector_helper_funcs);
1587
1588         ret = drm_connector_attach_encoder(connector, encoder);
1589         if (ret) {
1590                 dev_err(dev, "DRM attach connector to encoder failed: %d\n", ret);
1591                 return ret;
1592         }
1593
1594         drm_mode_config_reset(drm);
1595
1596         return 0;
1597 }
1598
1599 static int ssd130x_get_resources(struct ssd130x_device *ssd130x)
1600 {
1601         struct device *dev = ssd130x->dev;
1602
1603         ssd130x->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
1604         if (IS_ERR(ssd130x->reset))
1605                 return dev_err_probe(dev, PTR_ERR(ssd130x->reset),
1606                                      "Failed to get reset gpio\n");
1607
1608         ssd130x->vcc_reg = devm_regulator_get(dev, "vcc");
1609         if (IS_ERR(ssd130x->vcc_reg))
1610                 return dev_err_probe(dev, PTR_ERR(ssd130x->vcc_reg),
1611                                      "Failed to get VCC regulator\n");
1612
1613         return 0;
1614 }
1615
1616 struct ssd130x_device *ssd130x_probe(struct device *dev, struct regmap *regmap)
1617 {
1618         struct ssd130x_device *ssd130x;
1619         struct backlight_device *bl;
1620         struct drm_device *drm;
1621         int ret;
1622
1623         ssd130x = devm_drm_dev_alloc(dev, &ssd130x_drm_driver,
1624                                      struct ssd130x_device, drm);
1625         if (IS_ERR(ssd130x))
1626                 return ERR_PTR(dev_err_probe(dev, PTR_ERR(ssd130x),
1627                                              "Failed to allocate DRM device\n"));
1628
1629         drm = &ssd130x->drm;
1630
1631         ssd130x->dev = dev;
1632         ssd130x->regmap = regmap;
1633         ssd130x->device_info = device_get_match_data(dev);
1634
1635         if (ssd130x->device_info->page_mode_only)
1636                 ssd130x->page_address_mode = 1;
1637
1638         ssd130x_parse_properties(ssd130x);
1639
1640         ret = ssd130x_get_resources(ssd130x);
1641         if (ret)
1642                 return ERR_PTR(ret);
1643
1644         bl = devm_backlight_device_register(dev, dev_name(dev), dev, ssd130x,
1645                                             &ssd130xfb_bl_ops, NULL);
1646         if (IS_ERR(bl))
1647                 return ERR_PTR(dev_err_probe(dev, PTR_ERR(bl),
1648                                              "Unable to register backlight device\n"));
1649
1650         bl->props.brightness = ssd130x->contrast;
1651         bl->props.max_brightness = MAX_CONTRAST;
1652         ssd130x->bl_dev = bl;
1653
1654         ret = ssd130x_init_modeset(ssd130x);
1655         if (ret)
1656                 return ERR_PTR(ret);
1657
1658         ret = drm_dev_register(drm, 0);
1659         if (ret)
1660                 return ERR_PTR(dev_err_probe(dev, ret, "DRM device register failed\n"));
1661
1662         drm_fbdev_generic_setup(drm, 32);
1663
1664         return ssd130x;
1665 }
1666 EXPORT_SYMBOL_GPL(ssd130x_probe);
1667
1668 void ssd130x_remove(struct ssd130x_device *ssd130x)
1669 {
1670         drm_dev_unplug(&ssd130x->drm);
1671         drm_atomic_helper_shutdown(&ssd130x->drm);
1672 }
1673 EXPORT_SYMBOL_GPL(ssd130x_remove);
1674
1675 void ssd130x_shutdown(struct ssd130x_device *ssd130x)
1676 {
1677         drm_atomic_helper_shutdown(&ssd130x->drm);
1678 }
1679 EXPORT_SYMBOL_GPL(ssd130x_shutdown);
1680
1681 MODULE_DESCRIPTION(DRIVER_DESC);
1682 MODULE_AUTHOR("Javier Martinez Canillas <[email protected]>");
1683 MODULE_LICENSE("GPL v2");
This page took 0.130622 seconds and 4 git commands to generate.