1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * MIPI Display Bus Interface (DBI) LCD controller support |
4 | * |
5 | * Copyright 2016 Noralf Trønnes |
6 | */ |
7 | |
8 | #include <linux/backlight.h> |
9 | #include <linux/debugfs.h> |
10 | #include <linux/delay.h> |
11 | #include <linux/gpio/consumer.h> |
12 | #include <linux/module.h> |
13 | #include <linux/regulator/consumer.h> |
14 | #include <linux/spi/spi.h> |
15 | |
16 | #include <drm/drm_connector.h> |
17 | #include <drm/drm_damage_helper.h> |
18 | #include <drm/drm_drv.h> |
19 | #include <drm/drm_file.h> |
20 | #include <drm/drm_format_helper.h> |
21 | #include <drm/drm_fourcc.h> |
22 | #include <drm/drm_framebuffer.h> |
23 | #include <drm/drm_gem.h> |
24 | #include <drm/drm_gem_atomic_helper.h> |
25 | #include <drm/drm_gem_framebuffer_helper.h> |
26 | #include <drm/drm_mipi_dbi.h> |
27 | #include <drm/drm_modes.h> |
28 | #include <drm/drm_probe_helper.h> |
29 | #include <drm/drm_rect.h> |
30 | #include <video/mipi_display.h> |
31 | |
32 | #define MIPI_DBI_MAX_SPI_READ_SPEED 2000000 /* 2MHz */ |
33 | |
34 | #define DCS_POWER_MODE_DISPLAY BIT(2) |
35 | #define DCS_POWER_MODE_DISPLAY_NORMAL_MODE BIT(3) |
36 | #define DCS_POWER_MODE_SLEEP_MODE BIT(4) |
37 | #define DCS_POWER_MODE_PARTIAL_MODE BIT(5) |
38 | #define DCS_POWER_MODE_IDLE_MODE BIT(6) |
39 | #define DCS_POWER_MODE_RESERVED_MASK (BIT(0) | BIT(1) | BIT(7)) |
40 | |
41 | /** |
42 | * DOC: overview |
43 | * |
44 | * This library provides helpers for MIPI Display Bus Interface (DBI) |
45 | * compatible display controllers. |
46 | * |
47 | * Many controllers for tiny lcd displays are MIPI compliant and can use this |
48 | * library. If a controller uses registers 0x2A and 0x2B to set the area to |
49 | * update and uses register 0x2C to write to frame memory, it is most likely |
50 | * MIPI compliant. |
51 | * |
52 | * Only MIPI Type 1 displays are supported since a full frame memory is needed. |
53 | * |
54 | * There are 3 MIPI DBI implementation types: |
55 | * |
56 | * A. Motorola 6800 type parallel bus |
57 | * |
58 | * B. Intel 8080 type parallel bus |
59 | * |
60 | * C. SPI type with 3 options: |
61 | * |
62 | * 1. 9-bit with the Data/Command signal as the ninth bit |
63 | * 2. Same as above except it's sent as 16 bits |
64 | * 3. 8-bit with the Data/Command signal as a separate D/CX pin |
65 | * |
66 | * Currently mipi_dbi only supports Type C options 1 and 3 with |
67 | * mipi_dbi_spi_init(). |
68 | */ |
69 | |
70 | #define MIPI_DBI_DEBUG_COMMAND(cmd, data, len) \ |
71 | ({ \ |
72 | if (!len) \ |
73 | DRM_DEBUG_DRIVER("cmd=%02x\n", cmd); \ |
74 | else if (len <= 32) \ |
75 | DRM_DEBUG_DRIVER("cmd=%02x, par=%*ph\n", cmd, (int)len, data);\ |
76 | else \ |
77 | DRM_DEBUG_DRIVER("cmd=%02x, len=%zu\n", cmd, len); \ |
78 | }) |
79 | |
80 | static const u8 mipi_dbi_dcs_read_commands[] = { |
81 | MIPI_DCS_GET_DISPLAY_ID, |
82 | MIPI_DCS_GET_RED_CHANNEL, |
83 | MIPI_DCS_GET_GREEN_CHANNEL, |
84 | MIPI_DCS_GET_BLUE_CHANNEL, |
85 | MIPI_DCS_GET_DISPLAY_STATUS, |
86 | MIPI_DCS_GET_POWER_MODE, |
87 | MIPI_DCS_GET_ADDRESS_MODE, |
88 | MIPI_DCS_GET_PIXEL_FORMAT, |
89 | MIPI_DCS_GET_DISPLAY_MODE, |
90 | MIPI_DCS_GET_SIGNAL_MODE, |
91 | MIPI_DCS_GET_DIAGNOSTIC_RESULT, |
92 | MIPI_DCS_READ_MEMORY_START, |
93 | MIPI_DCS_READ_MEMORY_CONTINUE, |
94 | MIPI_DCS_GET_SCANLINE, |
95 | MIPI_DCS_GET_DISPLAY_BRIGHTNESS, |
96 | MIPI_DCS_GET_CONTROL_DISPLAY, |
97 | MIPI_DCS_GET_POWER_SAVE, |
98 | MIPI_DCS_GET_CABC_MIN_BRIGHTNESS, |
99 | MIPI_DCS_READ_DDB_START, |
100 | MIPI_DCS_READ_DDB_CONTINUE, |
101 | 0, /* sentinel */ |
102 | }; |
103 | |
104 | static bool mipi_dbi_command_is_read(struct mipi_dbi *dbi, u8 cmd) |
105 | { |
106 | unsigned int i; |
107 | |
108 | if (!dbi->read_commands) |
109 | return false; |
110 | |
111 | for (i = 0; i < 0xff; i++) { |
112 | if (!dbi->read_commands[i]) |
113 | return false; |
114 | if (cmd == dbi->read_commands[i]) |
115 | return true; |
116 | } |
117 | |
118 | return false; |
119 | } |
120 | |
121 | /** |
122 | * mipi_dbi_command_read - MIPI DCS read command |
123 | * @dbi: MIPI DBI structure |
124 | * @cmd: Command |
125 | * @val: Value read |
126 | * |
127 | * Send MIPI DCS read command to the controller. |
128 | * |
129 | * Returns: |
130 | * Zero on success, negative error code on failure. |
131 | */ |
132 | int mipi_dbi_command_read(struct mipi_dbi *dbi, u8 cmd, u8 *val) |
133 | { |
134 | if (!dbi->read_commands) |
135 | return -EACCES; |
136 | |
137 | if (!mipi_dbi_command_is_read(dbi, cmd)) |
138 | return -EINVAL; |
139 | |
140 | return mipi_dbi_command_buf(dbi, cmd, data: val, len: 1); |
141 | } |
142 | EXPORT_SYMBOL(mipi_dbi_command_read); |
143 | |
144 | /** |
145 | * mipi_dbi_command_buf - MIPI DCS command with parameter(s) in an array |
146 | * @dbi: MIPI DBI structure |
147 | * @cmd: Command |
148 | * @data: Parameter buffer |
149 | * @len: Buffer length |
150 | * |
151 | * Returns: |
152 | * Zero on success, negative error code on failure. |
153 | */ |
154 | int mipi_dbi_command_buf(struct mipi_dbi *dbi, u8 cmd, u8 *data, size_t len) |
155 | { |
156 | u8 *cmdbuf; |
157 | int ret; |
158 | |
159 | /* SPI requires dma-safe buffers */ |
160 | cmdbuf = kmemdup(p: &cmd, size: 1, GFP_KERNEL); |
161 | if (!cmdbuf) |
162 | return -ENOMEM; |
163 | |
164 | mutex_lock(&dbi->cmdlock); |
165 | ret = dbi->command(dbi, cmdbuf, data, len); |
166 | mutex_unlock(lock: &dbi->cmdlock); |
167 | |
168 | kfree(objp: cmdbuf); |
169 | |
170 | return ret; |
171 | } |
172 | EXPORT_SYMBOL(mipi_dbi_command_buf); |
173 | |
174 | /* This should only be used by mipi_dbi_command() */ |
175 | int mipi_dbi_command_stackbuf(struct mipi_dbi *dbi, u8 cmd, const u8 *data, |
176 | size_t len) |
177 | { |
178 | u8 *buf; |
179 | int ret; |
180 | |
181 | buf = kmemdup(p: data, size: len, GFP_KERNEL); |
182 | if (!buf) |
183 | return -ENOMEM; |
184 | |
185 | ret = mipi_dbi_command_buf(dbi, cmd, buf, len); |
186 | |
187 | kfree(objp: buf); |
188 | |
189 | return ret; |
190 | } |
191 | EXPORT_SYMBOL(mipi_dbi_command_stackbuf); |
192 | |
193 | /** |
194 | * mipi_dbi_buf_copy - Copy a framebuffer, transforming it if necessary |
195 | * @dst: The destination buffer |
196 | * @src: The source buffer |
197 | * @fb: The source framebuffer |
198 | * @clip: Clipping rectangle of the area to be copied |
199 | * @swap: When true, swap MSB/LSB of 16-bit values |
200 | * @fmtcnv_state: Format-conversion state |
201 | * |
202 | * Returns: |
203 | * Zero on success, negative error code on failure. |
204 | */ |
205 | int mipi_dbi_buf_copy(void *dst, struct iosys_map *src, struct drm_framebuffer *fb, |
206 | struct drm_rect *clip, bool swap, |
207 | struct drm_format_conv_state *fmtcnv_state) |
208 | { |
209 | struct drm_gem_object *gem = drm_gem_fb_get_obj(fb, plane: 0); |
210 | struct iosys_map dst_map = IOSYS_MAP_INIT_VADDR(dst); |
211 | int ret; |
212 | |
213 | ret = drm_gem_fb_begin_cpu_access(fb, dir: DMA_FROM_DEVICE); |
214 | if (ret) |
215 | return ret; |
216 | |
217 | switch (fb->format->format) { |
218 | case DRM_FORMAT_RGB565: |
219 | if (swap) |
220 | drm_fb_swab(dst: &dst_map, NULL, src, fb, clip, cached: !gem->import_attach, |
221 | state: fmtcnv_state); |
222 | else |
223 | drm_fb_memcpy(dst: &dst_map, NULL, src, fb, clip); |
224 | break; |
225 | case DRM_FORMAT_XRGB8888: |
226 | drm_fb_xrgb8888_to_rgb565(dst: &dst_map, NULL, src, fb, clip, state: fmtcnv_state, swab: swap); |
227 | break; |
228 | default: |
229 | drm_err_once(fb->dev, "Format is not supported: %p4cc\n" , |
230 | &fb->format->format); |
231 | ret = -EINVAL; |
232 | } |
233 | |
234 | drm_gem_fb_end_cpu_access(fb, dir: DMA_FROM_DEVICE); |
235 | |
236 | return ret; |
237 | } |
238 | EXPORT_SYMBOL(mipi_dbi_buf_copy); |
239 | |
240 | static void mipi_dbi_set_window_address(struct mipi_dbi_dev *dbidev, |
241 | unsigned int xs, unsigned int xe, |
242 | unsigned int ys, unsigned int ye) |
243 | { |
244 | struct mipi_dbi *dbi = &dbidev->dbi; |
245 | |
246 | xs += dbidev->left_offset; |
247 | xe += dbidev->left_offset; |
248 | ys += dbidev->top_offset; |
249 | ye += dbidev->top_offset; |
250 | |
251 | mipi_dbi_command(dbi, MIPI_DCS_SET_COLUMN_ADDRESS, (xs >> 8) & 0xff, |
252 | xs & 0xff, (xe >> 8) & 0xff, xe & 0xff); |
253 | mipi_dbi_command(dbi, MIPI_DCS_SET_PAGE_ADDRESS, (ys >> 8) & 0xff, |
254 | ys & 0xff, (ye >> 8) & 0xff, ye & 0xff); |
255 | } |
256 | |
257 | static void mipi_dbi_fb_dirty(struct iosys_map *src, struct drm_framebuffer *fb, |
258 | struct drm_rect *rect, struct drm_format_conv_state *fmtcnv_state) |
259 | { |
260 | struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(drm: fb->dev); |
261 | unsigned int height = rect->y2 - rect->y1; |
262 | unsigned int width = rect->x2 - rect->x1; |
263 | struct mipi_dbi *dbi = &dbidev->dbi; |
264 | bool swap = dbi->swap_bytes; |
265 | int ret = 0; |
266 | bool full; |
267 | void *tr; |
268 | |
269 | full = width == fb->width && height == fb->height; |
270 | |
271 | DRM_DEBUG_KMS("Flushing [FB:%d] " DRM_RECT_FMT "\n" , fb->base.id, DRM_RECT_ARG(rect)); |
272 | |
273 | if (!dbi->dc || !full || swap || |
274 | fb->format->format == DRM_FORMAT_XRGB8888) { |
275 | tr = dbidev->tx_buf; |
276 | ret = mipi_dbi_buf_copy(tr, src, fb, rect, swap, fmtcnv_state); |
277 | if (ret) |
278 | goto err_msg; |
279 | } else { |
280 | tr = src->vaddr; /* TODO: Use mapping abstraction properly */ |
281 | } |
282 | |
283 | mipi_dbi_set_window_address(dbidev, xs: rect->x1, xe: rect->x2 - 1, ys: rect->y1, |
284 | ye: rect->y2 - 1); |
285 | |
286 | ret = mipi_dbi_command_buf(dbi, MIPI_DCS_WRITE_MEMORY_START, tr, |
287 | width * height * 2); |
288 | err_msg: |
289 | if (ret) |
290 | drm_err_once(fb->dev, "Failed to update display %d\n" , ret); |
291 | } |
292 | |
293 | /** |
294 | * mipi_dbi_pipe_mode_valid - MIPI DBI mode-valid helper |
295 | * @pipe: Simple display pipe |
296 | * @mode: The mode to test |
297 | * |
298 | * This function validates a given display mode against the MIPI DBI's hardware |
299 | * display. Drivers can use this as their &drm_simple_display_pipe_funcs->mode_valid |
300 | * callback. |
301 | */ |
302 | enum drm_mode_status mipi_dbi_pipe_mode_valid(struct drm_simple_display_pipe *pipe, |
303 | const struct drm_display_mode *mode) |
304 | { |
305 | struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(drm: pipe->crtc.dev); |
306 | |
307 | return drm_crtc_helper_mode_valid_fixed(crtc: &pipe->crtc, mode, fixed_mode: &dbidev->mode); |
308 | } |
309 | EXPORT_SYMBOL(mipi_dbi_pipe_mode_valid); |
310 | |
311 | /** |
312 | * mipi_dbi_pipe_update - Display pipe update helper |
313 | * @pipe: Simple display pipe |
314 | * @old_state: Old plane state |
315 | * |
316 | * This function handles framebuffer flushing and vblank events. Drivers can use |
317 | * this as their &drm_simple_display_pipe_funcs->update callback. |
318 | */ |
319 | void mipi_dbi_pipe_update(struct drm_simple_display_pipe *pipe, |
320 | struct drm_plane_state *old_state) |
321 | { |
322 | struct drm_plane_state *state = pipe->plane.state; |
323 | struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(state); |
324 | struct drm_framebuffer *fb = state->fb; |
325 | struct drm_rect rect; |
326 | int idx; |
327 | |
328 | if (!pipe->crtc.state->active) |
329 | return; |
330 | |
331 | if (WARN_ON(!fb)) |
332 | return; |
333 | |
334 | if (!drm_dev_enter(dev: fb->dev, idx: &idx)) |
335 | return; |
336 | |
337 | if (drm_atomic_helper_damage_merged(old_state, state, rect: &rect)) |
338 | mipi_dbi_fb_dirty(src: &shadow_plane_state->data[0], fb, rect: &rect, |
339 | fmtcnv_state: &shadow_plane_state->fmtcnv_state); |
340 | |
341 | drm_dev_exit(idx); |
342 | } |
343 | EXPORT_SYMBOL(mipi_dbi_pipe_update); |
344 | |
345 | /** |
346 | * mipi_dbi_enable_flush - MIPI DBI enable helper |
347 | * @dbidev: MIPI DBI device structure |
348 | * @crtc_state: CRTC state |
349 | * @plane_state: Plane state |
350 | * |
351 | * Flushes the whole framebuffer and enables the backlight. Drivers can use this |
352 | * in their &drm_simple_display_pipe_funcs->enable callback. |
353 | * |
354 | * Note: Drivers which don't use mipi_dbi_pipe_update() because they have custom |
355 | * framebuffer flushing, can't use this function since they both use the same |
356 | * flushing code. |
357 | */ |
358 | void mipi_dbi_enable_flush(struct mipi_dbi_dev *dbidev, |
359 | struct drm_crtc_state *crtc_state, |
360 | struct drm_plane_state *plane_state) |
361 | { |
362 | struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(state: plane_state); |
363 | struct drm_framebuffer *fb = plane_state->fb; |
364 | struct drm_rect rect = { |
365 | .x1 = 0, |
366 | .x2 = fb->width, |
367 | .y1 = 0, |
368 | .y2 = fb->height, |
369 | }; |
370 | int idx; |
371 | |
372 | if (!drm_dev_enter(dev: &dbidev->drm, idx: &idx)) |
373 | return; |
374 | |
375 | mipi_dbi_fb_dirty(src: &shadow_plane_state->data[0], fb, rect: &rect, |
376 | fmtcnv_state: &shadow_plane_state->fmtcnv_state); |
377 | backlight_enable(bd: dbidev->backlight); |
378 | |
379 | drm_dev_exit(idx); |
380 | } |
381 | EXPORT_SYMBOL(mipi_dbi_enable_flush); |
382 | |
383 | static void mipi_dbi_blank(struct mipi_dbi_dev *dbidev) |
384 | { |
385 | struct drm_device *drm = &dbidev->drm; |
386 | u16 height = drm->mode_config.min_height; |
387 | u16 width = drm->mode_config.min_width; |
388 | struct mipi_dbi *dbi = &dbidev->dbi; |
389 | size_t len = width * height * 2; |
390 | int idx; |
391 | |
392 | if (!drm_dev_enter(dev: drm, idx: &idx)) |
393 | return; |
394 | |
395 | memset(dbidev->tx_buf, 0, len); |
396 | |
397 | mipi_dbi_set_window_address(dbidev, xs: 0, xe: width - 1, ys: 0, ye: height - 1); |
398 | mipi_dbi_command_buf(dbi, MIPI_DCS_WRITE_MEMORY_START, |
399 | (u8 *)dbidev->tx_buf, len); |
400 | |
401 | drm_dev_exit(idx); |
402 | } |
403 | |
404 | /** |
405 | * mipi_dbi_pipe_disable - MIPI DBI pipe disable helper |
406 | * @pipe: Display pipe |
407 | * |
408 | * This function disables backlight if present, if not the display memory is |
409 | * blanked. The regulator is disabled if in use. Drivers can use this as their |
410 | * &drm_simple_display_pipe_funcs->disable callback. |
411 | */ |
412 | void mipi_dbi_pipe_disable(struct drm_simple_display_pipe *pipe) |
413 | { |
414 | struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(drm: pipe->crtc.dev); |
415 | |
416 | DRM_DEBUG_KMS("\n" ); |
417 | |
418 | if (dbidev->backlight) |
419 | backlight_disable(bd: dbidev->backlight); |
420 | else |
421 | mipi_dbi_blank(dbidev); |
422 | |
423 | if (dbidev->regulator) |
424 | regulator_disable(regulator: dbidev->regulator); |
425 | if (dbidev->io_regulator) |
426 | regulator_disable(regulator: dbidev->io_regulator); |
427 | } |
428 | EXPORT_SYMBOL(mipi_dbi_pipe_disable); |
429 | |
430 | /** |
431 | * mipi_dbi_pipe_begin_fb_access - MIPI DBI pipe begin-access helper |
432 | * @pipe: Display pipe |
433 | * @plane_state: Plane state |
434 | * |
435 | * This function implements struct &drm_simple_display_funcs.begin_fb_access. |
436 | * |
437 | * See drm_gem_begin_shadow_fb_access() for details and mipi_dbi_pipe_cleanup_fb() |
438 | * for cleanup. |
439 | * |
440 | * Returns: |
441 | * 0 on success, or a negative errno code otherwise. |
442 | */ |
443 | int mipi_dbi_pipe_begin_fb_access(struct drm_simple_display_pipe *pipe, |
444 | struct drm_plane_state *plane_state) |
445 | { |
446 | return drm_gem_begin_shadow_fb_access(plane: &pipe->plane, plane_state); |
447 | } |
448 | EXPORT_SYMBOL(mipi_dbi_pipe_begin_fb_access); |
449 | |
450 | /** |
451 | * mipi_dbi_pipe_end_fb_access - MIPI DBI pipe end-access helper |
452 | * @pipe: Display pipe |
453 | * @plane_state: Plane state |
454 | * |
455 | * This function implements struct &drm_simple_display_funcs.end_fb_access. |
456 | * |
457 | * See mipi_dbi_pipe_begin_fb_access(). |
458 | */ |
459 | void mipi_dbi_pipe_end_fb_access(struct drm_simple_display_pipe *pipe, |
460 | struct drm_plane_state *plane_state) |
461 | { |
462 | drm_gem_end_shadow_fb_access(plane: &pipe->plane, plane_state); |
463 | } |
464 | EXPORT_SYMBOL(mipi_dbi_pipe_end_fb_access); |
465 | |
466 | /** |
467 | * mipi_dbi_pipe_reset_plane - MIPI DBI plane-reset helper |
468 | * @pipe: Display pipe |
469 | * |
470 | * This function implements struct &drm_simple_display_funcs.reset_plane |
471 | * for MIPI DBI planes. |
472 | */ |
473 | void mipi_dbi_pipe_reset_plane(struct drm_simple_display_pipe *pipe) |
474 | { |
475 | drm_gem_reset_shadow_plane(plane: &pipe->plane); |
476 | } |
477 | EXPORT_SYMBOL(mipi_dbi_pipe_reset_plane); |
478 | |
479 | /** |
480 | * mipi_dbi_pipe_duplicate_plane_state - duplicates MIPI DBI plane state |
481 | * @pipe: Display pipe |
482 | * |
483 | * This function implements struct &drm_simple_display_funcs.duplicate_plane_state |
484 | * for MIPI DBI planes. |
485 | * |
486 | * See drm_gem_duplicate_shadow_plane_state() for additional details. |
487 | * |
488 | * Returns: |
489 | * A pointer to a new plane state on success, or NULL otherwise. |
490 | */ |
491 | struct drm_plane_state *mipi_dbi_pipe_duplicate_plane_state(struct drm_simple_display_pipe *pipe) |
492 | { |
493 | return drm_gem_duplicate_shadow_plane_state(plane: &pipe->plane); |
494 | } |
495 | EXPORT_SYMBOL(mipi_dbi_pipe_duplicate_plane_state); |
496 | |
497 | /** |
498 | * mipi_dbi_pipe_destroy_plane_state - cleans up MIPI DBI plane state |
499 | * @pipe: Display pipe |
500 | * @plane_state: Plane state |
501 | * |
502 | * This function implements struct drm_simple_display_funcs.destroy_plane_state |
503 | * for MIPI DBI planes. |
504 | * |
505 | * See drm_gem_destroy_shadow_plane_state() for additional details. |
506 | */ |
507 | void mipi_dbi_pipe_destroy_plane_state(struct drm_simple_display_pipe *pipe, |
508 | struct drm_plane_state *plane_state) |
509 | { |
510 | drm_gem_destroy_shadow_plane_state(plane: &pipe->plane, plane_state); |
511 | } |
512 | EXPORT_SYMBOL(mipi_dbi_pipe_destroy_plane_state); |
513 | |
514 | static int mipi_dbi_connector_get_modes(struct drm_connector *connector) |
515 | { |
516 | struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(drm: connector->dev); |
517 | |
518 | return drm_connector_helper_get_modes_fixed(connector, fixed_mode: &dbidev->mode); |
519 | } |
520 | |
521 | static const struct drm_connector_helper_funcs mipi_dbi_connector_hfuncs = { |
522 | .get_modes = mipi_dbi_connector_get_modes, |
523 | }; |
524 | |
525 | static const struct drm_connector_funcs mipi_dbi_connector_funcs = { |
526 | .reset = drm_atomic_helper_connector_reset, |
527 | .fill_modes = drm_helper_probe_single_connector_modes, |
528 | .destroy = drm_connector_cleanup, |
529 | .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, |
530 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, |
531 | }; |
532 | |
533 | static int mipi_dbi_rotate_mode(struct drm_display_mode *mode, |
534 | unsigned int rotation) |
535 | { |
536 | if (rotation == 0 || rotation == 180) { |
537 | return 0; |
538 | } else if (rotation == 90 || rotation == 270) { |
539 | swap(mode->hdisplay, mode->vdisplay); |
540 | swap(mode->hsync_start, mode->vsync_start); |
541 | swap(mode->hsync_end, mode->vsync_end); |
542 | swap(mode->htotal, mode->vtotal); |
543 | swap(mode->width_mm, mode->height_mm); |
544 | return 0; |
545 | } else { |
546 | return -EINVAL; |
547 | } |
548 | } |
549 | |
550 | static const struct drm_mode_config_funcs mipi_dbi_mode_config_funcs = { |
551 | .fb_create = drm_gem_fb_create_with_dirty, |
552 | .atomic_check = drm_atomic_helper_check, |
553 | .atomic_commit = drm_atomic_helper_commit, |
554 | }; |
555 | |
556 | static const uint32_t mipi_dbi_formats[] = { |
557 | DRM_FORMAT_RGB565, |
558 | DRM_FORMAT_XRGB8888, |
559 | }; |
560 | |
561 | /** |
562 | * mipi_dbi_dev_init_with_formats - MIPI DBI device initialization with custom formats |
563 | * @dbidev: MIPI DBI device structure to initialize |
564 | * @funcs: Display pipe functions |
565 | * @formats: Array of supported formats (DRM_FORMAT\_\*). |
566 | * @format_count: Number of elements in @formats |
567 | * @mode: Display mode |
568 | * @rotation: Initial rotation in degrees Counter Clock Wise |
569 | * @tx_buf_size: Allocate a transmit buffer of this size. |
570 | * |
571 | * This function sets up a &drm_simple_display_pipe with a &drm_connector that |
572 | * has one fixed &drm_display_mode which is rotated according to @rotation. |
573 | * This mode is used to set the mode config min/max width/height properties. |
574 | * |
575 | * Use mipi_dbi_dev_init() if you don't need custom formats. |
576 | * |
577 | * Note: |
578 | * Some of the helper functions expects RGB565 to be the default format and the |
579 | * transmit buffer sized to fit that. |
580 | * |
581 | * Returns: |
582 | * Zero on success, negative error code on failure. |
583 | */ |
584 | int mipi_dbi_dev_init_with_formats(struct mipi_dbi_dev *dbidev, |
585 | const struct drm_simple_display_pipe_funcs *funcs, |
586 | const uint32_t *formats, unsigned int format_count, |
587 | const struct drm_display_mode *mode, |
588 | unsigned int rotation, size_t tx_buf_size) |
589 | { |
590 | static const uint64_t modifiers[] = { |
591 | DRM_FORMAT_MOD_LINEAR, |
592 | DRM_FORMAT_MOD_INVALID |
593 | }; |
594 | struct drm_device *drm = &dbidev->drm; |
595 | int ret; |
596 | |
597 | if (!dbidev->dbi.command) |
598 | return -EINVAL; |
599 | |
600 | ret = drmm_mode_config_init(dev: drm); |
601 | if (ret) |
602 | return ret; |
603 | |
604 | dbidev->tx_buf = devm_kmalloc(dev: drm->dev, size: tx_buf_size, GFP_KERNEL); |
605 | if (!dbidev->tx_buf) |
606 | return -ENOMEM; |
607 | |
608 | drm_mode_copy(dst: &dbidev->mode, src: mode); |
609 | ret = mipi_dbi_rotate_mode(mode: &dbidev->mode, rotation); |
610 | if (ret) { |
611 | DRM_ERROR("Illegal rotation value %u\n" , rotation); |
612 | return -EINVAL; |
613 | } |
614 | |
615 | drm_connector_helper_add(connector: &dbidev->connector, funcs: &mipi_dbi_connector_hfuncs); |
616 | ret = drm_connector_init(dev: drm, connector: &dbidev->connector, funcs: &mipi_dbi_connector_funcs, |
617 | DRM_MODE_CONNECTOR_SPI); |
618 | if (ret) |
619 | return ret; |
620 | |
621 | ret = drm_simple_display_pipe_init(dev: drm, pipe: &dbidev->pipe, funcs, formats, format_count, |
622 | format_modifiers: modifiers, connector: &dbidev->connector); |
623 | if (ret) |
624 | return ret; |
625 | |
626 | drm_plane_enable_fb_damage_clips(plane: &dbidev->pipe.plane); |
627 | |
628 | drm->mode_config.funcs = &mipi_dbi_mode_config_funcs; |
629 | drm->mode_config.min_width = dbidev->mode.hdisplay; |
630 | drm->mode_config.max_width = dbidev->mode.hdisplay; |
631 | drm->mode_config.min_height = dbidev->mode.vdisplay; |
632 | drm->mode_config.max_height = dbidev->mode.vdisplay; |
633 | dbidev->rotation = rotation; |
634 | |
635 | DRM_DEBUG_KMS("rotation = %u\n" , rotation); |
636 | |
637 | return 0; |
638 | } |
639 | EXPORT_SYMBOL(mipi_dbi_dev_init_with_formats); |
640 | |
641 | /** |
642 | * mipi_dbi_dev_init - MIPI DBI device initialization |
643 | * @dbidev: MIPI DBI device structure to initialize |
644 | * @funcs: Display pipe functions |
645 | * @mode: Display mode |
646 | * @rotation: Initial rotation in degrees Counter Clock Wise |
647 | * |
648 | * This function sets up a &drm_simple_display_pipe with a &drm_connector that |
649 | * has one fixed &drm_display_mode which is rotated according to @rotation. |
650 | * This mode is used to set the mode config min/max width/height properties. |
651 | * Additionally &mipi_dbi.tx_buf is allocated. |
652 | * |
653 | * Supported formats: Native RGB565 and emulated XRGB8888. |
654 | * |
655 | * Returns: |
656 | * Zero on success, negative error code on failure. |
657 | */ |
658 | int mipi_dbi_dev_init(struct mipi_dbi_dev *dbidev, |
659 | const struct drm_simple_display_pipe_funcs *funcs, |
660 | const struct drm_display_mode *mode, unsigned int rotation) |
661 | { |
662 | size_t bufsize = mode->vdisplay * mode->hdisplay * sizeof(u16); |
663 | |
664 | dbidev->drm.mode_config.preferred_depth = 16; |
665 | |
666 | return mipi_dbi_dev_init_with_formats(dbidev, funcs, mipi_dbi_formats, |
667 | ARRAY_SIZE(mipi_dbi_formats), mode, |
668 | rotation, bufsize); |
669 | } |
670 | EXPORT_SYMBOL(mipi_dbi_dev_init); |
671 | |
672 | /** |
673 | * mipi_dbi_hw_reset - Hardware reset of controller |
674 | * @dbi: MIPI DBI structure |
675 | * |
676 | * Reset controller if the &mipi_dbi->reset gpio is set. |
677 | */ |
678 | void mipi_dbi_hw_reset(struct mipi_dbi *dbi) |
679 | { |
680 | if (!dbi->reset) |
681 | return; |
682 | |
683 | gpiod_set_value_cansleep(desc: dbi->reset, value: 0); |
684 | usleep_range(min: 20, max: 1000); |
685 | gpiod_set_value_cansleep(desc: dbi->reset, value: 1); |
686 | msleep(msecs: 120); |
687 | } |
688 | EXPORT_SYMBOL(mipi_dbi_hw_reset); |
689 | |
690 | /** |
691 | * mipi_dbi_display_is_on - Check if display is on |
692 | * @dbi: MIPI DBI structure |
693 | * |
694 | * This function checks the Power Mode register (if readable) to see if |
695 | * display output is turned on. This can be used to see if the bootloader |
696 | * has already turned on the display avoiding flicker when the pipeline is |
697 | * enabled. |
698 | * |
699 | * Returns: |
700 | * true if the display can be verified to be on, false otherwise. |
701 | */ |
702 | bool mipi_dbi_display_is_on(struct mipi_dbi *dbi) |
703 | { |
704 | u8 val; |
705 | |
706 | if (mipi_dbi_command_read(dbi, MIPI_DCS_GET_POWER_MODE, &val)) |
707 | return false; |
708 | |
709 | val &= ~DCS_POWER_MODE_RESERVED_MASK; |
710 | |
711 | /* The poweron/reset value is 08h DCS_POWER_MODE_DISPLAY_NORMAL_MODE */ |
712 | if (val != (DCS_POWER_MODE_DISPLAY | |
713 | DCS_POWER_MODE_DISPLAY_NORMAL_MODE | DCS_POWER_MODE_SLEEP_MODE)) |
714 | return false; |
715 | |
716 | DRM_DEBUG_DRIVER("Display is ON\n" ); |
717 | |
718 | return true; |
719 | } |
720 | EXPORT_SYMBOL(mipi_dbi_display_is_on); |
721 | |
722 | static int mipi_dbi_poweron_reset_conditional(struct mipi_dbi_dev *dbidev, bool cond) |
723 | { |
724 | struct device *dev = dbidev->drm.dev; |
725 | struct mipi_dbi *dbi = &dbidev->dbi; |
726 | int ret; |
727 | |
728 | if (dbidev->regulator) { |
729 | ret = regulator_enable(regulator: dbidev->regulator); |
730 | if (ret) { |
731 | DRM_DEV_ERROR(dev, "Failed to enable regulator (%d)\n" , ret); |
732 | return ret; |
733 | } |
734 | } |
735 | |
736 | if (dbidev->io_regulator) { |
737 | ret = regulator_enable(regulator: dbidev->io_regulator); |
738 | if (ret) { |
739 | DRM_DEV_ERROR(dev, "Failed to enable I/O regulator (%d)\n" , ret); |
740 | if (dbidev->regulator) |
741 | regulator_disable(regulator: dbidev->regulator); |
742 | return ret; |
743 | } |
744 | } |
745 | |
746 | if (cond && mipi_dbi_display_is_on(dbi)) |
747 | return 1; |
748 | |
749 | mipi_dbi_hw_reset(dbi); |
750 | ret = mipi_dbi_command(dbi, MIPI_DCS_SOFT_RESET); |
751 | if (ret) { |
752 | DRM_DEV_ERROR(dev, "Failed to send reset command (%d)\n" , ret); |
753 | if (dbidev->regulator) |
754 | regulator_disable(regulator: dbidev->regulator); |
755 | if (dbidev->io_regulator) |
756 | regulator_disable(regulator: dbidev->io_regulator); |
757 | return ret; |
758 | } |
759 | |
760 | /* |
761 | * If we did a hw reset, we know the controller is in Sleep mode and |
762 | * per MIPI DSC spec should wait 5ms after soft reset. If we didn't, |
763 | * we assume worst case and wait 120ms. |
764 | */ |
765 | if (dbi->reset) |
766 | usleep_range(min: 5000, max: 20000); |
767 | else |
768 | msleep(msecs: 120); |
769 | |
770 | return 0; |
771 | } |
772 | |
773 | /** |
774 | * mipi_dbi_poweron_reset - MIPI DBI poweron and reset |
775 | * @dbidev: MIPI DBI device structure |
776 | * |
777 | * This function enables the regulator if used and does a hardware and software |
778 | * reset. |
779 | * |
780 | * Returns: |
781 | * Zero on success, or a negative error code. |
782 | */ |
783 | int mipi_dbi_poweron_reset(struct mipi_dbi_dev *dbidev) |
784 | { |
785 | return mipi_dbi_poweron_reset_conditional(dbidev, cond: false); |
786 | } |
787 | EXPORT_SYMBOL(mipi_dbi_poweron_reset); |
788 | |
789 | /** |
790 | * mipi_dbi_poweron_conditional_reset - MIPI DBI poweron and conditional reset |
791 | * @dbidev: MIPI DBI device structure |
792 | * |
793 | * This function enables the regulator if used and if the display is off, it |
794 | * does a hardware and software reset. If mipi_dbi_display_is_on() determines |
795 | * that the display is on, no reset is performed. |
796 | * |
797 | * Returns: |
798 | * Zero if the controller was reset, 1 if the display was already on, or a |
799 | * negative error code. |
800 | */ |
801 | int mipi_dbi_poweron_conditional_reset(struct mipi_dbi_dev *dbidev) |
802 | { |
803 | return mipi_dbi_poweron_reset_conditional(dbidev, cond: true); |
804 | } |
805 | EXPORT_SYMBOL(mipi_dbi_poweron_conditional_reset); |
806 | |
807 | #if IS_ENABLED(CONFIG_SPI) |
808 | |
809 | /** |
810 | * mipi_dbi_spi_cmd_max_speed - get the maximum SPI bus speed |
811 | * @spi: SPI device |
812 | * @len: The transfer buffer length. |
813 | * |
814 | * Many controllers have a max speed of 10MHz, but can be pushed way beyond |
815 | * that. Increase reliability by running pixel data at max speed and the rest |
816 | * at 10MHz, preventing transfer glitches from messing up the init settings. |
817 | */ |
818 | u32 mipi_dbi_spi_cmd_max_speed(struct spi_device *spi, size_t len) |
819 | { |
820 | if (len > 64) |
821 | return 0; /* use default */ |
822 | |
823 | return min_t(u32, 10000000, spi->max_speed_hz); |
824 | } |
825 | EXPORT_SYMBOL(mipi_dbi_spi_cmd_max_speed); |
826 | |
827 | static bool mipi_dbi_machine_little_endian(void) |
828 | { |
829 | #if defined(__LITTLE_ENDIAN) |
830 | return true; |
831 | #else |
832 | return false; |
833 | #endif |
834 | } |
835 | |
836 | /* |
837 | * MIPI DBI Type C Option 1 |
838 | * |
839 | * If the SPI controller doesn't have 9 bits per word support, |
840 | * use blocks of 9 bytes to send 8x 9-bit words using a 8-bit SPI transfer. |
841 | * Pad partial blocks with MIPI_DCS_NOP (zero). |
842 | * This is how the D/C bit (x) is added: |
843 | * x7654321 |
844 | * 0x765432 |
845 | * 10x76543 |
846 | * 210x7654 |
847 | * 3210x765 |
848 | * 43210x76 |
849 | * 543210x7 |
850 | * 6543210x |
851 | * 76543210 |
852 | */ |
853 | |
854 | static int mipi_dbi_spi1e_transfer(struct mipi_dbi *dbi, int dc, |
855 | const void *buf, size_t len, |
856 | unsigned int bpw) |
857 | { |
858 | bool swap_bytes = (bpw == 16 && mipi_dbi_machine_little_endian()); |
859 | size_t chunk, max_chunk = dbi->tx_buf9_len; |
860 | struct spi_device *spi = dbi->spi; |
861 | struct spi_transfer tr = { |
862 | .tx_buf = dbi->tx_buf9, |
863 | .bits_per_word = 8, |
864 | }; |
865 | struct spi_message m; |
866 | const u8 *src = buf; |
867 | int i, ret; |
868 | u8 *dst; |
869 | |
870 | if (drm_debug_enabled(DRM_UT_DRIVER)) |
871 | pr_debug("[drm:%s] dc=%d, max_chunk=%zu, transfers:\n" , |
872 | __func__, dc, max_chunk); |
873 | |
874 | tr.speed_hz = mipi_dbi_spi_cmd_max_speed(spi, len); |
875 | spi_message_init_with_transfers(m: &m, xfers: &tr, num_xfers: 1); |
876 | |
877 | if (!dc) { |
878 | if (WARN_ON_ONCE(len != 1)) |
879 | return -EINVAL; |
880 | |
881 | /* Command: pad no-op's (zeroes) at beginning of block */ |
882 | dst = dbi->tx_buf9; |
883 | memset(dst, 0, 9); |
884 | dst[8] = *src; |
885 | tr.len = 9; |
886 | |
887 | return spi_sync(spi, message: &m); |
888 | } |
889 | |
890 | /* max with room for adding one bit per byte */ |
891 | max_chunk = max_chunk / 9 * 8; |
892 | /* but no bigger than len */ |
893 | max_chunk = min(max_chunk, len); |
894 | /* 8 byte blocks */ |
895 | max_chunk = max_t(size_t, 8, max_chunk & ~0x7); |
896 | |
897 | while (len) { |
898 | size_t added = 0; |
899 | |
900 | chunk = min(len, max_chunk); |
901 | len -= chunk; |
902 | dst = dbi->tx_buf9; |
903 | |
904 | if (chunk < 8) { |
905 | u8 val, carry = 0; |
906 | |
907 | /* Data: pad no-op's (zeroes) at end of block */ |
908 | memset(dst, 0, 9); |
909 | |
910 | if (swap_bytes) { |
911 | for (i = 1; i < (chunk + 1); i++) { |
912 | val = src[1]; |
913 | *dst++ = carry | BIT(8 - i) | (val >> i); |
914 | carry = val << (8 - i); |
915 | i++; |
916 | val = src[0]; |
917 | *dst++ = carry | BIT(8 - i) | (val >> i); |
918 | carry = val << (8 - i); |
919 | src += 2; |
920 | } |
921 | *dst++ = carry; |
922 | } else { |
923 | for (i = 1; i < (chunk + 1); i++) { |
924 | val = *src++; |
925 | *dst++ = carry | BIT(8 - i) | (val >> i); |
926 | carry = val << (8 - i); |
927 | } |
928 | *dst++ = carry; |
929 | } |
930 | |
931 | chunk = 8; |
932 | added = 1; |
933 | } else { |
934 | for (i = 0; i < chunk; i += 8) { |
935 | if (swap_bytes) { |
936 | *dst++ = BIT(7) | (src[1] >> 1); |
937 | *dst++ = (src[1] << 7) | BIT(6) | (src[0] >> 2); |
938 | *dst++ = (src[0] << 6) | BIT(5) | (src[3] >> 3); |
939 | *dst++ = (src[3] << 5) | BIT(4) | (src[2] >> 4); |
940 | *dst++ = (src[2] << 4) | BIT(3) | (src[5] >> 5); |
941 | *dst++ = (src[5] << 3) | BIT(2) | (src[4] >> 6); |
942 | *dst++ = (src[4] << 2) | BIT(1) | (src[7] >> 7); |
943 | *dst++ = (src[7] << 1) | BIT(0); |
944 | *dst++ = src[6]; |
945 | } else { |
946 | *dst++ = BIT(7) | (src[0] >> 1); |
947 | *dst++ = (src[0] << 7) | BIT(6) | (src[1] >> 2); |
948 | *dst++ = (src[1] << 6) | BIT(5) | (src[2] >> 3); |
949 | *dst++ = (src[2] << 5) | BIT(4) | (src[3] >> 4); |
950 | *dst++ = (src[3] << 4) | BIT(3) | (src[4] >> 5); |
951 | *dst++ = (src[4] << 3) | BIT(2) | (src[5] >> 6); |
952 | *dst++ = (src[5] << 2) | BIT(1) | (src[6] >> 7); |
953 | *dst++ = (src[6] << 1) | BIT(0); |
954 | *dst++ = src[7]; |
955 | } |
956 | |
957 | src += 8; |
958 | added++; |
959 | } |
960 | } |
961 | |
962 | tr.len = chunk + added; |
963 | |
964 | ret = spi_sync(spi, message: &m); |
965 | if (ret) |
966 | return ret; |
967 | } |
968 | |
969 | return 0; |
970 | } |
971 | |
972 | static int mipi_dbi_spi1_transfer(struct mipi_dbi *dbi, int dc, |
973 | const void *buf, size_t len, |
974 | unsigned int bpw) |
975 | { |
976 | struct spi_device *spi = dbi->spi; |
977 | struct spi_transfer tr = { |
978 | .bits_per_word = 9, |
979 | }; |
980 | const u16 *src16 = buf; |
981 | const u8 *src8 = buf; |
982 | struct spi_message m; |
983 | size_t max_chunk; |
984 | u16 *dst16; |
985 | int ret; |
986 | |
987 | if (!spi_is_bpw_supported(spi, bpw: 9)) |
988 | return mipi_dbi_spi1e_transfer(dbi, dc, buf, len, bpw); |
989 | |
990 | tr.speed_hz = mipi_dbi_spi_cmd_max_speed(spi, len); |
991 | max_chunk = dbi->tx_buf9_len; |
992 | dst16 = dbi->tx_buf9; |
993 | |
994 | if (drm_debug_enabled(DRM_UT_DRIVER)) |
995 | pr_debug("[drm:%s] dc=%d, max_chunk=%zu, transfers:\n" , |
996 | __func__, dc, max_chunk); |
997 | |
998 | max_chunk = min(max_chunk / 2, len); |
999 | |
1000 | spi_message_init_with_transfers(m: &m, xfers: &tr, num_xfers: 1); |
1001 | tr.tx_buf = dst16; |
1002 | |
1003 | while (len) { |
1004 | size_t chunk = min(len, max_chunk); |
1005 | unsigned int i; |
1006 | |
1007 | if (bpw == 16 && mipi_dbi_machine_little_endian()) { |
1008 | for (i = 0; i < (chunk * 2); i += 2) { |
1009 | dst16[i] = *src16 >> 8; |
1010 | dst16[i + 1] = *src16++ & 0xFF; |
1011 | if (dc) { |
1012 | dst16[i] |= 0x0100; |
1013 | dst16[i + 1] |= 0x0100; |
1014 | } |
1015 | } |
1016 | } else { |
1017 | for (i = 0; i < chunk; i++) { |
1018 | dst16[i] = *src8++; |
1019 | if (dc) |
1020 | dst16[i] |= 0x0100; |
1021 | } |
1022 | } |
1023 | |
1024 | tr.len = chunk * 2; |
1025 | len -= chunk; |
1026 | |
1027 | ret = spi_sync(spi, message: &m); |
1028 | if (ret) |
1029 | return ret; |
1030 | } |
1031 | |
1032 | return 0; |
1033 | } |
1034 | |
1035 | static int mipi_dbi_typec1_command_read(struct mipi_dbi *dbi, u8 *cmd, |
1036 | u8 *data, size_t len) |
1037 | { |
1038 | struct spi_device *spi = dbi->spi; |
1039 | u32 speed_hz = min_t(u32, MIPI_DBI_MAX_SPI_READ_SPEED, |
1040 | spi->max_speed_hz / 2); |
1041 | struct spi_transfer tr[2] = { |
1042 | { |
1043 | .speed_hz = speed_hz, |
1044 | .bits_per_word = 9, |
1045 | .tx_buf = dbi->tx_buf9, |
1046 | .len = 2, |
1047 | }, { |
1048 | .speed_hz = speed_hz, |
1049 | .bits_per_word = 8, |
1050 | .len = len, |
1051 | .rx_buf = data, |
1052 | }, |
1053 | }; |
1054 | struct spi_message m; |
1055 | u16 *dst16; |
1056 | int ret; |
1057 | |
1058 | if (!len) |
1059 | return -EINVAL; |
1060 | |
1061 | if (!spi_is_bpw_supported(spi, bpw: 9)) { |
1062 | /* |
1063 | * FIXME: implement something like mipi_dbi_spi1e_transfer() but |
1064 | * for reads using emulation. |
1065 | */ |
1066 | dev_err(&spi->dev, |
1067 | "reading on host not supporting 9 bpw not yet implemented\n" ); |
1068 | return -EOPNOTSUPP; |
1069 | } |
1070 | |
1071 | /* |
1072 | * Turn the 8bit command into a 16bit version of the command in the |
1073 | * buffer. Only 9 bits of this will be used when executing the actual |
1074 | * transfer. |
1075 | */ |
1076 | dst16 = dbi->tx_buf9; |
1077 | dst16[0] = *cmd; |
1078 | |
1079 | spi_message_init_with_transfers(m: &m, xfers: tr, ARRAY_SIZE(tr)); |
1080 | ret = spi_sync(spi, message: &m); |
1081 | |
1082 | if (!ret) |
1083 | MIPI_DBI_DEBUG_COMMAND(*cmd, data, len); |
1084 | |
1085 | return ret; |
1086 | } |
1087 | |
1088 | static int mipi_dbi_typec1_command(struct mipi_dbi *dbi, u8 *cmd, |
1089 | u8 *parameters, size_t num) |
1090 | { |
1091 | unsigned int bpw = (*cmd == MIPI_DCS_WRITE_MEMORY_START) ? 16 : 8; |
1092 | int ret; |
1093 | |
1094 | if (mipi_dbi_command_is_read(dbi, cmd: *cmd)) |
1095 | return mipi_dbi_typec1_command_read(dbi, cmd, data: parameters, len: num); |
1096 | |
1097 | MIPI_DBI_DEBUG_COMMAND(*cmd, parameters, num); |
1098 | |
1099 | ret = mipi_dbi_spi1_transfer(dbi, dc: 0, buf: cmd, len: 1, bpw: 8); |
1100 | if (ret || !num) |
1101 | return ret; |
1102 | |
1103 | return mipi_dbi_spi1_transfer(dbi, dc: 1, buf: parameters, len: num, bpw); |
1104 | } |
1105 | |
1106 | /* MIPI DBI Type C Option 3 */ |
1107 | |
1108 | static int mipi_dbi_typec3_command_read(struct mipi_dbi *dbi, u8 *cmd, |
1109 | u8 *data, size_t len) |
1110 | { |
1111 | struct spi_device *spi = dbi->spi; |
1112 | u32 speed_hz = min_t(u32, MIPI_DBI_MAX_SPI_READ_SPEED, |
1113 | spi->max_speed_hz / 2); |
1114 | struct spi_transfer tr[2] = { |
1115 | { |
1116 | .speed_hz = speed_hz, |
1117 | .tx_buf = cmd, |
1118 | .len = 1, |
1119 | }, { |
1120 | .speed_hz = speed_hz, |
1121 | .len = len, |
1122 | }, |
1123 | }; |
1124 | struct spi_message m; |
1125 | u8 *buf; |
1126 | int ret; |
1127 | |
1128 | if (!len) |
1129 | return -EINVAL; |
1130 | |
1131 | /* |
1132 | * Support non-standard 24-bit and 32-bit Nokia read commands which |
1133 | * start with a dummy clock, so we need to read an extra byte. |
1134 | */ |
1135 | if (*cmd == MIPI_DCS_GET_DISPLAY_ID || |
1136 | *cmd == MIPI_DCS_GET_DISPLAY_STATUS) { |
1137 | if (!(len == 3 || len == 4)) |
1138 | return -EINVAL; |
1139 | |
1140 | tr[1].len = len + 1; |
1141 | } |
1142 | |
1143 | buf = kmalloc(size: tr[1].len, GFP_KERNEL); |
1144 | if (!buf) |
1145 | return -ENOMEM; |
1146 | |
1147 | tr[1].rx_buf = buf; |
1148 | |
1149 | spi_bus_lock(ctlr: spi->controller); |
1150 | gpiod_set_value_cansleep(desc: dbi->dc, value: 0); |
1151 | |
1152 | spi_message_init_with_transfers(m: &m, xfers: tr, ARRAY_SIZE(tr)); |
1153 | ret = spi_sync_locked(spi, message: &m); |
1154 | spi_bus_unlock(ctlr: spi->controller); |
1155 | if (ret) |
1156 | goto err_free; |
1157 | |
1158 | if (tr[1].len == len) { |
1159 | memcpy(data, buf, len); |
1160 | } else { |
1161 | unsigned int i; |
1162 | |
1163 | for (i = 0; i < len; i++) |
1164 | data[i] = (buf[i] << 1) | (buf[i + 1] >> 7); |
1165 | } |
1166 | |
1167 | MIPI_DBI_DEBUG_COMMAND(*cmd, data, len); |
1168 | |
1169 | err_free: |
1170 | kfree(objp: buf); |
1171 | |
1172 | return ret; |
1173 | } |
1174 | |
1175 | static int mipi_dbi_typec3_command(struct mipi_dbi *dbi, u8 *cmd, |
1176 | u8 *par, size_t num) |
1177 | { |
1178 | struct spi_device *spi = dbi->spi; |
1179 | unsigned int bpw = 8; |
1180 | u32 speed_hz; |
1181 | int ret; |
1182 | |
1183 | if (mipi_dbi_command_is_read(dbi, cmd: *cmd)) |
1184 | return mipi_dbi_typec3_command_read(dbi, cmd, data: par, len: num); |
1185 | |
1186 | MIPI_DBI_DEBUG_COMMAND(*cmd, par, num); |
1187 | |
1188 | spi_bus_lock(ctlr: spi->controller); |
1189 | gpiod_set_value_cansleep(desc: dbi->dc, value: 0); |
1190 | speed_hz = mipi_dbi_spi_cmd_max_speed(spi, 1); |
1191 | ret = mipi_dbi_spi_transfer(spi, speed_hz, bpw: 8, buf: cmd, len: 1); |
1192 | spi_bus_unlock(ctlr: spi->controller); |
1193 | if (ret || !num) |
1194 | return ret; |
1195 | |
1196 | if (*cmd == MIPI_DCS_WRITE_MEMORY_START && !dbi->swap_bytes) |
1197 | bpw = 16; |
1198 | |
1199 | spi_bus_lock(ctlr: spi->controller); |
1200 | gpiod_set_value_cansleep(desc: dbi->dc, value: 1); |
1201 | speed_hz = mipi_dbi_spi_cmd_max_speed(spi, num); |
1202 | ret = mipi_dbi_spi_transfer(spi, speed_hz, bpw, buf: par, len: num); |
1203 | spi_bus_unlock(ctlr: spi->controller); |
1204 | |
1205 | return ret; |
1206 | } |
1207 | |
1208 | /** |
1209 | * mipi_dbi_spi_init - Initialize MIPI DBI SPI interface |
1210 | * @spi: SPI device |
1211 | * @dbi: MIPI DBI structure to initialize |
1212 | * @dc: D/C gpio (optional) |
1213 | * |
1214 | * This function sets &mipi_dbi->command, enables &mipi_dbi->read_commands for the |
1215 | * usual read commands. It should be followed by a call to mipi_dbi_dev_init() or |
1216 | * a driver-specific init. |
1217 | * |
1218 | * If @dc is set, a Type C Option 3 interface is assumed, if not |
1219 | * Type C Option 1. |
1220 | * |
1221 | * If the SPI master driver doesn't support the necessary bits per word, |
1222 | * the following transformation is used: |
1223 | * |
1224 | * - 9-bit: reorder buffer as 9x 8-bit words, padded with no-op command. |
1225 | * - 16-bit: if big endian send as 8-bit, if little endian swap bytes |
1226 | * |
1227 | * Returns: |
1228 | * Zero on success, negative error code on failure. |
1229 | */ |
1230 | int mipi_dbi_spi_init(struct spi_device *spi, struct mipi_dbi *dbi, |
1231 | struct gpio_desc *dc) |
1232 | { |
1233 | struct device *dev = &spi->dev; |
1234 | int ret; |
1235 | |
1236 | /* |
1237 | * Even though it's not the SPI device that does DMA (the master does), |
1238 | * the dma mask is necessary for the dma_alloc_wc() in the GEM code |
1239 | * (e.g., drm_gem_dma_create()). The dma_addr returned will be a physical |
1240 | * address which might be different from the bus address, but this is |
1241 | * not a problem since the address will not be used. |
1242 | * The virtual address is used in the transfer and the SPI core |
1243 | * re-maps it on the SPI master device using the DMA streaming API |
1244 | * (spi_map_buf()). |
1245 | */ |
1246 | if (!dev->coherent_dma_mask) { |
1247 | ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32)); |
1248 | if (ret) { |
1249 | dev_warn(dev, "Failed to set dma mask %d\n" , ret); |
1250 | return ret; |
1251 | } |
1252 | } |
1253 | |
1254 | dbi->spi = spi; |
1255 | dbi->read_commands = mipi_dbi_dcs_read_commands; |
1256 | |
1257 | if (dc) { |
1258 | dbi->command = mipi_dbi_typec3_command; |
1259 | dbi->dc = dc; |
1260 | if (mipi_dbi_machine_little_endian() && !spi_is_bpw_supported(spi, bpw: 16)) |
1261 | dbi->swap_bytes = true; |
1262 | } else { |
1263 | dbi->command = mipi_dbi_typec1_command; |
1264 | dbi->tx_buf9_len = SZ_16K; |
1265 | dbi->tx_buf9 = devm_kmalloc(dev, size: dbi->tx_buf9_len, GFP_KERNEL); |
1266 | if (!dbi->tx_buf9) |
1267 | return -ENOMEM; |
1268 | } |
1269 | |
1270 | mutex_init(&dbi->cmdlock); |
1271 | |
1272 | DRM_DEBUG_DRIVER("SPI speed: %uMHz\n" , spi->max_speed_hz / 1000000); |
1273 | |
1274 | return 0; |
1275 | } |
1276 | EXPORT_SYMBOL(mipi_dbi_spi_init); |
1277 | |
1278 | /** |
1279 | * mipi_dbi_spi_transfer - SPI transfer helper |
1280 | * @spi: SPI device |
1281 | * @speed_hz: Override speed (optional) |
1282 | * @bpw: Bits per word |
1283 | * @buf: Buffer to transfer |
1284 | * @len: Buffer length |
1285 | * |
1286 | * This SPI transfer helper breaks up the transfer of @buf into chunks which |
1287 | * the SPI controller driver can handle. The SPI bus must be locked when |
1288 | * calling this. |
1289 | * |
1290 | * Returns: |
1291 | * Zero on success, negative error code on failure. |
1292 | */ |
1293 | int mipi_dbi_spi_transfer(struct spi_device *spi, u32 speed_hz, |
1294 | u8 bpw, const void *buf, size_t len) |
1295 | { |
1296 | size_t max_chunk = spi_max_transfer_size(spi); |
1297 | struct spi_transfer tr = { |
1298 | .bits_per_word = bpw, |
1299 | .speed_hz = speed_hz, |
1300 | }; |
1301 | struct spi_message m; |
1302 | size_t chunk; |
1303 | int ret; |
1304 | |
1305 | /* In __spi_validate, there's a validation that no partial transfers |
1306 | * are accepted (xfer->len % w_size must be zero). |
1307 | * Here we align max_chunk to multiple of 2 (16bits), |
1308 | * to prevent transfers from being rejected. |
1309 | */ |
1310 | max_chunk = ALIGN_DOWN(max_chunk, 2); |
1311 | |
1312 | spi_message_init_with_transfers(m: &m, xfers: &tr, num_xfers: 1); |
1313 | |
1314 | while (len) { |
1315 | chunk = min(len, max_chunk); |
1316 | |
1317 | tr.tx_buf = buf; |
1318 | tr.len = chunk; |
1319 | buf += chunk; |
1320 | len -= chunk; |
1321 | |
1322 | ret = spi_sync_locked(spi, message: &m); |
1323 | if (ret) |
1324 | return ret; |
1325 | } |
1326 | |
1327 | return 0; |
1328 | } |
1329 | EXPORT_SYMBOL(mipi_dbi_spi_transfer); |
1330 | |
1331 | #endif /* CONFIG_SPI */ |
1332 | |
1333 | #ifdef CONFIG_DEBUG_FS |
1334 | |
1335 | static ssize_t mipi_dbi_debugfs_command_write(struct file *file, |
1336 | const char __user *ubuf, |
1337 | size_t count, loff_t *ppos) |
1338 | { |
1339 | struct seq_file *m = file->private_data; |
1340 | struct mipi_dbi_dev *dbidev = m->private; |
1341 | u8 val, cmd = 0, parameters[64]; |
1342 | char *buf, *pos, *token; |
1343 | int i, ret, idx; |
1344 | |
1345 | if (!drm_dev_enter(dev: &dbidev->drm, idx: &idx)) |
1346 | return -ENODEV; |
1347 | |
1348 | buf = memdup_user_nul(ubuf, count); |
1349 | if (IS_ERR(ptr: buf)) { |
1350 | ret = PTR_ERR(ptr: buf); |
1351 | goto err_exit; |
1352 | } |
1353 | |
1354 | /* strip trailing whitespace */ |
1355 | for (i = count - 1; i > 0; i--) |
1356 | if (isspace(buf[i])) |
1357 | buf[i] = '\0'; |
1358 | else |
1359 | break; |
1360 | i = 0; |
1361 | pos = buf; |
1362 | while (pos) { |
1363 | token = strsep(&pos, " " ); |
1364 | if (!token) { |
1365 | ret = -EINVAL; |
1366 | goto err_free; |
1367 | } |
1368 | |
1369 | ret = kstrtou8(s: token, base: 16, res: &val); |
1370 | if (ret < 0) |
1371 | goto err_free; |
1372 | |
1373 | if (token == buf) |
1374 | cmd = val; |
1375 | else |
1376 | parameters[i++] = val; |
1377 | |
1378 | if (i == 64) { |
1379 | ret = -E2BIG; |
1380 | goto err_free; |
1381 | } |
1382 | } |
1383 | |
1384 | ret = mipi_dbi_command_buf(&dbidev->dbi, cmd, parameters, i); |
1385 | |
1386 | err_free: |
1387 | kfree(objp: buf); |
1388 | err_exit: |
1389 | drm_dev_exit(idx); |
1390 | |
1391 | return ret < 0 ? ret : count; |
1392 | } |
1393 | |
1394 | static int mipi_dbi_debugfs_command_show(struct seq_file *m, void *unused) |
1395 | { |
1396 | struct mipi_dbi_dev *dbidev = m->private; |
1397 | struct mipi_dbi *dbi = &dbidev->dbi; |
1398 | u8 cmd, val[4]; |
1399 | int ret, idx; |
1400 | size_t len; |
1401 | |
1402 | if (!drm_dev_enter(dev: &dbidev->drm, idx: &idx)) |
1403 | return -ENODEV; |
1404 | |
1405 | for (cmd = 0; cmd < 255; cmd++) { |
1406 | if (!mipi_dbi_command_is_read(dbi, cmd)) |
1407 | continue; |
1408 | |
1409 | switch (cmd) { |
1410 | case MIPI_DCS_READ_MEMORY_START: |
1411 | case MIPI_DCS_READ_MEMORY_CONTINUE: |
1412 | len = 2; |
1413 | break; |
1414 | case MIPI_DCS_GET_DISPLAY_ID: |
1415 | len = 3; |
1416 | break; |
1417 | case MIPI_DCS_GET_DISPLAY_STATUS: |
1418 | len = 4; |
1419 | break; |
1420 | default: |
1421 | len = 1; |
1422 | break; |
1423 | } |
1424 | |
1425 | seq_printf(m, fmt: "%02x: " , cmd); |
1426 | ret = mipi_dbi_command_buf(dbi, cmd, val, len); |
1427 | if (ret) { |
1428 | seq_puts(m, s: "XX\n" ); |
1429 | continue; |
1430 | } |
1431 | seq_printf(m, fmt: "%*phN\n" , (int)len, val); |
1432 | } |
1433 | |
1434 | drm_dev_exit(idx); |
1435 | |
1436 | return 0; |
1437 | } |
1438 | |
1439 | static int mipi_dbi_debugfs_command_open(struct inode *inode, |
1440 | struct file *file) |
1441 | { |
1442 | return single_open(file, mipi_dbi_debugfs_command_show, |
1443 | inode->i_private); |
1444 | } |
1445 | |
1446 | static const struct file_operations mipi_dbi_debugfs_command_fops = { |
1447 | .owner = THIS_MODULE, |
1448 | .open = mipi_dbi_debugfs_command_open, |
1449 | .read = seq_read, |
1450 | .llseek = seq_lseek, |
1451 | .release = single_release, |
1452 | .write = mipi_dbi_debugfs_command_write, |
1453 | }; |
1454 | |
1455 | /** |
1456 | * mipi_dbi_debugfs_init - Create debugfs entries |
1457 | * @minor: DRM minor |
1458 | * |
1459 | * This function creates a 'command' debugfs file for sending commands to the |
1460 | * controller or getting the read command values. |
1461 | * Drivers can use this as their &drm_driver->debugfs_init callback. |
1462 | * |
1463 | */ |
1464 | void mipi_dbi_debugfs_init(struct drm_minor *minor) |
1465 | { |
1466 | struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(drm: minor->dev); |
1467 | umode_t mode = S_IFREG | S_IWUSR; |
1468 | |
1469 | if (dbidev->dbi.read_commands) |
1470 | mode |= S_IRUGO; |
1471 | debugfs_create_file(name: "command" , mode, parent: minor->debugfs_root, data: dbidev, |
1472 | fops: &mipi_dbi_debugfs_command_fops); |
1473 | } |
1474 | EXPORT_SYMBOL(mipi_dbi_debugfs_init); |
1475 | |
1476 | #endif |
1477 | |
1478 | MODULE_LICENSE("GPL" ); |
1479 | |