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