linux/drivers/gpu/drm/panel/panel-sitronix-st7789v.c
<<
>>
Prefs
   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
  14#include <drm/drm_device.h>
  15#include <drm/drm_modes.h>
  16#include <drm/drm_panel.h>
  17
  18#define ST7789V_COLMOD_RGB_FMT_18BITS           (6 << 4)
  19#define ST7789V_COLMOD_CTRL_FMT_18BITS          (6 << 0)
  20
  21#define ST7789V_RAMCTRL_CMD             0xb0
  22#define ST7789V_RAMCTRL_RM_RGB                  BIT(4)
  23#define ST7789V_RAMCTRL_DM_RGB                  BIT(0)
  24#define ST7789V_RAMCTRL_MAGIC                   (3 << 6)
  25#define ST7789V_RAMCTRL_EPF(n)                  (((n) & 3) << 4)
  26
  27#define ST7789V_RGBCTRL_CMD             0xb1
  28#define ST7789V_RGBCTRL_WO                      BIT(7)
  29#define ST7789V_RGBCTRL_RCM(n)                  (((n) & 3) << 5)
  30#define ST7789V_RGBCTRL_VSYNC_HIGH              BIT(3)
  31#define ST7789V_RGBCTRL_HSYNC_HIGH              BIT(2)
  32#define ST7789V_RGBCTRL_PCLK_HIGH               BIT(1)
  33#define ST7789V_RGBCTRL_VBP(n)                  ((n) & 0x7f)
  34#define ST7789V_RGBCTRL_HBP(n)                  ((n) & 0x1f)
  35
  36#define ST7789V_PORCTRL_CMD             0xb2
  37#define ST7789V_PORCTRL_IDLE_BP(n)              (((n) & 0xf) << 4)
  38#define ST7789V_PORCTRL_IDLE_FP(n)              ((n) & 0xf)
  39#define ST7789V_PORCTRL_PARTIAL_BP(n)           (((n) & 0xf) << 4)
  40#define ST7789V_PORCTRL_PARTIAL_FP(n)           ((n) & 0xf)
  41
  42#define ST7789V_GCTRL_CMD               0xb7
  43#define ST7789V_GCTRL_VGHS(n)                   (((n) & 7) << 4)
  44#define ST7789V_GCTRL_VGLS(n)                   ((n) & 7)
  45
  46#define ST7789V_VCOMS_CMD               0xbb
  47
  48#define ST7789V_LCMCTRL_CMD             0xc0
  49#define ST7789V_LCMCTRL_XBGR                    BIT(5)
  50#define ST7789V_LCMCTRL_XMX                     BIT(3)
  51#define ST7789V_LCMCTRL_XMH                     BIT(2)
  52
  53#define ST7789V_VDVVRHEN_CMD            0xc2
  54#define ST7789V_VDVVRHEN_CMDEN                  BIT(0)
  55
  56#define ST7789V_VRHS_CMD                0xc3
  57
  58#define ST7789V_VDVS_CMD                0xc4
  59
  60#define ST7789V_FRCTRL2_CMD             0xc6
  61
  62#define ST7789V_PWCTRL1_CMD             0xd0
  63#define ST7789V_PWCTRL1_MAGIC                   0xa4
  64#define ST7789V_PWCTRL1_AVDD(n)                 (((n) & 3) << 6)
  65#define ST7789V_PWCTRL1_AVCL(n)                 (((n) & 3) << 4)
  66#define ST7789V_PWCTRL1_VDS(n)                  ((n) & 3)
  67
  68#define ST7789V_PVGAMCTRL_CMD           0xe0
  69#define ST7789V_PVGAMCTRL_JP0(n)                (((n) & 3) << 4)
  70#define ST7789V_PVGAMCTRL_JP1(n)                (((n) & 3) << 4)
  71#define ST7789V_PVGAMCTRL_VP0(n)                ((n) & 0xf)
  72#define ST7789V_PVGAMCTRL_VP1(n)                ((n) & 0x3f)
  73#define ST7789V_PVGAMCTRL_VP2(n)                ((n) & 0x3f)
  74#define ST7789V_PVGAMCTRL_VP4(n)                ((n) & 0x1f)
  75#define ST7789V_PVGAMCTRL_VP6(n)                ((n) & 0x1f)
  76#define ST7789V_PVGAMCTRL_VP13(n)               ((n) & 0xf)
  77#define ST7789V_PVGAMCTRL_VP20(n)               ((n) & 0x7f)
  78#define ST7789V_PVGAMCTRL_VP27(n)               ((n) & 7)
  79#define ST7789V_PVGAMCTRL_VP36(n)               (((n) & 7) << 4)
  80#define ST7789V_PVGAMCTRL_VP43(n)               ((n) & 0x7f)
  81#define ST7789V_PVGAMCTRL_VP50(n)               ((n) & 0xf)
  82#define ST7789V_PVGAMCTRL_VP57(n)               ((n) & 0x1f)
  83#define ST7789V_PVGAMCTRL_VP59(n)               ((n) & 0x1f)
  84#define ST7789V_PVGAMCTRL_VP61(n)               ((n) & 0x3f)
  85#define ST7789V_PVGAMCTRL_VP62(n)               ((n) & 0x3f)
  86#define ST7789V_PVGAMCTRL_VP63(n)               (((n) & 0xf) << 4)
  87
  88#define ST7789V_NVGAMCTRL_CMD           0xe1
  89#define ST7789V_NVGAMCTRL_JN0(n)                (((n) & 3) << 4)
  90#define ST7789V_NVGAMCTRL_JN1(n)                (((n) & 3) << 4)
  91#define ST7789V_NVGAMCTRL_VN0(n)                ((n) & 0xf)
  92#define ST7789V_NVGAMCTRL_VN1(n)                ((n) & 0x3f)
  93#define ST7789V_NVGAMCTRL_VN2(n)                ((n) & 0x3f)
  94#define ST7789V_NVGAMCTRL_VN4(n)                ((n) & 0x1f)
  95#define ST7789V_NVGAMCTRL_VN6(n)                ((n) & 0x1f)
  96#define ST7789V_NVGAMCTRL_VN13(n)               ((n) & 0xf)
  97#define ST7789V_NVGAMCTRL_VN20(n)               ((n) & 0x7f)
  98#define ST7789V_NVGAMCTRL_VN27(n)               ((n) & 7)
  99#define ST7789V_NVGAMCTRL_VN36(n)               (((n) & 7) << 4)
 100#define ST7789V_NVGAMCTRL_VN43(n)               ((n) & 0x7f)
 101#define ST7789V_NVGAMCTRL_VN50(n)               ((n) & 0xf)
 102#define ST7789V_NVGAMCTRL_VN57(n)               ((n) & 0x1f)
 103#define ST7789V_NVGAMCTRL_VN59(n)               ((n) & 0x1f)
 104#define ST7789V_NVGAMCTRL_VN61(n)               ((n) & 0x3f)
 105#define ST7789V_NVGAMCTRL_VN62(n)               ((n) & 0x3f)
 106#define ST7789V_NVGAMCTRL_VN63(n)               (((n) & 0xf) << 4)
 107
 108#define ST7789V_TEST(val, func)                 \
 109        do {                                    \
 110                if ((val = (func)))             \
 111                        return val;             \
 112        } while (0)
 113
 114struct st7789v {
 115        struct drm_panel panel;
 116        struct spi_device *spi;
 117        struct gpio_desc *reset;
 118        struct regulator *power;
 119};
 120
 121enum st7789v_prefix {
 122        ST7789V_COMMAND = 0,
 123        ST7789V_DATA = 1,
 124};
 125
 126static inline struct st7789v *panel_to_st7789v(struct drm_panel *panel)
 127{
 128        return container_of(panel, struct st7789v, panel);
 129}
 130
 131static int st7789v_spi_write(struct st7789v *ctx, enum st7789v_prefix prefix,
 132                             u8 data)
 133{
 134        struct spi_transfer xfer = { };
 135        struct spi_message msg;
 136        u16 txbuf = ((prefix & 1) << 8) | data;
 137
 138        spi_message_init(&msg);
 139
 140        xfer.tx_buf = &txbuf;
 141        xfer.bits_per_word = 9;
 142        xfer.len = sizeof(txbuf);
 143
 144        spi_message_add_tail(&xfer, &msg);
 145        return spi_sync(ctx->spi, &msg);
 146}
 147
 148static int st7789v_write_command(struct st7789v *ctx, u8 cmd)
 149{
 150        return st7789v_spi_write(ctx, ST7789V_COMMAND, cmd);
 151}
 152
 153static int st7789v_write_data(struct st7789v *ctx, u8 cmd)
 154{
 155        return st7789v_spi_write(ctx, ST7789V_DATA, cmd);
 156}
 157
 158static const struct drm_display_mode default_mode = {
 159        .clock = 7000,
 160        .hdisplay = 240,
 161        .hsync_start = 240 + 38,
 162        .hsync_end = 240 + 38 + 10,
 163        .htotal = 240 + 38 + 10 + 10,
 164        .vdisplay = 320,
 165        .vsync_start = 320 + 8,
 166        .vsync_end = 320 + 8 + 4,
 167        .vtotal = 320 + 8 + 4 + 4,
 168        .vrefresh = 60,
 169};
 170
 171static int st7789v_get_modes(struct drm_panel *panel,
 172                             struct drm_connector *connector)
 173{
 174        struct drm_display_mode *mode;
 175
 176        mode = drm_mode_duplicate(connector->dev, &default_mode);
 177        if (!mode) {
 178                dev_err(panel->dev, "failed to add mode %ux%ux@%u\n",
 179                        default_mode.hdisplay, default_mode.vdisplay,
 180                        default_mode.vrefresh);
 181                return -ENOMEM;
 182        }
 183
 184        drm_mode_set_name(mode);
 185
 186        mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
 187        drm_mode_probed_add(connector, mode);
 188
 189        connector->display_info.width_mm = 61;
 190        connector->display_info.height_mm = 103;
 191
 192        return 1;
 193}
 194
 195static int st7789v_prepare(struct drm_panel *panel)
 196{
 197        struct st7789v *ctx = panel_to_st7789v(panel);
 198        int ret;
 199
 200        ret = regulator_enable(ctx->power);
 201        if (ret)
 202                return ret;
 203
 204        gpiod_set_value(ctx->reset, 1);
 205        msleep(30);
 206        gpiod_set_value(ctx->reset, 0);
 207        msleep(120);
 208
 209        ST7789V_TEST(ret, st7789v_write_command(ctx, MIPI_DCS_EXIT_SLEEP_MODE));
 210
 211        /* We need to wait 120ms after a sleep out command */
 212        msleep(120);
 213
 214        ST7789V_TEST(ret, st7789v_write_command(ctx,
 215                                                MIPI_DCS_SET_ADDRESS_MODE));
 216        ST7789V_TEST(ret, st7789v_write_data(ctx, 0));
 217
 218        ST7789V_TEST(ret, st7789v_write_command(ctx,
 219                                                MIPI_DCS_SET_PIXEL_FORMAT));
 220        ST7789V_TEST(ret, st7789v_write_data(ctx,
 221                                             (MIPI_DCS_PIXEL_FMT_18BIT << 4) |
 222                                             (MIPI_DCS_PIXEL_FMT_18BIT)));
 223
 224        ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_PORCTRL_CMD));
 225        ST7789V_TEST(ret, st7789v_write_data(ctx, 0xc));
 226        ST7789V_TEST(ret, st7789v_write_data(ctx, 0xc));
 227        ST7789V_TEST(ret, st7789v_write_data(ctx, 0));
 228        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PORCTRL_IDLE_BP(3) |
 229                                             ST7789V_PORCTRL_IDLE_FP(3)));
 230        ST7789V_TEST(ret, st7789v_write_data(ctx,
 231                                             ST7789V_PORCTRL_PARTIAL_BP(3) |
 232                                             ST7789V_PORCTRL_PARTIAL_FP(3)));
 233
 234        ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_GCTRL_CMD));
 235        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_GCTRL_VGLS(5) |
 236                                             ST7789V_GCTRL_VGHS(3)));
 237
 238        ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_VCOMS_CMD));
 239        ST7789V_TEST(ret, st7789v_write_data(ctx, 0x2b));
 240
 241        ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_LCMCTRL_CMD));
 242        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_LCMCTRL_XMH |
 243                                             ST7789V_LCMCTRL_XMX |
 244                                             ST7789V_LCMCTRL_XBGR));
 245
 246        ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_VDVVRHEN_CMD));
 247        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_VDVVRHEN_CMDEN));
 248
 249        ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_VRHS_CMD));
 250        ST7789V_TEST(ret, st7789v_write_data(ctx, 0xf));
 251
 252        ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_VDVS_CMD));
 253        ST7789V_TEST(ret, st7789v_write_data(ctx, 0x20));
 254
 255        ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_FRCTRL2_CMD));
 256        ST7789V_TEST(ret, st7789v_write_data(ctx, 0xf));
 257
 258        ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_PWCTRL1_CMD));
 259        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PWCTRL1_MAGIC));
 260        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PWCTRL1_AVDD(2) |
 261                                             ST7789V_PWCTRL1_AVCL(2) |
 262                                             ST7789V_PWCTRL1_VDS(1)));
 263
 264        ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_PVGAMCTRL_CMD));
 265        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP63(0xd)));
 266        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP1(0xca)));
 267        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP2(0xe)));
 268        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP4(8)));
 269        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP6(9)));
 270        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP13(7)));
 271        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP20(0x2d)));
 272        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP27(0xb) |
 273                                             ST7789V_PVGAMCTRL_VP36(3)));
 274        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP43(0x3d)));
 275        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_JP1(3) |
 276                                             ST7789V_PVGAMCTRL_VP50(4)));
 277        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP57(0xa)));
 278        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP59(0xa)));
 279        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP61(0x1b)));
 280        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP62(0x28)));
 281
 282        ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_NVGAMCTRL_CMD));
 283        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN63(0xd)));
 284        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN1(0xca)));
 285        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN2(0xf)));
 286        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN4(8)));
 287        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN6(8)));
 288        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN13(7)));
 289        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN20(0x2e)));
 290        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN27(0xc) |
 291                                             ST7789V_NVGAMCTRL_VN36(5)));
 292        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN43(0x40)));
 293        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_JN1(3) |
 294                                             ST7789V_NVGAMCTRL_VN50(4)));
 295        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN57(9)));
 296        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN59(0xb)));
 297        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN61(0x1b)));
 298        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN62(0x28)));
 299
 300        ST7789V_TEST(ret, st7789v_write_command(ctx, MIPI_DCS_ENTER_INVERT_MODE));
 301
 302        ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_RAMCTRL_CMD));
 303        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_RAMCTRL_DM_RGB |
 304                                             ST7789V_RAMCTRL_RM_RGB));
 305        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_RAMCTRL_EPF(3) |
 306                                             ST7789V_RAMCTRL_MAGIC));
 307
 308        ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_RGBCTRL_CMD));
 309        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_RGBCTRL_WO |
 310                                             ST7789V_RGBCTRL_RCM(2) |
 311                                             ST7789V_RGBCTRL_VSYNC_HIGH |
 312                                             ST7789V_RGBCTRL_HSYNC_HIGH |
 313                                             ST7789V_RGBCTRL_PCLK_HIGH));
 314        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_RGBCTRL_VBP(8)));
 315        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_RGBCTRL_HBP(20)));
 316
 317        return 0;
 318}
 319
 320static int st7789v_enable(struct drm_panel *panel)
 321{
 322        struct st7789v *ctx = panel_to_st7789v(panel);
 323
 324        return st7789v_write_command(ctx, MIPI_DCS_SET_DISPLAY_ON);
 325}
 326
 327static int st7789v_disable(struct drm_panel *panel)
 328{
 329        struct st7789v *ctx = panel_to_st7789v(panel);
 330        int ret;
 331
 332        ST7789V_TEST(ret, st7789v_write_command(ctx, MIPI_DCS_SET_DISPLAY_OFF));
 333
 334        return 0;
 335}
 336
 337static int st7789v_unprepare(struct drm_panel *panel)
 338{
 339        struct st7789v *ctx = panel_to_st7789v(panel);
 340        int ret;
 341
 342        ST7789V_TEST(ret, st7789v_write_command(ctx, MIPI_DCS_ENTER_SLEEP_MODE));
 343
 344        regulator_disable(ctx->power);
 345
 346        return 0;
 347}
 348
 349static const struct drm_panel_funcs st7789v_drm_funcs = {
 350        .disable        = st7789v_disable,
 351        .enable         = st7789v_enable,
 352        .get_modes      = st7789v_get_modes,
 353        .prepare        = st7789v_prepare,
 354        .unprepare      = st7789v_unprepare,
 355};
 356
 357static int st7789v_probe(struct spi_device *spi)
 358{
 359        struct st7789v *ctx;
 360        int ret;
 361
 362        ctx = devm_kzalloc(&spi->dev, sizeof(*ctx), GFP_KERNEL);
 363        if (!ctx)
 364                return -ENOMEM;
 365
 366        spi_set_drvdata(spi, ctx);
 367        ctx->spi = spi;
 368
 369        drm_panel_init(&ctx->panel, &spi->dev, &st7789v_drm_funcs,
 370                       DRM_MODE_CONNECTOR_DPI);
 371
 372        ctx->power = devm_regulator_get(&spi->dev, "power");
 373        if (IS_ERR(ctx->power))
 374                return PTR_ERR(ctx->power);
 375
 376        ctx->reset = devm_gpiod_get(&spi->dev, "reset", GPIOD_OUT_LOW);
 377        if (IS_ERR(ctx->reset)) {
 378                dev_err(&spi->dev, "Couldn't get our reset line\n");
 379                return PTR_ERR(ctx->reset);
 380        }
 381
 382        ret = drm_panel_of_backlight(&ctx->panel);
 383        if (ret)
 384                return ret;
 385
 386        ret = drm_panel_add(&ctx->panel);
 387        if (ret < 0)
 388                return ret;
 389
 390        return 0;
 391}
 392
 393static int st7789v_remove(struct spi_device *spi)
 394{
 395        struct st7789v *ctx = spi_get_drvdata(spi);
 396
 397        drm_panel_remove(&ctx->panel);
 398
 399        return 0;
 400}
 401
 402static const struct of_device_id st7789v_of_match[] = {
 403        { .compatible = "sitronix,st7789v" },
 404        { }
 405};
 406MODULE_DEVICE_TABLE(of, st7789v_of_match);
 407
 408static struct spi_driver st7789v_driver = {
 409        .probe = st7789v_probe,
 410        .remove = st7789v_remove,
 411        .driver = {
 412                .name = "st7789v",
 413                .of_match_table = st7789v_of_match,
 414        },
 415};
 416module_spi_driver(st7789v_driver);
 417
 418MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
 419MODULE_DESCRIPTION("Sitronix st7789v LCD Driver");
 420MODULE_LICENSE("GPL v2");
 421