1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2017 Free Electrons 4 */ 5 6 #include <linux/delay.h> 7 #include <linux/gpio/consumer.h> 8 #include <linux/module.h> 9 #include <linux/regulator/consumer.h> 10 #include <linux/spi/spi.h> 11 12 #include <video/mipi_display.h> 13 #include <linux/media-bus-format.h> 14 15 #include <drm/drm_device.h> 16 #include <drm/drm_modes.h> 17 #include <drm/drm_panel.h> 18 19 #define ST7789V_RAMCTRL_CMD 0xb0 20 #define ST7789V_RAMCTRL_RM_RGB BIT(4) 21 #define ST7789V_RAMCTRL_DM_RGB BIT(0) 22 #define ST7789V_RAMCTRL_MAGIC (3 << 6) 23 #define ST7789V_RAMCTRL_EPF(n) (((n) & 3) << 4) 24 25 #define ST7789V_RGBCTRL_CMD 0xb1 26 #define ST7789V_RGBCTRL_WO BIT(7) 27 #define ST7789V_RGBCTRL_RCM(n) (((n) & 3) << 5) 28 #define ST7789V_RGBCTRL_VSYNC_HIGH BIT(3) 29 #define ST7789V_RGBCTRL_HSYNC_HIGH BIT(2) 30 #define ST7789V_RGBCTRL_PCLK_FALLING BIT(1) 31 #define ST7789V_RGBCTRL_DE_LOW BIT(0) 32 #define ST7789V_RGBCTRL_VBP(n) ((n) & 0x7f) 33 #define ST7789V_RGBCTRL_HBP(n) ((n) & 0x1f) 34 35 #define ST7789V_PORCTRL_CMD 0xb2 36 #define ST7789V_PORCTRL_IDLE_BP(n) (((n) & 0xf) << 4) 37 #define ST7789V_PORCTRL_IDLE_FP(n) ((n) & 0xf) 38 #define ST7789V_PORCTRL_PARTIAL_BP(n) (((n) & 0xf) << 4) 39 #define ST7789V_PORCTRL_PARTIAL_FP(n) ((n) & 0xf) 40 41 #define ST7789V_GCTRL_CMD 0xb7 42 #define ST7789V_GCTRL_VGHS(n) (((n) & 7) << 4) 43 #define ST7789V_GCTRL_VGLS(n) ((n) & 7) 44 45 #define ST7789V_VCOMS_CMD 0xbb 46 47 #define ST7789V_LCMCTRL_CMD 0xc0 48 #define ST7789V_LCMCTRL_XBGR BIT(5) 49 #define ST7789V_LCMCTRL_XMX BIT(3) 50 #define ST7789V_LCMCTRL_XMH BIT(2) 51 52 #define ST7789V_VDVVRHEN_CMD 0xc2 53 #define ST7789V_VDVVRHEN_CMDEN BIT(0) 54 55 #define ST7789V_VRHS_CMD 0xc3 56 57 #define ST7789V_VDVS_CMD 0xc4 58 59 #define ST7789V_FRCTRL2_CMD 0xc6 60 61 #define ST7789V_PWCTRL1_CMD 0xd0 62 #define ST7789V_PWCTRL1_MAGIC 0xa4 63 #define ST7789V_PWCTRL1_AVDD(n) (((n) & 3) << 6) 64 #define ST7789V_PWCTRL1_AVCL(n) (((n) & 3) << 4) 65 #define ST7789V_PWCTRL1_VDS(n) ((n) & 3) 66 67 #define ST7789V_PVGAMCTRL_CMD 0xe0 68 #define ST7789V_PVGAMCTRL_JP0(n) (((n) & 3) << 4) 69 #define ST7789V_PVGAMCTRL_JP1(n) (((n) & 3) << 4) 70 #define ST7789V_PVGAMCTRL_VP0(n) ((n) & 0xf) 71 #define ST7789V_PVGAMCTRL_VP1(n) ((n) & 0x3f) 72 #define ST7789V_PVGAMCTRL_VP2(n) ((n) & 0x3f) 73 #define ST7789V_PVGAMCTRL_VP4(n) ((n) & 0x1f) 74 #define ST7789V_PVGAMCTRL_VP6(n) ((n) & 0x1f) 75 #define ST7789V_PVGAMCTRL_VP13(n) ((n) & 0xf) 76 #define ST7789V_PVGAMCTRL_VP20(n) ((n) & 0x7f) 77 #define ST7789V_PVGAMCTRL_VP27(n) ((n) & 7) 78 #define ST7789V_PVGAMCTRL_VP36(n) (((n) & 7) << 4) 79 #define ST7789V_PVGAMCTRL_VP43(n) ((n) & 0x7f) 80 #define ST7789V_PVGAMCTRL_VP50(n) ((n) & 0xf) 81 #define ST7789V_PVGAMCTRL_VP57(n) ((n) & 0x1f) 82 #define ST7789V_PVGAMCTRL_VP59(n) ((n) & 0x1f) 83 #define ST7789V_PVGAMCTRL_VP61(n) ((n) & 0x3f) 84 #define ST7789V_PVGAMCTRL_VP62(n) ((n) & 0x3f) 85 #define ST7789V_PVGAMCTRL_VP63(n) (((n) & 0xf) << 4) 86 87 #define ST7789V_NVGAMCTRL_CMD 0xe1 88 #define ST7789V_NVGAMCTRL_JN0(n) (((n) & 3) << 4) 89 #define ST7789V_NVGAMCTRL_JN1(n) (((n) & 3) << 4) 90 #define ST7789V_NVGAMCTRL_VN0(n) ((n) & 0xf) 91 #define ST7789V_NVGAMCTRL_VN1(n) ((n) & 0x3f) 92 #define ST7789V_NVGAMCTRL_VN2(n) ((n) & 0x3f) 93 #define ST7789V_NVGAMCTRL_VN4(n) ((n) & 0x1f) 94 #define ST7789V_NVGAMCTRL_VN6(n) ((n) & 0x1f) 95 #define ST7789V_NVGAMCTRL_VN13(n) ((n) & 0xf) 96 #define ST7789V_NVGAMCTRL_VN20(n) ((n) & 0x7f) 97 #define ST7789V_NVGAMCTRL_VN27(n) ((n) & 7) 98 #define ST7789V_NVGAMCTRL_VN36(n) (((n) & 7) << 4) 99 #define ST7789V_NVGAMCTRL_VN43(n) ((n) & 0x7f) 100 #define ST7789V_NVGAMCTRL_VN50(n) ((n) & 0xf) 101 #define ST7789V_NVGAMCTRL_VN57(n) ((n) & 0x1f) 102 #define ST7789V_NVGAMCTRL_VN59(n) ((n) & 0x1f) 103 #define ST7789V_NVGAMCTRL_VN61(n) ((n) & 0x3f) 104 #define ST7789V_NVGAMCTRL_VN62(n) ((n) & 0x3f) 105 #define ST7789V_NVGAMCTRL_VN63(n) (((n) & 0xf) << 4) 106 107 #define ST7789V_TEST(val, func) \ 108 do { \ 109 if ((val = (func))) \ 110 return val; \ 111 } while (0) 112 113 #define ST7789V_IDS { 0x85, 0x85, 0x52 } 114 #define ST7789V_IDS_SIZE 3 115 116 struct st7789_panel_info { 117 const struct drm_display_mode *mode; 118 u32 bus_format; 119 u32 bus_flags; 120 bool invert_mode; 121 bool partial_mode; 122 u16 partial_start; 123 u16 partial_end; 124 }; 125 126 struct st7789v { 127 struct drm_panel panel; 128 const struct st7789_panel_info *info; 129 struct spi_device *spi; 130 struct gpio_desc *reset; 131 struct regulator *power; 132 enum drm_panel_orientation orientation; 133 }; 134 135 enum st7789v_prefix { 136 ST7789V_COMMAND = 0, 137 ST7789V_DATA = 1, 138 }; 139 140 static inline struct st7789v *panel_to_st7789v(struct drm_panel *panel) 141 { 142 return container_of(panel, struct st7789v, panel); 143 } 144 145 static int st7789v_spi_write(struct st7789v *ctx, enum st7789v_prefix prefix, 146 u8 data) 147 { 148 struct spi_transfer xfer = { }; 149 u16 txbuf = ((prefix & 1) << 8) | data; 150 151 xfer.tx_buf = &txbuf; 152 xfer.len = sizeof(txbuf); 153 154 return spi_sync_transfer(ctx->spi, &xfer, 1); 155 } 156 157 static int st7789v_write_command(struct st7789v *ctx, u8 cmd) 158 { 159 return st7789v_spi_write(ctx, ST7789V_COMMAND, cmd); 160 } 161 162 static int st7789v_write_data(struct st7789v *ctx, u8 cmd) 163 { 164 return st7789v_spi_write(ctx, ST7789V_DATA, cmd); 165 } 166 167 static int st7789v_read_data(struct st7789v *ctx, u8 cmd, u8 *buf, 168 unsigned int len) 169 { 170 struct spi_transfer xfer[2] = { }; 171 struct spi_message msg; 172 u16 txbuf = ((ST7789V_COMMAND & 1) << 8) | cmd; 173 u16 rxbuf[4] = {}; 174 u8 bit9 = 0; 175 int ret, i; 176 177 switch (len) { 178 case 1: 179 case 3: 180 case 4: 181 break; 182 default: 183 return -EOPNOTSUPP; 184 } 185 186 spi_message_init(&msg); 187 188 xfer[0].tx_buf = &txbuf; 189 xfer[0].len = sizeof(txbuf); 190 spi_message_add_tail(&xfer[0], &msg); 191 192 xfer[1].rx_buf = rxbuf; 193 xfer[1].len = len * 2; 194 spi_message_add_tail(&xfer[1], &msg); 195 196 ret = spi_sync(ctx->spi, &msg); 197 if (ret) 198 return ret; 199 200 for (i = 0; i < len; i++) { 201 buf[i] = rxbuf[i] >> i | (bit9 << (9 - i)); 202 if (i) 203 bit9 = rxbuf[i] & GENMASK(i - 1, 0); 204 } 205 206 return 0; 207 } 208 209 static int st7789v_check_id(struct drm_panel *panel) 210 { 211 const u8 st7789v_ids[ST7789V_IDS_SIZE] = ST7789V_IDS; 212 struct st7789v *ctx = panel_to_st7789v(panel); 213 bool invalid_ids = false; 214 int ret, i; 215 u8 ids[3]; 216 217 if (ctx->spi->mode & SPI_NO_RX) 218 return 0; 219 220 ret = st7789v_read_data(ctx, MIPI_DCS_GET_DISPLAY_ID, ids, ST7789V_IDS_SIZE); 221 if (ret) 222 return ret; 223 224 for (i = 0; i < ST7789V_IDS_SIZE; i++) { 225 if (ids[i] != st7789v_ids[i]) { 226 invalid_ids = true; 227 break; 228 } 229 } 230 231 if (invalid_ids) 232 return -EIO; 233 234 return 0; 235 } 236 237 static const struct drm_display_mode default_mode = { 238 .clock = 7000, 239 .hdisplay = 240, 240 .hsync_start = 240 + 38, 241 .hsync_end = 240 + 38 + 10, 242 .htotal = 240 + 38 + 10 + 10, 243 .vdisplay = 320, 244 .vsync_start = 320 + 8, 245 .vsync_end = 320 + 8 + 4, 246 .vtotal = 320 + 8 + 4 + 4, 247 .width_mm = 61, 248 .height_mm = 103, 249 .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC, 250 }; 251 252 static const struct drm_display_mode t28cp45tn89_mode = { 253 .clock = 6008, 254 .hdisplay = 240, 255 .hsync_start = 240 + 38, 256 .hsync_end = 240 + 38 + 10, 257 .htotal = 240 + 38 + 10 + 10, 258 .vdisplay = 320, 259 .vsync_start = 320 + 8, 260 .vsync_end = 320 + 8 + 4, 261 .vtotal = 320 + 8 + 4 + 4, 262 .width_mm = 43, 263 .height_mm = 57, 264 .flags = DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC, 265 }; 266 267 static const struct drm_display_mode et028013dma_mode = { 268 .clock = 3000, 269 .hdisplay = 240, 270 .hsync_start = 240 + 38, 271 .hsync_end = 240 + 38 + 10, 272 .htotal = 240 + 38 + 10 + 10, 273 .vdisplay = 320, 274 .vsync_start = 320 + 8, 275 .vsync_end = 320 + 8 + 4, 276 .vtotal = 320 + 8 + 4 + 4, 277 .width_mm = 43, 278 .height_mm = 58, 279 .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC, 280 }; 281 282 static const struct drm_display_mode jt240mhqs_hwt_ek_e3_mode = { 283 .clock = 6000, 284 .hdisplay = 240, 285 .hsync_start = 240 + 28, 286 .hsync_end = 240 + 28 + 10, 287 .htotal = 240 + 28 + 10 + 10, 288 .vdisplay = 280, 289 .vsync_start = 280 + 8, 290 .vsync_end = 280 + 8 + 4, 291 .vtotal = 280 + 8 + 4 + 4, 292 .width_mm = 43, 293 .height_mm = 37, 294 .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC, 295 }; 296 297 static const struct st7789_panel_info default_panel = { 298 .mode = &default_mode, 299 .invert_mode = true, 300 .bus_format = MEDIA_BUS_FMT_RGB666_1X18, 301 .bus_flags = DRM_BUS_FLAG_DE_HIGH | 302 DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE, 303 }; 304 305 static const struct st7789_panel_info t28cp45tn89_panel = { 306 .mode = &t28cp45tn89_mode, 307 .invert_mode = false, 308 .bus_format = MEDIA_BUS_FMT_RGB565_1X16, 309 .bus_flags = DRM_BUS_FLAG_DE_HIGH | 310 DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE, 311 }; 312 313 static const struct st7789_panel_info et028013dma_panel = { 314 .mode = &et028013dma_mode, 315 .invert_mode = true, 316 .bus_format = MEDIA_BUS_FMT_RGB666_1X18, 317 .bus_flags = DRM_BUS_FLAG_DE_HIGH | 318 DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE, 319 }; 320 321 static const struct st7789_panel_info jt240mhqs_hwt_ek_e3_panel = { 322 .mode = &jt240mhqs_hwt_ek_e3_mode, 323 .invert_mode = true, 324 .bus_format = MEDIA_BUS_FMT_RGB666_1X18, 325 .bus_flags = DRM_BUS_FLAG_DE_HIGH | 326 DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE, 327 .partial_mode = true, 328 .partial_start = 38, 329 .partial_end = 318, 330 }; 331 332 static int st7789v_get_modes(struct drm_panel *panel, 333 struct drm_connector *connector) 334 { 335 struct st7789v *ctx = panel_to_st7789v(panel); 336 struct drm_display_mode *mode; 337 338 mode = drm_mode_duplicate(connector->dev, ctx->info->mode); 339 if (!mode) { 340 dev_err(panel->dev, "failed to add mode %ux%u@%u\n", 341 ctx->info->mode->hdisplay, ctx->info->mode->vdisplay, 342 drm_mode_vrefresh(ctx->info->mode)); 343 return -ENOMEM; 344 } 345 346 drm_mode_set_name(mode); 347 348 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; 349 drm_mode_probed_add(connector, mode); 350 351 connector->display_info.bpc = 6; 352 connector->display_info.width_mm = ctx->info->mode->width_mm; 353 connector->display_info.height_mm = ctx->info->mode->height_mm; 354 connector->display_info.bus_flags = ctx->info->bus_flags; 355 drm_display_info_set_bus_formats(&connector->display_info, 356 &ctx->info->bus_format, 1); 357 358 /* 359 * TODO: Remove once all drm drivers call 360 * drm_connector_set_orientation_from_panel() 361 */ 362 drm_connector_set_panel_orientation(connector, ctx->orientation); 363 364 return 1; 365 } 366 367 static enum drm_panel_orientation st7789v_get_orientation(struct drm_panel *p) 368 { 369 struct st7789v *ctx = panel_to_st7789v(p); 370 371 return ctx->orientation; 372 } 373 374 static int st7789v_prepare(struct drm_panel *panel) 375 { 376 struct st7789v *ctx = panel_to_st7789v(panel); 377 u8 mode, pixel_fmt, polarity; 378 int ret; 379 380 if (!ctx->info->partial_mode) 381 mode = ST7789V_RGBCTRL_WO; 382 else 383 mode = 0; 384 385 switch (ctx->info->bus_format) { 386 case MEDIA_BUS_FMT_RGB666_1X18: 387 pixel_fmt = MIPI_DCS_PIXEL_FMT_18BIT; 388 break; 389 case MEDIA_BUS_FMT_RGB565_1X16: 390 pixel_fmt = MIPI_DCS_PIXEL_FMT_16BIT; 391 break; 392 default: 393 dev_err(panel->dev, "unsupported bus format: %d\n", 394 ctx->info->bus_format); 395 return -EINVAL; 396 } 397 398 pixel_fmt = (pixel_fmt << 4) | pixel_fmt; 399 400 polarity = 0; 401 if (ctx->info->mode->flags & DRM_MODE_FLAG_PVSYNC) 402 polarity |= ST7789V_RGBCTRL_VSYNC_HIGH; 403 if (ctx->info->mode->flags & DRM_MODE_FLAG_PHSYNC) 404 polarity |= ST7789V_RGBCTRL_HSYNC_HIGH; 405 if (ctx->info->bus_flags & DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE) 406 polarity |= ST7789V_RGBCTRL_PCLK_FALLING; 407 if (ctx->info->bus_flags & DRM_BUS_FLAG_DE_LOW) 408 polarity |= ST7789V_RGBCTRL_DE_LOW; 409 410 ret = regulator_enable(ctx->power); 411 if (ret) 412 return ret; 413 414 gpiod_set_value(ctx->reset, 1); 415 msleep(30); 416 gpiod_set_value(ctx->reset, 0); 417 msleep(120); 418 419 /* 420 * Avoid failing if the IDs are invalid in case the Rx bus width 421 * description is missing. 422 */ 423 ret = st7789v_check_id(panel); 424 if (ret) 425 dev_warn(panel->dev, "Unrecognized panel IDs"); 426 427 ST7789V_TEST(ret, st7789v_write_command(ctx, MIPI_DCS_EXIT_SLEEP_MODE)); 428 429 /* We need to wait 120ms after a sleep out command */ 430 msleep(120); 431 432 ST7789V_TEST(ret, st7789v_write_command(ctx, 433 MIPI_DCS_SET_ADDRESS_MODE)); 434 ST7789V_TEST(ret, st7789v_write_data(ctx, 0)); 435 436 ST7789V_TEST(ret, st7789v_write_command(ctx, 437 MIPI_DCS_SET_PIXEL_FORMAT)); 438 ST7789V_TEST(ret, st7789v_write_data(ctx, pixel_fmt)); 439 440 ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_PORCTRL_CMD)); 441 ST7789V_TEST(ret, st7789v_write_data(ctx, 0xc)); 442 ST7789V_TEST(ret, st7789v_write_data(ctx, 0xc)); 443 ST7789V_TEST(ret, st7789v_write_data(ctx, 0)); 444 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PORCTRL_IDLE_BP(3) | 445 ST7789V_PORCTRL_IDLE_FP(3))); 446 ST7789V_TEST(ret, st7789v_write_data(ctx, 447 ST7789V_PORCTRL_PARTIAL_BP(3) | 448 ST7789V_PORCTRL_PARTIAL_FP(3))); 449 450 ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_GCTRL_CMD)); 451 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_GCTRL_VGLS(5) | 452 ST7789V_GCTRL_VGHS(3))); 453 454 ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_VCOMS_CMD)); 455 ST7789V_TEST(ret, st7789v_write_data(ctx, 0x2b)); 456 457 ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_LCMCTRL_CMD)); 458 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_LCMCTRL_XMH | 459 ST7789V_LCMCTRL_XMX | 460 ST7789V_LCMCTRL_XBGR)); 461 462 ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_VDVVRHEN_CMD)); 463 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_VDVVRHEN_CMDEN)); 464 465 ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_VRHS_CMD)); 466 ST7789V_TEST(ret, st7789v_write_data(ctx, 0xf)); 467 468 ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_VDVS_CMD)); 469 ST7789V_TEST(ret, st7789v_write_data(ctx, 0x20)); 470 471 ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_FRCTRL2_CMD)); 472 ST7789V_TEST(ret, st7789v_write_data(ctx, 0xf)); 473 474 ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_PWCTRL1_CMD)); 475 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PWCTRL1_MAGIC)); 476 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PWCTRL1_AVDD(2) | 477 ST7789V_PWCTRL1_AVCL(2) | 478 ST7789V_PWCTRL1_VDS(1))); 479 480 ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_PVGAMCTRL_CMD)); 481 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP63(0xd))); 482 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP1(0xca))); 483 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP2(0xe))); 484 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP4(8))); 485 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP6(9))); 486 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP13(7))); 487 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP20(0x2d))); 488 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP27(0xb) | 489 ST7789V_PVGAMCTRL_VP36(3))); 490 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP43(0x3d))); 491 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_JP1(3) | 492 ST7789V_PVGAMCTRL_VP50(4))); 493 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP57(0xa))); 494 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP59(0xa))); 495 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP61(0x1b))); 496 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP62(0x28))); 497 498 ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_NVGAMCTRL_CMD)); 499 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN63(0xd))); 500 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN1(0xca))); 501 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN2(0xf))); 502 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN4(8))); 503 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN6(8))); 504 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN13(7))); 505 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN20(0x2e))); 506 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN27(0xc) | 507 ST7789V_NVGAMCTRL_VN36(5))); 508 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN43(0x40))); 509 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_JN1(3) | 510 ST7789V_NVGAMCTRL_VN50(4))); 511 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN57(9))); 512 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN59(0xb))); 513 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN61(0x1b))); 514 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN62(0x28))); 515 516 if (ctx->info->invert_mode) { 517 ST7789V_TEST(ret, st7789v_write_command(ctx, 518 MIPI_DCS_ENTER_INVERT_MODE)); 519 } else { 520 ST7789V_TEST(ret, st7789v_write_command(ctx, 521 MIPI_DCS_EXIT_INVERT_MODE)); 522 } 523 524 if (ctx->info->partial_mode) { 525 u8 area_data[4] = { 526 (ctx->info->partial_start >> 8) & 0xff, 527 (ctx->info->partial_start >> 0) & 0xff, 528 ((ctx->info->partial_end - 1) >> 8) & 0xff, 529 ((ctx->info->partial_end - 1) >> 0) & 0xff, 530 }; 531 532 /* Caution: if userspace ever pushes a mode different from the 533 * expected one (i.e., the one advertised by get_modes), we'll 534 * add margins. 535 */ 536 537 ST7789V_TEST(ret, st7789v_write_command( 538 ctx, MIPI_DCS_ENTER_PARTIAL_MODE)); 539 540 ST7789V_TEST(ret, st7789v_write_command( 541 ctx, MIPI_DCS_SET_PAGE_ADDRESS)); 542 ST7789V_TEST(ret, st7789v_write_data(ctx, area_data[0])); 543 ST7789V_TEST(ret, st7789v_write_data(ctx, area_data[1])); 544 ST7789V_TEST(ret, st7789v_write_data(ctx, area_data[2])); 545 ST7789V_TEST(ret, st7789v_write_data(ctx, area_data[3])); 546 547 ST7789V_TEST(ret, st7789v_write_command( 548 ctx, MIPI_DCS_SET_PARTIAL_ROWS)); 549 ST7789V_TEST(ret, st7789v_write_data(ctx, area_data[0])); 550 ST7789V_TEST(ret, st7789v_write_data(ctx, area_data[1])); 551 ST7789V_TEST(ret, st7789v_write_data(ctx, area_data[2])); 552 ST7789V_TEST(ret, st7789v_write_data(ctx, area_data[3])); 553 } 554 555 ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_RAMCTRL_CMD)); 556 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_RAMCTRL_DM_RGB | 557 ST7789V_RAMCTRL_RM_RGB)); 558 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_RAMCTRL_EPF(3) | 559 ST7789V_RAMCTRL_MAGIC)); 560 561 ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_RGBCTRL_CMD)); 562 ST7789V_TEST(ret, st7789v_write_data(ctx, mode | 563 ST7789V_RGBCTRL_RCM(2) | 564 polarity)); 565 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_RGBCTRL_VBP(8))); 566 ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_RGBCTRL_HBP(20))); 567 568 return 0; 569 } 570 571 static int st7789v_enable(struct drm_panel *panel) 572 { 573 struct st7789v *ctx = panel_to_st7789v(panel); 574 575 return st7789v_write_command(ctx, MIPI_DCS_SET_DISPLAY_ON); 576 } 577 578 static int st7789v_disable(struct drm_panel *panel) 579 { 580 struct st7789v *ctx = panel_to_st7789v(panel); 581 int ret; 582 583 ST7789V_TEST(ret, st7789v_write_command(ctx, MIPI_DCS_SET_DISPLAY_OFF)); 584 585 return 0; 586 } 587 588 static int st7789v_unprepare(struct drm_panel *panel) 589 { 590 struct st7789v *ctx = panel_to_st7789v(panel); 591 int ret; 592 593 ST7789V_TEST(ret, st7789v_write_command(ctx, MIPI_DCS_ENTER_SLEEP_MODE)); 594 595 regulator_disable(ctx->power); 596 597 return 0; 598 } 599 600 static const struct drm_panel_funcs st7789v_drm_funcs = { 601 .disable = st7789v_disable, 602 .enable = st7789v_enable, 603 .get_modes = st7789v_get_modes, 604 .get_orientation = st7789v_get_orientation, 605 .prepare = st7789v_prepare, 606 .unprepare = st7789v_unprepare, 607 }; 608 609 static int st7789v_probe(struct spi_device *spi) 610 { 611 struct device *dev = &spi->dev; 612 struct st7789v *ctx; 613 int ret; 614 615 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); 616 if (!ctx) 617 return -ENOMEM; 618 619 spi_set_drvdata(spi, ctx); 620 ctx->spi = spi; 621 622 spi->bits_per_word = 9; 623 ret = spi_setup(spi); 624 if (ret < 0) 625 return dev_err_probe(&spi->dev, ret, "Failed to setup spi\n"); 626 627 ctx->info = device_get_match_data(&spi->dev); 628 629 drm_panel_init(&ctx->panel, dev, &st7789v_drm_funcs, 630 DRM_MODE_CONNECTOR_DPI); 631 632 ctx->power = devm_regulator_get(dev, "power"); 633 ret = PTR_ERR_OR_ZERO(ctx->power); 634 if (ret) 635 return dev_err_probe(dev, ret, "Failed to get regulator\n"); 636 637 ctx->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); 638 ret = PTR_ERR_OR_ZERO(ctx->reset); 639 if (ret) 640 return dev_err_probe(dev, ret, "Failed to get reset line\n"); 641 642 ret = drm_panel_of_backlight(&ctx->panel); 643 if (ret) 644 return dev_err_probe(dev, ret, "Failed to get backlight\n"); 645 646 of_drm_get_panel_orientation(spi->dev.of_node, &ctx->orientation); 647 648 drm_panel_add(&ctx->panel); 649 650 return 0; 651 } 652 653 static void st7789v_remove(struct spi_device *spi) 654 { 655 struct st7789v *ctx = spi_get_drvdata(spi); 656 657 drm_panel_remove(&ctx->panel); 658 } 659 660 static const struct spi_device_id st7789v_spi_id[] = { 661 { "st7789v", (unsigned long) &default_panel }, 662 { "t28cp45tn89-v17", (unsigned long) &t28cp45tn89_panel }, 663 { "et028013dma", (unsigned long) &et028013dma_panel }, 664 { "jt240mhqs-hwt-ek-e3", (unsigned long) &jt240mhqs_hwt_ek_e3_panel }, 665 { } 666 }; 667 MODULE_DEVICE_TABLE(spi, st7789v_spi_id); 668 669 static const struct of_device_id st7789v_of_match[] = { 670 { .compatible = "sitronix,st7789v", .data = &default_panel }, 671 { .compatible = "inanbo,t28cp45tn89-v17", .data = &t28cp45tn89_panel }, 672 { .compatible = "edt,et028013dma", .data = &et028013dma_panel }, 673 { .compatible = "jasonic,jt240mhqs-hwt-ek-e3", 674 .data = &jt240mhqs_hwt_ek_e3_panel }, 675 { } 676 }; 677 MODULE_DEVICE_TABLE(of, st7789v_of_match); 678 679 static struct spi_driver st7789v_driver = { 680 .probe = st7789v_probe, 681 .remove = st7789v_remove, 682 .id_table = st7789v_spi_id, 683 .driver = { 684 .name = "st7789v", 685 .of_match_table = st7789v_of_match, 686 }, 687 }; 688 module_spi_driver(st7789v_driver); 689 690 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>"); 691 MODULE_DESCRIPTION("Sitronix st7789v LCD Driver"); 692 MODULE_LICENSE("GPL v2"); 693