linux/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (C) 2014 NVIDIA Corporation
   4 */
   5
   6#include <linux/delay.h>
   7#include <linux/gpio/consumer.h>
   8#include <linux/module.h>
   9#include <linux/of.h>
  10#include <linux/regulator/consumer.h>
  11
  12#include <video/mipi_display.h>
  13
  14#include <drm/drm_crtc.h>
  15#include <drm/drm_device.h>
  16#include <drm/drm_mipi_dsi.h>
  17#include <drm/drm_panel.h>
  18
  19struct sharp_panel {
  20        struct drm_panel base;
  21        /* the datasheet refers to them as DSI-LINK1 and DSI-LINK2 */
  22        struct mipi_dsi_device *link1;
  23        struct mipi_dsi_device *link2;
  24
  25        struct regulator *supply;
  26
  27        bool prepared;
  28        bool enabled;
  29
  30        const struct drm_display_mode *mode;
  31};
  32
  33static inline struct sharp_panel *to_sharp_panel(struct drm_panel *panel)
  34{
  35        return container_of(panel, struct sharp_panel, base);
  36}
  37
  38static void sharp_wait_frames(struct sharp_panel *sharp, unsigned int frames)
  39{
  40        unsigned int refresh = drm_mode_vrefresh(sharp->mode);
  41
  42        if (WARN_ON(frames > refresh))
  43                return;
  44
  45        msleep(1000 / (refresh / frames));
  46}
  47
  48static int sharp_panel_write(struct sharp_panel *sharp, u16 offset, u8 value)
  49{
  50        u8 payload[3] = { offset >> 8, offset & 0xff, value };
  51        struct mipi_dsi_device *dsi = sharp->link1;
  52        ssize_t err;
  53
  54        err = mipi_dsi_generic_write(dsi, payload, sizeof(payload));
  55        if (err < 0) {
  56                dev_err(&dsi->dev, "failed to write %02x to %04x: %zd\n",
  57                        value, offset, err);
  58                return err;
  59        }
  60
  61        err = mipi_dsi_dcs_nop(dsi);
  62        if (err < 0) {
  63                dev_err(&dsi->dev, "failed to send DCS nop: %zd\n", err);
  64                return err;
  65        }
  66
  67        usleep_range(10, 20);
  68
  69        return 0;
  70}
  71
  72static __maybe_unused int sharp_panel_read(struct sharp_panel *sharp,
  73                                           u16 offset, u8 *value)
  74{
  75        ssize_t err;
  76
  77        cpu_to_be16s(&offset);
  78
  79        err = mipi_dsi_generic_read(sharp->link1, &offset, sizeof(offset),
  80                                    value, sizeof(*value));
  81        if (err < 0)
  82                dev_err(&sharp->link1->dev, "failed to read from %04x: %zd\n",
  83                        offset, err);
  84
  85        return err;
  86}
  87
  88static int sharp_panel_disable(struct drm_panel *panel)
  89{
  90        struct sharp_panel *sharp = to_sharp_panel(panel);
  91
  92        if (!sharp->enabled)
  93                return 0;
  94
  95        sharp->enabled = false;
  96
  97        return 0;
  98}
  99
 100static int sharp_panel_unprepare(struct drm_panel *panel)
 101{
 102        struct sharp_panel *sharp = to_sharp_panel(panel);
 103        int err;
 104
 105        if (!sharp->prepared)
 106                return 0;
 107
 108        sharp_wait_frames(sharp, 4);
 109
 110        err = mipi_dsi_dcs_set_display_off(sharp->link1);
 111        if (err < 0)
 112                dev_err(panel->dev, "failed to set display off: %d\n", err);
 113
 114        err = mipi_dsi_dcs_enter_sleep_mode(sharp->link1);
 115        if (err < 0)
 116                dev_err(panel->dev, "failed to enter sleep mode: %d\n", err);
 117
 118        msleep(120);
 119
 120        regulator_disable(sharp->supply);
 121
 122        sharp->prepared = false;
 123
 124        return 0;
 125}
 126
 127static int sharp_setup_symmetrical_split(struct mipi_dsi_device *left,
 128                                         struct mipi_dsi_device *right,
 129                                         const struct drm_display_mode *mode)
 130{
 131        int err;
 132
 133        err = mipi_dsi_dcs_set_column_address(left, 0, mode->hdisplay / 2 - 1);
 134        if (err < 0) {
 135                dev_err(&left->dev, "failed to set column address: %d\n", err);
 136                return err;
 137        }
 138
 139        err = mipi_dsi_dcs_set_page_address(left, 0, mode->vdisplay - 1);
 140        if (err < 0) {
 141                dev_err(&left->dev, "failed to set page address: %d\n", err);
 142                return err;
 143        }
 144
 145        err = mipi_dsi_dcs_set_column_address(right, mode->hdisplay / 2,
 146                                              mode->hdisplay - 1);
 147        if (err < 0) {
 148                dev_err(&right->dev, "failed to set column address: %d\n", err);
 149                return err;
 150        }
 151
 152        err = mipi_dsi_dcs_set_page_address(right, 0, mode->vdisplay - 1);
 153        if (err < 0) {
 154                dev_err(&right->dev, "failed to set page address: %d\n", err);
 155                return err;
 156        }
 157
 158        return 0;
 159}
 160
 161static int sharp_panel_prepare(struct drm_panel *panel)
 162{
 163        struct sharp_panel *sharp = to_sharp_panel(panel);
 164        u8 format = MIPI_DCS_PIXEL_FMT_24BIT;
 165        int err;
 166
 167        if (sharp->prepared)
 168                return 0;
 169
 170        err = regulator_enable(sharp->supply);
 171        if (err < 0)
 172                return err;
 173
 174        /*
 175         * According to the datasheet, the panel needs around 10 ms to fully
 176         * power up. At least another 120 ms is required before exiting sleep
 177         * mode to make sure the panel is ready. Throw in another 20 ms for
 178         * good measure.
 179         */
 180        msleep(150);
 181
 182        err = mipi_dsi_dcs_exit_sleep_mode(sharp->link1);
 183        if (err < 0) {
 184                dev_err(panel->dev, "failed to exit sleep mode: %d\n", err);
 185                goto poweroff;
 186        }
 187
 188        /*
 189         * The MIPI DCS specification mandates this delay only between the
 190         * exit_sleep_mode and enter_sleep_mode commands, so it isn't strictly
 191         * necessary here.
 192         */
 193        /*
 194        msleep(120);
 195        */
 196
 197        /* set left-right mode */
 198        err = sharp_panel_write(sharp, 0x1000, 0x2a);
 199        if (err < 0) {
 200                dev_err(panel->dev, "failed to set left-right mode: %d\n", err);
 201                goto poweroff;
 202        }
 203
 204        /* enable command mode */
 205        err = sharp_panel_write(sharp, 0x1001, 0x01);
 206        if (err < 0) {
 207                dev_err(panel->dev, "failed to enable command mode: %d\n", err);
 208                goto poweroff;
 209        }
 210
 211        err = mipi_dsi_dcs_set_pixel_format(sharp->link1, format);
 212        if (err < 0) {
 213                dev_err(panel->dev, "failed to set pixel format: %d\n", err);
 214                goto poweroff;
 215        }
 216
 217        /*
 218         * TODO: The device supports both left-right and even-odd split
 219         * configurations, but this driver currently supports only the left-
 220         * right split. To support a different mode a mechanism needs to be
 221         * put in place to communicate the configuration back to the DSI host
 222         * controller.
 223         */
 224        err = sharp_setup_symmetrical_split(sharp->link1, sharp->link2,
 225                                            sharp->mode);
 226        if (err < 0) {
 227                dev_err(panel->dev, "failed to set up symmetrical split: %d\n",
 228                        err);
 229                goto poweroff;
 230        }
 231
 232        err = mipi_dsi_dcs_set_display_on(sharp->link1);
 233        if (err < 0) {
 234                dev_err(panel->dev, "failed to set display on: %d\n", err);
 235                goto poweroff;
 236        }
 237
 238        sharp->prepared = true;
 239
 240        /* wait for 6 frames before continuing */
 241        sharp_wait_frames(sharp, 6);
 242
 243        return 0;
 244
 245poweroff:
 246        regulator_disable(sharp->supply);
 247        return err;
 248}
 249
 250static int sharp_panel_enable(struct drm_panel *panel)
 251{
 252        struct sharp_panel *sharp = to_sharp_panel(panel);
 253
 254        if (sharp->enabled)
 255                return 0;
 256
 257        sharp->enabled = true;
 258
 259        return 0;
 260}
 261
 262static const struct drm_display_mode default_mode = {
 263        .clock = 278000,
 264        .hdisplay = 2560,
 265        .hsync_start = 2560 + 128,
 266        .hsync_end = 2560 + 128 + 64,
 267        .htotal = 2560 + 128 + 64 + 64,
 268        .vdisplay = 1600,
 269        .vsync_start = 1600 + 4,
 270        .vsync_end = 1600 + 4 + 8,
 271        .vtotal = 1600 + 4 + 8 + 32,
 272};
 273
 274static int sharp_panel_get_modes(struct drm_panel *panel,
 275                                 struct drm_connector *connector)
 276{
 277        struct drm_display_mode *mode;
 278
 279        mode = drm_mode_duplicate(connector->dev, &default_mode);
 280        if (!mode) {
 281                dev_err(panel->dev, "failed to add mode %ux%ux@%u\n",
 282                        default_mode.hdisplay, default_mode.vdisplay,
 283                        drm_mode_vrefresh(&default_mode));
 284                return -ENOMEM;
 285        }
 286
 287        drm_mode_set_name(mode);
 288
 289        drm_mode_probed_add(connector, mode);
 290
 291        connector->display_info.width_mm = 217;
 292        connector->display_info.height_mm = 136;
 293
 294        return 1;
 295}
 296
 297static const struct drm_panel_funcs sharp_panel_funcs = {
 298        .disable = sharp_panel_disable,
 299        .unprepare = sharp_panel_unprepare,
 300        .prepare = sharp_panel_prepare,
 301        .enable = sharp_panel_enable,
 302        .get_modes = sharp_panel_get_modes,
 303};
 304
 305static const struct of_device_id sharp_of_match[] = {
 306        { .compatible = "sharp,lq101r1sx01", },
 307        { }
 308};
 309MODULE_DEVICE_TABLE(of, sharp_of_match);
 310
 311static int sharp_panel_add(struct sharp_panel *sharp)
 312{
 313        int ret;
 314
 315        sharp->mode = &default_mode;
 316
 317        sharp->supply = devm_regulator_get(&sharp->link1->dev, "power");
 318        if (IS_ERR(sharp->supply))
 319                return PTR_ERR(sharp->supply);
 320
 321        drm_panel_init(&sharp->base, &sharp->link1->dev, &sharp_panel_funcs,
 322                       DRM_MODE_CONNECTOR_DSI);
 323
 324        ret = drm_panel_of_backlight(&sharp->base);
 325        if (ret)
 326                return ret;
 327
 328        drm_panel_add(&sharp->base);
 329
 330        return 0;
 331}
 332
 333static void sharp_panel_del(struct sharp_panel *sharp)
 334{
 335        if (sharp->base.dev)
 336                drm_panel_remove(&sharp->base);
 337
 338        if (sharp->link2)
 339                put_device(&sharp->link2->dev);
 340}
 341
 342static int sharp_panel_probe(struct mipi_dsi_device *dsi)
 343{
 344        struct mipi_dsi_device *secondary = NULL;
 345        struct sharp_panel *sharp;
 346        struct device_node *np;
 347        int err;
 348
 349        dsi->lanes = 4;
 350        dsi->format = MIPI_DSI_FMT_RGB888;
 351        dsi->mode_flags = MIPI_DSI_MODE_LPM;
 352
 353        /* Find DSI-LINK1 */
 354        np = of_parse_phandle(dsi->dev.of_node, "link2", 0);
 355        if (np) {
 356                secondary = of_find_mipi_dsi_device_by_node(np);
 357                of_node_put(np);
 358
 359                if (!secondary)
 360                        return -EPROBE_DEFER;
 361        }
 362
 363        /* register a panel for only the DSI-LINK1 interface */
 364        if (secondary) {
 365                sharp = devm_kzalloc(&dsi->dev, sizeof(*sharp), GFP_KERNEL);
 366                if (!sharp) {
 367                        put_device(&secondary->dev);
 368                        return -ENOMEM;
 369                }
 370
 371                mipi_dsi_set_drvdata(dsi, sharp);
 372
 373                sharp->link2 = secondary;
 374                sharp->link1 = dsi;
 375
 376                err = sharp_panel_add(sharp);
 377                if (err < 0) {
 378                        put_device(&secondary->dev);
 379                        return err;
 380                }
 381        }
 382
 383        err = mipi_dsi_attach(dsi);
 384        if (err < 0) {
 385                if (secondary)
 386                        sharp_panel_del(sharp);
 387
 388                return err;
 389        }
 390
 391        return 0;
 392}
 393
 394static int sharp_panel_remove(struct mipi_dsi_device *dsi)
 395{
 396        struct sharp_panel *sharp = mipi_dsi_get_drvdata(dsi);
 397        int err;
 398
 399        /* only detach from host for the DSI-LINK2 interface */
 400        if (!sharp) {
 401                mipi_dsi_detach(dsi);
 402                return 0;
 403        }
 404
 405        err = drm_panel_disable(&sharp->base);
 406        if (err < 0)
 407                dev_err(&dsi->dev, "failed to disable panel: %d\n", err);
 408
 409        err = mipi_dsi_detach(dsi);
 410        if (err < 0)
 411                dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", err);
 412
 413        sharp_panel_del(sharp);
 414
 415        return 0;
 416}
 417
 418static void sharp_panel_shutdown(struct mipi_dsi_device *dsi)
 419{
 420        struct sharp_panel *sharp = mipi_dsi_get_drvdata(dsi);
 421
 422        /* nothing to do for DSI-LINK2 */
 423        if (!sharp)
 424                return;
 425
 426        drm_panel_disable(&sharp->base);
 427}
 428
 429static struct mipi_dsi_driver sharp_panel_driver = {
 430        .driver = {
 431                .name = "panel-sharp-lq101r1sx01",
 432                .of_match_table = sharp_of_match,
 433        },
 434        .probe = sharp_panel_probe,
 435        .remove = sharp_panel_remove,
 436        .shutdown = sharp_panel_shutdown,
 437};
 438module_mipi_dsi_driver(sharp_panel_driver);
 439
 440MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
 441MODULE_DESCRIPTION("Sharp LQ101R1SX01 panel driver");
 442MODULE_LICENSE("GPL v2");
 443