Linux Audio

Check our new training course

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