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};
 169
 170static int st7789v_get_modes(struct drm_panel *panel,
 171                             struct drm_connector *connector)
 172{
 173        struct drm_display_mode *mode;
 174
 175        mode = drm_mode_duplicate(connector->dev, &default_mode);
 176        if (!mode) {
 177                dev_err(panel->dev, "failed to add mode %ux%ux@%u\n",
 178                        default_mode.hdisplay, default_mode.vdisplay,
 179                        drm_mode_vrefresh(&default_mode));
 180                return -ENOMEM;
 181        }
 182
 183        drm_mode_set_name(mode);
 184
 185        mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
 186        drm_mode_probed_add(connector, mode);
 187
 188        connector->display_info.width_mm = 61;
 189        connector->display_info.height_mm = 103;
 190
 191        return 1;
 192}
 193
 194static int st7789v_prepare(struct drm_panel *panel)
 195{
 196        struct st7789v *ctx = panel_to_st7789v(panel);
 197        int ret;
 198
 199        ret = regulator_enable(ctx->power);
 200        if (ret)
 201                return ret;
 202
 203        gpiod_set_value(ctx->reset, 1);
 204        msleep(30);
 205        gpiod_set_value(ctx->reset, 0);
 206        msleep(120);
 207
 208        ST7789V_TEST(ret, st7789v_write_command(ctx, MIPI_DCS_EXIT_SLEEP_MODE));
 209
 210        /* We need to wait 120ms after a sleep out command */
 211        msleep(120);
 212
 213        ST7789V_TEST(ret, st7789v_write_command(ctx,
 214                                                MIPI_DCS_SET_ADDRESS_MODE));
 215        ST7789V_TEST(ret, st7789v_write_data(ctx, 0));
 216
 217        ST7789V_TEST(ret, st7789v_write_command(ctx,
 218                                                MIPI_DCS_SET_PIXEL_FORMAT));
 219        ST7789V_TEST(ret, st7789v_write_data(ctx,
 220                                             (MIPI_DCS_PIXEL_FMT_18BIT << 4) |
 221                                             (MIPI_DCS_PIXEL_FMT_18BIT)));
 222
 223        ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_PORCTRL_CMD));
 224        ST7789V_TEST(ret, st7789v_write_data(ctx, 0xc));
 225        ST7789V_TEST(ret, st7789v_write_data(ctx, 0xc));
 226        ST7789V_TEST(ret, st7789v_write_data(ctx, 0));
 227        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PORCTRL_IDLE_BP(3) |
 228                                             ST7789V_PORCTRL_IDLE_FP(3)));
 229        ST7789V_TEST(ret, st7789v_write_data(ctx,
 230                                             ST7789V_PORCTRL_PARTIAL_BP(3) |
 231                                             ST7789V_PORCTRL_PARTIAL_FP(3)));
 232
 233        ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_GCTRL_CMD));
 234        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_GCTRL_VGLS(5) |
 235                                             ST7789V_GCTRL_VGHS(3)));
 236
 237        ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_VCOMS_CMD));
 238        ST7789V_TEST(ret, st7789v_write_data(ctx, 0x2b));
 239
 240        ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_LCMCTRL_CMD));
 241        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_LCMCTRL_XMH |
 242                                             ST7789V_LCMCTRL_XMX |
 243                                             ST7789V_LCMCTRL_XBGR));
 244
 245        ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_VDVVRHEN_CMD));
 246        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_VDVVRHEN_CMDEN));
 247
 248        ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_VRHS_CMD));
 249        ST7789V_TEST(ret, st7789v_write_data(ctx, 0xf));
 250
 251        ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_VDVS_CMD));
 252        ST7789V_TEST(ret, st7789v_write_data(ctx, 0x20));
 253
 254        ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_FRCTRL2_CMD));
 255        ST7789V_TEST(ret, st7789v_write_data(ctx, 0xf));
 256
 257        ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_PWCTRL1_CMD));
 258        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PWCTRL1_MAGIC));
 259        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PWCTRL1_AVDD(2) |
 260                                             ST7789V_PWCTRL1_AVCL(2) |
 261                                             ST7789V_PWCTRL1_VDS(1)));
 262
 263        ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_PVGAMCTRL_CMD));
 264        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP63(0xd)));
 265        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP1(0xca)));
 266        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP2(0xe)));
 267        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP4(8)));
 268        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP6(9)));
 269        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP13(7)));
 270        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP20(0x2d)));
 271        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP27(0xb) |
 272                                             ST7789V_PVGAMCTRL_VP36(3)));
 273        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP43(0x3d)));
 274        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_JP1(3) |
 275                                             ST7789V_PVGAMCTRL_VP50(4)));
 276        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP57(0xa)));
 277        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP59(0xa)));
 278        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP61(0x1b)));
 279        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP62(0x28)));
 280
 281        ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_NVGAMCTRL_CMD));
 282        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN63(0xd)));
 283        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN1(0xca)));
 284        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN2(0xf)));
 285        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN4(8)));
 286        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN6(8)));
 287        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN13(7)));
 288        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN20(0x2e)));
 289        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN27(0xc) |
 290                                             ST7789V_NVGAMCTRL_VN36(5)));
 291        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN43(0x40)));
 292        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_JN1(3) |
 293                                             ST7789V_NVGAMCTRL_VN50(4)));
 294        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN57(9)));
 295        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN59(0xb)));
 296        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN61(0x1b)));
 297        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN62(0x28)));
 298
 299        ST7789V_TEST(ret, st7789v_write_command(ctx, MIPI_DCS_ENTER_INVERT_MODE));
 300
 301        ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_RAMCTRL_CMD));
 302        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_RAMCTRL_DM_RGB |
 303                                             ST7789V_RAMCTRL_RM_RGB));
 304        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_RAMCTRL_EPF(3) |
 305                                             ST7789V_RAMCTRL_MAGIC));
 306
 307        ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_RGBCTRL_CMD));
 308        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_RGBCTRL_WO |
 309                                             ST7789V_RGBCTRL_RCM(2) |
 310                                             ST7789V_RGBCTRL_VSYNC_HIGH |
 311                                             ST7789V_RGBCTRL_HSYNC_HIGH |
 312                                             ST7789V_RGBCTRL_PCLK_HIGH));
 313        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_RGBCTRL_VBP(8)));
 314        ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_RGBCTRL_HBP(20)));
 315
 316        return 0;
 317}
 318
 319static int st7789v_enable(struct drm_panel *panel)
 320{
 321        struct st7789v *ctx = panel_to_st7789v(panel);
 322
 323        return st7789v_write_command(ctx, MIPI_DCS_SET_DISPLAY_ON);
 324}
 325
 326static int st7789v_disable(struct drm_panel *panel)
 327{
 328        struct st7789v *ctx = panel_to_st7789v(panel);
 329        int ret;
 330
 331        ST7789V_TEST(ret, st7789v_write_command(ctx, MIPI_DCS_SET_DISPLAY_OFF));
 332
 333        return 0;
 334}
 335
 336static int st7789v_unprepare(struct drm_panel *panel)
 337{
 338        struct st7789v *ctx = panel_to_st7789v(panel);
 339        int ret;
 340
 341        ST7789V_TEST(ret, st7789v_write_command(ctx, MIPI_DCS_ENTER_SLEEP_MODE));
 342
 343        regulator_disable(ctx->power);
 344
 345        return 0;
 346}
 347
 348static const struct drm_panel_funcs st7789v_drm_funcs = {
 349        .disable        = st7789v_disable,
 350        .enable         = st7789v_enable,
 351        .get_modes      = st7789v_get_modes,
 352        .prepare        = st7789v_prepare,
 353        .unprepare      = st7789v_unprepare,
 354};
 355
 356static int st7789v_probe(struct spi_device *spi)
 357{
 358        struct st7789v *ctx;
 359        int ret;
 360
 361        ctx = devm_kzalloc(&spi->dev, sizeof(*ctx), GFP_KERNEL);
 362        if (!ctx)
 363                return -ENOMEM;
 364
 365        spi_set_drvdata(spi, ctx);
 366        ctx->spi = spi;
 367
 368        drm_panel_init(&ctx->panel, &spi->dev, &st7789v_drm_funcs,
 369                       DRM_MODE_CONNECTOR_DPI);
 370
 371        ctx->power = devm_regulator_get(&spi->dev, "power");
 372        if (IS_ERR(ctx->power))
 373                return PTR_ERR(ctx->power);
 374
 375        ctx->reset = devm_gpiod_get(&spi->dev, "reset", GPIOD_OUT_LOW);
 376        if (IS_ERR(ctx->reset)) {
 377                dev_err(&spi->dev, "Couldn't get our reset line\n");
 378                return PTR_ERR(ctx->reset);
 379        }
 380
 381        ret = drm_panel_of_backlight(&ctx->panel);
 382        if (ret)
 383                return ret;
 384
 385        drm_panel_add(&ctx->panel);
 386
 387        return 0;
 388}
 389
 390static int st7789v_remove(struct spi_device *spi)
 391{
 392        struct st7789v *ctx = spi_get_drvdata(spi);
 393
 394        drm_panel_remove(&ctx->panel);
 395
 396        return 0;
 397}
 398
 399static const struct of_device_id st7789v_of_match[] = {
 400        { .compatible = "sitronix,st7789v" },
 401        { }
 402};
 403MODULE_DEVICE_TABLE(of, st7789v_of_match);
 404
 405static struct spi_driver st7789v_driver = {
 406        .probe = st7789v_probe,
 407        .remove = st7789v_remove,
 408        .driver = {
 409                .name = "st7789v",
 410                .of_match_table = st7789v_of_match,
 411        },
 412};
 413module_spi_driver(st7789v_driver);
 414
 415MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
 416MODULE_DESCRIPTION("Sitronix st7789v LCD Driver");
 417MODULE_LICENSE("GPL v2");
 418