linux/drivers/gpu/drm/panel/panel-simple.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2013, NVIDIA Corporation.  All rights reserved.
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sub license,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice (including the
  12 * next paragraph) shall be included in all copies or substantial portions
  13 * of the Software.
  14 *
  15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  21 * DEALINGS IN THE SOFTWARE.
  22 */
  23
  24#include <linux/backlight.h>
  25#include <linux/gpio/consumer.h>
  26#include <linux/module.h>
  27#include <linux/of_platform.h>
  28#include <linux/platform_device.h>
  29#include <linux/regulator/consumer.h>
  30
  31#include <drm/drmP.h>
  32#include <drm/drm_crtc.h>
  33#include <drm/drm_mipi_dsi.h>
  34#include <drm/drm_panel.h>
  35
  36#include <video/display_timing.h>
  37#include <video/videomode.h>
  38
  39struct panel_desc {
  40        const struct drm_display_mode *modes;
  41        unsigned int num_modes;
  42        const struct display_timing *timings;
  43        unsigned int num_timings;
  44
  45        unsigned int bpc;
  46
  47        /**
  48         * @width: width (in millimeters) of the panel's active display area
  49         * @height: height (in millimeters) of the panel's active display area
  50         */
  51        struct {
  52                unsigned int width;
  53                unsigned int height;
  54        } size;
  55
  56        /**
  57         * @prepare: the time (in milliseconds) that it takes for the panel to
  58         *           become ready and start receiving video data
  59         * @enable: the time (in milliseconds) that it takes for the panel to
  60         *          display the first valid frame after starting to receive
  61         *          video data
  62         * @disable: the time (in milliseconds) that it takes for the panel to
  63         *           turn the display off (no content is visible)
  64         * @unprepare: the time (in milliseconds) that it takes for the panel
  65         *             to power itself down completely
  66         */
  67        struct {
  68                unsigned int prepare;
  69                unsigned int enable;
  70                unsigned int disable;
  71                unsigned int unprepare;
  72        } delay;
  73
  74        u32 bus_format;
  75        u32 bus_flags;
  76};
  77
  78struct panel_simple {
  79        struct drm_panel base;
  80        bool prepared;
  81        bool enabled;
  82
  83        const struct panel_desc *desc;
  84
  85        struct backlight_device *backlight;
  86        struct regulator *supply;
  87        struct i2c_adapter *ddc;
  88
  89        struct gpio_desc *enable_gpio;
  90};
  91
  92static inline struct panel_simple *to_panel_simple(struct drm_panel *panel)
  93{
  94        return container_of(panel, struct panel_simple, base);
  95}
  96
  97static int panel_simple_get_fixed_modes(struct panel_simple *panel)
  98{
  99        struct drm_connector *connector = panel->base.connector;
 100        struct drm_device *drm = panel->base.drm;
 101        struct drm_display_mode *mode;
 102        unsigned int i, num = 0;
 103
 104        if (!panel->desc)
 105                return 0;
 106
 107        for (i = 0; i < panel->desc->num_timings; i++) {
 108                const struct display_timing *dt = &panel->desc->timings[i];
 109                struct videomode vm;
 110
 111                videomode_from_timing(dt, &vm);
 112                mode = drm_mode_create(drm);
 113                if (!mode) {
 114                        dev_err(drm->dev, "failed to add mode %ux%u\n",
 115                                dt->hactive.typ, dt->vactive.typ);
 116                        continue;
 117                }
 118
 119                drm_display_mode_from_videomode(&vm, mode);
 120
 121                mode->type |= DRM_MODE_TYPE_DRIVER;
 122
 123                if (panel->desc->num_timings == 1)
 124                        mode->type |= DRM_MODE_TYPE_PREFERRED;
 125
 126                drm_mode_probed_add(connector, mode);
 127                num++;
 128        }
 129
 130        for (i = 0; i < panel->desc->num_modes; i++) {
 131                const struct drm_display_mode *m = &panel->desc->modes[i];
 132
 133                mode = drm_mode_duplicate(drm, m);
 134                if (!mode) {
 135                        dev_err(drm->dev, "failed to add mode %ux%u@%u\n",
 136                                m->hdisplay, m->vdisplay, m->vrefresh);
 137                        continue;
 138                }
 139
 140                mode->type |= DRM_MODE_TYPE_DRIVER;
 141
 142                if (panel->desc->num_modes == 1)
 143                        mode->type |= DRM_MODE_TYPE_PREFERRED;
 144
 145                drm_mode_set_name(mode);
 146
 147                drm_mode_probed_add(connector, mode);
 148                num++;
 149        }
 150
 151        connector->display_info.bpc = panel->desc->bpc;
 152        connector->display_info.width_mm = panel->desc->size.width;
 153        connector->display_info.height_mm = panel->desc->size.height;
 154        if (panel->desc->bus_format)
 155                drm_display_info_set_bus_formats(&connector->display_info,
 156                                                 &panel->desc->bus_format, 1);
 157        connector->display_info.bus_flags = panel->desc->bus_flags;
 158
 159        return num;
 160}
 161
 162static int panel_simple_disable(struct drm_panel *panel)
 163{
 164        struct panel_simple *p = to_panel_simple(panel);
 165
 166        if (!p->enabled)
 167                return 0;
 168
 169        if (p->backlight) {
 170                p->backlight->props.power = FB_BLANK_POWERDOWN;
 171                p->backlight->props.state |= BL_CORE_FBBLANK;
 172                backlight_update_status(p->backlight);
 173        }
 174
 175        if (p->desc->delay.disable)
 176                msleep(p->desc->delay.disable);
 177
 178        p->enabled = false;
 179
 180        return 0;
 181}
 182
 183static int panel_simple_unprepare(struct drm_panel *panel)
 184{
 185        struct panel_simple *p = to_panel_simple(panel);
 186
 187        if (!p->prepared)
 188                return 0;
 189
 190        gpiod_set_value_cansleep(p->enable_gpio, 0);
 191
 192        regulator_disable(p->supply);
 193
 194        if (p->desc->delay.unprepare)
 195                msleep(p->desc->delay.unprepare);
 196
 197        p->prepared = false;
 198
 199        return 0;
 200}
 201
 202static int panel_simple_prepare(struct drm_panel *panel)
 203{
 204        struct panel_simple *p = to_panel_simple(panel);
 205        int err;
 206
 207        if (p->prepared)
 208                return 0;
 209
 210        err = regulator_enable(p->supply);
 211        if (err < 0) {
 212                dev_err(panel->dev, "failed to enable supply: %d\n", err);
 213                return err;
 214        }
 215
 216        gpiod_set_value_cansleep(p->enable_gpio, 1);
 217
 218        if (p->desc->delay.prepare)
 219                msleep(p->desc->delay.prepare);
 220
 221        p->prepared = true;
 222
 223        return 0;
 224}
 225
 226static int panel_simple_enable(struct drm_panel *panel)
 227{
 228        struct panel_simple *p = to_panel_simple(panel);
 229
 230        if (p->enabled)
 231                return 0;
 232
 233        if (p->desc->delay.enable)
 234                msleep(p->desc->delay.enable);
 235
 236        if (p->backlight) {
 237                p->backlight->props.state &= ~BL_CORE_FBBLANK;
 238                p->backlight->props.power = FB_BLANK_UNBLANK;
 239                backlight_update_status(p->backlight);
 240        }
 241
 242        p->enabled = true;
 243
 244        return 0;
 245}
 246
 247static int panel_simple_get_modes(struct drm_panel *panel)
 248{
 249        struct panel_simple *p = to_panel_simple(panel);
 250        int num = 0;
 251
 252        /* probe EDID if a DDC bus is available */
 253        if (p->ddc) {
 254                struct edid *edid = drm_get_edid(panel->connector, p->ddc);
 255                drm_mode_connector_update_edid_property(panel->connector, edid);
 256                if (edid) {
 257                        num += drm_add_edid_modes(panel->connector, edid);
 258                        kfree(edid);
 259                }
 260        }
 261
 262        /* add hard-coded panel modes */
 263        num += panel_simple_get_fixed_modes(p);
 264
 265        return num;
 266}
 267
 268static int panel_simple_get_timings(struct drm_panel *panel,
 269                                    unsigned int num_timings,
 270                                    struct display_timing *timings)
 271{
 272        struct panel_simple *p = to_panel_simple(panel);
 273        unsigned int i;
 274
 275        if (p->desc->num_timings < num_timings)
 276                num_timings = p->desc->num_timings;
 277
 278        if (timings)
 279                for (i = 0; i < num_timings; i++)
 280                        timings[i] = p->desc->timings[i];
 281
 282        return p->desc->num_timings;
 283}
 284
 285static const struct drm_panel_funcs panel_simple_funcs = {
 286        .disable = panel_simple_disable,
 287        .unprepare = panel_simple_unprepare,
 288        .prepare = panel_simple_prepare,
 289        .enable = panel_simple_enable,
 290        .get_modes = panel_simple_get_modes,
 291        .get_timings = panel_simple_get_timings,
 292};
 293
 294static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
 295{
 296        struct device_node *backlight, *ddc;
 297        struct panel_simple *panel;
 298        int err;
 299
 300        panel = devm_kzalloc(dev, sizeof(*panel), GFP_KERNEL);
 301        if (!panel)
 302                return -ENOMEM;
 303
 304        panel->enabled = false;
 305        panel->prepared = false;
 306        panel->desc = desc;
 307
 308        panel->supply = devm_regulator_get(dev, "power");
 309        if (IS_ERR(panel->supply))
 310                return PTR_ERR(panel->supply);
 311
 312        panel->enable_gpio = devm_gpiod_get_optional(dev, "enable",
 313                                                     GPIOD_OUT_LOW);
 314        if (IS_ERR(panel->enable_gpio)) {
 315                err = PTR_ERR(panel->enable_gpio);
 316                if (err != -EPROBE_DEFER)
 317                        dev_err(dev, "failed to request GPIO: %d\n", err);
 318                return err;
 319        }
 320
 321        backlight = of_parse_phandle(dev->of_node, "backlight", 0);
 322        if (backlight) {
 323                panel->backlight = of_find_backlight_by_node(backlight);
 324                of_node_put(backlight);
 325
 326                if (!panel->backlight)
 327                        return -EPROBE_DEFER;
 328        }
 329
 330        ddc = of_parse_phandle(dev->of_node, "ddc-i2c-bus", 0);
 331        if (ddc) {
 332                panel->ddc = of_find_i2c_adapter_by_node(ddc);
 333                of_node_put(ddc);
 334
 335                if (!panel->ddc) {
 336                        err = -EPROBE_DEFER;
 337                        goto free_backlight;
 338                }
 339        }
 340
 341        drm_panel_init(&panel->base);
 342        panel->base.dev = dev;
 343        panel->base.funcs = &panel_simple_funcs;
 344
 345        err = drm_panel_add(&panel->base);
 346        if (err < 0)
 347                goto free_ddc;
 348
 349        dev_set_drvdata(dev, panel);
 350
 351        return 0;
 352
 353free_ddc:
 354        if (panel->ddc)
 355                put_device(&panel->ddc->dev);
 356free_backlight:
 357        if (panel->backlight)
 358                put_device(&panel->backlight->dev);
 359
 360        return err;
 361}
 362
 363static int panel_simple_remove(struct device *dev)
 364{
 365        struct panel_simple *panel = dev_get_drvdata(dev);
 366
 367        drm_panel_detach(&panel->base);
 368        drm_panel_remove(&panel->base);
 369
 370        panel_simple_disable(&panel->base);
 371        panel_simple_unprepare(&panel->base);
 372
 373        if (panel->ddc)
 374                put_device(&panel->ddc->dev);
 375
 376        if (panel->backlight)
 377                put_device(&panel->backlight->dev);
 378
 379        return 0;
 380}
 381
 382static void panel_simple_shutdown(struct device *dev)
 383{
 384        struct panel_simple *panel = dev_get_drvdata(dev);
 385
 386        panel_simple_disable(&panel->base);
 387        panel_simple_unprepare(&panel->base);
 388}
 389
 390static const struct drm_display_mode ampire_am_480272h3tmqw_t01h_mode = {
 391        .clock = 9000,
 392        .hdisplay = 480,
 393        .hsync_start = 480 + 2,
 394        .hsync_end = 480 + 2 + 41,
 395        .htotal = 480 + 2 + 41 + 2,
 396        .vdisplay = 272,
 397        .vsync_start = 272 + 2,
 398        .vsync_end = 272 + 2 + 10,
 399        .vtotal = 272 + 2 + 10 + 2,
 400        .vrefresh = 60,
 401        .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC,
 402};
 403
 404static const struct panel_desc ampire_am_480272h3tmqw_t01h = {
 405        .modes = &ampire_am_480272h3tmqw_t01h_mode,
 406        .num_modes = 1,
 407        .bpc = 8,
 408        .size = {
 409                .width = 105,
 410                .height = 67,
 411        },
 412        .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
 413};
 414
 415static const struct drm_display_mode ampire_am800480r3tmqwa1h_mode = {
 416        .clock = 33333,
 417        .hdisplay = 800,
 418        .hsync_start = 800 + 0,
 419        .hsync_end = 800 + 0 + 255,
 420        .htotal = 800 + 0 + 255 + 0,
 421        .vdisplay = 480,
 422        .vsync_start = 480 + 2,
 423        .vsync_end = 480 + 2 + 45,
 424        .vtotal = 480 + 2 + 45 + 0,
 425        .vrefresh = 60,
 426        .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC,
 427};
 428
 429static const struct panel_desc ampire_am800480r3tmqwa1h = {
 430        .modes = &ampire_am800480r3tmqwa1h_mode,
 431        .num_modes = 1,
 432        .bpc = 6,
 433        .size = {
 434                .width = 152,
 435                .height = 91,
 436        },
 437        .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
 438};
 439
 440static const struct drm_display_mode auo_b101aw03_mode = {
 441        .clock = 51450,
 442        .hdisplay = 1024,
 443        .hsync_start = 1024 + 156,
 444        .hsync_end = 1024 + 156 + 8,
 445        .htotal = 1024 + 156 + 8 + 156,
 446        .vdisplay = 600,
 447        .vsync_start = 600 + 16,
 448        .vsync_end = 600 + 16 + 6,
 449        .vtotal = 600 + 16 + 6 + 16,
 450        .vrefresh = 60,
 451};
 452
 453static const struct panel_desc auo_b101aw03 = {
 454        .modes = &auo_b101aw03_mode,
 455        .num_modes = 1,
 456        .bpc = 6,
 457        .size = {
 458                .width = 223,
 459                .height = 125,
 460        },
 461};
 462
 463static const struct drm_display_mode auo_b101ean01_mode = {
 464        .clock = 72500,
 465        .hdisplay = 1280,
 466        .hsync_start = 1280 + 119,
 467        .hsync_end = 1280 + 119 + 32,
 468        .htotal = 1280 + 119 + 32 + 21,
 469        .vdisplay = 800,
 470        .vsync_start = 800 + 4,
 471        .vsync_end = 800 + 4 + 20,
 472        .vtotal = 800 + 4 + 20 + 8,
 473        .vrefresh = 60,
 474};
 475
 476static const struct panel_desc auo_b101ean01 = {
 477        .modes = &auo_b101ean01_mode,
 478        .num_modes = 1,
 479        .bpc = 6,
 480        .size = {
 481                .width = 217,
 482                .height = 136,
 483        },
 484};
 485
 486static const struct drm_display_mode auo_b101xtn01_mode = {
 487        .clock = 72000,
 488        .hdisplay = 1366,
 489        .hsync_start = 1366 + 20,
 490        .hsync_end = 1366 + 20 + 70,
 491        .htotal = 1366 + 20 + 70,
 492        .vdisplay = 768,
 493        .vsync_start = 768 + 14,
 494        .vsync_end = 768 + 14 + 42,
 495        .vtotal = 768 + 14 + 42,
 496        .vrefresh = 60,
 497        .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
 498};
 499
 500static const struct panel_desc auo_b101xtn01 = {
 501        .modes = &auo_b101xtn01_mode,
 502        .num_modes = 1,
 503        .bpc = 6,
 504        .size = {
 505                .width = 223,
 506                .height = 125,
 507        },
 508};
 509
 510static const struct drm_display_mode auo_b116xw03_mode = {
 511        .clock = 70589,
 512        .hdisplay = 1366,
 513        .hsync_start = 1366 + 40,
 514        .hsync_end = 1366 + 40 + 40,
 515        .htotal = 1366 + 40 + 40 + 32,
 516        .vdisplay = 768,
 517        .vsync_start = 768 + 10,
 518        .vsync_end = 768 + 10 + 12,
 519        .vtotal = 768 + 10 + 12 + 6,
 520        .vrefresh = 60,
 521};
 522
 523static const struct panel_desc auo_b116xw03 = {
 524        .modes = &auo_b116xw03_mode,
 525        .num_modes = 1,
 526        .bpc = 6,
 527        .size = {
 528                .width = 256,
 529                .height = 144,
 530        },
 531};
 532
 533static const struct drm_display_mode auo_b133xtn01_mode = {
 534        .clock = 69500,
 535        .hdisplay = 1366,
 536        .hsync_start = 1366 + 48,
 537        .hsync_end = 1366 + 48 + 32,
 538        .htotal = 1366 + 48 + 32 + 20,
 539        .vdisplay = 768,
 540        .vsync_start = 768 + 3,
 541        .vsync_end = 768 + 3 + 6,
 542        .vtotal = 768 + 3 + 6 + 13,
 543        .vrefresh = 60,
 544};
 545
 546static const struct panel_desc auo_b133xtn01 = {
 547        .modes = &auo_b133xtn01_mode,
 548        .num_modes = 1,
 549        .bpc = 6,
 550        .size = {
 551                .width = 293,
 552                .height = 165,
 553        },
 554};
 555
 556static const struct drm_display_mode auo_b133htn01_mode = {
 557        .clock = 150660,
 558        .hdisplay = 1920,
 559        .hsync_start = 1920 + 172,
 560        .hsync_end = 1920 + 172 + 80,
 561        .htotal = 1920 + 172 + 80 + 60,
 562        .vdisplay = 1080,
 563        .vsync_start = 1080 + 25,
 564        .vsync_end = 1080 + 25 + 10,
 565        .vtotal = 1080 + 25 + 10 + 10,
 566        .vrefresh = 60,
 567};
 568
 569static const struct panel_desc auo_b133htn01 = {
 570        .modes = &auo_b133htn01_mode,
 571        .num_modes = 1,
 572        .bpc = 6,
 573        .size = {
 574                .width = 293,
 575                .height = 165,
 576        },
 577        .delay = {
 578                .prepare = 105,
 579                .enable = 20,
 580                .unprepare = 50,
 581        },
 582};
 583
 584static const struct drm_display_mode auo_g104sn02_mode = {
 585        .clock = 40000,
 586        .hdisplay = 800,
 587        .hsync_start = 800 + 40,
 588        .hsync_end = 800 + 40 + 216,
 589        .htotal = 800 + 40 + 216 + 128,
 590        .vdisplay = 600,
 591        .vsync_start = 600 + 10,
 592        .vsync_end = 600 + 10 + 35,
 593        .vtotal = 600 + 10 + 35 + 2,
 594        .vrefresh = 60,
 595};
 596
 597static const struct panel_desc auo_g104sn02 = {
 598        .modes = &auo_g104sn02_mode,
 599        .num_modes = 1,
 600        .bpc = 8,
 601        .size = {
 602                .width = 211,
 603                .height = 158,
 604        },
 605};
 606
 607static const struct display_timing auo_g133han01_timings = {
 608        .pixelclock = { 134000000, 141200000, 149000000 },
 609        .hactive = { 1920, 1920, 1920 },
 610        .hfront_porch = { 39, 58, 77 },
 611        .hback_porch = { 59, 88, 117 },
 612        .hsync_len = { 28, 42, 56 },
 613        .vactive = { 1080, 1080, 1080 },
 614        .vfront_porch = { 3, 8, 11 },
 615        .vback_porch = { 5, 14, 19 },
 616        .vsync_len = { 4, 14, 19 },
 617};
 618
 619static const struct panel_desc auo_g133han01 = {
 620        .timings = &auo_g133han01_timings,
 621        .num_timings = 1,
 622        .bpc = 8,
 623        .size = {
 624                .width = 293,
 625                .height = 165,
 626        },
 627        .delay = {
 628                .prepare = 200,
 629                .enable = 50,
 630                .disable = 50,
 631                .unprepare = 1000,
 632        },
 633        .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
 634};
 635
 636static const struct display_timing auo_g185han01_timings = {
 637        .pixelclock = { 120000000, 144000000, 175000000 },
 638        .hactive = { 1920, 1920, 1920 },
 639        .hfront_porch = { 18, 60, 74 },
 640        .hback_porch = { 12, 44, 54 },
 641        .hsync_len = { 10, 24, 32 },
 642        .vactive = { 1080, 1080, 1080 },
 643        .vfront_porch = { 6, 10, 40 },
 644        .vback_porch = { 2, 5, 20 },
 645        .vsync_len = { 2, 5, 20 },
 646};
 647
 648static const struct panel_desc auo_g185han01 = {
 649        .timings = &auo_g185han01_timings,
 650        .num_timings = 1,
 651        .bpc = 8,
 652        .size = {
 653                .width = 409,
 654                .height = 230,
 655        },
 656        .delay = {
 657                .prepare = 50,
 658                .enable = 200,
 659                .disable = 110,
 660                .unprepare = 1000,
 661        },
 662        .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
 663};
 664
 665static const struct display_timing auo_p320hvn03_timings = {
 666        .pixelclock = { 106000000, 148500000, 164000000 },
 667        .hactive = { 1920, 1920, 1920 },
 668        .hfront_porch = { 25, 50, 130 },
 669        .hback_porch = { 25, 50, 130 },
 670        .hsync_len = { 20, 40, 105 },
 671        .vactive = { 1080, 1080, 1080 },
 672        .vfront_porch = { 8, 17, 150 },
 673        .vback_porch = { 8, 17, 150 },
 674        .vsync_len = { 4, 11, 100 },
 675};
 676
 677static const struct panel_desc auo_p320hvn03 = {
 678        .timings = &auo_p320hvn03_timings,
 679        .num_timings = 1,
 680        .bpc = 8,
 681        .size = {
 682                .width = 698,
 683                .height = 393,
 684        },
 685        .delay = {
 686                .prepare = 1,
 687                .enable = 450,
 688                .unprepare = 500,
 689        },
 690        .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
 691};
 692
 693static const struct drm_display_mode auo_t215hvn01_mode = {
 694        .clock = 148800,
 695        .hdisplay = 1920,
 696        .hsync_start = 1920 + 88,
 697        .hsync_end = 1920 + 88 + 44,
 698        .htotal = 1920 + 88 + 44 + 148,
 699        .vdisplay = 1080,
 700        .vsync_start = 1080 + 4,
 701        .vsync_end = 1080 + 4 + 5,
 702        .vtotal = 1080 + 4 + 5 + 36,
 703        .vrefresh = 60,
 704};
 705
 706static const struct panel_desc auo_t215hvn01 = {
 707        .modes = &auo_t215hvn01_mode,
 708        .num_modes = 1,
 709        .bpc = 8,
 710        .size = {
 711                .width = 430,
 712                .height = 270,
 713        },
 714        .delay = {
 715                .disable = 5,
 716                .unprepare = 1000,
 717        }
 718};
 719
 720static const struct drm_display_mode avic_tm070ddh03_mode = {
 721        .clock = 51200,
 722        .hdisplay = 1024,
 723        .hsync_start = 1024 + 160,
 724        .hsync_end = 1024 + 160 + 4,
 725        .htotal = 1024 + 160 + 4 + 156,
 726        .vdisplay = 600,
 727        .vsync_start = 600 + 17,
 728        .vsync_end = 600 + 17 + 1,
 729        .vtotal = 600 + 17 + 1 + 17,
 730        .vrefresh = 60,
 731};
 732
 733static const struct panel_desc avic_tm070ddh03 = {
 734        .modes = &avic_tm070ddh03_mode,
 735        .num_modes = 1,
 736        .bpc = 8,
 737        .size = {
 738                .width = 154,
 739                .height = 90,
 740        },
 741        .delay = {
 742                .prepare = 20,
 743                .enable = 200,
 744                .disable = 200,
 745        },
 746};
 747
 748static const struct drm_display_mode boe_nv101wxmn51_modes[] = {
 749        {
 750                .clock = 71900,
 751                .hdisplay = 1280,
 752                .hsync_start = 1280 + 48,
 753                .hsync_end = 1280 + 48 + 32,
 754                .htotal = 1280 + 48 + 32 + 80,
 755                .vdisplay = 800,
 756                .vsync_start = 800 + 3,
 757                .vsync_end = 800 + 3 + 5,
 758                .vtotal = 800 + 3 + 5 + 24,
 759                .vrefresh = 60,
 760        },
 761        {
 762                .clock = 57500,
 763                .hdisplay = 1280,
 764                .hsync_start = 1280 + 48,
 765                .hsync_end = 1280 + 48 + 32,
 766                .htotal = 1280 + 48 + 32 + 80,
 767                .vdisplay = 800,
 768                .vsync_start = 800 + 3,
 769                .vsync_end = 800 + 3 + 5,
 770                .vtotal = 800 + 3 + 5 + 24,
 771                .vrefresh = 48,
 772        },
 773};
 774
 775static const struct panel_desc boe_nv101wxmn51 = {
 776        .modes = boe_nv101wxmn51_modes,
 777        .num_modes = ARRAY_SIZE(boe_nv101wxmn51_modes),
 778        .bpc = 8,
 779        .size = {
 780                .width = 217,
 781                .height = 136,
 782        },
 783        .delay = {
 784                .prepare = 210,
 785                .enable = 50,
 786                .unprepare = 160,
 787        },
 788};
 789
 790static const struct drm_display_mode chunghwa_claa070wp03xg_mode = {
 791        .clock = 66770,
 792        .hdisplay = 800,
 793        .hsync_start = 800 + 49,
 794        .hsync_end = 800 + 49 + 33,
 795        .htotal = 800 + 49 + 33 + 17,
 796        .vdisplay = 1280,
 797        .vsync_start = 1280 + 1,
 798        .vsync_end = 1280 + 1 + 7,
 799        .vtotal = 1280 + 1 + 7 + 15,
 800        .vrefresh = 60,
 801        .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
 802};
 803
 804static const struct panel_desc chunghwa_claa070wp03xg = {
 805        .modes = &chunghwa_claa070wp03xg_mode,
 806        .num_modes = 1,
 807        .bpc = 6,
 808        .size = {
 809                .width = 94,
 810                .height = 150,
 811        },
 812};
 813
 814static const struct drm_display_mode chunghwa_claa101wa01a_mode = {
 815        .clock = 72070,
 816        .hdisplay = 1366,
 817        .hsync_start = 1366 + 58,
 818        .hsync_end = 1366 + 58 + 58,
 819        .htotal = 1366 + 58 + 58 + 58,
 820        .vdisplay = 768,
 821        .vsync_start = 768 + 4,
 822        .vsync_end = 768 + 4 + 4,
 823        .vtotal = 768 + 4 + 4 + 4,
 824        .vrefresh = 60,
 825};
 826
 827static const struct panel_desc chunghwa_claa101wa01a = {
 828        .modes = &chunghwa_claa101wa01a_mode,
 829        .num_modes = 1,
 830        .bpc = 6,
 831        .size = {
 832                .width = 220,
 833                .height = 120,
 834        },
 835};
 836
 837static const struct drm_display_mode chunghwa_claa101wb01_mode = {
 838        .clock = 69300,
 839        .hdisplay = 1366,
 840        .hsync_start = 1366 + 48,
 841        .hsync_end = 1366 + 48 + 32,
 842        .htotal = 1366 + 48 + 32 + 20,
 843        .vdisplay = 768,
 844        .vsync_start = 768 + 16,
 845        .vsync_end = 768 + 16 + 8,
 846        .vtotal = 768 + 16 + 8 + 16,
 847        .vrefresh = 60,
 848};
 849
 850static const struct panel_desc chunghwa_claa101wb01 = {
 851        .modes = &chunghwa_claa101wb01_mode,
 852        .num_modes = 1,
 853        .bpc = 6,
 854        .size = {
 855                .width = 223,
 856                .height = 125,
 857        },
 858};
 859
 860static const struct drm_display_mode edt_et057090dhu_mode = {
 861        .clock = 25175,
 862        .hdisplay = 640,
 863        .hsync_start = 640 + 16,
 864        .hsync_end = 640 + 16 + 30,
 865        .htotal = 640 + 16 + 30 + 114,
 866        .vdisplay = 480,
 867        .vsync_start = 480 + 10,
 868        .vsync_end = 480 + 10 + 3,
 869        .vtotal = 480 + 10 + 3 + 32,
 870        .vrefresh = 60,
 871        .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
 872};
 873
 874static const struct panel_desc edt_et057090dhu = {
 875        .modes = &edt_et057090dhu_mode,
 876        .num_modes = 1,
 877        .bpc = 6,
 878        .size = {
 879                .width = 115,
 880                .height = 86,
 881        },
 882        .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
 883        .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_NEGEDGE,
 884};
 885
 886static const struct drm_display_mode edt_etm0700g0dh6_mode = {
 887        .clock = 33260,
 888        .hdisplay = 800,
 889        .hsync_start = 800 + 40,
 890        .hsync_end = 800 + 40 + 128,
 891        .htotal = 800 + 40 + 128 + 88,
 892        .vdisplay = 480,
 893        .vsync_start = 480 + 10,
 894        .vsync_end = 480 + 10 + 2,
 895        .vtotal = 480 + 10 + 2 + 33,
 896        .vrefresh = 60,
 897        .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
 898};
 899
 900static const struct panel_desc edt_etm0700g0dh6 = {
 901        .modes = &edt_etm0700g0dh6_mode,
 902        .num_modes = 1,
 903        .bpc = 6,
 904        .size = {
 905                .width = 152,
 906                .height = 91,
 907        },
 908        .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
 909        .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_NEGEDGE,
 910};
 911
 912static const struct drm_display_mode foxlink_fl500wvr00_a0t_mode = {
 913        .clock = 32260,
 914        .hdisplay = 800,
 915        .hsync_start = 800 + 168,
 916        .hsync_end = 800 + 168 + 64,
 917        .htotal = 800 + 168 + 64 + 88,
 918        .vdisplay = 480,
 919        .vsync_start = 480 + 37,
 920        .vsync_end = 480 + 37 + 2,
 921        .vtotal = 480 + 37 + 2 + 8,
 922        .vrefresh = 60,
 923};
 924
 925static const struct panel_desc foxlink_fl500wvr00_a0t = {
 926        .modes = &foxlink_fl500wvr00_a0t_mode,
 927        .num_modes = 1,
 928        .bpc = 8,
 929        .size = {
 930                .width = 108,
 931                .height = 65,
 932        },
 933        .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
 934};
 935
 936static const struct drm_display_mode giantplus_gpg482739qs5_mode = {
 937        .clock = 9000,
 938        .hdisplay = 480,
 939        .hsync_start = 480 + 5,
 940        .hsync_end = 480 + 5 + 1,
 941        .htotal = 480 + 5 + 1 + 40,
 942        .vdisplay = 272,
 943        .vsync_start = 272 + 8,
 944        .vsync_end = 272 + 8 + 1,
 945        .vtotal = 272 + 8 + 1 + 8,
 946        .vrefresh = 60,
 947};
 948
 949static const struct panel_desc giantplus_gpg482739qs5 = {
 950        .modes = &giantplus_gpg482739qs5_mode,
 951        .num_modes = 1,
 952        .bpc = 8,
 953        .size = {
 954                .width = 95,
 955                .height = 54,
 956        },
 957        .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
 958};
 959
 960static const struct display_timing hannstar_hsd070pww1_timing = {
 961        .pixelclock = { 64300000, 71100000, 82000000 },
 962        .hactive = { 1280, 1280, 1280 },
 963        .hfront_porch = { 1, 1, 10 },
 964        .hback_porch = { 1, 1, 10 },
 965        /*
 966         * According to the data sheet, the minimum horizontal blanking interval
 967         * is 54 clocks (1 + 52 + 1), but tests with a Nitrogen6X have shown the
 968         * minimum working horizontal blanking interval to be 60 clocks.
 969         */
 970        .hsync_len = { 58, 158, 661 },
 971        .vactive = { 800, 800, 800 },
 972        .vfront_porch = { 1, 1, 10 },
 973        .vback_porch = { 1, 1, 10 },
 974        .vsync_len = { 1, 21, 203 },
 975        .flags = DISPLAY_FLAGS_DE_HIGH,
 976};
 977
 978static const struct panel_desc hannstar_hsd070pww1 = {
 979        .timings = &hannstar_hsd070pww1_timing,
 980        .num_timings = 1,
 981        .bpc = 6,
 982        .size = {
 983                .width = 151,
 984                .height = 94,
 985        },
 986        .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
 987};
 988
 989static const struct display_timing hannstar_hsd100pxn1_timing = {
 990        .pixelclock = { 55000000, 65000000, 75000000 },
 991        .hactive = { 1024, 1024, 1024 },
 992        .hfront_porch = { 40, 40, 40 },
 993        .hback_porch = { 220, 220, 220 },
 994        .hsync_len = { 20, 60, 100 },
 995        .vactive = { 768, 768, 768 },
 996        .vfront_porch = { 7, 7, 7 },
 997        .vback_porch = { 21, 21, 21 },
 998        .vsync_len = { 10, 10, 10 },
 999        .flags = DISPLAY_FLAGS_DE_HIGH,
1000};
1001
1002static const struct panel_desc hannstar_hsd100pxn1 = {
1003        .timings = &hannstar_hsd100pxn1_timing,
1004        .num_timings = 1,
1005        .bpc = 6,
1006        .size = {
1007                .width = 203,
1008                .height = 152,
1009        },
1010        .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
1011};
1012
1013static const struct drm_display_mode hitachi_tx23d38vm0caa_mode = {
1014        .clock = 33333,
1015        .hdisplay = 800,
1016        .hsync_start = 800 + 85,
1017        .hsync_end = 800 + 85 + 86,
1018        .htotal = 800 + 85 + 86 + 85,
1019        .vdisplay = 480,
1020        .vsync_start = 480 + 16,
1021        .vsync_end = 480 + 16 + 13,
1022        .vtotal = 480 + 16 + 13 + 16,
1023        .vrefresh = 60,
1024};
1025
1026static const struct panel_desc hitachi_tx23d38vm0caa = {
1027        .modes = &hitachi_tx23d38vm0caa_mode,
1028        .num_modes = 1,
1029        .bpc = 6,
1030        .size = {
1031                .width = 195,
1032                .height = 117,
1033        },
1034        .delay = {
1035                .enable = 160,
1036                .disable = 160,
1037        },
1038};
1039
1040static const struct drm_display_mode innolux_at043tn24_mode = {
1041        .clock = 9000,
1042        .hdisplay = 480,
1043        .hsync_start = 480 + 2,
1044        .hsync_end = 480 + 2 + 41,
1045        .htotal = 480 + 2 + 41 + 2,
1046        .vdisplay = 272,
1047        .vsync_start = 272 + 2,
1048        .vsync_end = 272 + 2 + 10,
1049        .vtotal = 272 + 2 + 10 + 2,
1050        .vrefresh = 60,
1051        .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
1052};
1053
1054static const struct panel_desc innolux_at043tn24 = {
1055        .modes = &innolux_at043tn24_mode,
1056        .num_modes = 1,
1057        .bpc = 8,
1058        .size = {
1059                .width = 95,
1060                .height = 54,
1061        },
1062        .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
1063        .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_POSEDGE,
1064};
1065
1066static const struct drm_display_mode innolux_at070tn92_mode = {
1067        .clock = 33333,
1068        .hdisplay = 800,
1069        .hsync_start = 800 + 210,
1070        .hsync_end = 800 + 210 + 20,
1071        .htotal = 800 + 210 + 20 + 46,
1072        .vdisplay = 480,
1073        .vsync_start = 480 + 22,
1074        .vsync_end = 480 + 22 + 10,
1075        .vtotal = 480 + 22 + 23 + 10,
1076        .vrefresh = 60,
1077};
1078
1079static const struct panel_desc innolux_at070tn92 = {
1080        .modes = &innolux_at070tn92_mode,
1081        .num_modes = 1,
1082        .size = {
1083                .width = 154,
1084                .height = 86,
1085        },
1086        .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
1087};
1088
1089static const struct display_timing innolux_g101ice_l01_timing = {
1090        .pixelclock = { 60400000, 71100000, 74700000 },
1091        .hactive = { 1280, 1280, 1280 },
1092        .hfront_porch = { 41, 80, 100 },
1093        .hback_porch = { 40, 79, 99 },
1094        .hsync_len = { 1, 1, 1 },
1095        .vactive = { 800, 800, 800 },
1096        .vfront_porch = { 5, 11, 14 },
1097        .vback_porch = { 4, 11, 14 },
1098        .vsync_len = { 1, 1, 1 },
1099        .flags = DISPLAY_FLAGS_DE_HIGH,
1100};
1101
1102static const struct panel_desc innolux_g101ice_l01 = {
1103        .timings = &innolux_g101ice_l01_timing,
1104        .num_timings = 1,
1105        .bpc = 8,
1106        .size = {
1107                .width = 217,
1108                .height = 135,
1109        },
1110        .delay = {
1111                .enable = 200,
1112                .disable = 200,
1113        },
1114        .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
1115};
1116
1117static const struct display_timing innolux_g121i1_l01_timing = {
1118        .pixelclock = { 67450000, 71000000, 74550000 },
1119        .hactive = { 1280, 1280, 1280 },
1120        .hfront_porch = { 40, 80, 160 },
1121        .hback_porch = { 39, 79, 159 },
1122        .hsync_len = { 1, 1, 1 },
1123        .vactive = { 800, 800, 800 },
1124        .vfront_porch = { 5, 11, 100 },
1125        .vback_porch = { 4, 11, 99 },
1126        .vsync_len = { 1, 1, 1 },
1127};
1128
1129static const struct panel_desc innolux_g121i1_l01 = {
1130        .timings = &innolux_g121i1_l01_timing,
1131        .num_timings = 1,
1132        .bpc = 6,
1133        .size = {
1134                .width = 261,
1135                .height = 163,
1136        },
1137        .delay = {
1138                .enable = 200,
1139                .disable = 20,
1140        },
1141        .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
1142};
1143
1144static const struct drm_display_mode innolux_g121x1_l03_mode = {
1145        .clock = 65000,
1146        .hdisplay = 1024,
1147        .hsync_start = 1024 + 0,
1148        .hsync_end = 1024 + 1,
1149        .htotal = 1024 + 0 + 1 + 320,
1150        .vdisplay = 768,
1151        .vsync_start = 768 + 38,
1152        .vsync_end = 768 + 38 + 1,
1153        .vtotal = 768 + 38 + 1 + 0,
1154        .vrefresh = 60,
1155        .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
1156};
1157
1158static const struct panel_desc innolux_g121x1_l03 = {
1159        .modes = &innolux_g121x1_l03_mode,
1160        .num_modes = 1,
1161        .bpc = 6,
1162        .size = {
1163                .width = 246,
1164                .height = 185,
1165        },
1166        .delay = {
1167                .enable = 200,
1168                .unprepare = 200,
1169                .disable = 400,
1170        },
1171};
1172
1173static const struct drm_display_mode innolux_n116bge_mode = {
1174        .clock = 76420,
1175        .hdisplay = 1366,
1176        .hsync_start = 1366 + 136,
1177        .hsync_end = 1366 + 136 + 30,
1178        .htotal = 1366 + 136 + 30 + 60,
1179        .vdisplay = 768,
1180        .vsync_start = 768 + 8,
1181        .vsync_end = 768 + 8 + 12,
1182        .vtotal = 768 + 8 + 12 + 12,
1183        .vrefresh = 60,
1184        .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
1185};
1186
1187static const struct panel_desc innolux_n116bge = {
1188        .modes = &innolux_n116bge_mode,
1189        .num_modes = 1,
1190        .bpc = 6,
1191        .size = {
1192                .width = 256,
1193                .height = 144,
1194        },
1195};
1196
1197static const struct drm_display_mode innolux_n156bge_l21_mode = {
1198        .clock = 69300,
1199        .hdisplay = 1366,
1200        .hsync_start = 1366 + 16,
1201        .hsync_end = 1366 + 16 + 34,
1202        .htotal = 1366 + 16 + 34 + 50,
1203        .vdisplay = 768,
1204        .vsync_start = 768 + 2,
1205        .vsync_end = 768 + 2 + 6,
1206        .vtotal = 768 + 2 + 6 + 12,
1207        .vrefresh = 60,
1208};
1209
1210static const struct panel_desc innolux_n156bge_l21 = {
1211        .modes = &innolux_n156bge_l21_mode,
1212        .num_modes = 1,
1213        .bpc = 6,
1214        .size = {
1215                .width = 344,
1216                .height = 193,
1217        },
1218};
1219
1220static const struct drm_display_mode innolux_zj070na_01p_mode = {
1221        .clock = 51501,
1222        .hdisplay = 1024,
1223        .hsync_start = 1024 + 128,
1224        .hsync_end = 1024 + 128 + 64,
1225        .htotal = 1024 + 128 + 64 + 128,
1226        .vdisplay = 600,
1227        .vsync_start = 600 + 16,
1228        .vsync_end = 600 + 16 + 4,
1229        .vtotal = 600 + 16 + 4 + 16,
1230        .vrefresh = 60,
1231};
1232
1233static const struct panel_desc innolux_zj070na_01p = {
1234        .modes = &innolux_zj070na_01p_mode,
1235        .num_modes = 1,
1236        .bpc = 6,
1237        .size = {
1238                .width = 154,
1239                .height = 90,
1240        },
1241};
1242
1243static const struct display_timing koe_tx31d200vm0baa_timing = {
1244        .pixelclock = { 39600000, 43200000, 48000000 },
1245        .hactive = { 1280, 1280, 1280 },
1246        .hfront_porch = { 16, 36, 56 },
1247        .hback_porch = { 16, 36, 56 },
1248        .hsync_len = { 8, 8, 8 },
1249        .vactive = { 480, 480, 480 },
1250        .vfront_porch = { 6, 21, 33.5 },
1251        .vback_porch = { 6, 21, 33.5 },
1252        .vsync_len = { 8, 8, 8 },
1253        .flags = DISPLAY_FLAGS_DE_HIGH,
1254};
1255
1256static const struct panel_desc koe_tx31d200vm0baa = {
1257        .timings = &koe_tx31d200vm0baa_timing,
1258        .num_timings = 1,
1259        .bpc = 6,
1260        .size = {
1261                .width = 292,
1262                .height = 109,
1263        },
1264        .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
1265};
1266
1267static const struct display_timing kyo_tcg121xglp_timing = {
1268        .pixelclock = { 52000000, 65000000, 71000000 },
1269        .hactive = { 1024, 1024, 1024 },
1270        .hfront_porch = { 2, 2, 2 },
1271        .hback_porch = { 2, 2, 2 },
1272        .hsync_len = { 86, 124, 244 },
1273        .vactive = { 768, 768, 768 },
1274        .vfront_porch = { 2, 2, 2 },
1275        .vback_porch = { 2, 2, 2 },
1276        .vsync_len = { 6, 34, 73 },
1277        .flags = DISPLAY_FLAGS_DE_HIGH,
1278};
1279
1280static const struct panel_desc kyo_tcg121xglp = {
1281        .timings = &kyo_tcg121xglp_timing,
1282        .num_timings = 1,
1283        .bpc = 8,
1284        .size = {
1285                .width = 246,
1286                .height = 184,
1287        },
1288        .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
1289};
1290
1291static const struct drm_display_mode lg_lb070wv8_mode = {
1292        .clock = 33246,
1293        .hdisplay = 800,
1294        .hsync_start = 800 + 88,
1295        .hsync_end = 800 + 88 + 80,
1296        .htotal = 800 + 88 + 80 + 88,
1297        .vdisplay = 480,
1298        .vsync_start = 480 + 10,
1299        .vsync_end = 480 + 10 + 25,
1300        .vtotal = 480 + 10 + 25 + 10,
1301        .vrefresh = 60,
1302};
1303
1304static const struct panel_desc lg_lb070wv8 = {
1305        .modes = &lg_lb070wv8_mode,
1306        .num_modes = 1,
1307        .bpc = 16,
1308        .size = {
1309                .width = 151,
1310                .height = 91,
1311        },
1312        .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
1313};
1314
1315static const struct drm_display_mode lg_lp079qx1_sp0v_mode = {
1316        .clock = 200000,
1317        .hdisplay = 1536,
1318        .hsync_start = 1536 + 12,
1319        .hsync_end = 1536 + 12 + 16,
1320        .htotal = 1536 + 12 + 16 + 48,
1321        .vdisplay = 2048,
1322        .vsync_start = 2048 + 8,
1323        .vsync_end = 2048 + 8 + 4,
1324        .vtotal = 2048 + 8 + 4 + 8,
1325        .vrefresh = 60,
1326        .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
1327};
1328
1329static const struct panel_desc lg_lp079qx1_sp0v = {
1330        .modes = &lg_lp079qx1_sp0v_mode,
1331        .num_modes = 1,
1332        .size = {
1333                .width = 129,
1334                .height = 171,
1335        },
1336};
1337
1338static const struct drm_display_mode lg_lp097qx1_spa1_mode = {
1339        .clock = 205210,
1340        .hdisplay = 2048,
1341        .hsync_start = 2048 + 150,
1342        .hsync_end = 2048 + 150 + 5,
1343        .htotal = 2048 + 150 + 5 + 5,
1344        .vdisplay = 1536,
1345        .vsync_start = 1536 + 3,
1346        .vsync_end = 1536 + 3 + 1,
1347        .vtotal = 1536 + 3 + 1 + 9,
1348        .vrefresh = 60,
1349};
1350
1351static const struct panel_desc lg_lp097qx1_spa1 = {
1352        .modes = &lg_lp097qx1_spa1_mode,
1353        .num_modes = 1,
1354        .size = {
1355                .width = 208,
1356                .height = 147,
1357        },
1358};
1359
1360static const struct drm_display_mode lg_lp120up1_mode = {
1361        .clock = 162300,
1362        .hdisplay = 1920,
1363        .hsync_start = 1920 + 40,
1364        .hsync_end = 1920 + 40 + 40,
1365        .htotal = 1920 + 40 + 40+ 80,
1366        .vdisplay = 1280,
1367        .vsync_start = 1280 + 4,
1368        .vsync_end = 1280 + 4 + 4,
1369        .vtotal = 1280 + 4 + 4 + 12,
1370        .vrefresh = 60,
1371};
1372
1373static const struct panel_desc lg_lp120up1 = {
1374        .modes = &lg_lp120up1_mode,
1375        .num_modes = 1,
1376        .bpc = 8,
1377        .size = {
1378                .width = 267,
1379                .height = 183,
1380        },
1381};
1382
1383static const struct drm_display_mode lg_lp129qe_mode = {
1384        .clock = 285250,
1385        .hdisplay = 2560,
1386        .hsync_start = 2560 + 48,
1387        .hsync_end = 2560 + 48 + 32,
1388        .htotal = 2560 + 48 + 32 + 80,
1389        .vdisplay = 1700,
1390        .vsync_start = 1700 + 3,
1391        .vsync_end = 1700 + 3 + 10,
1392        .vtotal = 1700 + 3 + 10 + 36,
1393        .vrefresh = 60,
1394};
1395
1396static const struct panel_desc lg_lp129qe = {
1397        .modes = &lg_lp129qe_mode,
1398        .num_modes = 1,
1399        .bpc = 8,
1400        .size = {
1401                .width = 272,
1402                .height = 181,
1403        },
1404};
1405
1406static const struct drm_display_mode mitsubishi_aa070mc01_mode = {
1407        .clock = 30400,
1408        .hdisplay = 800,
1409        .hsync_start = 800 + 0,
1410        .hsync_end = 800 + 1,
1411        .htotal = 800 + 0 + 1 + 160,
1412        .vdisplay = 480,
1413        .vsync_start = 480 + 0,
1414        .vsync_end = 480 + 48 + 1,
1415        .vtotal = 480 + 48 + 1 + 0,
1416        .vrefresh = 60,
1417        .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
1418};
1419
1420static const struct panel_desc mitsubishi_aa070mc01 = {
1421        .modes = &mitsubishi_aa070mc01_mode,
1422        .num_modes = 1,
1423        .bpc = 8,
1424        .size = {
1425                .width = 152,
1426                .height = 91,
1427        },
1428
1429        .delay = {
1430                .enable = 200,
1431                .unprepare = 200,
1432                .disable = 400,
1433        },
1434        .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
1435        .bus_flags = DRM_BUS_FLAG_DE_HIGH,
1436};
1437
1438static const struct display_timing nec_nl12880bc20_05_timing = {
1439        .pixelclock = { 67000000, 71000000, 75000000 },
1440        .hactive = { 1280, 1280, 1280 },
1441        .hfront_porch = { 2, 30, 30 },
1442        .hback_porch = { 6, 100, 100 },
1443        .hsync_len = { 2, 30, 30 },
1444        .vactive = { 800, 800, 800 },
1445        .vfront_porch = { 5, 5, 5 },
1446        .vback_porch = { 11, 11, 11 },
1447        .vsync_len = { 7, 7, 7 },
1448};
1449
1450static const struct panel_desc nec_nl12880bc20_05 = {
1451        .timings = &nec_nl12880bc20_05_timing,
1452        .num_timings = 1,
1453        .bpc = 8,
1454        .size = {
1455                .width = 261,
1456                .height = 163,
1457        },
1458        .delay = {
1459                .enable = 50,
1460                .disable = 50,
1461        },
1462        .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
1463};
1464
1465static const struct drm_display_mode nec_nl4827hc19_05b_mode = {
1466        .clock = 10870,
1467        .hdisplay = 480,
1468        .hsync_start = 480 + 2,
1469        .hsync_end = 480 + 2 + 41,
1470        .htotal = 480 + 2 + 41 + 2,
1471        .vdisplay = 272,
1472        .vsync_start = 272 + 2,
1473        .vsync_end = 272 + 2 + 4,
1474        .vtotal = 272 + 2 + 4 + 2,
1475        .vrefresh = 74,
1476        .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
1477};
1478
1479static const struct panel_desc nec_nl4827hc19_05b = {
1480        .modes = &nec_nl4827hc19_05b_mode,
1481        .num_modes = 1,
1482        .bpc = 8,
1483        .size = {
1484                .width = 95,
1485                .height = 54,
1486        },
1487        .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
1488        .bus_flags = DRM_BUS_FLAG_PIXDATA_POSEDGE,
1489};
1490
1491static const struct drm_display_mode netron_dy_e231732_mode = {
1492        .clock = 66000,
1493        .hdisplay = 1024,
1494        .hsync_start = 1024 + 160,
1495        .hsync_end = 1024 + 160 + 70,
1496        .htotal = 1024 + 160 + 70 + 90,
1497        .vdisplay = 600,
1498        .vsync_start = 600 + 127,
1499        .vsync_end = 600 + 127 + 20,
1500        .vtotal = 600 + 127 + 20 + 3,
1501        .vrefresh = 60,
1502};
1503
1504static const struct panel_desc netron_dy_e231732 = {
1505        .modes = &netron_dy_e231732_mode,
1506        .num_modes = 1,
1507        .size = {
1508                .width = 154,
1509                .height = 87,
1510        },
1511        .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
1512};
1513
1514static const struct display_timing nlt_nl192108ac18_02d_timing = {
1515        .pixelclock = { 130000000, 148350000, 163000000 },
1516        .hactive = { 1920, 1920, 1920 },
1517        .hfront_porch = { 80, 100, 100 },
1518        .hback_porch = { 100, 120, 120 },
1519        .hsync_len = { 50, 60, 60 },
1520        .vactive = { 1080, 1080, 1080 },
1521        .vfront_porch = { 12, 30, 30 },
1522        .vback_porch = { 4, 10, 10 },
1523        .vsync_len = { 4, 5, 5 },
1524};
1525
1526static const struct panel_desc nlt_nl192108ac18_02d = {
1527        .timings = &nlt_nl192108ac18_02d_timing,
1528        .num_timings = 1,
1529        .bpc = 8,
1530        .size = {
1531                .width = 344,
1532                .height = 194,
1533        },
1534        .delay = {
1535                .unprepare = 500,
1536        },
1537        .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
1538};
1539
1540static const struct drm_display_mode nvd_9128_mode = {
1541        .clock = 29500,
1542        .hdisplay = 800,
1543        .hsync_start = 800 + 130,
1544        .hsync_end = 800 + 130 + 98,
1545        .htotal = 800 + 0 + 130 + 98,
1546        .vdisplay = 480,
1547        .vsync_start = 480 + 10,
1548        .vsync_end = 480 + 10 + 50,
1549        .vtotal = 480 + 0 + 10 + 50,
1550};
1551
1552static const struct panel_desc nvd_9128 = {
1553        .modes = &nvd_9128_mode,
1554        .num_modes = 1,
1555        .bpc = 8,
1556        .size = {
1557                .width = 156,
1558                .height = 88,
1559        },
1560        .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
1561};
1562
1563static const struct display_timing okaya_rs800480t_7x0gp_timing = {
1564        .pixelclock = { 30000000, 30000000, 40000000 },
1565        .hactive = { 800, 800, 800 },
1566        .hfront_porch = { 40, 40, 40 },
1567        .hback_porch = { 40, 40, 40 },
1568        .hsync_len = { 1, 48, 48 },
1569        .vactive = { 480, 480, 480 },
1570        .vfront_porch = { 13, 13, 13 },
1571        .vback_porch = { 29, 29, 29 },
1572        .vsync_len = { 3, 3, 3 },
1573        .flags = DISPLAY_FLAGS_DE_HIGH,
1574};
1575
1576static const struct panel_desc okaya_rs800480t_7x0gp = {
1577        .timings = &okaya_rs800480t_7x0gp_timing,
1578        .num_timings = 1,
1579        .bpc = 6,
1580        .size = {
1581                .width = 154,
1582                .height = 87,
1583        },
1584        .delay = {
1585                .prepare = 41,
1586                .enable = 50,
1587                .unprepare = 41,
1588                .disable = 50,
1589        },
1590        .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
1591};
1592
1593static const struct drm_display_mode olimex_lcd_olinuxino_43ts_mode = {
1594        .clock = 9000,
1595        .hdisplay = 480,
1596        .hsync_start = 480 + 5,
1597        .hsync_end = 480 + 5 + 30,
1598        .htotal = 480 + 5 + 30 + 10,
1599        .vdisplay = 272,
1600        .vsync_start = 272 + 8,
1601        .vsync_end = 272 + 8 + 5,
1602        .vtotal = 272 + 8 + 5 + 3,
1603        .vrefresh = 60,
1604};
1605
1606static const struct panel_desc olimex_lcd_olinuxino_43ts = {
1607        .modes = &olimex_lcd_olinuxino_43ts_mode,
1608        .num_modes = 1,
1609        .size = {
1610                .width = 95,
1611                .height = 54,
1612        },
1613        .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
1614};
1615
1616/*
1617 * 800x480 CVT. The panel appears to be quite accepting, at least as far as
1618 * pixel clocks, but this is the timing that was being used in the Adafruit
1619 * installation instructions.
1620 */
1621static const struct drm_display_mode ontat_yx700wv03_mode = {
1622        .clock = 29500,
1623        .hdisplay = 800,
1624        .hsync_start = 824,
1625        .hsync_end = 896,
1626        .htotal = 992,
1627        .vdisplay = 480,
1628        .vsync_start = 483,
1629        .vsync_end = 493,
1630        .vtotal = 500,
1631        .vrefresh = 60,
1632        .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
1633};
1634
1635/*
1636 * Specification at:
1637 * https://www.adafruit.com/images/product-files/2406/c3163.pdf
1638 */
1639static const struct panel_desc ontat_yx700wv03 = {
1640        .modes = &ontat_yx700wv03_mode,
1641        .num_modes = 1,
1642        .bpc = 8,
1643        .size = {
1644                .width = 154,
1645                .height = 83,
1646        },
1647        .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
1648};
1649
1650static const struct drm_display_mode ortustech_com43h4m85ulc_mode  = {
1651        .clock = 25000,
1652        .hdisplay = 480,
1653        .hsync_start = 480 + 10,
1654        .hsync_end = 480 + 10 + 10,
1655        .htotal = 480 + 10 + 10 + 15,
1656        .vdisplay = 800,
1657        .vsync_start = 800 + 3,
1658        .vsync_end = 800 + 3 + 3,
1659        .vtotal = 800 + 3 + 3 + 3,
1660        .vrefresh = 60,
1661};
1662
1663static const struct panel_desc ortustech_com43h4m85ulc = {
1664        .modes = &ortustech_com43h4m85ulc_mode,
1665        .num_modes = 1,
1666        .bpc = 8,
1667        .size = {
1668                .width = 56,
1669                .height = 93,
1670        },
1671        .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
1672        .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_POSEDGE,
1673};
1674
1675static const struct drm_display_mode qd43003c0_40_mode = {
1676        .clock = 9000,
1677        .hdisplay = 480,
1678        .hsync_start = 480 + 8,
1679        .hsync_end = 480 + 8 + 4,
1680        .htotal = 480 + 8 + 4 + 39,
1681        .vdisplay = 272,
1682        .vsync_start = 272 + 4,
1683        .vsync_end = 272 + 4 + 10,
1684        .vtotal = 272 + 4 + 10 + 2,
1685        .vrefresh = 60,
1686};
1687
1688static const struct panel_desc qd43003c0_40 = {
1689        .modes = &qd43003c0_40_mode,
1690        .num_modes = 1,
1691        .bpc = 8,
1692        .size = {
1693                .width = 95,
1694                .height = 53,
1695        },
1696        .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
1697};
1698
1699static const struct drm_display_mode samsung_lsn122dl01_c01_mode = {
1700        .clock = 271560,
1701        .hdisplay = 2560,
1702        .hsync_start = 2560 + 48,
1703        .hsync_end = 2560 + 48 + 32,
1704        .htotal = 2560 + 48 + 32 + 80,
1705        .vdisplay = 1600,
1706        .vsync_start = 1600 + 2,
1707        .vsync_end = 1600 + 2 + 5,
1708        .vtotal = 1600 + 2 + 5 + 57,
1709        .vrefresh = 60,
1710};
1711
1712static const struct panel_desc samsung_lsn122dl01_c01 = {
1713        .modes = &samsung_lsn122dl01_c01_mode,
1714        .num_modes = 1,
1715        .size = {
1716                .width = 263,
1717                .height = 164,
1718        },
1719};
1720
1721static const struct drm_display_mode samsung_ltn101nt05_mode = {
1722        .clock = 54030,
1723        .hdisplay = 1024,
1724        .hsync_start = 1024 + 24,
1725        .hsync_end = 1024 + 24 + 136,
1726        .htotal = 1024 + 24 + 136 + 160,
1727        .vdisplay = 600,
1728        .vsync_start = 600 + 3,
1729        .vsync_end = 600 + 3 + 6,
1730        .vtotal = 600 + 3 + 6 + 61,
1731        .vrefresh = 60,
1732};
1733
1734static const struct panel_desc samsung_ltn101nt05 = {
1735        .modes = &samsung_ltn101nt05_mode,
1736        .num_modes = 1,
1737        .bpc = 6,
1738        .size = {
1739                .width = 223,
1740                .height = 125,
1741        },
1742};
1743
1744static const struct drm_display_mode samsung_ltn140at29_301_mode = {
1745        .clock = 76300,
1746        .hdisplay = 1366,
1747        .hsync_start = 1366 + 64,
1748        .hsync_end = 1366 + 64 + 48,
1749        .htotal = 1366 + 64 + 48 + 128,
1750        .vdisplay = 768,
1751        .vsync_start = 768 + 2,
1752        .vsync_end = 768 + 2 + 5,
1753        .vtotal = 768 + 2 + 5 + 17,
1754        .vrefresh = 60,
1755};
1756
1757static const struct panel_desc samsung_ltn140at29_301 = {
1758        .modes = &samsung_ltn140at29_301_mode,
1759        .num_modes = 1,
1760        .bpc = 6,
1761        .size = {
1762                .width = 320,
1763                .height = 187,
1764        },
1765};
1766
1767static const struct display_timing sharp_lq101k1ly04_timing = {
1768        .pixelclock = { 60000000, 65000000, 80000000 },
1769        .hactive = { 1280, 1280, 1280 },
1770        .hfront_porch = { 20, 20, 20 },
1771        .hback_porch = { 20, 20, 20 },
1772        .hsync_len = { 10, 10, 10 },
1773        .vactive = { 800, 800, 800 },
1774        .vfront_porch = { 4, 4, 4 },
1775        .vback_porch = { 4, 4, 4 },
1776        .vsync_len = { 4, 4, 4 },
1777        .flags = DISPLAY_FLAGS_PIXDATA_POSEDGE,
1778};
1779
1780static const struct panel_desc sharp_lq101k1ly04 = {
1781        .timings = &sharp_lq101k1ly04_timing,
1782        .num_timings = 1,
1783        .bpc = 8,
1784        .size = {
1785                .width = 217,
1786                .height = 136,
1787        },
1788        .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
1789};
1790
1791static const struct display_timing sharp_lq123p1jx31_timing = {
1792        .pixelclock = { 252750000, 252750000, 266604720 },
1793        .hactive = { 2400, 2400, 2400 },
1794        .hfront_porch = { 48, 48, 48 },
1795        .hback_porch = { 80, 80, 84 },
1796        .hsync_len = { 32, 32, 32 },
1797        .vactive = { 1600, 1600, 1600 },
1798        .vfront_porch = { 3, 3, 3 },
1799        .vback_porch = { 33, 33, 120 },
1800        .vsync_len = { 10, 10, 10 },
1801        .flags = DISPLAY_FLAGS_VSYNC_LOW | DISPLAY_FLAGS_HSYNC_LOW,
1802};
1803
1804static const struct panel_desc sharp_lq123p1jx31 = {
1805        .timings = &sharp_lq123p1jx31_timing,
1806        .num_timings = 1,
1807        .bpc = 8,
1808        .size = {
1809                .width = 259,
1810                .height = 173,
1811        },
1812        .delay = {
1813                .prepare = 110,
1814                .enable = 50,
1815                .unprepare = 550,
1816        },
1817};
1818
1819static const struct drm_display_mode sharp_lq150x1lg11_mode = {
1820        .clock = 71100,
1821        .hdisplay = 1024,
1822        .hsync_start = 1024 + 168,
1823        .hsync_end = 1024 + 168 + 64,
1824        .htotal = 1024 + 168 + 64 + 88,
1825        .vdisplay = 768,
1826        .vsync_start = 768 + 37,
1827        .vsync_end = 768 + 37 + 2,
1828        .vtotal = 768 + 37 + 2 + 8,
1829        .vrefresh = 60,
1830};
1831
1832static const struct panel_desc sharp_lq150x1lg11 = {
1833        .modes = &sharp_lq150x1lg11_mode,
1834        .num_modes = 1,
1835        .bpc = 6,
1836        .size = {
1837                .width = 304,
1838                .height = 228,
1839        },
1840        .bus_format = MEDIA_BUS_FMT_RGB565_1X16,
1841};
1842
1843static const struct drm_display_mode shelly_sca07010_bfn_lnn_mode = {
1844        .clock = 33300,
1845        .hdisplay = 800,
1846        .hsync_start = 800 + 1,
1847        .hsync_end = 800 + 1 + 64,
1848        .htotal = 800 + 1 + 64 + 64,
1849        .vdisplay = 480,
1850        .vsync_start = 480 + 1,
1851        .vsync_end = 480 + 1 + 23,
1852        .vtotal = 480 + 1 + 23 + 22,
1853        .vrefresh = 60,
1854};
1855
1856static const struct panel_desc shelly_sca07010_bfn_lnn = {
1857        .modes = &shelly_sca07010_bfn_lnn_mode,
1858        .num_modes = 1,
1859        .size = {
1860                .width = 152,
1861                .height = 91,
1862        },
1863        .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
1864};
1865
1866static const struct drm_display_mode starry_kr122ea0sra_mode = {
1867        .clock = 147000,
1868        .hdisplay = 1920,
1869        .hsync_start = 1920 + 16,
1870        .hsync_end = 1920 + 16 + 16,
1871        .htotal = 1920 + 16 + 16 + 32,
1872        .vdisplay = 1200,
1873        .vsync_start = 1200 + 15,
1874        .vsync_end = 1200 + 15 + 2,
1875        .vtotal = 1200 + 15 + 2 + 18,
1876        .vrefresh = 60,
1877        .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
1878};
1879
1880static const struct panel_desc starry_kr122ea0sra = {
1881        .modes = &starry_kr122ea0sra_mode,
1882        .num_modes = 1,
1883        .size = {
1884                .width = 263,
1885                .height = 164,
1886        },
1887        .delay = {
1888                .prepare = 10 + 200,
1889                .enable = 50,
1890                .unprepare = 10 + 500,
1891        },
1892};
1893
1894static const struct display_timing tianma_tm070jdhg30_timing = {
1895        .pixelclock = { 62600000, 68200000, 78100000 },
1896        .hactive = { 1280, 1280, 1280 },
1897        .hfront_porch = { 15, 64, 159 },
1898        .hback_porch = { 5, 5, 5 },
1899        .hsync_len = { 1, 1, 256 },
1900        .vactive = { 800, 800, 800 },
1901        .vfront_porch = { 3, 40, 99 },
1902        .vback_porch = { 2, 2, 2 },
1903        .vsync_len = { 1, 1, 128 },
1904        .flags = DISPLAY_FLAGS_DE_HIGH,
1905};
1906
1907static const struct panel_desc tianma_tm070jdhg30 = {
1908        .timings = &tianma_tm070jdhg30_timing,
1909        .num_timings = 1,
1910        .bpc = 8,
1911        .size = {
1912                .width = 151,
1913                .height = 95,
1914        },
1915        .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
1916};
1917
1918static const struct display_timing tianma_tm070rvhg71_timing = {
1919        .pixelclock = { 27700000, 29200000, 39600000 },
1920        .hactive = { 800, 800, 800 },
1921        .hfront_porch = { 12, 40, 212 },
1922        .hback_porch = { 88, 88, 88 },
1923        .hsync_len = { 1, 1, 40 },
1924        .vactive = { 480, 480, 480 },
1925        .vfront_porch = { 1, 13, 88 },
1926        .vback_porch = { 32, 32, 32 },
1927        .vsync_len = { 1, 1, 3 },
1928        .flags = DISPLAY_FLAGS_DE_HIGH,
1929};
1930
1931static const struct panel_desc tianma_tm070rvhg71 = {
1932        .timings = &tianma_tm070rvhg71_timing,
1933        .num_timings = 1,
1934        .bpc = 8,
1935        .size = {
1936                .width = 154,
1937                .height = 86,
1938        },
1939        .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
1940};
1941
1942static const struct drm_display_mode toshiba_lt089ac29000_mode = {
1943        .clock = 79500,
1944        .hdisplay = 1280,
1945        .hsync_start = 1280 + 192,
1946        .hsync_end = 1280 + 192 + 128,
1947        .htotal = 1280 + 192 + 128 + 64,
1948        .vdisplay = 768,
1949        .vsync_start = 768 + 20,
1950        .vsync_end = 768 + 20 + 7,
1951        .vtotal = 768 + 20 + 7 + 3,
1952        .vrefresh = 60,
1953};
1954
1955static const struct panel_desc toshiba_lt089ac29000 = {
1956        .modes = &toshiba_lt089ac29000_mode,
1957        .num_modes = 1,
1958        .size = {
1959                .width = 194,
1960                .height = 116,
1961        },
1962        .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
1963        .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_POSEDGE,
1964};
1965
1966static const struct drm_display_mode tpk_f07a_0102_mode = {
1967        .clock = 33260,
1968        .hdisplay = 800,
1969        .hsync_start = 800 + 40,
1970        .hsync_end = 800 + 40 + 128,
1971        .htotal = 800 + 40 + 128 + 88,
1972        .vdisplay = 480,
1973        .vsync_start = 480 + 10,
1974        .vsync_end = 480 + 10 + 2,
1975        .vtotal = 480 + 10 + 2 + 33,
1976        .vrefresh = 60,
1977};
1978
1979static const struct panel_desc tpk_f07a_0102 = {
1980        .modes = &tpk_f07a_0102_mode,
1981        .num_modes = 1,
1982        .size = {
1983                .width = 152,
1984                .height = 91,
1985        },
1986        .bus_flags = DRM_BUS_FLAG_PIXDATA_POSEDGE,
1987};
1988
1989static const struct drm_display_mode tpk_f10a_0102_mode = {
1990        .clock = 45000,
1991        .hdisplay = 1024,
1992        .hsync_start = 1024 + 176,
1993        .hsync_end = 1024 + 176 + 5,
1994        .htotal = 1024 + 176 + 5 + 88,
1995        .vdisplay = 600,
1996        .vsync_start = 600 + 20,
1997        .vsync_end = 600 + 20 + 5,
1998        .vtotal = 600 + 20 + 5 + 25,
1999        .vrefresh = 60,
2000};
2001
2002static const struct panel_desc tpk_f10a_0102 = {
2003        .modes = &tpk_f10a_0102_mode,
2004        .num_modes = 1,
2005        .size = {
2006                .width = 223,
2007                .height = 125,
2008        },
2009};
2010
2011static const struct display_timing urt_umsh_8596md_timing = {
2012        .pixelclock = { 33260000, 33260000, 33260000 },
2013        .hactive = { 800, 800, 800 },
2014        .hfront_porch = { 41, 41, 41 },
2015        .hback_porch = { 216 - 128, 216 - 128, 216 - 128 },
2016        .hsync_len = { 71, 128, 128 },
2017        .vactive = { 480, 480, 480 },
2018        .vfront_porch = { 10, 10, 10 },
2019        .vback_porch = { 35 - 2, 35 - 2, 35 - 2 },
2020        .vsync_len = { 2, 2, 2 },
2021        .flags = DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_NEGEDGE |
2022                DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW,
2023};
2024
2025static const struct panel_desc urt_umsh_8596md_lvds = {
2026        .timings = &urt_umsh_8596md_timing,
2027        .num_timings = 1,
2028        .bpc = 6,
2029        .size = {
2030                .width = 152,
2031                .height = 91,
2032        },
2033        .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
2034};
2035
2036static const struct panel_desc urt_umsh_8596md_parallel = {
2037        .timings = &urt_umsh_8596md_timing,
2038        .num_timings = 1,
2039        .bpc = 6,
2040        .size = {
2041                .width = 152,
2042                .height = 91,
2043        },
2044        .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
2045};
2046
2047static const struct drm_display_mode winstar_wf35ltiacd_mode = {
2048        .clock = 6410,
2049        .hdisplay = 320,
2050        .hsync_start = 320 + 20,
2051        .hsync_end = 320 + 20 + 30,
2052        .htotal = 320 + 20 + 30 + 38,
2053        .vdisplay = 240,
2054        .vsync_start = 240 + 4,
2055        .vsync_end = 240 + 4 + 3,
2056        .vtotal = 240 + 4 + 3 + 15,
2057        .vrefresh = 60,
2058        .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
2059};
2060
2061static const struct panel_desc winstar_wf35ltiacd = {
2062        .modes = &winstar_wf35ltiacd_mode,
2063        .num_modes = 1,
2064        .bpc = 8,
2065        .size = {
2066                .width = 70,
2067                .height = 53,
2068        },
2069        .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
2070};
2071
2072static const struct of_device_id platform_of_match[] = {
2073        {
2074                .compatible = "ampire,am-480272h3tmqw-t01h",
2075                .data = &ampire_am_480272h3tmqw_t01h,
2076        }, {
2077                .compatible = "ampire,am800480r3tmqwa1h",
2078                .data = &ampire_am800480r3tmqwa1h,
2079        }, {
2080                .compatible = "auo,b101aw03",
2081                .data = &auo_b101aw03,
2082        }, {
2083                .compatible = "auo,b101ean01",
2084                .data = &auo_b101ean01,
2085        }, {
2086                .compatible = "auo,b101xtn01",
2087                .data = &auo_b101xtn01,
2088        }, {
2089                .compatible = "auo,b116xw03",
2090                .data = &auo_b116xw03,
2091        }, {
2092                .compatible = "auo,b133htn01",
2093                .data = &auo_b133htn01,
2094        }, {
2095                .compatible = "auo,b133xtn01",
2096                .data = &auo_b133xtn01,
2097        }, {
2098                .compatible = "auo,g104sn02",
2099                .data = &auo_g104sn02,
2100        }, {
2101                .compatible = "auo,g133han01",
2102                .data = &auo_g133han01,
2103        }, {
2104                .compatible = "auo,g185han01",
2105                .data = &auo_g185han01,
2106        }, {
2107                .compatible = "auo,p320hvn03",
2108                .data = &auo_p320hvn03,
2109        }, {
2110                .compatible = "auo,t215hvn01",
2111                .data = &auo_t215hvn01,
2112        }, {
2113                .compatible = "avic,tm070ddh03",
2114                .data = &avic_tm070ddh03,
2115        }, {
2116                .compatible = "boe,nv101wxmn51",
2117                .data = &boe_nv101wxmn51,
2118        }, {
2119                .compatible = "chunghwa,claa070wp03xg",
2120                .data = &chunghwa_claa070wp03xg,
2121        }, {
2122                .compatible = "chunghwa,claa101wa01a",
2123                .data = &chunghwa_claa101wa01a
2124        }, {
2125                .compatible = "chunghwa,claa101wb01",
2126                .data = &chunghwa_claa101wb01
2127        }, {
2128                .compatible = "edt,et057090dhu",
2129                .data = &edt_et057090dhu,
2130        }, {
2131                .compatible = "edt,et070080dh6",
2132                .data = &edt_etm0700g0dh6,
2133        }, {
2134                .compatible = "edt,etm0700g0dh6",
2135                .data = &edt_etm0700g0dh6,
2136        }, {
2137                .compatible = "foxlink,fl500wvr00-a0t",
2138                .data = &foxlink_fl500wvr00_a0t,
2139        }, {
2140                .compatible = "giantplus,gpg482739qs5",
2141                .data = &giantplus_gpg482739qs5
2142        }, {
2143                .compatible = "hannstar,hsd070pww1",
2144                .data = &hannstar_hsd070pww1,
2145        }, {
2146                .compatible = "hannstar,hsd100pxn1",
2147                .data = &hannstar_hsd100pxn1,
2148        }, {
2149                .compatible = "hit,tx23d38vm0caa",
2150                .data = &hitachi_tx23d38vm0caa
2151        }, {
2152                .compatible = "innolux,at043tn24",
2153                .data = &innolux_at043tn24,
2154        }, {
2155                .compatible = "innolux,at070tn92",
2156                .data = &innolux_at070tn92,
2157        }, {
2158                .compatible ="innolux,g101ice-l01",
2159                .data = &innolux_g101ice_l01
2160        }, {
2161                .compatible ="innolux,g121i1-l01",
2162                .data = &innolux_g121i1_l01
2163        }, {
2164                .compatible = "innolux,g121x1-l03",
2165                .data = &innolux_g121x1_l03,
2166        }, {
2167                .compatible = "innolux,n116bge",
2168                .data = &innolux_n116bge,
2169        }, {
2170                .compatible = "innolux,n156bge-l21",
2171                .data = &innolux_n156bge_l21,
2172        }, {
2173                .compatible = "innolux,zj070na-01p",
2174                .data = &innolux_zj070na_01p,
2175        }, {
2176                .compatible = "koe,tx31d200vm0baa",
2177                .data = &koe_tx31d200vm0baa,
2178        }, {
2179                .compatible = "kyo,tcg121xglp",
2180                .data = &kyo_tcg121xglp,
2181        }, {
2182                .compatible = "lg,lb070wv8",
2183                .data = &lg_lb070wv8,
2184        }, {
2185                .compatible = "lg,lp079qx1-sp0v",
2186                .data = &lg_lp079qx1_sp0v,
2187        }, {
2188                .compatible = "lg,lp097qx1-spa1",
2189                .data = &lg_lp097qx1_spa1,
2190        }, {
2191                .compatible = "lg,lp120up1",
2192                .data = &lg_lp120up1,
2193        }, {
2194                .compatible = "lg,lp129qe",
2195                .data = &lg_lp129qe,
2196        }, {
2197                .compatible = "mitsubishi,aa070mc01-ca1",
2198                .data = &mitsubishi_aa070mc01,
2199        }, {
2200                .compatible = "nec,nl12880bc20-05",
2201                .data = &nec_nl12880bc20_05,
2202        }, {
2203                .compatible = "nec,nl4827hc19-05b",
2204                .data = &nec_nl4827hc19_05b,
2205        }, {
2206                .compatible = "netron-dy,e231732",
2207                .data = &netron_dy_e231732,
2208        }, {
2209                .compatible = "nlt,nl192108ac18-02d",
2210                .data = &nlt_nl192108ac18_02d,
2211        }, {
2212                .compatible = "nvd,9128",
2213                .data = &nvd_9128,
2214        }, {
2215                .compatible = "okaya,rs800480t-7x0gp",
2216                .data = &okaya_rs800480t_7x0gp,
2217        }, {
2218                .compatible = "olimex,lcd-olinuxino-43-ts",
2219                .data = &olimex_lcd_olinuxino_43ts,
2220        }, {
2221                .compatible = "ontat,yx700wv03",
2222                .data = &ontat_yx700wv03,
2223        }, {
2224                .compatible = "ortustech,com43h4m85ulc",
2225                .data = &ortustech_com43h4m85ulc,
2226        }, {
2227                .compatible = "qiaodian,qd43003c0-40",
2228                .data = &qd43003c0_40,
2229        }, {
2230                .compatible = "samsung,lsn122dl01-c01",
2231                .data = &samsung_lsn122dl01_c01,
2232        }, {
2233                .compatible = "samsung,ltn101nt05",
2234                .data = &samsung_ltn101nt05,
2235        }, {
2236                .compatible = "samsung,ltn140at29-301",
2237                .data = &samsung_ltn140at29_301,
2238        }, {
2239                .compatible = "sharp,lq101k1ly04",
2240                .data = &sharp_lq101k1ly04,
2241        }, {
2242                .compatible = "sharp,lq123p1jx31",
2243                .data = &sharp_lq123p1jx31,
2244        }, {
2245                .compatible = "sharp,lq150x1lg11",
2246                .data = &sharp_lq150x1lg11,
2247        }, {
2248                .compatible = "shelly,sca07010-bfn-lnn",
2249                .data = &shelly_sca07010_bfn_lnn,
2250        }, {
2251                .compatible = "starry,kr122ea0sra",
2252                .data = &starry_kr122ea0sra,
2253        }, {
2254                .compatible = "tianma,tm070jdhg30",
2255                .data = &tianma_tm070jdhg30,
2256        }, {
2257                .compatible = "tianma,tm070rvhg71",
2258                .data = &tianma_tm070rvhg71,
2259        }, {
2260                .compatible = "toshiba,lt089ac29000",
2261                .data = &toshiba_lt089ac29000,
2262        }, {
2263                .compatible = "tpk,f07a-0102",
2264                .data = &tpk_f07a_0102,
2265        }, {
2266                .compatible = "tpk,f10a-0102",
2267                .data = &tpk_f10a_0102,
2268        }, {
2269                .compatible = "urt,umsh-8596md-t",
2270                .data = &urt_umsh_8596md_parallel,
2271        }, {
2272                .compatible = "urt,umsh-8596md-1t",
2273                .data = &urt_umsh_8596md_parallel,
2274        }, {
2275                .compatible = "urt,umsh-8596md-7t",
2276                .data = &urt_umsh_8596md_parallel,
2277        }, {
2278                .compatible = "urt,umsh-8596md-11t",
2279                .data = &urt_umsh_8596md_lvds,
2280        }, {
2281                .compatible = "urt,umsh-8596md-19t",
2282                .data = &urt_umsh_8596md_lvds,
2283        }, {
2284                .compatible = "urt,umsh-8596md-20t",
2285                .data = &urt_umsh_8596md_parallel,
2286        }, {
2287                .compatible = "winstar,wf35ltiacd",
2288                .data = &winstar_wf35ltiacd,
2289        }, {
2290                /* sentinel */
2291        }
2292};
2293MODULE_DEVICE_TABLE(of, platform_of_match);
2294
2295static int panel_simple_platform_probe(struct platform_device *pdev)
2296{
2297        const struct of_device_id *id;
2298
2299        id = of_match_node(platform_of_match, pdev->dev.of_node);
2300        if (!id)
2301                return -ENODEV;
2302
2303        return panel_simple_probe(&pdev->dev, id->data);
2304}
2305
2306static int panel_simple_platform_remove(struct platform_device *pdev)
2307{
2308        return panel_simple_remove(&pdev->dev);
2309}
2310
2311static void panel_simple_platform_shutdown(struct platform_device *pdev)
2312{
2313        panel_simple_shutdown(&pdev->dev);
2314}
2315
2316static struct platform_driver panel_simple_platform_driver = {
2317        .driver = {
2318                .name = "panel-simple",
2319                .of_match_table = platform_of_match,
2320        },
2321        .probe = panel_simple_platform_probe,
2322        .remove = panel_simple_platform_remove,
2323        .shutdown = panel_simple_platform_shutdown,
2324};
2325
2326struct panel_desc_dsi {
2327        struct panel_desc desc;
2328
2329        unsigned long flags;
2330        enum mipi_dsi_pixel_format format;
2331        unsigned int lanes;
2332};
2333
2334static const struct drm_display_mode auo_b080uan01_mode = {
2335        .clock = 154500,
2336        .hdisplay = 1200,
2337        .hsync_start = 1200 + 62,
2338        .hsync_end = 1200 + 62 + 4,
2339        .htotal = 1200 + 62 + 4 + 62,
2340        .vdisplay = 1920,
2341        .vsync_start = 1920 + 9,
2342        .vsync_end = 1920 + 9 + 2,
2343        .vtotal = 1920 + 9 + 2 + 8,
2344        .vrefresh = 60,
2345};
2346
2347static const struct panel_desc_dsi auo_b080uan01 = {
2348        .desc = {
2349                .modes = &auo_b080uan01_mode,
2350                .num_modes = 1,
2351                .bpc = 8,
2352                .size = {
2353                        .width = 108,
2354                        .height = 272,
2355                },
2356        },
2357        .flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS,
2358        .format = MIPI_DSI_FMT_RGB888,
2359        .lanes = 4,
2360};
2361
2362static const struct drm_display_mode boe_tv080wum_nl0_mode = {
2363        .clock = 160000,
2364        .hdisplay = 1200,
2365        .hsync_start = 1200 + 120,
2366        .hsync_end = 1200 + 120 + 20,
2367        .htotal = 1200 + 120 + 20 + 21,
2368        .vdisplay = 1920,
2369        .vsync_start = 1920 + 21,
2370        .vsync_end = 1920 + 21 + 3,
2371        .vtotal = 1920 + 21 + 3 + 18,
2372        .vrefresh = 60,
2373        .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
2374};
2375
2376static const struct panel_desc_dsi boe_tv080wum_nl0 = {
2377        .desc = {
2378                .modes = &boe_tv080wum_nl0_mode,
2379                .num_modes = 1,
2380                .size = {
2381                        .width = 107,
2382                        .height = 172,
2383                },
2384        },
2385        .flags = MIPI_DSI_MODE_VIDEO |
2386                 MIPI_DSI_MODE_VIDEO_BURST |
2387                 MIPI_DSI_MODE_VIDEO_SYNC_PULSE,
2388        .format = MIPI_DSI_FMT_RGB888,
2389        .lanes = 4,
2390};
2391
2392static const struct drm_display_mode lg_ld070wx3_sl01_mode = {
2393        .clock = 71000,
2394        .hdisplay = 800,
2395        .hsync_start = 800 + 32,
2396        .hsync_end = 800 + 32 + 1,
2397        .htotal = 800 + 32 + 1 + 57,
2398        .vdisplay = 1280,
2399        .vsync_start = 1280 + 28,
2400        .vsync_end = 1280 + 28 + 1,
2401        .vtotal = 1280 + 28 + 1 + 14,
2402        .vrefresh = 60,
2403};
2404
2405static const struct panel_desc_dsi lg_ld070wx3_sl01 = {
2406        .desc = {
2407                .modes = &lg_ld070wx3_sl01_mode,
2408                .num_modes = 1,
2409                .bpc = 8,
2410                .size = {
2411                        .width = 94,
2412                        .height = 151,
2413                },
2414        },
2415        .flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS,
2416        .format = MIPI_DSI_FMT_RGB888,
2417        .lanes = 4,
2418};
2419
2420static const struct drm_display_mode lg_lh500wx1_sd03_mode = {
2421        .clock = 67000,
2422        .hdisplay = 720,
2423        .hsync_start = 720 + 12,
2424        .hsync_end = 720 + 12 + 4,
2425        .htotal = 720 + 12 + 4 + 112,
2426        .vdisplay = 1280,
2427        .vsync_start = 1280 + 8,
2428        .vsync_end = 1280 + 8 + 4,
2429        .vtotal = 1280 + 8 + 4 + 12,
2430        .vrefresh = 60,
2431};
2432
2433static const struct panel_desc_dsi lg_lh500wx1_sd03 = {
2434        .desc = {
2435                .modes = &lg_lh500wx1_sd03_mode,
2436                .num_modes = 1,
2437                .bpc = 8,
2438                .size = {
2439                        .width = 62,
2440                        .height = 110,
2441                },
2442        },
2443        .flags = MIPI_DSI_MODE_VIDEO,
2444        .format = MIPI_DSI_FMT_RGB888,
2445        .lanes = 4,
2446};
2447
2448static const struct drm_display_mode panasonic_vvx10f004b00_mode = {
2449        .clock = 157200,
2450        .hdisplay = 1920,
2451        .hsync_start = 1920 + 154,
2452        .hsync_end = 1920 + 154 + 16,
2453        .htotal = 1920 + 154 + 16 + 32,
2454        .vdisplay = 1200,
2455        .vsync_start = 1200 + 17,
2456        .vsync_end = 1200 + 17 + 2,
2457        .vtotal = 1200 + 17 + 2 + 16,
2458        .vrefresh = 60,
2459};
2460
2461static const struct panel_desc_dsi panasonic_vvx10f004b00 = {
2462        .desc = {
2463                .modes = &panasonic_vvx10f004b00_mode,
2464                .num_modes = 1,
2465                .bpc = 8,
2466                .size = {
2467                        .width = 217,
2468                        .height = 136,
2469                },
2470        },
2471        .flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
2472                 MIPI_DSI_CLOCK_NON_CONTINUOUS,
2473        .format = MIPI_DSI_FMT_RGB888,
2474        .lanes = 4,
2475};
2476
2477static const struct of_device_id dsi_of_match[] = {
2478        {
2479                .compatible = "auo,b080uan01",
2480                .data = &auo_b080uan01
2481        }, {
2482                .compatible = "boe,tv080wum-nl0",
2483                .data = &boe_tv080wum_nl0
2484        }, {
2485                .compatible = "lg,ld070wx3-sl01",
2486                .data = &lg_ld070wx3_sl01
2487        }, {
2488                .compatible = "lg,lh500wx1-sd03",
2489                .data = &lg_lh500wx1_sd03
2490        }, {
2491                .compatible = "panasonic,vvx10f004b00",
2492                .data = &panasonic_vvx10f004b00
2493        }, {
2494                /* sentinel */
2495        }
2496};
2497MODULE_DEVICE_TABLE(of, dsi_of_match);
2498
2499static int panel_simple_dsi_probe(struct mipi_dsi_device *dsi)
2500{
2501        const struct panel_desc_dsi *desc;
2502        const struct of_device_id *id;
2503        int err;
2504
2505        id = of_match_node(dsi_of_match, dsi->dev.of_node);
2506        if (!id)
2507                return -ENODEV;
2508
2509        desc = id->data;
2510
2511        err = panel_simple_probe(&dsi->dev, &desc->desc);
2512        if (err < 0)
2513                return err;
2514
2515        dsi->mode_flags = desc->flags;
2516        dsi->format = desc->format;
2517        dsi->lanes = desc->lanes;
2518
2519        return mipi_dsi_attach(dsi);
2520}
2521
2522static int panel_simple_dsi_remove(struct mipi_dsi_device *dsi)
2523{
2524        int err;
2525
2526        err = mipi_dsi_detach(dsi);
2527        if (err < 0)
2528                dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", err);
2529
2530        return panel_simple_remove(&dsi->dev);
2531}
2532
2533static void panel_simple_dsi_shutdown(struct mipi_dsi_device *dsi)
2534{
2535        panel_simple_shutdown(&dsi->dev);
2536}
2537
2538static struct mipi_dsi_driver panel_simple_dsi_driver = {
2539        .driver = {
2540                .name = "panel-simple-dsi",
2541                .of_match_table = dsi_of_match,
2542        },
2543        .probe = panel_simple_dsi_probe,
2544        .remove = panel_simple_dsi_remove,
2545        .shutdown = panel_simple_dsi_shutdown,
2546};
2547
2548static int __init panel_simple_init(void)
2549{
2550        int err;
2551
2552        err = platform_driver_register(&panel_simple_platform_driver);
2553        if (err < 0)
2554                return err;
2555
2556        if (IS_ENABLED(CONFIG_DRM_MIPI_DSI)) {
2557                err = mipi_dsi_driver_register(&panel_simple_dsi_driver);
2558                if (err < 0)
2559                        return err;
2560        }
2561
2562        return 0;
2563}
2564module_init(panel_simple_init);
2565
2566static void __exit panel_simple_exit(void)
2567{
2568        if (IS_ENABLED(CONFIG_DRM_MIPI_DSI))
2569                mipi_dsi_driver_unregister(&panel_simple_dsi_driver);
2570
2571        platform_driver_unregister(&panel_simple_platform_driver);
2572}
2573module_exit(panel_simple_exit);
2574
2575MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
2576MODULE_DESCRIPTION("DRM Driver for Simple Panels");
2577MODULE_LICENSE("GPL and additional rights");
2578