0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/backlight.h>
0009 #include <linux/debugfs.h>
0010 #include <linux/delay.h>
0011 #include <linux/gpio/consumer.h>
0012 #include <linux/module.h>
0013 #include <linux/regulator/consumer.h>
0014 #include <linux/spi/spi.h>
0015
0016 #include <drm/drm_connector.h>
0017 #include <drm/drm_damage_helper.h>
0018 #include <drm/drm_drv.h>
0019 #include <drm/drm_file.h>
0020 #include <drm/drm_format_helper.h>
0021 #include <drm/drm_fourcc.h>
0022 #include <drm/drm_framebuffer.h>
0023 #include <drm/drm_gem.h>
0024 #include <drm/drm_gem_framebuffer_helper.h>
0025 #include <drm/drm_mipi_dbi.h>
0026 #include <drm/drm_modes.h>
0027 #include <drm/drm_probe_helper.h>
0028 #include <drm/drm_rect.h>
0029 #include <video/mipi_display.h>
0030
0031 #define MIPI_DBI_MAX_SPI_READ_SPEED 2000000
0032
0033 #define DCS_POWER_MODE_DISPLAY BIT(2)
0034 #define DCS_POWER_MODE_DISPLAY_NORMAL_MODE BIT(3)
0035 #define DCS_POWER_MODE_SLEEP_MODE BIT(4)
0036 #define DCS_POWER_MODE_PARTIAL_MODE BIT(5)
0037 #define DCS_POWER_MODE_IDLE_MODE BIT(6)
0038 #define DCS_POWER_MODE_RESERVED_MASK (BIT(0) | BIT(1) | BIT(7))
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069 #define MIPI_DBI_DEBUG_COMMAND(cmd, data, len) \
0070 ({ \
0071 if (!len) \
0072 DRM_DEBUG_DRIVER("cmd=%02x\n", cmd); \
0073 else if (len <= 32) \
0074 DRM_DEBUG_DRIVER("cmd=%02x, par=%*ph\n", cmd, (int)len, data);\
0075 else \
0076 DRM_DEBUG_DRIVER("cmd=%02x, len=%zu\n", cmd, len); \
0077 })
0078
0079 static const u8 mipi_dbi_dcs_read_commands[] = {
0080 MIPI_DCS_GET_DISPLAY_ID,
0081 MIPI_DCS_GET_RED_CHANNEL,
0082 MIPI_DCS_GET_GREEN_CHANNEL,
0083 MIPI_DCS_GET_BLUE_CHANNEL,
0084 MIPI_DCS_GET_DISPLAY_STATUS,
0085 MIPI_DCS_GET_POWER_MODE,
0086 MIPI_DCS_GET_ADDRESS_MODE,
0087 MIPI_DCS_GET_PIXEL_FORMAT,
0088 MIPI_DCS_GET_DISPLAY_MODE,
0089 MIPI_DCS_GET_SIGNAL_MODE,
0090 MIPI_DCS_GET_DIAGNOSTIC_RESULT,
0091 MIPI_DCS_READ_MEMORY_START,
0092 MIPI_DCS_READ_MEMORY_CONTINUE,
0093 MIPI_DCS_GET_SCANLINE,
0094 MIPI_DCS_GET_DISPLAY_BRIGHTNESS,
0095 MIPI_DCS_GET_CONTROL_DISPLAY,
0096 MIPI_DCS_GET_POWER_SAVE,
0097 MIPI_DCS_GET_CABC_MIN_BRIGHTNESS,
0098 MIPI_DCS_READ_DDB_START,
0099 MIPI_DCS_READ_DDB_CONTINUE,
0100 0,
0101 };
0102
0103 static bool mipi_dbi_command_is_read(struct mipi_dbi *dbi, u8 cmd)
0104 {
0105 unsigned int i;
0106
0107 if (!dbi->read_commands)
0108 return false;
0109
0110 for (i = 0; i < 0xff; i++) {
0111 if (!dbi->read_commands[i])
0112 return false;
0113 if (cmd == dbi->read_commands[i])
0114 return true;
0115 }
0116
0117 return false;
0118 }
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131 int mipi_dbi_command_read(struct mipi_dbi *dbi, u8 cmd, u8 *val)
0132 {
0133 if (!dbi->read_commands)
0134 return -EACCES;
0135
0136 if (!mipi_dbi_command_is_read(dbi, cmd))
0137 return -EINVAL;
0138
0139 return mipi_dbi_command_buf(dbi, cmd, val, 1);
0140 }
0141 EXPORT_SYMBOL(mipi_dbi_command_read);
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153 int mipi_dbi_command_buf(struct mipi_dbi *dbi, u8 cmd, u8 *data, size_t len)
0154 {
0155 u8 *cmdbuf;
0156 int ret;
0157
0158
0159 cmdbuf = kmemdup(&cmd, 1, GFP_KERNEL);
0160 if (!cmdbuf)
0161 return -ENOMEM;
0162
0163 mutex_lock(&dbi->cmdlock);
0164 ret = dbi->command(dbi, cmdbuf, data, len);
0165 mutex_unlock(&dbi->cmdlock);
0166
0167 kfree(cmdbuf);
0168
0169 return ret;
0170 }
0171 EXPORT_SYMBOL(mipi_dbi_command_buf);
0172
0173
0174 int mipi_dbi_command_stackbuf(struct mipi_dbi *dbi, u8 cmd, const u8 *data,
0175 size_t len)
0176 {
0177 u8 *buf;
0178 int ret;
0179
0180 buf = kmemdup(data, len, GFP_KERNEL);
0181 if (!buf)
0182 return -ENOMEM;
0183
0184 ret = mipi_dbi_command_buf(dbi, cmd, buf, len);
0185
0186 kfree(buf);
0187
0188 return ret;
0189 }
0190 EXPORT_SYMBOL(mipi_dbi_command_stackbuf);
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202 int mipi_dbi_buf_copy(void *dst, struct drm_framebuffer *fb,
0203 struct drm_rect *clip, bool swap)
0204 {
0205 struct drm_gem_object *gem = drm_gem_fb_get_obj(fb, 0);
0206 struct iosys_map map[DRM_FORMAT_MAX_PLANES];
0207 struct iosys_map data[DRM_FORMAT_MAX_PLANES];
0208 void *src;
0209 int ret;
0210
0211 ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);
0212 if (ret)
0213 return ret;
0214
0215 ret = drm_gem_fb_vmap(fb, map, data);
0216 if (ret)
0217 goto out_drm_gem_fb_end_cpu_access;
0218 src = data[0].vaddr;
0219
0220 switch (fb->format->format) {
0221 case DRM_FORMAT_RGB565:
0222 if (swap)
0223 drm_fb_swab(dst, 0, src, fb, clip, !gem->import_attach);
0224 else
0225 drm_fb_memcpy(dst, 0, src, fb, clip);
0226 break;
0227 case DRM_FORMAT_XRGB8888:
0228 drm_fb_xrgb8888_to_rgb565(dst, 0, src, fb, clip, swap);
0229 break;
0230 default:
0231 drm_err_once(fb->dev, "Format is not supported: %p4cc\n",
0232 &fb->format->format);
0233 ret = -EINVAL;
0234 }
0235
0236 drm_gem_fb_vunmap(fb, map);
0237 out_drm_gem_fb_end_cpu_access:
0238 drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
0239
0240 return ret;
0241 }
0242 EXPORT_SYMBOL(mipi_dbi_buf_copy);
0243
0244 static void mipi_dbi_set_window_address(struct mipi_dbi_dev *dbidev,
0245 unsigned int xs, unsigned int xe,
0246 unsigned int ys, unsigned int ye)
0247 {
0248 struct mipi_dbi *dbi = &dbidev->dbi;
0249
0250 xs += dbidev->left_offset;
0251 xe += dbidev->left_offset;
0252 ys += dbidev->top_offset;
0253 ye += dbidev->top_offset;
0254
0255 mipi_dbi_command(dbi, MIPI_DCS_SET_COLUMN_ADDRESS, (xs >> 8) & 0xff,
0256 xs & 0xff, (xe >> 8) & 0xff, xe & 0xff);
0257 mipi_dbi_command(dbi, MIPI_DCS_SET_PAGE_ADDRESS, (ys >> 8) & 0xff,
0258 ys & 0xff, (ye >> 8) & 0xff, ye & 0xff);
0259 }
0260
0261 static void mipi_dbi_fb_dirty(struct drm_framebuffer *fb, struct drm_rect *rect)
0262 {
0263 struct iosys_map map[DRM_FORMAT_MAX_PLANES];
0264 struct iosys_map data[DRM_FORMAT_MAX_PLANES];
0265 struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(fb->dev);
0266 unsigned int height = rect->y2 - rect->y1;
0267 unsigned int width = rect->x2 - rect->x1;
0268 struct mipi_dbi *dbi = &dbidev->dbi;
0269 bool swap = dbi->swap_bytes;
0270 int idx, ret = 0;
0271 bool full;
0272 void *tr;
0273
0274 if (WARN_ON(!fb))
0275 return;
0276
0277 if (!drm_dev_enter(fb->dev, &idx))
0278 return;
0279
0280 ret = drm_gem_fb_vmap(fb, map, data);
0281 if (ret)
0282 goto err_drm_dev_exit;
0283
0284 full = width == fb->width && height == fb->height;
0285
0286 DRM_DEBUG_KMS("Flushing [FB:%d] " DRM_RECT_FMT "\n", fb->base.id, DRM_RECT_ARG(rect));
0287
0288 if (!dbi->dc || !full || swap ||
0289 fb->format->format == DRM_FORMAT_XRGB8888) {
0290 tr = dbidev->tx_buf;
0291 ret = mipi_dbi_buf_copy(dbidev->tx_buf, fb, rect, swap);
0292 if (ret)
0293 goto err_msg;
0294 } else {
0295 tr = data[0].vaddr;
0296 }
0297
0298 mipi_dbi_set_window_address(dbidev, rect->x1, rect->x2 - 1, rect->y1,
0299 rect->y2 - 1);
0300
0301 ret = mipi_dbi_command_buf(dbi, MIPI_DCS_WRITE_MEMORY_START, tr,
0302 width * height * 2);
0303 err_msg:
0304 if (ret)
0305 drm_err_once(fb->dev, "Failed to update display %d\n", ret);
0306
0307 drm_gem_fb_vunmap(fb, map);
0308
0309 err_drm_dev_exit:
0310 drm_dev_exit(idx);
0311 }
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321 void mipi_dbi_pipe_update(struct drm_simple_display_pipe *pipe,
0322 struct drm_plane_state *old_state)
0323 {
0324 struct drm_plane_state *state = pipe->plane.state;
0325 struct drm_rect rect;
0326
0327 if (!pipe->crtc.state->active)
0328 return;
0329
0330 if (drm_atomic_helper_damage_merged(old_state, state, &rect))
0331 mipi_dbi_fb_dirty(state->fb, &rect);
0332 }
0333 EXPORT_SYMBOL(mipi_dbi_pipe_update);
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348 void mipi_dbi_enable_flush(struct mipi_dbi_dev *dbidev,
0349 struct drm_crtc_state *crtc_state,
0350 struct drm_plane_state *plane_state)
0351 {
0352 struct drm_framebuffer *fb = plane_state->fb;
0353 struct drm_rect rect = {
0354 .x1 = 0,
0355 .x2 = fb->width,
0356 .y1 = 0,
0357 .y2 = fb->height,
0358 };
0359 int idx;
0360
0361 if (!drm_dev_enter(&dbidev->drm, &idx))
0362 return;
0363
0364 mipi_dbi_fb_dirty(fb, &rect);
0365 backlight_enable(dbidev->backlight);
0366
0367 drm_dev_exit(idx);
0368 }
0369 EXPORT_SYMBOL(mipi_dbi_enable_flush);
0370
0371 static void mipi_dbi_blank(struct mipi_dbi_dev *dbidev)
0372 {
0373 struct drm_device *drm = &dbidev->drm;
0374 u16 height = drm->mode_config.min_height;
0375 u16 width = drm->mode_config.min_width;
0376 struct mipi_dbi *dbi = &dbidev->dbi;
0377 size_t len = width * height * 2;
0378 int idx;
0379
0380 if (!drm_dev_enter(drm, &idx))
0381 return;
0382
0383 memset(dbidev->tx_buf, 0, len);
0384
0385 mipi_dbi_set_window_address(dbidev, 0, width - 1, 0, height - 1);
0386 mipi_dbi_command_buf(dbi, MIPI_DCS_WRITE_MEMORY_START,
0387 (u8 *)dbidev->tx_buf, len);
0388
0389 drm_dev_exit(idx);
0390 }
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400 void mipi_dbi_pipe_disable(struct drm_simple_display_pipe *pipe)
0401 {
0402 struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(pipe->crtc.dev);
0403
0404 DRM_DEBUG_KMS("\n");
0405
0406 if (dbidev->backlight)
0407 backlight_disable(dbidev->backlight);
0408 else
0409 mipi_dbi_blank(dbidev);
0410
0411 if (dbidev->regulator)
0412 regulator_disable(dbidev->regulator);
0413 }
0414 EXPORT_SYMBOL(mipi_dbi_pipe_disable);
0415
0416 static int mipi_dbi_connector_get_modes(struct drm_connector *connector)
0417 {
0418 struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(connector->dev);
0419 struct drm_display_mode *mode;
0420
0421 mode = drm_mode_duplicate(connector->dev, &dbidev->mode);
0422 if (!mode) {
0423 DRM_ERROR("Failed to duplicate mode\n");
0424 return 0;
0425 }
0426
0427 if (mode->name[0] == '\0')
0428 drm_mode_set_name(mode);
0429
0430 mode->type |= DRM_MODE_TYPE_PREFERRED;
0431 drm_mode_probed_add(connector, mode);
0432
0433 if (mode->width_mm) {
0434 connector->display_info.width_mm = mode->width_mm;
0435 connector->display_info.height_mm = mode->height_mm;
0436 }
0437
0438 return 1;
0439 }
0440
0441 static const struct drm_connector_helper_funcs mipi_dbi_connector_hfuncs = {
0442 .get_modes = mipi_dbi_connector_get_modes,
0443 };
0444
0445 static const struct drm_connector_funcs mipi_dbi_connector_funcs = {
0446 .reset = drm_atomic_helper_connector_reset,
0447 .fill_modes = drm_helper_probe_single_connector_modes,
0448 .destroy = drm_connector_cleanup,
0449 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
0450 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
0451 };
0452
0453 static int mipi_dbi_rotate_mode(struct drm_display_mode *mode,
0454 unsigned int rotation)
0455 {
0456 if (rotation == 0 || rotation == 180) {
0457 return 0;
0458 } else if (rotation == 90 || rotation == 270) {
0459 swap(mode->hdisplay, mode->vdisplay);
0460 swap(mode->hsync_start, mode->vsync_start);
0461 swap(mode->hsync_end, mode->vsync_end);
0462 swap(mode->htotal, mode->vtotal);
0463 swap(mode->width_mm, mode->height_mm);
0464 return 0;
0465 } else {
0466 return -EINVAL;
0467 }
0468 }
0469
0470 static const struct drm_mode_config_funcs mipi_dbi_mode_config_funcs = {
0471 .fb_create = drm_gem_fb_create_with_dirty,
0472 .atomic_check = drm_atomic_helper_check,
0473 .atomic_commit = drm_atomic_helper_commit,
0474 };
0475
0476 static const uint32_t mipi_dbi_formats[] = {
0477 DRM_FORMAT_RGB565,
0478 DRM_FORMAT_XRGB8888,
0479 };
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504 int mipi_dbi_dev_init_with_formats(struct mipi_dbi_dev *dbidev,
0505 const struct drm_simple_display_pipe_funcs *funcs,
0506 const uint32_t *formats, unsigned int format_count,
0507 const struct drm_display_mode *mode,
0508 unsigned int rotation, size_t tx_buf_size)
0509 {
0510 static const uint64_t modifiers[] = {
0511 DRM_FORMAT_MOD_LINEAR,
0512 DRM_FORMAT_MOD_INVALID
0513 };
0514 struct drm_device *drm = &dbidev->drm;
0515 int ret;
0516
0517 if (!dbidev->dbi.command)
0518 return -EINVAL;
0519
0520 ret = drmm_mode_config_init(drm);
0521 if (ret)
0522 return ret;
0523
0524 dbidev->tx_buf = devm_kmalloc(drm->dev, tx_buf_size, GFP_KERNEL);
0525 if (!dbidev->tx_buf)
0526 return -ENOMEM;
0527
0528 drm_mode_copy(&dbidev->mode, mode);
0529 ret = mipi_dbi_rotate_mode(&dbidev->mode, rotation);
0530 if (ret) {
0531 DRM_ERROR("Illegal rotation value %u\n", rotation);
0532 return -EINVAL;
0533 }
0534
0535 drm_connector_helper_add(&dbidev->connector, &mipi_dbi_connector_hfuncs);
0536 ret = drm_connector_init(drm, &dbidev->connector, &mipi_dbi_connector_funcs,
0537 DRM_MODE_CONNECTOR_SPI);
0538 if (ret)
0539 return ret;
0540
0541 ret = drm_simple_display_pipe_init(drm, &dbidev->pipe, funcs, formats, format_count,
0542 modifiers, &dbidev->connector);
0543 if (ret)
0544 return ret;
0545
0546 drm_plane_enable_fb_damage_clips(&dbidev->pipe.plane);
0547
0548 drm->mode_config.funcs = &mipi_dbi_mode_config_funcs;
0549 drm->mode_config.min_width = dbidev->mode.hdisplay;
0550 drm->mode_config.max_width = dbidev->mode.hdisplay;
0551 drm->mode_config.min_height = dbidev->mode.vdisplay;
0552 drm->mode_config.max_height = dbidev->mode.vdisplay;
0553 dbidev->rotation = rotation;
0554
0555 DRM_DEBUG_KMS("rotation = %u\n", rotation);
0556
0557 return 0;
0558 }
0559 EXPORT_SYMBOL(mipi_dbi_dev_init_with_formats);
0560
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572
0573
0574
0575
0576
0577
0578 int mipi_dbi_dev_init(struct mipi_dbi_dev *dbidev,
0579 const struct drm_simple_display_pipe_funcs *funcs,
0580 const struct drm_display_mode *mode, unsigned int rotation)
0581 {
0582 size_t bufsize = mode->vdisplay * mode->hdisplay * sizeof(u16);
0583
0584 dbidev->drm.mode_config.preferred_depth = 16;
0585
0586 return mipi_dbi_dev_init_with_formats(dbidev, funcs, mipi_dbi_formats,
0587 ARRAY_SIZE(mipi_dbi_formats), mode,
0588 rotation, bufsize);
0589 }
0590 EXPORT_SYMBOL(mipi_dbi_dev_init);
0591
0592
0593
0594
0595
0596
0597
0598 void mipi_dbi_hw_reset(struct mipi_dbi *dbi)
0599 {
0600 if (!dbi->reset)
0601 return;
0602
0603 gpiod_set_value_cansleep(dbi->reset, 0);
0604 usleep_range(20, 1000);
0605 gpiod_set_value_cansleep(dbi->reset, 1);
0606 msleep(120);
0607 }
0608 EXPORT_SYMBOL(mipi_dbi_hw_reset);
0609
0610
0611
0612
0613
0614
0615
0616
0617
0618
0619
0620
0621
0622 bool mipi_dbi_display_is_on(struct mipi_dbi *dbi)
0623 {
0624 u8 val;
0625
0626 if (mipi_dbi_command_read(dbi, MIPI_DCS_GET_POWER_MODE, &val))
0627 return false;
0628
0629 val &= ~DCS_POWER_MODE_RESERVED_MASK;
0630
0631
0632 if (val != (DCS_POWER_MODE_DISPLAY |
0633 DCS_POWER_MODE_DISPLAY_NORMAL_MODE | DCS_POWER_MODE_SLEEP_MODE))
0634 return false;
0635
0636 DRM_DEBUG_DRIVER("Display is ON\n");
0637
0638 return true;
0639 }
0640 EXPORT_SYMBOL(mipi_dbi_display_is_on);
0641
0642 static int mipi_dbi_poweron_reset_conditional(struct mipi_dbi_dev *dbidev, bool cond)
0643 {
0644 struct device *dev = dbidev->drm.dev;
0645 struct mipi_dbi *dbi = &dbidev->dbi;
0646 int ret;
0647
0648 if (dbidev->regulator) {
0649 ret = regulator_enable(dbidev->regulator);
0650 if (ret) {
0651 DRM_DEV_ERROR(dev, "Failed to enable regulator (%d)\n", ret);
0652 return ret;
0653 }
0654 }
0655
0656 if (cond && mipi_dbi_display_is_on(dbi))
0657 return 1;
0658
0659 mipi_dbi_hw_reset(dbi);
0660 ret = mipi_dbi_command(dbi, MIPI_DCS_SOFT_RESET);
0661 if (ret) {
0662 DRM_DEV_ERROR(dev, "Failed to send reset command (%d)\n", ret);
0663 if (dbidev->regulator)
0664 regulator_disable(dbidev->regulator);
0665 return ret;
0666 }
0667
0668
0669
0670
0671
0672
0673 if (dbi->reset)
0674 usleep_range(5000, 20000);
0675 else
0676 msleep(120);
0677
0678 return 0;
0679 }
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690
0691 int mipi_dbi_poweron_reset(struct mipi_dbi_dev *dbidev)
0692 {
0693 return mipi_dbi_poweron_reset_conditional(dbidev, false);
0694 }
0695 EXPORT_SYMBOL(mipi_dbi_poweron_reset);
0696
0697
0698
0699
0700
0701
0702
0703
0704
0705
0706
0707
0708
0709 int mipi_dbi_poweron_conditional_reset(struct mipi_dbi_dev *dbidev)
0710 {
0711 return mipi_dbi_poweron_reset_conditional(dbidev, true);
0712 }
0713 EXPORT_SYMBOL(mipi_dbi_poweron_conditional_reset);
0714
0715 #if IS_ENABLED(CONFIG_SPI)
0716
0717
0718
0719
0720
0721
0722
0723
0724
0725
0726 u32 mipi_dbi_spi_cmd_max_speed(struct spi_device *spi, size_t len)
0727 {
0728 if (len > 64)
0729 return 0;
0730
0731 return min_t(u32, 10000000, spi->max_speed_hz);
0732 }
0733 EXPORT_SYMBOL(mipi_dbi_spi_cmd_max_speed);
0734
0735 static bool mipi_dbi_machine_little_endian(void)
0736 {
0737 #if defined(__LITTLE_ENDIAN)
0738 return true;
0739 #else
0740 return false;
0741 #endif
0742 }
0743
0744
0745
0746
0747
0748
0749
0750
0751
0752
0753
0754
0755
0756
0757
0758
0759
0760
0761
0762 static int mipi_dbi_spi1e_transfer(struct mipi_dbi *dbi, int dc,
0763 const void *buf, size_t len,
0764 unsigned int bpw)
0765 {
0766 bool swap_bytes = (bpw == 16 && mipi_dbi_machine_little_endian());
0767 size_t chunk, max_chunk = dbi->tx_buf9_len;
0768 struct spi_device *spi = dbi->spi;
0769 struct spi_transfer tr = {
0770 .tx_buf = dbi->tx_buf9,
0771 .bits_per_word = 8,
0772 };
0773 struct spi_message m;
0774 const u8 *src = buf;
0775 int i, ret;
0776 u8 *dst;
0777
0778 if (drm_debug_enabled(DRM_UT_DRIVER))
0779 pr_debug("[drm:%s] dc=%d, max_chunk=%zu, transfers:\n",
0780 __func__, dc, max_chunk);
0781
0782 tr.speed_hz = mipi_dbi_spi_cmd_max_speed(spi, len);
0783 spi_message_init_with_transfers(&m, &tr, 1);
0784
0785 if (!dc) {
0786 if (WARN_ON_ONCE(len != 1))
0787 return -EINVAL;
0788
0789
0790 dst = dbi->tx_buf9;
0791 memset(dst, 0, 9);
0792 dst[8] = *src;
0793 tr.len = 9;
0794
0795 return spi_sync(spi, &m);
0796 }
0797
0798
0799 max_chunk = max_chunk / 9 * 8;
0800
0801 max_chunk = min(max_chunk, len);
0802
0803 max_chunk = max_t(size_t, 8, max_chunk & ~0x7);
0804
0805 while (len) {
0806 size_t added = 0;
0807
0808 chunk = min(len, max_chunk);
0809 len -= chunk;
0810 dst = dbi->tx_buf9;
0811
0812 if (chunk < 8) {
0813 u8 val, carry = 0;
0814
0815
0816 memset(dst, 0, 9);
0817
0818 if (swap_bytes) {
0819 for (i = 1; i < (chunk + 1); i++) {
0820 val = src[1];
0821 *dst++ = carry | BIT(8 - i) | (val >> i);
0822 carry = val << (8 - i);
0823 i++;
0824 val = src[0];
0825 *dst++ = carry | BIT(8 - i) | (val >> i);
0826 carry = val << (8 - i);
0827 src += 2;
0828 }
0829 *dst++ = carry;
0830 } else {
0831 for (i = 1; i < (chunk + 1); i++) {
0832 val = *src++;
0833 *dst++ = carry | BIT(8 - i) | (val >> i);
0834 carry = val << (8 - i);
0835 }
0836 *dst++ = carry;
0837 }
0838
0839 chunk = 8;
0840 added = 1;
0841 } else {
0842 for (i = 0; i < chunk; i += 8) {
0843 if (swap_bytes) {
0844 *dst++ = BIT(7) | (src[1] >> 1);
0845 *dst++ = (src[1] << 7) | BIT(6) | (src[0] >> 2);
0846 *dst++ = (src[0] << 6) | BIT(5) | (src[3] >> 3);
0847 *dst++ = (src[3] << 5) | BIT(4) | (src[2] >> 4);
0848 *dst++ = (src[2] << 4) | BIT(3) | (src[5] >> 5);
0849 *dst++ = (src[5] << 3) | BIT(2) | (src[4] >> 6);
0850 *dst++ = (src[4] << 2) | BIT(1) | (src[7] >> 7);
0851 *dst++ = (src[7] << 1) | BIT(0);
0852 *dst++ = src[6];
0853 } else {
0854 *dst++ = BIT(7) | (src[0] >> 1);
0855 *dst++ = (src[0] << 7) | BIT(6) | (src[1] >> 2);
0856 *dst++ = (src[1] << 6) | BIT(5) | (src[2] >> 3);
0857 *dst++ = (src[2] << 5) | BIT(4) | (src[3] >> 4);
0858 *dst++ = (src[3] << 4) | BIT(3) | (src[4] >> 5);
0859 *dst++ = (src[4] << 3) | BIT(2) | (src[5] >> 6);
0860 *dst++ = (src[5] << 2) | BIT(1) | (src[6] >> 7);
0861 *dst++ = (src[6] << 1) | BIT(0);
0862 *dst++ = src[7];
0863 }
0864
0865 src += 8;
0866 added++;
0867 }
0868 }
0869
0870 tr.len = chunk + added;
0871
0872 ret = spi_sync(spi, &m);
0873 if (ret)
0874 return ret;
0875 }
0876
0877 return 0;
0878 }
0879
0880 static int mipi_dbi_spi1_transfer(struct mipi_dbi *dbi, int dc,
0881 const void *buf, size_t len,
0882 unsigned int bpw)
0883 {
0884 struct spi_device *spi = dbi->spi;
0885 struct spi_transfer tr = {
0886 .bits_per_word = 9,
0887 };
0888 const u16 *src16 = buf;
0889 const u8 *src8 = buf;
0890 struct spi_message m;
0891 size_t max_chunk;
0892 u16 *dst16;
0893 int ret;
0894
0895 if (!spi_is_bpw_supported(spi, 9))
0896 return mipi_dbi_spi1e_transfer(dbi, dc, buf, len, bpw);
0897
0898 tr.speed_hz = mipi_dbi_spi_cmd_max_speed(spi, len);
0899 max_chunk = dbi->tx_buf9_len;
0900 dst16 = dbi->tx_buf9;
0901
0902 if (drm_debug_enabled(DRM_UT_DRIVER))
0903 pr_debug("[drm:%s] dc=%d, max_chunk=%zu, transfers:\n",
0904 __func__, dc, max_chunk);
0905
0906 max_chunk = min(max_chunk / 2, len);
0907
0908 spi_message_init_with_transfers(&m, &tr, 1);
0909 tr.tx_buf = dst16;
0910
0911 while (len) {
0912 size_t chunk = min(len, max_chunk);
0913 unsigned int i;
0914
0915 if (bpw == 16 && mipi_dbi_machine_little_endian()) {
0916 for (i = 0; i < (chunk * 2); i += 2) {
0917 dst16[i] = *src16 >> 8;
0918 dst16[i + 1] = *src16++ & 0xFF;
0919 if (dc) {
0920 dst16[i] |= 0x0100;
0921 dst16[i + 1] |= 0x0100;
0922 }
0923 }
0924 } else {
0925 for (i = 0; i < chunk; i++) {
0926 dst16[i] = *src8++;
0927 if (dc)
0928 dst16[i] |= 0x0100;
0929 }
0930 }
0931
0932 tr.len = chunk * 2;
0933 len -= chunk;
0934
0935 ret = spi_sync(spi, &m);
0936 if (ret)
0937 return ret;
0938 }
0939
0940 return 0;
0941 }
0942
0943 static int mipi_dbi_typec1_command_read(struct mipi_dbi *dbi, u8 *cmd,
0944 u8 *data, size_t len)
0945 {
0946 struct spi_device *spi = dbi->spi;
0947 u32 speed_hz = min_t(u32, MIPI_DBI_MAX_SPI_READ_SPEED,
0948 spi->max_speed_hz / 2);
0949 struct spi_transfer tr[2] = {
0950 {
0951 .speed_hz = speed_hz,
0952 .bits_per_word = 9,
0953 .tx_buf = dbi->tx_buf9,
0954 .len = 2,
0955 }, {
0956 .speed_hz = speed_hz,
0957 .bits_per_word = 8,
0958 .len = len,
0959 .rx_buf = data,
0960 },
0961 };
0962 struct spi_message m;
0963 u16 *dst16;
0964 int ret;
0965
0966 if (!len)
0967 return -EINVAL;
0968
0969 if (!spi_is_bpw_supported(spi, 9)) {
0970
0971
0972
0973
0974 dev_err(&spi->dev,
0975 "reading on host not supporting 9 bpw not yet implemented\n");
0976 return -EOPNOTSUPP;
0977 }
0978
0979
0980
0981
0982
0983
0984 dst16 = dbi->tx_buf9;
0985 dst16[0] = *cmd;
0986
0987 spi_message_init_with_transfers(&m, tr, ARRAY_SIZE(tr));
0988 ret = spi_sync(spi, &m);
0989
0990 if (!ret)
0991 MIPI_DBI_DEBUG_COMMAND(*cmd, data, len);
0992
0993 return ret;
0994 }
0995
0996 static int mipi_dbi_typec1_command(struct mipi_dbi *dbi, u8 *cmd,
0997 u8 *parameters, size_t num)
0998 {
0999 unsigned int bpw = (*cmd == MIPI_DCS_WRITE_MEMORY_START) ? 16 : 8;
1000 int ret;
1001
1002 if (mipi_dbi_command_is_read(dbi, *cmd))
1003 return mipi_dbi_typec1_command_read(dbi, cmd, parameters, num);
1004
1005 MIPI_DBI_DEBUG_COMMAND(*cmd, parameters, num);
1006
1007 ret = mipi_dbi_spi1_transfer(dbi, 0, cmd, 1, 8);
1008 if (ret || !num)
1009 return ret;
1010
1011 return mipi_dbi_spi1_transfer(dbi, 1, parameters, num, bpw);
1012 }
1013
1014
1015
1016 static int mipi_dbi_typec3_command_read(struct mipi_dbi *dbi, u8 *cmd,
1017 u8 *data, size_t len)
1018 {
1019 struct spi_device *spi = dbi->spi;
1020 u32 speed_hz = min_t(u32, MIPI_DBI_MAX_SPI_READ_SPEED,
1021 spi->max_speed_hz / 2);
1022 struct spi_transfer tr[2] = {
1023 {
1024 .speed_hz = speed_hz,
1025 .tx_buf = cmd,
1026 .len = 1,
1027 }, {
1028 .speed_hz = speed_hz,
1029 .len = len,
1030 },
1031 };
1032 struct spi_message m;
1033 u8 *buf;
1034 int ret;
1035
1036 if (!len)
1037 return -EINVAL;
1038
1039
1040
1041
1042
1043 if (*cmd == MIPI_DCS_GET_DISPLAY_ID ||
1044 *cmd == MIPI_DCS_GET_DISPLAY_STATUS) {
1045 if (!(len == 3 || len == 4))
1046 return -EINVAL;
1047
1048 tr[1].len = len + 1;
1049 }
1050
1051 buf = kmalloc(tr[1].len, GFP_KERNEL);
1052 if (!buf)
1053 return -ENOMEM;
1054
1055 tr[1].rx_buf = buf;
1056 gpiod_set_value_cansleep(dbi->dc, 0);
1057
1058 spi_message_init_with_transfers(&m, tr, ARRAY_SIZE(tr));
1059 ret = spi_sync(spi, &m);
1060 if (ret)
1061 goto err_free;
1062
1063 if (tr[1].len == len) {
1064 memcpy(data, buf, len);
1065 } else {
1066 unsigned int i;
1067
1068 for (i = 0; i < len; i++)
1069 data[i] = (buf[i] << 1) | (buf[i + 1] >> 7);
1070 }
1071
1072 MIPI_DBI_DEBUG_COMMAND(*cmd, data, len);
1073
1074 err_free:
1075 kfree(buf);
1076
1077 return ret;
1078 }
1079
1080 static int mipi_dbi_typec3_command(struct mipi_dbi *dbi, u8 *cmd,
1081 u8 *par, size_t num)
1082 {
1083 struct spi_device *spi = dbi->spi;
1084 unsigned int bpw = 8;
1085 u32 speed_hz;
1086 int ret;
1087
1088 if (mipi_dbi_command_is_read(dbi, *cmd))
1089 return mipi_dbi_typec3_command_read(dbi, cmd, par, num);
1090
1091 MIPI_DBI_DEBUG_COMMAND(*cmd, par, num);
1092
1093 gpiod_set_value_cansleep(dbi->dc, 0);
1094 speed_hz = mipi_dbi_spi_cmd_max_speed(spi, 1);
1095 ret = mipi_dbi_spi_transfer(spi, speed_hz, 8, cmd, 1);
1096 if (ret || !num)
1097 return ret;
1098
1099 if (*cmd == MIPI_DCS_WRITE_MEMORY_START && !dbi->swap_bytes)
1100 bpw = 16;
1101
1102 gpiod_set_value_cansleep(dbi->dc, 1);
1103 speed_hz = mipi_dbi_spi_cmd_max_speed(spi, num);
1104
1105 return mipi_dbi_spi_transfer(spi, speed_hz, bpw, par, num);
1106 }
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130 int mipi_dbi_spi_init(struct spi_device *spi, struct mipi_dbi *dbi,
1131 struct gpio_desc *dc)
1132 {
1133 struct device *dev = &spi->dev;
1134 int ret;
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146 if (!dev->coherent_dma_mask) {
1147 ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
1148 if (ret) {
1149 dev_warn(dev, "Failed to set dma mask %d\n", ret);
1150 return ret;
1151 }
1152 }
1153
1154 dbi->spi = spi;
1155 dbi->read_commands = mipi_dbi_dcs_read_commands;
1156
1157 if (dc) {
1158 dbi->command = mipi_dbi_typec3_command;
1159 dbi->dc = dc;
1160 if (mipi_dbi_machine_little_endian() && !spi_is_bpw_supported(spi, 16))
1161 dbi->swap_bytes = true;
1162 } else {
1163 dbi->command = mipi_dbi_typec1_command;
1164 dbi->tx_buf9_len = SZ_16K;
1165 dbi->tx_buf9 = devm_kmalloc(dev, dbi->tx_buf9_len, GFP_KERNEL);
1166 if (!dbi->tx_buf9)
1167 return -ENOMEM;
1168 }
1169
1170 mutex_init(&dbi->cmdlock);
1171
1172 DRM_DEBUG_DRIVER("SPI speed: %uMHz\n", spi->max_speed_hz / 1000000);
1173
1174 return 0;
1175 }
1176 EXPORT_SYMBOL(mipi_dbi_spi_init);
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192 int mipi_dbi_spi_transfer(struct spi_device *spi, u32 speed_hz,
1193 u8 bpw, const void *buf, size_t len)
1194 {
1195 size_t max_chunk = spi_max_transfer_size(spi);
1196 struct spi_transfer tr = {
1197 .bits_per_word = bpw,
1198 .speed_hz = speed_hz,
1199 };
1200 struct spi_message m;
1201 size_t chunk;
1202 int ret;
1203
1204
1205
1206
1207
1208
1209 max_chunk = ALIGN_DOWN(max_chunk, 2);
1210
1211 spi_message_init_with_transfers(&m, &tr, 1);
1212
1213 while (len) {
1214 chunk = min(len, max_chunk);
1215
1216 tr.tx_buf = buf;
1217 tr.len = chunk;
1218 buf += chunk;
1219 len -= chunk;
1220
1221 ret = spi_sync(spi, &m);
1222 if (ret)
1223 return ret;
1224 }
1225
1226 return 0;
1227 }
1228 EXPORT_SYMBOL(mipi_dbi_spi_transfer);
1229
1230 #endif
1231
1232 #ifdef CONFIG_DEBUG_FS
1233
1234 static ssize_t mipi_dbi_debugfs_command_write(struct file *file,
1235 const char __user *ubuf,
1236 size_t count, loff_t *ppos)
1237 {
1238 struct seq_file *m = file->private_data;
1239 struct mipi_dbi_dev *dbidev = m->private;
1240 u8 val, cmd = 0, parameters[64];
1241 char *buf, *pos, *token;
1242 int i, ret, idx;
1243
1244 if (!drm_dev_enter(&dbidev->drm, &idx))
1245 return -ENODEV;
1246
1247 buf = memdup_user_nul(ubuf, count);
1248 if (IS_ERR(buf)) {
1249 ret = PTR_ERR(buf);
1250 goto err_exit;
1251 }
1252
1253
1254 for (i = count - 1; i > 0; i--)
1255 if (isspace(buf[i]))
1256 buf[i] = '\0';
1257 else
1258 break;
1259 i = 0;
1260 pos = buf;
1261 while (pos) {
1262 token = strsep(&pos, " ");
1263 if (!token) {
1264 ret = -EINVAL;
1265 goto err_free;
1266 }
1267
1268 ret = kstrtou8(token, 16, &val);
1269 if (ret < 0)
1270 goto err_free;
1271
1272 if (token == buf)
1273 cmd = val;
1274 else
1275 parameters[i++] = val;
1276
1277 if (i == 64) {
1278 ret = -E2BIG;
1279 goto err_free;
1280 }
1281 }
1282
1283 ret = mipi_dbi_command_buf(&dbidev->dbi, cmd, parameters, i);
1284
1285 err_free:
1286 kfree(buf);
1287 err_exit:
1288 drm_dev_exit(idx);
1289
1290 return ret < 0 ? ret : count;
1291 }
1292
1293 static int mipi_dbi_debugfs_command_show(struct seq_file *m, void *unused)
1294 {
1295 struct mipi_dbi_dev *dbidev = m->private;
1296 struct mipi_dbi *dbi = &dbidev->dbi;
1297 u8 cmd, val[4];
1298 int ret, idx;
1299 size_t len;
1300
1301 if (!drm_dev_enter(&dbidev->drm, &idx))
1302 return -ENODEV;
1303
1304 for (cmd = 0; cmd < 255; cmd++) {
1305 if (!mipi_dbi_command_is_read(dbi, cmd))
1306 continue;
1307
1308 switch (cmd) {
1309 case MIPI_DCS_READ_MEMORY_START:
1310 case MIPI_DCS_READ_MEMORY_CONTINUE:
1311 len = 2;
1312 break;
1313 case MIPI_DCS_GET_DISPLAY_ID:
1314 len = 3;
1315 break;
1316 case MIPI_DCS_GET_DISPLAY_STATUS:
1317 len = 4;
1318 break;
1319 default:
1320 len = 1;
1321 break;
1322 }
1323
1324 seq_printf(m, "%02x: ", cmd);
1325 ret = mipi_dbi_command_buf(dbi, cmd, val, len);
1326 if (ret) {
1327 seq_puts(m, "XX\n");
1328 continue;
1329 }
1330 seq_printf(m, "%*phN\n", (int)len, val);
1331 }
1332
1333 drm_dev_exit(idx);
1334
1335 return 0;
1336 }
1337
1338 static int mipi_dbi_debugfs_command_open(struct inode *inode,
1339 struct file *file)
1340 {
1341 return single_open(file, mipi_dbi_debugfs_command_show,
1342 inode->i_private);
1343 }
1344
1345 static const struct file_operations mipi_dbi_debugfs_command_fops = {
1346 .owner = THIS_MODULE,
1347 .open = mipi_dbi_debugfs_command_open,
1348 .read = seq_read,
1349 .llseek = seq_lseek,
1350 .release = single_release,
1351 .write = mipi_dbi_debugfs_command_write,
1352 };
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363 void mipi_dbi_debugfs_init(struct drm_minor *minor)
1364 {
1365 struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(minor->dev);
1366 umode_t mode = S_IFREG | S_IWUSR;
1367
1368 if (dbidev->dbi.read_commands)
1369 mode |= S_IRUGO;
1370 debugfs_create_file("command", mode, minor->debugfs_root, dbidev,
1371 &mipi_dbi_debugfs_command_fops);
1372 }
1373 EXPORT_SYMBOL(mipi_dbi_debugfs_init);
1374
1375 #endif
1376
1377 MODULE_LICENSE("GPL");