Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/gpu/drm/panel/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 144 kB image not shown  

Quelle  panel-simple.c   Sprache: C

 
/*
 * Copyright (C) 2013, NVIDIA Corporation.  All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sub license,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */


#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>

#include <video/display_timing.h>
#include <video/of_display_timing.h>
#include <video/videomode.h>

#include <drm/drm_crtc.h>
#include <drm/drm_device.h>
#include <drm/drm_edid.h>
#include <drm/drm_mipi_dsi.h>
#include <drm/drm_panel.h>
#include <drm/drm_of.h>

/**
 * struct panel_desc - Describes a simple panel.
 */

struct panel_desc {
 /**
 * @modes: Pointer to array of fixed modes appropriate for this panel.
 *
 * If only one mode then this can just be the address of the mode.
 * NOTE: cannot be used with "timings" and also if this is specified
 * then you cannot override the mode in the device tree.
 */

 const struct drm_display_mode *modes;

 /** @num_modes: Number of elements in modes array. */
 unsigned int num_modes;

 /**
 * @timings: Pointer to array of display timings
 *
 * NOTE: cannot be used with "modes" and also these will be used to
 * validate a device tree override if one is present.
 */

 const struct display_timing *timings;

 /** @num_timings: Number of elements in timings array. */
 unsigned int num_timings;

 /** @bpc: Bits per color. */
 unsigned int bpc;

 /** @size: Structure containing the physical size of this panel. */
 struct {
  /**
 * @size.width: Width (in mm) of the active display area.
 */

  unsigned int width;

  /**
 * @size.height: Height (in mm) of the active display area.
 */

  unsigned int height;
 } size;

 /** @delay: Structure containing various delay values for this panel. */
 struct {
  /**
 * @delay.prepare: Time for the panel to become ready.
 *
 * The time (in milliseconds) that it takes for the panel to
 * become ready and start receiving video data
 */

  unsigned int prepare;

  /**
 * @delay.enable: Time for the panel to display a valid frame.
 *
 * The time (in milliseconds) that it takes for the panel to
 * display the first valid frame after starting to receive
 * video data.
 */

  unsigned int enable;

  /**
 * @delay.disable: Time for the panel to turn the display off.
 *
 * The time (in milliseconds) that it takes for the panel to
 * turn the display off (no content is visible).
 */

  unsigned int disable;

  /**
 * @delay.unprepare: Time to power down completely.
 *
 * The time (in milliseconds) that it takes for the panel
 * to power itself down completely.
 *
 * This time is used to prevent a future "prepare" from
 * starting until at least this many milliseconds has passed.
 * If at prepare time less time has passed since unprepare
 * finished, the driver waits for the remaining time.
 */

  unsigned int unprepare;
 } delay;

 /** @bus_format: See MEDIA_BUS_FMT_... defines. */
 u32 bus_format;

 /** @bus_flags: See DRM_BUS_FLAG_... defines. */
 u32 bus_flags;

 /** @connector_type: LVDS, eDP, DSI, DPI, etc. */
 int connector_type;
};

struct panel_desc_dsi {
 struct panel_desc desc;

 unsigned long flags;
 enum mipi_dsi_pixel_format format;
 unsigned int lanes;
};

struct panel_simple {
 struct drm_panel base;

 ktime_t unprepared_time;

 const struct panel_desc *desc;

 struct regulator *supply;
 struct i2c_adapter *ddc;

 struct gpio_desc *enable_gpio;

 const struct drm_edid *drm_edid;

 struct drm_display_mode override_mode;

 enum drm_panel_orientation orientation;
};

static inline struct panel_simple *to_panel_simple(struct drm_panel *panel)
{
 return container_of(panel, struct panel_simple, base);
}

static unsigned int panel_simple_get_timings_modes(struct panel_simple *panel,
         struct drm_connector *connector)
{
 struct drm_display_mode *mode;
 unsigned int i, num = 0;

 for (i = 0; i < panel->desc->num_timings; i++) {
  const struct display_timing *dt = &panel->desc->timings[i];
  struct videomode vm;

  videomode_from_timing(dt, &vm);
  mode = drm_mode_create(connector->dev);
  if (!mode) {
   dev_err(panel->base.dev, "failed to add mode %ux%u\n",
    dt->hactive.typ, dt->vactive.typ);
   continue;
  }

  drm_display_mode_from_videomode(&vm, mode);

  mode->type |= DRM_MODE_TYPE_DRIVER;

  if (panel->desc->num_timings == 1)
   mode->type |= DRM_MODE_TYPE_PREFERRED;

  drm_mode_probed_add(connector, mode);
  num++;
 }

 return num;
}

static unsigned int panel_simple_get_display_modes(struct panel_simple *panel,
         struct drm_connector *connector)
{
 struct drm_display_mode *mode;
 unsigned int i, num = 0;

 for (i = 0; i < panel->desc->num_modes; i++) {
  const struct drm_display_mode *m = &panel->desc->modes[i];

  mode = drm_mode_duplicate(connector->dev, m);
  if (!mode) {
   dev_err(panel->base.dev, "failed to add mode %ux%u@%u\n",
    m->hdisplay, m->vdisplay,
    drm_mode_vrefresh(m));
   continue;
  }

  mode->type |= DRM_MODE_TYPE_DRIVER;

  if (panel->desc->num_modes == 1)
   mode->type |= DRM_MODE_TYPE_PREFERRED;

  drm_mode_set_name(mode);

  drm_mode_probed_add(connector, mode);
  num++;
 }

 return num;
}

static int panel_simple_get_non_edid_modes(struct panel_simple *panel,
        struct drm_connector *connector)
{
 struct drm_display_mode *mode;
 bool has_override = panel->override_mode.type;
 unsigned int num = 0;

 if (!panel->desc)
  return 0;

 if (has_override) {
  mode = drm_mode_duplicate(connector->dev,
       &panel->override_mode);
  if (mode) {
   drm_mode_probed_add(connector, mode);
   num = 1;
  } else {
   dev_err(panel->base.dev, "failed to add override mode\n");
  }
 }

 /* Only add timings if override was not there or failed to validate */
 if (num == 0 && panel->desc->num_timings)
  num = panel_simple_get_timings_modes(panel, connector);

 /*
 * Only add fixed modes if timings/override added no mode.
 *
 * We should only ever have either the display timings specified
 * or a fixed mode. Anything else is rather bogus.
 */

 WARN_ON(panel->desc->num_timings && panel->desc->num_modes);
 if (num == 0)
  num = panel_simple_get_display_modes(panel, connector);

 connector->display_info.bpc = panel->desc->bpc;
 connector->display_info.width_mm = panel->desc->size.width;
 connector->display_info.height_mm = panel->desc->size.height;
 if (panel->desc->bus_format)
  drm_display_info_set_bus_formats(&connector->display_info,
       &panel->desc->bus_format, 1);
 connector->display_info.bus_flags = panel->desc->bus_flags;

 return num;
}

static void panel_simple_wait(ktime_t start_ktime, unsigned int min_ms)
{
 ktime_t now_ktime, min_ktime;

 if (!min_ms)
  return;

 min_ktime = ktime_add(start_ktime, ms_to_ktime(min_ms));
 now_ktime = ktime_get_boottime();

 if (ktime_before(now_ktime, min_ktime))
  msleep(ktime_to_ms(ktime_sub(min_ktime, now_ktime)) + 1);
}

static int panel_simple_disable(struct drm_panel *panel)
{
 struct panel_simple *p = to_panel_simple(panel);

 if (p->desc->delay.disable)
  msleep(p->desc->delay.disable);

 return 0;
}

static int panel_simple_suspend(struct device *dev)
{
 struct panel_simple *p = dev_get_drvdata(dev);

 gpiod_set_value_cansleep(p->enable_gpio, 0);
 regulator_disable(p->supply);
 p->unprepared_time = ktime_get_boottime();

 drm_edid_free(p->drm_edid);
 p->drm_edid = NULL;

 return 0;
}

static int panel_simple_unprepare(struct drm_panel *panel)
{
 int ret;

 pm_runtime_mark_last_busy(panel->dev);
 ret = pm_runtime_put_autosuspend(panel->dev);
 if (ret < 0)
  return ret;

 return 0;
}

static int panel_simple_resume(struct device *dev)
{
 struct panel_simple *p = dev_get_drvdata(dev);
 int err;

 panel_simple_wait(p->unprepared_time, p->desc->delay.unprepare);

 err = regulator_enable(p->supply);
 if (err < 0) {
  dev_err(dev, "failed to enable supply: %d\n", err);
  return err;
 }

 gpiod_set_value_cansleep(p->enable_gpio, 1);

 if (p->desc->delay.prepare)
  msleep(p->desc->delay.prepare);

 return 0;
}

static int panel_simple_prepare(struct drm_panel *panel)
{
 int ret;

 ret = pm_runtime_get_sync(panel->dev);
 if (ret < 0) {
  pm_runtime_put_autosuspend(panel->dev);
  return ret;
 }

 return 0;
}

static int panel_simple_enable(struct drm_panel *panel)
{
 struct panel_simple *p = to_panel_simple(panel);

 if (p->desc->delay.enable)
  msleep(p->desc->delay.enable);

 return 0;
}

static int panel_simple_get_modes(struct drm_panel *panel,
      struct drm_connector *connector)
{
 struct panel_simple *p = to_panel_simple(panel);
 int num = 0;

 /* probe EDID if a DDC bus is available */
 if (p->ddc) {
  pm_runtime_get_sync(panel->dev);

  if (!p->drm_edid)
   p->drm_edid = drm_edid_read_ddc(connector, p->ddc);

  drm_edid_connector_update(connector, p->drm_edid);

  num += drm_edid_connector_add_modes(connector);

  pm_runtime_mark_last_busy(panel->dev);
  pm_runtime_put_autosuspend(panel->dev);
 }

 /* add hard-coded panel modes */
 num += panel_simple_get_non_edid_modes(p, connector);

 /*
 * TODO: Remove once all drm drivers call
 * drm_connector_set_orientation_from_panel()
 */

 drm_connector_set_panel_orientation(connector, p->orientation);

 return num;
}

static int panel_simple_get_timings(struct drm_panel *panel,
        unsigned int num_timings,
        struct display_timing *timings)
{
 struct panel_simple *p = to_panel_simple(panel);
 unsigned int i;

 if (p->desc->num_timings < num_timings)
  num_timings = p->desc->num_timings;

 if (timings)
  for (i = 0; i < num_timings; i++)
   timings[i] = p->desc->timings[i];

 return p->desc->num_timings;
}

static enum drm_panel_orientation panel_simple_get_orientation(struct drm_panel *panel)
{
 struct panel_simple *p = to_panel_simple(panel);

 return p->orientation;
}

static const struct drm_panel_funcs panel_simple_funcs = {
 .disable = panel_simple_disable,
 .unprepare = panel_simple_unprepare,
 .prepare = panel_simple_prepare,
 .enable = panel_simple_enable,
 .get_modes = panel_simple_get_modes,
 .get_orientation = panel_simple_get_orientation,
 .get_timings = panel_simple_get_timings,
};

static struct panel_desc *panel_dpi_probe(struct device *dev)
{
 struct display_timing *timing;
 const struct device_node *np;
 struct panel_desc *desc;
 unsigned int bus_flags;
 struct videomode vm;
 int ret;

 np = dev->of_node;
 desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
 if (!desc)
  return ERR_PTR(-ENOMEM);

 timing = devm_kzalloc(dev, sizeof(*timing), GFP_KERNEL);
 if (!timing)
  return ERR_PTR(-ENOMEM);

 ret = of_get_display_timing(np, "panel-timing", timing);
 if (ret < 0) {
  dev_err(dev, "%pOF: no panel-timing node found for \"panel-dpi\" binding\n",
   np);
  return ERR_PTR(ret);
 }

 desc->timings = timing;
 desc->num_timings = 1;

 of_property_read_u32(np, "width-mm", &desc->size.width);
 of_property_read_u32(np, "height-mm", &desc->size.height);

 /* Extract bus_flags from display_timing */
 bus_flags = 0;
 vm.flags = timing->flags;
 drm_bus_flags_from_videomode(&vm, &bus_flags);
 desc->bus_flags = bus_flags;

 /* We do not know the connector for the DT node, so guess it */
 desc->connector_type = DRM_MODE_CONNECTOR_DPI;

 return desc;
}

#define PANEL_SIMPLE_BOUNDS_CHECK(to_check, bounds, field) \
 (to_check->field.typ >= bounds->field.min && \
  to_check->field.typ <= bounds->field.max)
static void panel_simple_parse_panel_timing_node(struct device *dev,
       struct panel_simple *panel,
       const struct display_timing *ot)
{
 const struct panel_desc *desc = panel->desc;
 struct videomode vm;
 unsigned int i;

 if (WARN_ON(desc->num_modes)) {
  dev_err(dev, "Reject override mode: panel has a fixed mode\n");
  return;
 }
 if (WARN_ON(!desc->num_timings)) {
  dev_err(dev, "Reject override mode: no timings specified\n");
  return;
 }

 for (i = 0; i < panel->desc->num_timings; i++) {
  const struct display_timing *dt = &panel->desc->timings[i];

  if (!PANEL_SIMPLE_BOUNDS_CHECK(ot, dt, hactive) ||
      !PANEL_SIMPLE_BOUNDS_CHECK(ot, dt, hfront_porch) ||
      !PANEL_SIMPLE_BOUNDS_CHECK(ot, dt, hback_porch) ||
      !PANEL_SIMPLE_BOUNDS_CHECK(ot, dt, hsync_len) ||
      !PANEL_SIMPLE_BOUNDS_CHECK(ot, dt, vactive) ||
      !PANEL_SIMPLE_BOUNDS_CHECK(ot, dt, vfront_porch) ||
      !PANEL_SIMPLE_BOUNDS_CHECK(ot, dt, vback_porch) ||
      !PANEL_SIMPLE_BOUNDS_CHECK(ot, dt, vsync_len))
   continue;

  if (ot->flags != dt->flags)
   continue;

  videomode_from_timing(ot, &vm);
  drm_display_mode_from_videomode(&vm, &panel->override_mode);
  panel->override_mode.type |= DRM_MODE_TYPE_DRIVER |
          DRM_MODE_TYPE_PREFERRED;
  break;
 }

 if (WARN_ON(!panel->override_mode.type))
  dev_err(dev, "Reject override mode: No display_timing found\n");
}

static int panel_simple_override_nondefault_lvds_datamapping(struct device *dev,
            struct panel_simple *panel)
{
 int ret, bpc;

 ret = drm_of_lvds_get_data_mapping(dev->of_node);
 if (ret < 0) {
  if (ret == -EINVAL)
   dev_warn(dev, "Ignore invalid data-mapping property\n");

  /*
 * Ignore non-existing or malformatted property, fallback to
 * default data-mapping, and return 0.
 */

  return 0;
 }

 switch (ret) {
 default:
  WARN_ON(1);
  fallthrough;
 case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
  fallthrough;
 case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
  bpc = 8;
  break;
 case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
  bpc = 6;
 }

 if (panel->desc->bpc != bpc || panel->desc->bus_format != ret) {
  struct panel_desc *override_desc;

  override_desc = devm_kmemdup(dev, panel->desc, sizeof(*panel->desc), GFP_KERNEL);
  if (!override_desc)
   return -ENOMEM;

  override_desc->bus_format = ret;
  override_desc->bpc = bpc;
  panel->desc = override_desc;
 }

 return 0;
}

static const struct panel_desc *panel_simple_get_desc(struct device *dev)
{
 if (IS_ENABLED(CONFIG_DRM_MIPI_DSI) &&
     dev_is_mipi_dsi(dev)) {
  const struct panel_desc_dsi *dsi_desc;

  dsi_desc = of_device_get_match_data(dev);
  if (!dsi_desc)
   return ERR_PTR(-ENODEV);

  return &dsi_desc->desc;
 }

 if (dev_is_platform(dev)) {
  const struct panel_desc *desc;

  desc = of_device_get_match_data(dev);
  if (!desc) {
   /*
 * panel-dpi probes without a descriptor and
 * panel_dpi_probe() will initialize one for us
 * based on the device tree.
 */

   if (of_device_is_compatible(dev->of_node, "panel-dpi"))
    return panel_dpi_probe(dev);
   else
    return ERR_PTR(-ENODEV);
  }

  return desc;
 }

 return ERR_PTR(-ENODEV);
}

static struct panel_simple *panel_simple_probe(struct device *dev)
{
 const struct panel_desc *desc;
 struct panel_simple *panel;
 struct display_timing dt;
 struct device_node *ddc;
 int connector_type;
 u32 bus_flags;
 int err;

 desc = panel_simple_get_desc(dev);
 if (IS_ERR(desc))
  return ERR_CAST(desc);

 panel = devm_drm_panel_alloc(dev, struct panel_simple, base,
         &panel_simple_funcs, desc->connector_type);
 if (IS_ERR(panel))
  return ERR_CAST(panel);

 panel->desc = desc;

 panel->supply = devm_regulator_get(dev, "power");
 if (IS_ERR(panel->supply))
  return ERR_CAST(panel->supply);

 panel->enable_gpio = devm_gpiod_get_optional(dev, "enable",
           GPIOD_OUT_LOW);
 if (IS_ERR(panel->enable_gpio))
  return dev_err_cast_probe(dev, panel->enable_gpio,
       "failed to request GPIO\n");

 err = of_drm_get_panel_orientation(dev->of_node, &panel->orientation);
 if (err) {
  dev_err(dev, "%pOF: failed to get orientation %d\n", dev->of_node, err);
  return ERR_PTR(err);
 }

 ddc = of_parse_phandle(dev->of_node, "ddc-i2c-bus", 0);
 if (ddc) {
  panel->ddc = of_find_i2c_adapter_by_node(ddc);
  of_node_put(ddc);

  if (!panel->ddc)
   return ERR_PTR(-EPROBE_DEFER);
 }

 if (!of_device_is_compatible(dev->of_node, "panel-dpi") &&
     !of_get_display_timing(dev->of_node, "panel-timing", &dt))
  panel_simple_parse_panel_timing_node(dev, panel, &dt);

 if (desc->connector_type == DRM_MODE_CONNECTOR_LVDS) {
  /* Optional data-mapping property for overriding bus format */
  err = panel_simple_override_nondefault_lvds_datamapping(dev, panel);
  if (err)
   goto free_ddc;
 }

 connector_type = desc->connector_type;
 /* Catch common mistakes for panels. */
 switch (connector_type) {
 case 0:
  dev_warn(dev, "Specify missing connector_type\n");
  connector_type = DRM_MODE_CONNECTOR_DPI;
  break;
 case DRM_MODE_CONNECTOR_LVDS:
  WARN_ON(desc->bus_flags &
   ~(DRM_BUS_FLAG_DE_LOW |
     DRM_BUS_FLAG_DE_HIGH |
     DRM_BUS_FLAG_DATA_MSB_TO_LSB |
     DRM_BUS_FLAG_DATA_LSB_TO_MSB));
  WARN_ON(desc->bus_format != MEDIA_BUS_FMT_RGB666_1X7X3_SPWG &&
   desc->bus_format != MEDIA_BUS_FMT_RGB888_1X7X4_SPWG &&
   desc->bus_format != MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA);
  WARN_ON(desc->bus_format == MEDIA_BUS_FMT_RGB666_1X7X3_SPWG &&
   desc->bpc != 6);
  WARN_ON((desc->bus_format == MEDIA_BUS_FMT_RGB888_1X7X4_SPWG ||
    desc->bus_format == MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA) &&
   desc->bpc != 8);
  break;
 case DRM_MODE_CONNECTOR_eDP:
  dev_warn(dev, "eDP panels moved to panel-edp\n");
  err = -EINVAL;
  goto free_ddc;
 case DRM_MODE_CONNECTOR_DSI:
  if (desc->bpc != 6 && desc->bpc != 8)
   dev_warn(dev, "Expected bpc in {6,8} but got: %u\n", desc->bpc);
  break;
 case DRM_MODE_CONNECTOR_DPI:
  bus_flags = DRM_BUS_FLAG_DE_LOW |
       DRM_BUS_FLAG_DE_HIGH |
       DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE |
       DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE |
       DRM_BUS_FLAG_DATA_MSB_TO_LSB |
       DRM_BUS_FLAG_DATA_LSB_TO_MSB |
       DRM_BUS_FLAG_SYNC_SAMPLE_POSEDGE |
       DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE;
  if (desc->bus_flags & ~bus_flags)
   dev_warn(dev, "Unexpected bus_flags(%d)\n", desc->bus_flags & ~bus_flags);
  if (!(desc->bus_flags & bus_flags))
   dev_warn(dev, "Specify missing bus_flags\n");
  if (desc->bus_format == 0)
   dev_warn(dev, "Specify missing bus_format\n");
  if (desc->bpc != 6 && desc->bpc != 8)
   dev_warn(dev, "Expected bpc in {6,8} but got: %u\n", desc->bpc);
  break;
 default:
  dev_warn(dev, "Specify a valid connector_type: %d\n", desc->connector_type);
  connector_type = DRM_MODE_CONNECTOR_DPI;
  break;
 }

 dev_set_drvdata(dev, panel);

 /*
 * We use runtime PM for prepare / unprepare since those power the panel
 * on and off and those can be very slow operations. This is important
 * to optimize powering the panel on briefly to read the EDID before
 * fully enabling the panel.
 */

 pm_runtime_enable(dev);
 pm_runtime_set_autosuspend_delay(dev, 1000);
 pm_runtime_use_autosuspend(dev);

 err = drm_panel_of_backlight(&panel->base);
 if (err) {
  dev_err_probe(dev, err, "Could not find backlight\n");
  goto disable_pm_runtime;
 }

 drm_panel_add(&panel->base);

 return panel;

disable_pm_runtime:
 pm_runtime_dont_use_autosuspend(dev);
 pm_runtime_disable(dev);
free_ddc:
 if (panel->ddc)
  put_device(&panel->ddc->dev);

 return ERR_PTR(err);
}

static void panel_simple_shutdown(struct device *dev)
{
 struct panel_simple *panel = dev_get_drvdata(dev);

 /*
 * NOTE: the following two calls don't really belong here. It is the
 * responsibility of a correctly written DRM modeset driver to call
 * drm_atomic_helper_shutdown() at shutdown time and that should
 * cause the panel to be disabled / unprepared if needed. For now,
 * however, we'll keep these calls due to the sheer number of
 * different DRM modeset drivers used with panel-simple. Once we've
 * confirmed that all DRM modeset drivers using this panel properly
 * call drm_atomic_helper_shutdown() we can simply delete the two
 * calls below.
 *
 * TO BE EXPLICIT: THE CALLS BELOW SHOULDN'T BE COPIED TO ANY NEW
 * PANEL DRIVERS.
 *
 * FIXME: If we're still haven't figured out if all DRM modeset
 * drivers properly call drm_atomic_helper_shutdown() but we _have_
 * managed to make sure that DRM modeset drivers get their shutdown()
 * callback before the panel's shutdown() callback (perhaps using
 * device link), we could add a WARN_ON here to help move forward.
 */

 if (panel->base.enabled)
  drm_panel_disable(&panel->base);
 if (panel->base.prepared)
  drm_panel_unprepare(&panel->base);
}

static void panel_simple_remove(struct device *dev)
{
 struct panel_simple *panel = dev_get_drvdata(dev);

 drm_panel_remove(&panel->base);
 panel_simple_shutdown(dev);

 pm_runtime_dont_use_autosuspend(dev);
 pm_runtime_disable(dev);
 if (panel->ddc)
  put_device(&panel->ddc->dev);
}

static const struct drm_display_mode ampire_am_1280800n3tzqw_t00h_mode = {
 .clock = 71100,
 .hdisplay = 1280,
 .hsync_start = 1280 + 40,
 .hsync_end = 1280 + 40 + 80,
 .htotal = 1280 + 40 + 80 + 40,
 .vdisplay = 800,
 .vsync_start = 800 + 3,
 .vsync_end = 800 + 3 + 10,
 .vtotal = 800 + 3 + 10 + 10,
 .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC,
};

static const struct panel_desc ampire_am_1280800n3tzqw_t00h = {
 .modes = &ire_am_1280800n3tzqw_t00h_mode,
 .num_modes = 1,
 .bpc = 8,
 .size = {
  .width = 217,
  .height = 136,
 },
 .bus_flags = DRM_BUS_FLAG_DE_HIGH,
 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct drm_display_mode ampire_am_480272h3tmqw_t01h_mode = {
 .clock = 9000,
 .hdisplay = 480,
 .hsync_start = 480 + 2,
 .hsync_end = 480 + 2 + 41,
 .htotal = 480 + 2 + 41 + 2,
 .vdisplay = 272,
 .vsync_start = 272 + 2,
 .vsync_end = 272 + 2 + 10,
 .vtotal = 272 + 2 + 10 + 2,
 .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC,
};

static const struct panel_desc ampire_am_480272h3tmqw_t01h = {
 .modes = &ire_am_480272h3tmqw_t01h_mode,
 .num_modes = 1,
 .bpc = 8,
 .size = {
  .width = 99,
  .height = 58,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
};

static const struct drm_display_mode ampire_am800480r3tmqwa1h_mode = {
 .clock = 33333,
 .hdisplay = 800,
 .hsync_start = 800 + 0,
 .hsync_end = 800 + 0 + 255,
 .htotal = 800 + 0 + 255 + 0,
 .vdisplay = 480,
 .vsync_start = 480 + 2,
 .vsync_end = 480 + 2 + 45,
 .vtotal = 480 + 2 + 45 + 0,
 .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC,
};

static const struct display_timing ampire_am_800480l1tmqw_t00h_timing = {
 .pixelclock = { 29930000, 33260000, 36590000 },
 .hactive = { 800, 800, 800 },
 .hfront_porch = { 1, 40, 168 },
 .hback_porch = { 88, 88, 88 },
 .hsync_len = { 1, 128, 128 },
 .vactive = { 480, 480, 480 },
 .vfront_porch = { 1, 35, 37 },
 .vback_porch = { 8, 8, 8 },
 .vsync_len = { 1, 2, 2 },
 .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW |
   DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE |
   DISPLAY_FLAGS_SYNC_POSEDGE,
};

static const struct panel_desc ampire_am_800480l1tmqw_t00h = {
 .timings = &ire_am_800480l1tmqw_t00h_timing,
 .num_timings = 1,
 .bpc = 8,
 .size = {
  .width = 111,
  .height = 67,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH |
       DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE |
       DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE,
 .connector_type = DRM_MODE_CONNECTOR_DPI,
};

static const struct panel_desc ampire_am800480r3tmqwa1h = {
 .modes = &ire_am800480r3tmqwa1h_mode,
 .num_modes = 1,
 .bpc = 6,
 .size = {
  .width = 152,
  .height = 91,
 },
 .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
};

static const struct display_timing ampire_am800600p5tmqw_tb8h_timing = {
 .pixelclock = { 34500000, 39600000, 50400000 },
 .hactive = { 800, 800, 800 },
 .hfront_porch = { 12, 112, 312 },
 .hback_porch = { 87, 87, 48 },
 .hsync_len = { 1, 1, 40 },
 .vactive = { 600, 600, 600 },
 .vfront_porch = { 1, 21, 61 },
 .vback_porch = { 38, 38, 19 },
 .vsync_len = { 1, 1, 20 },
 .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW |
  DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE |
  DISPLAY_FLAGS_SYNC_POSEDGE,
};

static const struct panel_desc ampire_am800600p5tmqwtb8h = {
 .timings = &ire_am800600p5tmqw_tb8h_timing,
 .num_timings = 1,
 .bpc = 6,
 .size = {
  .width = 162,
  .height = 122,
 },
 .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH |
  DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE |
  DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE,
 .connector_type = DRM_MODE_CONNECTOR_DPI,
};

static const struct display_timing santek_st0700i5y_rbslw_f_timing = {
 .pixelclock = { 26400000, 33300000, 46800000 },
 .hactive = { 800, 800, 800 },
 .hfront_porch = { 16, 210, 354 },
 .hback_porch = { 45, 36, 6 },
 .hsync_len = { 1, 10, 40 },
 .vactive = { 480, 480, 480 },
 .vfront_porch = { 7, 22, 147 },
 .vback_porch = { 22, 13, 3 },
 .vsync_len = { 1, 10, 20 },
 .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW |
  DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE
};

static const struct panel_desc armadeus_st0700_adapt = {
 .timings = &santek_st0700i5y_rbslw_f_timing,
 .num_timings = 1,
 .bpc = 6,
 .size = {
  .width = 154,
  .height = 86,
 },
 .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE,
};

static const struct drm_display_mode auo_b101aw03_mode = {
 .clock = 51450,
 .hdisplay = 1024,
 .hsync_start = 1024 + 156,
 .hsync_end = 1024 + 156 + 8,
 .htotal = 1024 + 156 + 8 + 156,
 .vdisplay = 600,
 .vsync_start = 600 + 16,
 .vsync_end = 600 + 16 + 6,
 .vtotal = 600 + 16 + 6 + 16,
};

static const struct panel_desc auo_b101aw03 = {
 .modes = &auo_b101aw03_mode,
 .num_modes = 1,
 .bpc = 6,
 .size = {
  .width = 223,
  .height = 125,
 },
 .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct drm_display_mode auo_b101xtn01_mode = {
 .clock = 72000,
 .hdisplay = 1366,
 .hsync_start = 1366 + 20,
 .hsync_end = 1366 + 20 + 70,
 .htotal = 1366 + 20 + 70,
 .vdisplay = 768,
 .vsync_start = 768 + 14,
 .vsync_end = 768 + 14 + 42,
 .vtotal = 768 + 14 + 42,
 .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
};

static const struct panel_desc auo_b101xtn01 = {
 .modes = &auo_b101xtn01_mode,
 .num_modes = 1,
 .bpc = 6,
 .size = {
  .width = 223,
  .height = 125,
 },
};

static const struct drm_display_mode auo_b116xw03_mode = {
 .clock = 70589,
 .hdisplay = 1366,
 .hsync_start = 1366 + 40,
 .hsync_end = 1366 + 40 + 40,
 .htotal = 1366 + 40 + 40 + 32,
 .vdisplay = 768,
 .vsync_start = 768 + 10,
 .vsync_end = 768 + 10 + 12,
 .vtotal = 768 + 10 + 12 + 6,
 .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
};

static const struct panel_desc auo_b116xw03 = {
 .modes = &auo_b116xw03_mode,
 .num_modes = 1,
 .bpc = 6,
 .size = {
  .width = 256,
  .height = 144,
 },
 .delay = {
  .prepare = 1,
  .enable = 200,
  .disable = 200,
  .unprepare = 500,
 },
 .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct display_timing auo_g070vvn01_timings = {
 .pixelclock = { 33300000, 34209000, 45000000 },
 .hactive = { 800, 800, 800 },
 .hfront_porch = { 20, 40, 200 },
 .hback_porch = { 87, 40, 1 },
 .hsync_len = { 1, 48, 87 },
 .vactive = { 480, 480, 480 },
 .vfront_porch = { 5, 13, 200 },
 .vback_porch = { 31, 31, 29 },
 .vsync_len = { 1, 1, 3 },
};

static const struct panel_desc auo_g070vvn01 = {
 .timings = &auo_g070vvn01_timings,
 .num_timings = 1,
 .bpc = 8,
 .size = {
  .width = 152,
  .height = 91,
 },
 .delay = {
  .prepare = 200,
  .enable = 50,
  .disable = 50,
  .unprepare = 1000,
 },
};

static const struct display_timing auo_g101evn010_timing = {
 .pixelclock = { 64000000, 68930000, 85000000 },
 .hactive = { 1280, 1280, 1280 },
 .hfront_porch = { 8, 64, 256 },
 .hback_porch = { 8, 64, 256 },
 .hsync_len = { 40, 168, 767 },
 .vactive = { 800, 800, 800 },
 .vfront_porch = { 4, 8, 100 },
 .vback_porch = { 4, 8, 100 },
 .vsync_len = { 8, 16, 223 },
};

static const struct panel_desc auo_g101evn010 = {
 .timings = &auo_g101evn010_timing,
 .num_timings = 1,
 .bpc = 6,
 .size = {
  .width = 216,
  .height = 135,
 },
 .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct drm_display_mode auo_g104sn02_mode = {
 .clock = 40000,
 .hdisplay = 800,
 .hsync_start = 800 + 40,
 .hsync_end = 800 + 40 + 216,
 .htotal = 800 + 40 + 216 + 128,
 .vdisplay = 600,
 .vsync_start = 600 + 10,
 .vsync_end = 600 + 10 + 35,
 .vtotal = 600 + 10 + 35 + 2,
};

static const struct panel_desc auo_g104sn02 = {
 .modes = &auo_g104sn02_mode,
 .num_modes = 1,
 .bpc = 8,
 .size = {
  .width = 211,
  .height = 158,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct drm_display_mode auo_g104stn01_mode = {
 .clock = 40000,
 .hdisplay = 800,
 .hsync_start = 800 + 40,
 .hsync_end = 800 + 40 + 88,
 .htotal = 800 + 40 + 88 + 128,
 .vdisplay = 600,
 .vsync_start = 600 + 1,
 .vsync_end = 600 + 1 + 23,
 .vtotal = 600 + 1 + 23 + 4,
};

static const struct panel_desc auo_g104stn01 = {
 .modes = &auo_g104stn01_mode,
 .num_modes = 1,
 .bpc = 8,
 .size = {
  .width = 211,
  .height = 158,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct display_timing auo_g121ean01_timing = {
 .pixelclock = { 60000000, 74400000, 90000000 },
 .hactive = { 1280, 1280, 1280 },
 .hfront_porch = { 20, 50, 100 },
 .hback_porch = { 20, 50, 100 },
 .hsync_len = { 30, 100, 200 },
 .vactive = { 800, 800, 800 },
 .vfront_porch = { 2, 10, 25 },
 .vback_porch = { 2, 10, 25 },
 .vsync_len = { 4, 18, 50 },
};

static const struct panel_desc auo_g121ean01 = {
 .timings = &auo_g121ean01_timing,
 .num_timings = 1,
 .bpc = 8,
 .size = {
  .width = 261,
  .height = 163,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct display_timing auo_g133han01_timings = {
 .pixelclock = { 134000000, 141200000, 149000000 },
 .hactive = { 1920, 1920, 1920 },
 .hfront_porch = { 39, 58, 77 },
 .hback_porch = { 59, 88, 117 },
 .hsync_len = { 28, 42, 56 },
 .vactive = { 1080, 1080, 1080 },
 .vfront_porch = { 3, 8, 11 },
 .vback_porch = { 5, 14, 19 },
 .vsync_len = { 4, 14, 19 },
};

static const struct panel_desc auo_g133han01 = {
 .timings = &auo_g133han01_timings,
 .num_timings = 1,
 .bpc = 8,
 .size = {
  .width = 293,
  .height = 165,
 },
 .delay = {
  .prepare = 200,
  .enable = 50,
  .disable = 50,
  .unprepare = 1000,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct display_timing auo_g156han04_timings = {
 .pixelclock = { 137000000, 141000000, 146000000 },
 .hactive = { 1920, 1920, 1920 },
 .hfront_porch = { 60, 60, 60 },
 .hback_porch = { 90, 92, 111 },
 .hsync_len =  { 32, 32, 32 },
 .vactive = { 1080, 1080, 1080 },
 .vfront_porch = { 12, 12, 12 },
 .vback_porch = { 24, 36, 56 },
 .vsync_len = { 8, 8, 8 },
};

static const struct panel_desc auo_g156han04 = {
 .timings = &auo_g156han04_timings,
 .num_timings = 1,
 .bpc = 8,
 .size = {
  .width = 344,
  .height = 194,
 },
 .delay = {
  .prepare = 50,  /* T2 */
  .enable = 200,  /* T3 */
  .disable = 110,  /* T10 */
  .unprepare = 1000, /* T13 */
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct drm_display_mode auo_g156xtn01_mode = {
 .clock = 76000,
 .hdisplay = 1366,
 .hsync_start = 1366 + 33,
 .hsync_end = 1366 + 33 + 67,
 .htotal = 1560,
 .vdisplay = 768,
 .vsync_start = 768 + 4,
 .vsync_end = 768 + 4 + 4,
 .vtotal = 806,
};

static const struct panel_desc auo_g156xtn01 = {
 .modes = &auo_g156xtn01_mode,
 .num_modes = 1,
 .bpc = 8,
 .size = {
  .width = 344,
  .height = 194,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct display_timing auo_g185han01_timings = {
 .pixelclock = { 120000000, 144000000, 175000000 },
 .hactive = { 1920, 1920, 1920 },
 .hfront_porch = { 36, 120, 148 },
 .hback_porch = { 24, 88, 108 },
 .hsync_len = { 20, 48, 64 },
 .vactive = { 1080, 1080, 1080 },
 .vfront_porch = { 6, 10, 40 },
 .vback_porch = { 2, 5, 20 },
 .vsync_len = { 2, 5, 20 },
};

static const struct panel_desc auo_g185han01 = {
 .timings = &auo_g185han01_timings,
 .num_timings = 1,
 .bpc = 8,
 .size = {
  .width = 409,
  .height = 230,
 },
 .delay = {
  .prepare = 50,
  .enable = 200,
  .disable = 110,
  .unprepare = 1000,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct display_timing auo_g190ean01_timings = {
 .pixelclock = { 90000000, 108000000, 135000000 },
 .hactive = { 1280, 1280, 1280 },
 .hfront_porch = { 126, 184, 1266 },
 .hback_porch = { 84, 122, 844 },
 .hsync_len = { 70, 102, 704 },
 .vactive = { 1024, 1024, 1024 },
 .vfront_porch = { 4, 26, 76 },
 .vback_porch = { 2, 8, 25 },
 .vsync_len = { 2, 8, 25 },
};

static const struct panel_desc auo_g190ean01 = {
 .timings = &auo_g190ean01_timings,
 .num_timings = 1,
 .bpc = 8,
 .size = {
  .width = 376,
  .height = 301,
 },
 .delay = {
  .prepare = 50,
  .enable = 200,
  .disable = 110,
  .unprepare = 1000,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct display_timing auo_p238han01_timings = {
 .pixelclock = { 107400000, 142400000, 180000000 },
 .hactive = { 1920, 1920, 1920 },
 .hfront_porch = { 30, 70, 650 },
 .hback_porch = { 30, 70, 650 },
 .hsync_len = { 20, 40, 136 },
 .vactive = { 1080, 1080, 1080 },
 .vfront_porch = { 5, 19, 318 },
 .vback_porch = { 5, 19, 318 },
 .vsync_len = { 4, 12, 120 },
};

static const struct panel_desc auo_p238han01 = {
 .timings = &auo_p238han01_timings,
 .num_timings = 1,
 .bpc = 8,
 .size = {
  .width = 527,
  .height = 296,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct display_timing auo_p320hvn03_timings = {
 .pixelclock = { 106000000, 148500000, 164000000 },
 .hactive = { 1920, 1920, 1920 },
 .hfront_porch = { 25, 50, 130 },
 .hback_porch = { 25, 50, 130 },
 .hsync_len = { 20, 40, 105 },
 .vactive = { 1080, 1080, 1080 },
 .vfront_porch = { 8, 17, 150 },
 .vback_porch = { 8, 17, 150 },
 .vsync_len = { 4, 11, 100 },
};

static const struct panel_desc auo_p320hvn03 = {
 .timings = &auo_p320hvn03_timings,
 .num_timings = 1,
 .bpc = 8,
 .size = {
  .width = 698,
  .height = 393,
 },
 .delay = {
  .prepare = 1,
  .enable = 450,
  .unprepare = 500,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct drm_display_mode auo_t215hvn01_mode = {
 .clock = 148800,
 .hdisplay = 1920,
 .hsync_start = 1920 + 88,
 .hsync_end = 1920 + 88 + 44,
 .htotal = 1920 + 88 + 44 + 148,
 .vdisplay = 1080,
 .vsync_start = 1080 + 4,
 .vsync_end = 1080 + 4 + 5,
 .vtotal = 1080 + 4 + 5 + 36,
};

static const struct panel_desc auo_t215hvn01 = {
 .modes = &auo_t215hvn01_mode,
 .num_modes = 1,
 .bpc = 8,
 .size = {
  .width = 430,
  .height = 270,
 },
 .delay = {
  .disable = 5,
  .unprepare = 1000,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct drm_display_mode avic_tm070ddh03_mode = {
 .clock = 51200,
 .hdisplay = 1024,
 .hsync_start = 1024 + 160,
 .hsync_end = 1024 + 160 + 4,
 .htotal = 1024 + 160 + 4 + 156,
 .vdisplay = 600,
 .vsync_start = 600 + 17,
 .vsync_end = 600 + 17 + 1,
 .vtotal = 600 + 17 + 1 + 17,
};

static const struct panel_desc avic_tm070ddh03 = {
 .modes = &avic_tm070ddh03_mode,
 .num_modes = 1,
 .bpc = 8,
 .size = {
  .width = 154,
  .height = 90,
 },
 .delay = {
  .prepare = 20,
  .enable = 200,
  .disable = 200,
 },
};

static const struct drm_display_mode bananapi_s070wv20_ct16_mode = {
 .clock = 30000,
 .hdisplay = 800,
 .hsync_start = 800 + 40,
 .hsync_end = 800 + 40 + 48,
 .htotal = 800 + 40 + 48 + 40,
 .vdisplay = 480,
 .vsync_start = 480 + 13,
 .vsync_end = 480 + 13 + 3,
 .vtotal = 480 + 13 + 3 + 29,
};

static const struct panel_desc bananapi_s070wv20_ct16 = {
 .modes = &bananapi_s070wv20_ct16_mode,
 .num_modes = 1,
 .bpc = 6,
 .size = {
  .width = 154,
  .height = 86,
 },
};

static const struct display_timing boe_av101hdt_a10_timing = {
 .pixelclock = { 74210000, 75330000, 76780000, },
 .hactive = { 1280, 1280, 1280, },
 .hfront_porch = { 10, 42, 33, },
 .hback_porch = { 10, 18, 33, },
 .hsync_len = { 30, 10, 30, },
 .vactive = { 720, 720, 720, },
 .vfront_porch = { 200, 183, 200, },
 .vback_porch = { 8, 8, 8, },
 .vsync_len = { 2, 19, 2, },
 .flags = DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW,
};

static const struct panel_desc boe_av101hdt_a10 = {
 .timings = &boe_av101hdt_a10_timing,
 .num_timings = 1,
 .bpc = 8,
 .size = {
  .width = 224,
  .height = 126,
 },
 .delay = {
  .enable = 50,
  .disable = 50,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct display_timing boe_av123z7m_n17_timing = {
 .pixelclock = { 86600000, 88000000, 90800000, },
 .hactive = { 1920, 1920, 1920, },
 .hfront_porch = { 10, 10, 10, },
 .hback_porch = { 10, 10, 10, },
 .hsync_len = { 9, 12, 25, },
 .vactive = { 720, 720, 720, },
 .vfront_porch = { 7, 10, 13, },
 .vback_porch = { 7, 10, 13, },
 .vsync_len = { 7, 11, 14, },
 .flags = DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW,
};

static const struct panel_desc boe_av123z7m_n17 = {
 .timings = &boe_av123z7m_n17_timing,
 .bpc = 8,
 .num_timings = 1,
 .size = {
  .width = 292,
  .height = 110,
 },
 .delay = {
  .prepare = 50,
  .disable = 50,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct drm_display_mode boe_bp101wx1_100_mode = {
 .clock = 78945,
 .hdisplay = 1280,
 .hsync_start = 1280 + 0,
 .hsync_end = 1280 + 0 + 2,
 .htotal = 1280 + 62 + 0 + 2,
 .vdisplay = 800,
 .vsync_start = 800 + 8,
 .vsync_end = 800 + 8 + 2,
 .vtotal = 800 + 6 + 8 + 2,
};

static const struct panel_desc boe_bp082wx1_100 = {
 .modes = &boe_bp101wx1_100_mode,
 .num_modes = 1,
 .bpc = 8,
 .size = {
  .width = 177,
  .height = 110,
 },
 .delay = {
  .enable = 50,
  .disable = 50,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct panel_desc boe_bp101wx1_100 = {
 .modes = &boe_bp101wx1_100_mode,
 .num_modes = 1,
 .bpc = 8,
 .size = {
  .width = 217,
  .height = 136,
 },
 .delay = {
  .enable = 50,
  .disable = 50,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct display_timing boe_ev121wxm_n10_1850_timing = {
 .pixelclock = { 69922000, 71000000, 72293000 },
 .hactive = { 1280, 1280, 1280 },
 .hfront_porch = { 48, 48, 48 },
 .hback_porch = { 80, 80, 80 },
 .hsync_len = { 32, 32, 32 },
 .vactive = { 800, 800, 800 },
 .vfront_porch = { 3, 3, 3 },
 .vback_porch = { 14, 14, 14 },
 .vsync_len = { 6, 6, 6 },
};

static const struct panel_desc boe_ev121wxm_n10_1850 = {
 .timings = &boe_ev121wxm_n10_1850_timing,
 .num_timings = 1,
 .bpc = 8,
 .size = {
  .width = 261,
  .height = 163,
 },
 .delay = {
  .prepare = 9,
  .enable = 300,
  .unprepare = 300,
  .disable = 560,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct drm_display_mode boe_hv070wsa_mode = {
 .clock = 42105,
 .hdisplay = 1024,
 .hsync_start = 1024 + 30,
 .hsync_end = 1024 + 30 + 30,
 .htotal = 1024 + 30 + 30 + 30,
 .vdisplay = 600,
 .vsync_start = 600 + 10,
 .vsync_end = 600 + 10 + 10,
 .vtotal = 600 + 10 + 10 + 10,
};

static const struct panel_desc boe_hv070wsa = {
 .modes = &boe_hv070wsa_mode,
 .num_modes = 1,
 .bpc = 8,
 .size = {
  .width = 154,
  .height = 90,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct display_timing cct_cmt430b19n00_timing = {
 .pixelclock = { 8000000, 9000000, 12000000 },
 .hactive = { 480, 480, 480 },
 .hfront_porch = { 2, 8, 75 },
 .hback_porch = { 3, 43, 43 },
 .hsync_len = { 2, 4, 75 },
 .vactive = { 272, 272, 272 },
 .vfront_porch = { 2, 8, 37 },
 .vback_porch = { 2, 12, 12 },
 .vsync_len = { 2, 4, 37 },
 .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW
};

static const struct panel_desc cct_cmt430b19n00 = {
 .timings = &cct_cmt430b19n00_timing,
 .num_timings = 1,
 .bpc = 8,
 .size = {
  .width = 95,
  .height = 53,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE,
 .connector_type = DRM_MODE_CONNECTOR_DPI,
};

static const struct drm_display_mode cdtech_s043wq26h_ct7_mode = {
 .clock = 9000,
 .hdisplay = 480,
 .hsync_start = 480 + 5,
 .hsync_end = 480 + 5 + 5,
 .htotal = 480 + 5 + 5 + 40,
 .vdisplay = 272,
 .vsync_start = 272 + 8,
 .vsync_end = 272 + 8 + 8,
 .vtotal = 272 + 8 + 8 + 8,
 .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
};

static const struct panel_desc cdtech_s043wq26h_ct7 = {
 .modes = &cdtech_s043wq26h_ct7_mode,
 .num_modes = 1,
 .bpc = 8,
 .size = {
  .width = 95,
  .height = 54,
 },
 .bus_flags = DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,
};

/* S070PWS19HP-FC21 2017/04/22 */
static const struct drm_display_mode cdtech_s070pws19hp_fc21_mode = {
 .clock = 51200,
 .hdisplay = 1024,
 .hsync_start = 1024 + 160,
 .hsync_end = 1024 + 160 + 20,
 .htotal = 1024 + 160 + 20 + 140,
 .vdisplay = 600,
 .vsync_start = 600 + 12,
 .vsync_end = 600 + 12 + 3,
 .vtotal = 600 + 12 + 3 + 20,
 .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
};

static const struct panel_desc cdtech_s070pws19hp_fc21 = {
 .modes = &cdtech_s070pws19hp_fc21_mode,
 .num_modes = 1,
 .bpc = 6,
 .size = {
  .width = 154,
  .height = 86,
 },
 .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE,
 .connector_type = DRM_MODE_CONNECTOR_DPI,
};

/* S070SWV29HG-DC44 2017/09/21 */
static const struct drm_display_mode cdtech_s070swv29hg_dc44_mode = {
 .clock = 33300,
 .hdisplay = 800,
 .hsync_start = 800 + 210,
 .hsync_end = 800 + 210 + 2,
 .htotal = 800 + 210 + 2 + 44,
 .vdisplay = 480,
 .vsync_start = 480 + 22,
 .vsync_end = 480 + 22 + 2,
 .vtotal = 480 + 22 + 2 + 21,
 .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
};

static const struct panel_desc cdtech_s070swv29hg_dc44 = {
 .modes = &cdtech_s070swv29hg_dc44_mode,
 .num_modes = 1,
 .bpc = 6,
 .size = {
  .width = 154,
  .height = 86,
 },
 .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE,
 .connector_type = DRM_MODE_CONNECTOR_DPI,
};

static const struct drm_display_mode cdtech_s070wv95_ct16_mode = {
 .clock = 35000,
 .hdisplay = 800,
 .hsync_start = 800 + 40,
 .hsync_end = 800 + 40 + 40,
 .htotal = 800 + 40 + 40 + 48,
 .vdisplay = 480,
 .vsync_start = 480 + 29,
 .vsync_end = 480 + 29 + 13,
 .vtotal = 480 + 29 + 13 + 3,
 .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
};

static const struct panel_desc cdtech_s070wv95_ct16 = {
 .modes = &cdtech_s070wv95_ct16_mode,
 .num_modes = 1,
 .bpc = 8,
 .size = {
  .width = 154,
  .height = 85,
 },
};

static const struct display_timing chefree_ch101olhlwh_002_timing = {
 .pixelclock = { 68900000, 71100000, 73400000 },
 .hactive = { 1280, 1280, 1280 },
 .hfront_porch = { 65, 80, 95 },
 .hback_porch = { 64, 79, 94 },
 .hsync_len = { 1, 1, 1 },
 .vactive = { 800, 800, 800 },
 .vfront_porch = { 7, 11, 14 },
 .vback_porch = { 7, 11, 14 },
 .vsync_len = { 1, 1, 1 },
 .flags = DISPLAY_FLAGS_DE_HIGH,
};

static const struct panel_desc chefree_ch101olhlwh_002 = {
 .timings = &chefree_ch101olhlwh_002_timing,
 .num_timings = 1,
 .bpc = 8,
 .size = {
  .width = 217,
  .height = 135,
 },
 .delay = {
  .enable = 200,
  .disable = 200,
 },
 .bus_flags = DRM_BUS_FLAG_DE_HIGH,
 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct drm_display_mode chunghwa_claa070wp03xg_mode = {
 .clock = 66770,
 .hdisplay = 800,
 .hsync_start = 800 + 49,
 .hsync_end = 800 + 49 + 33,
 .htotal = 800 + 49 + 33 + 17,
 .vdisplay = 1280,
 .vsync_start = 1280 + 1,
 .vsync_end = 1280 + 1 + 7,
 .vtotal = 1280 + 1 + 7 + 15,
 .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
};

static const struct panel_desc chunghwa_claa070wp03xg = {
 .modes = &chunghwa_claa070wp03xg_mode,
 .num_modes = 1,
 .bpc = 6,
 .size = {
  .width = 94,
  .height = 150,
 },
 .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct drm_display_mode chunghwa_claa101wa01a_mode = {
 .clock = 72070,
 .hdisplay = 1366,
 .hsync_start = 1366 + 58,
 .hsync_end = 1366 + 58 + 58,
 .htotal = 1366 + 58 + 58 + 58,
 .vdisplay = 768,
 .vsync_start = 768 + 4,
 .vsync_end = 768 + 4 + 4,
 .vtotal = 768 + 4 + 4 + 4,
};

static const struct panel_desc chunghwa_claa101wa01a = {
 .modes = &chunghwa_claa101wa01a_mode,
 .num_modes = 1,
 .bpc = 6,
 .size = {
  .width = 220,
  .height = 120,
 },
 .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct drm_display_mode chunghwa_claa101wb01_mode = {
 .clock = 69300,
 .hdisplay = 1366,
 .hsync_start = 1366 + 48,
 .hsync_end = 1366 + 48 + 32,
 .htotal = 1366 + 48 + 32 + 20,
 .vdisplay = 768,
 .vsync_start = 768 + 16,
 .vsync_end = 768 + 16 + 8,
 .vtotal = 768 + 16 + 8 + 16,
};

static const struct panel_desc chunghwa_claa101wb01 = {
 .modes = &chunghwa_claa101wb01_mode,
 .num_modes = 1,
 .bpc = 6,
 .size = {
  .width = 223,
  .height = 125,
 },
 .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct display_timing dataimage_fg040346dsswbg04_timing = {
 .pixelclock = { 5000000, 9000000, 12000000 },
 .hactive = { 480, 480, 480 },
 .hfront_porch = { 12, 12, 12 },
 .hback_porch = { 12, 12, 12 },
 .hsync_len = { 21, 21, 21 },
 .vactive = { 272, 272, 272 },
 .vfront_porch = { 4, 4, 4 },
 .vback_porch = { 4, 4, 4 },
 .vsync_len = { 8, 8, 8 },
};

static const struct panel_desc dataimage_fg040346dsswbg04 = {
 .timings = &dataimage_fg040346dsswbg04_timing,
 .num_timings = 1,
 .bpc = 8,
 .size = {
  .width = 95,
  .height = 54,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,
 .connector_type = DRM_MODE_CONNECTOR_DPI,
};

static const struct display_timing dataimage_fg1001l0dsswmg01_timing = {
 .pixelclock = { 68900000, 71110000, 73400000 },
 .hactive = { 1280, 1280, 1280 },
 .vactive = { 800, 800, 800 },
 .hback_porch = { 100, 100, 100 },
 .hfront_porch = { 100, 100, 100 },
 .vback_porch = { 5, 5, 5 },
 .vfront_porch = { 5, 5, 5 },
 .hsync_len = { 24, 24, 24 },
 .vsync_len = { 3, 3, 3 },
 .flags = DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE |
   DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW,
};

static const struct panel_desc dataimage_fg1001l0dsswmg01 = {
 .timings = &dataimage_fg1001l0dsswmg01_timing,
 .num_timings = 1,
 .bpc = 8,
 .size = {
  .width = 217,
  .height = 136,
 },
};

static const struct drm_display_mode dataimage_scf0700c48ggu18_mode = {
 .clock = 33260,
 .hdisplay = 800,
 .hsync_start = 800 + 40,
 .hsync_end = 800 + 40 + 128,
 .htotal = 800 + 40 + 128 + 88,
 .vdisplay = 480,
 .vsync_start = 480 + 10,
 .vsync_end = 480 + 10 + 2,
 .vtotal = 480 + 10 + 2 + 33,
 .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
};

static const struct panel_desc dataimage_scf0700c48ggu18 = {
 .modes = &dataimage_scf0700c48ggu18_mode,
 .num_modes = 1,
 .bpc = 8,
 .size = {
  .width = 152,
  .height = 91,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,
};

static const struct display_timing dlc_dlc0700yzg_1_timing = {
 .pixelclock = { 45000000, 51200000, 57000000 },
 .hactive = { 1024, 1024, 1024 },
 .hfront_porch = { 100, 106, 113 },
 .hback_porch = { 100, 106, 113 },
 .hsync_len = { 100, 108, 114 },
 .vactive = { 600, 600, 600 },
 .vfront_porch = { 8, 11, 15 },
 .vback_porch = { 8, 11, 15 },
 .vsync_len = { 9, 13, 15 },
 .flags = DISPLAY_FLAGS_DE_HIGH,
};

static const struct panel_desc dlc_dlc0700yzg_1 = {
 .timings = &dlc_dlc0700yzg_1_timing,
 .num_timings = 1,
 .bpc = 6,
 .size = {
  .width = 154,
  .height = 86,
 },
 .delay = {
  .prepare = 30,
  .enable = 200,
  .disable = 200,
 },
 .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct display_timing dlc_dlc1010gig_timing = {
 .pixelclock = { 68900000, 71100000, 73400000 },
 .hactive = { 1280, 1280, 1280 },
 .hfront_porch = { 43, 53, 63 },
 .hback_porch = { 43, 53, 63 },
 .hsync_len = { 44, 54, 64 },
 .vactive = { 800, 800, 800 },
 .vfront_porch = { 5, 8, 11 },
 .vback_porch = { 5, 8, 11 },
 .vsync_len = { 5, 7, 11 },
 .flags = DISPLAY_FLAGS_DE_HIGH,
};

static const struct panel_desc dlc_dlc1010gig = {
 .timings = &dlc_dlc1010gig_timing,
 .num_timings = 1,
 .bpc = 8,
 .size = {
  .width = 216,
  .height = 135,
 },
 .delay = {
  .prepare = 60,
  .enable = 150,
  .disable = 100,
  .unprepare = 60,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct drm_display_mode edt_et035012dm6_mode = {
 .clock = 6500,
 .hdisplay = 320,
 .hsync_start = 320 + 20,
 .hsync_end = 320 + 20 + 30,
 .htotal = 320 + 20 + 68,
 .vdisplay = 240,
 .vsync_start = 240 + 4,
 .vsync_end = 240 + 4 + 4,
 .vtotal = 240 + 4 + 4 + 14,
 .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
};

static const struct panel_desc edt_et035012dm6 = {
 .modes = &edt_et035012dm6_mode,
 .num_modes = 1,
 .bpc = 8,
 .size = {
  .width = 70,
  .height = 52,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
 .bus_flags = DRM_BUS_FLAG_DE_LOW | DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE,
};

static const struct drm_display_mode edt_etm0350g0dh6_mode = {
 .clock = 6520,
 .hdisplay = 320,
 .hsync_start = 320 + 20,
 .hsync_end = 320 + 20 + 68,
 .htotal = 320 + 20 + 68,
 .vdisplay = 240,
 .vsync_start = 240 + 4,
 .vsync_end = 240 + 4 + 18,
 .vtotal = 240 + 4 + 18,
 .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
};

static const struct panel_desc edt_etm0350g0dh6 = {
 .modes = &edt_etm0350g0dh6_mode,
 .num_modes = 1,
 .bpc = 6,
 .size = {
  .width = 70,
  .height = 53,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE,
 .connector_type = DRM_MODE_CONNECTOR_DPI,
};

static const struct drm_display_mode edt_etm043080dh6gp_mode = {
 .clock = 10870,
 .hdisplay = 480,
 .hsync_start = 480 + 8,
 .hsync_end = 480 + 8 + 4,
 .htotal = 480 + 8 + 4 + 41,

 /*
 * IWG22M: Y resolution changed for "dc_linuxfb" module crashing while
 * fb_align
 */


 .vdisplay = 288,
 .vsync_start = 288 + 2,
 .vsync_end = 288 + 2 + 4,
 .vtotal = 288 + 2 + 4 + 10,
};

static const struct panel_desc edt_etm043080dh6gp = {
 .modes = &edt_etm043080dh6gp_mode,
 .num_modes = 1,
 .bpc = 8,
 .size = {
  .width = 100,
  .height = 65,
 },
 .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
 .connector_type = DRM_MODE_CONNECTOR_DPI,
};

static const struct drm_display_mode edt_etm0430g0dh6_mode = {
 .clock = 9000,
 .hdisplay = 480,
 .hsync_start = 480 + 2,
 .hsync_end = 480 + 2 + 41,
 .htotal = 480 + 2 + 41 + 2,
 .vdisplay = 272,
 .vsync_start = 272 + 2,
 .vsync_end = 272 + 2 + 10,
 .vtotal = 272 + 2 + 10 + 2,
 .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
};

static const struct panel_desc edt_etm0430g0dh6 = {
 .modes = &edt_etm0430g0dh6_mode,
 .num_modes = 1,
 .bpc = 6,
 .size = {
  .width = 95,
  .height = 54,
 },
 .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE,
 .connector_type = DRM_MODE_CONNECTOR_DPI,
};

static const struct drm_display_mode edt_et057090dhu_mode = {
 .clock = 25175,
 .hdisplay = 640,
 .hsync_start = 640 + 16,
 .hsync_end = 640 + 16 + 30,
 .htotal = 640 + 16 + 30 + 114,
 .vdisplay = 480,
 .vsync_start = 480 + 10,
 .vsync_end = 480 + 10 + 3,
 .vtotal = 480 + 10 + 3 + 32,
 .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
};

static const struct panel_desc edt_et057090dhu = {
 .modes = &edt_et057090dhu_mode,
 .num_modes = 1,
 .bpc = 6,
 .size = {
  .width = 115,
  .height = 86,
 },
 .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE,
 .connector_type = DRM_MODE_CONNECTOR_DPI,
};

static const struct drm_display_mode edt_etm0700g0dh6_mode = {
 .clock = 33260,
 .hdisplay = 800,
 .hsync_start = 800 + 40,
 .hsync_end = 800 + 40 + 128,
 .htotal = 800 + 40 + 128 + 88,
 .vdisplay = 480,
 .vsync_start = 480 + 10,
 .vsync_end = 480 + 10 + 2,
 .vtotal = 480 + 10 + 2 + 33,
 .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
};

static const struct panel_desc edt_etm0700g0dh6 = {
 .modes = &edt_etm0700g0dh6_mode,
 .num_modes = 1,
 .bpc = 6,
 .size = {
  .width = 152,
  .height = 91,
 },
 .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE,
 .connector_type = DRM_MODE_CONNECTOR_DPI,
};

static const struct panel_desc edt_etm0700g0bdh6 = {
 .modes = &edt_etm0700g0dh6_mode,
 .num_modes = 1,
 .bpc = 6,
 .size = {
  .width = 152,
  .height = 91,
 },
 .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,
 .connector_type = DRM_MODE_CONNECTOR_DPI,
};

static const struct display_timing edt_etml0700y5dha_timing = {
 .pixelclock = { 40800000, 51200000, 67200000 },
 .hactive = { 1024, 1024, 1024 },
 .hfront_porch = { 30, 106, 125 },
 .hback_porch = { 30, 106, 125 },
 .hsync_len = { 30, 108, 126 },
 .vactive = { 600, 600, 600 },
 .vfront_porch = { 3, 12, 67},
 .vback_porch = { 3, 12, 67 },
 .vsync_len = { 4, 11, 66 },
 .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW |
   DISPLAY_FLAGS_DE_HIGH,
};

static const struct panel_desc edt_etml0700y5dha = {
 .timings = &edt_etml0700y5dha_timing,
 .num_timings = 1,
 .bpc = 8,
 .size = {
  .width = 155,
  .height = 86,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct display_timing edt_etml1010g3dra_timing = {
 .pixelclock = { 66300000, 72400000, 78900000 },
 .hactive = { 1280, 1280, 1280 },
 .hfront_porch = { 12, 72, 132 },
 .hback_porch = { 86, 86, 86 },
 .hsync_len = { 2, 2, 2 },
 .vactive = { 800, 800, 800 },
 .vfront_porch = { 1, 15, 49 },
 .vback_porch = { 21, 21, 21 },
 .vsync_len = { 2, 2, 2 },
 .flags = DISPLAY_FLAGS_VSYNC_LOW | DISPLAY_FLAGS_HSYNC_LOW |
   DISPLAY_FLAGS_DE_HIGH,
};

static const struct panel_desc edt_etml1010g3dra = {
 .timings = &edt_etml1010g3dra_timing,
 .num_timings = 1,
 .bpc = 8,
 .size = {
  .width = 216,
  .height = 135,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct drm_display_mode edt_etmv570g2dhu_mode = {
 .clock = 25175,
 .hdisplay = 640,
 .hsync_start = 640,
 .hsync_end = 640 + 16,
 .htotal = 640 + 16 + 30 + 114,
 .vdisplay = 480,
 .vsync_start = 480 + 10,
 .vsync_end = 480 + 10 + 3,
 .vtotal = 480 + 10 + 3 + 35,
 .flags = DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_PHSYNC,
};

static const struct panel_desc edt_etmv570g2dhu = {
 .modes = &edt_etmv570g2dhu_mode,
 .num_modes = 1,
 .bpc = 6,
 .size = {
  .width = 115,
  .height = 86,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE,
 .connector_type = DRM_MODE_CONNECTOR_DPI,
};

static const struct display_timing eink_vb3300_kca_timing = {
 .pixelclock = { 40000000, 40000000, 40000000 },
 .hactive = { 334, 334, 334 },
 .hfront_porch = { 1, 1, 1 },
 .hback_porch = { 1, 1, 1 },
 .hsync_len = { 1, 1, 1 },
 .vactive = { 1405, 1405, 1405 },
 .vfront_porch = { 1, 1, 1 },
 .vback_porch = { 1, 1, 1 },
 .vsync_len = { 1, 1, 1 },
 .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW |
   DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE,
};

static const struct panel_desc eink_vb3300_kca = {
 .timings = &eink_vb3300_kca_timing,
 .num_timings = 1,
 .bpc = 6,
 .size = {
  .width = 157,
  .height = 209,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,
 .connector_type = DRM_MODE_CONNECTOR_DPI,
};

static const struct display_timing evervision_vgg644804_timing = {
 .pixelclock = { 25175000, 25175000, 25175000 },
 .hactive = { 640, 640, 640 },
 .hfront_porch = { 16, 16, 16 },
 .hback_porch = { 82, 114, 170 },
 .hsync_len = { 5, 30, 30 },
 .vactive = { 480, 480, 480 },
 .vfront_porch = { 10, 10, 10 },
 .vback_porch = { 30, 32, 34 },
 .vsync_len = { 1, 3, 5 },
 .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW |
   DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE |
   DISPLAY_FLAGS_SYNC_POSEDGE,
};

static const struct panel_desc evervision_vgg644804 = {
 .timings = &evervision_vgg644804_timing,
 .num_timings = 1,
 .bpc = 6,
 .size = {
  .width = 115,
  .height = 86,
 },
 .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct display_timing evervision_vgg804821_timing = {
 .pixelclock = { 27600000, 33300000, 50000000 },
 .hactive = { 800, 800, 800 },
 .hfront_porch = { 40, 66, 70 },
 .hback_porch = { 40, 67, 70 },
 .hsync_len = { 40, 67, 70 },
 .vactive = { 480, 480, 480 },
 .vfront_porch = { 6, 10, 10 },
 .vback_porch = { 7, 11, 11 },
 .vsync_len = { 7, 11, 11 },
 .flags = DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH |
   DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_NEGEDGE |
   DISPLAY_FLAGS_SYNC_NEGEDGE,
};

static const struct panel_desc evervision_vgg804821 = {
 .timings = &evervision_vgg804821_timing,
 .num_timings = 1,
 .bpc = 8,
 .size = {
  .width = 108,
  .height = 64,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE,
};

static const struct drm_display_mode foxlink_fl500wvr00_a0t_mode = {
 .clock = 32260,
 .hdisplay = 800,
 .hsync_start = 800 + 168,
 .hsync_end = 800 + 168 + 64,
 .htotal = 800 + 168 + 64 + 88,
 .vdisplay = 480,
 .vsync_start = 480 + 37,
 .vsync_end = 480 + 37 + 2,
 .vtotal = 480 + 37 + 2 + 8,
};

static const struct panel_desc foxlink_fl500wvr00_a0t = {
 .modes = &foxlink_fl500wvr00_a0t_mode,
 .num_modes = 1,
 .bpc = 8,
 .size = {
  .width = 108,
  .height = 65,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
};

static const struct drm_display_mode frida_frd350h54004_modes[] = {
 { /* 60 Hz */
  .clock = 6000,
  .hdisplay = 320,
  .hsync_start = 320 + 44,
  .hsync_end = 320 + 44 + 16,
  .htotal = 320 + 44 + 16 + 20,
  .vdisplay = 240,
  .vsync_start = 240 + 2,
  .vsync_end = 240 + 2 + 6,
  .vtotal = 240 + 2 + 6 + 2,
  .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
 },
 { /* 50 Hz */
  .clock = 5400,
  .hdisplay = 320,
  .hsync_start = 320 + 56,
  .hsync_end = 320 + 56 + 16,
  .htotal = 320 + 56 + 16 + 40,
  .vdisplay = 240,
  .vsync_start = 240 + 2,
  .vsync_end = 240 + 2 + 6,
  .vtotal = 240 + 2 + 6 + 2,
  .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
 },
};

static const struct panel_desc frida_frd350h54004 = {
 .modes = frida_frd350h54004_modes,
 .num_modes = ARRAY_SIZE(frida_frd350h54004_modes),
 .bpc = 8,
 .size = {
  .width = 77,
  .height = 64,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE,
 .connector_type = DRM_MODE_CONNECTOR_DPI,
};

static const struct drm_display_mode friendlyarm_hd702e_mode = {
 .clock  = 67185,
 .hdisplay = 800,
 .hsync_start = 800 + 20,
 .hsync_end = 800 + 20 + 24,
 .htotal  = 800 + 20 + 24 + 20,
 .vdisplay = 1280,
 .vsync_start = 1280 + 4,
 .vsync_end = 1280 + 4 + 8,
 .vtotal  = 1280 + 4 + 8 + 4,
 .flags  = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
};

static const struct panel_desc friendlyarm_hd702e = {
 .modes = &friendlyarm_hd702e_mode,
 .num_modes = 1,
 .size = {
  .width = 94,
  .height = 151,
 },
};

static const struct drm_display_mode giantplus_gpg482739qs5_mode = {
 .clock = 9000,
 .hdisplay = 480,
 .hsync_start = 480 + 5,
 .hsync_end = 480 + 5 + 1,
 .htotal = 480 + 5 + 1 + 40,
 .vdisplay = 272,
 .vsync_start = 272 + 8,
 .vsync_end = 272 + 8 + 1,
 .vtotal = 272 + 8 + 1 + 8,
};

static const struct panel_desc giantplus_gpg482739qs5 = {
 .modes = &giantplus_gpg482739qs5_mode,
 .num_modes = 1,
 .bpc = 8,
 .size = {
  .width = 95,
  .height = 54,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
};

static const struct display_timing giantplus_gpm940b0_timing = {
 .pixelclock = { 13500000, 27000000, 27500000 },
 .hactive = { 320, 320, 320 },
 .hfront_porch = { 14, 686, 718 },
 .hback_porch = { 50, 70, 255 },
 .hsync_len = { 1, 1, 1 },
 .vactive = { 240, 240, 240 },
 .vfront_porch = { 1, 1, 179 },
 .vback_porch = { 1, 21, 31 },
 .vsync_len = { 1, 1, 6 },
 .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW,
};

static const struct panel_desc giantplus_gpm940b0 = {
 .timings = &giantplus_gpm940b0_timing,
 .num_timings = 1,
 .bpc = 8,
 .size = {
  .width = 60,
  .height = 45,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_3X8,
 .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE,
};

static const struct display_timing hannstar_hsd070pww1_timing = {
 .pixelclock = { 64300000, 71100000, 82000000 },
 .hactive = { 1280, 1280, 1280 },
 .hfront_porch = { 1, 1, 10 },
 .hback_porch = { 1, 1, 10 },
 /*
 * According to the data sheet, the minimum horizontal blanking interval
 * is 54 clocks (1 + 52 + 1), but tests with a Nitrogen6X have shown the
 * minimum working horizontal blanking interval to be 60 clocks.
 */

 .hsync_len = { 58, 158, 661 },
 .vactive = { 800, 800, 800 },
 .vfront_porch = { 1, 1, 10 },
 .vback_porch = { 1, 1, 10 },
 .vsync_len = { 1, 21, 203 },
 .flags = DISPLAY_FLAGS_DE_HIGH,
};

static const struct panel_desc hannstar_hsd070pww1 = {
 .timings = &hannstar_hsd070pww1_timing,
 .num_timings = 1,
 .bpc = 6,
 .size = {
  .width = 151,
  .height = 94,
 },
 .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct display_timing hannstar_hsd100pxn1_timing = {
 .pixelclock = { 55000000, 65000000, 75000000 },
 .hactive = { 1024, 1024, 1024 },
 .hfront_porch = { 40, 40, 40 },
 .hback_porch = { 220, 220, 220 },
 .hsync_len = { 20, 60, 100 },
 .vactive = { 768, 768, 768 },
 .vfront_porch = { 7, 7, 7 },
 .vback_porch = { 21, 21, 21 },
 .vsync_len = { 10, 10, 10 },
 .flags = DISPLAY_FLAGS_DE_HIGH,
};

static const struct panel_desc hannstar_hsd100pxn1 = {
 .timings = &hannstar_hsd100pxn1_timing,
 .num_timings = 1,
 .bpc = 6,
 .size = {
  .width = 203,
  .height = 152,
 },
 .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct display_timing hannstar_hsd101pww2_timing = {
 .pixelclock = { 64300000, 71100000, 82000000 },
 .hactive = { 1280, 1280, 1280 },
 .hfront_porch = { 1, 1, 10 },
 .hback_porch = { 1, 1, 10 },
 .hsync_len = { 58, 158, 661 },
 .vactive = { 800, 800, 800 },
 .vfront_porch = { 1, 1, 10 },
 .vback_porch = { 1, 1, 10 },
 .vsync_len = { 1, 21, 203 },
 .flags = DISPLAY_FLAGS_DE_HIGH,
};

static const struct panel_desc hannstar_hsd101pww2 = {
 .timings = &hannstar_hsd101pww2_timing,
 .num_timings = 1,
 .bpc = 8,
 .size = {
  .width = 217,
  .height = 136,
 },
 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
 .connector_type = DRM_MODE_CONNECTOR_LVDS,
};

static const struct drm_display_mode hitachi_tx23d38vm0caa_mode = {
 .clock = 33333,
 .hdisplay = 800,
 .hsync_start = 800 + 85,
 .hsync_end = 800 + 85 + 86,
 .htotal = 800 + 85 + 86 + 85,
 .vdisplay = 480,
 .vsync_start = 480 + 16,
 .vsync_end = 480 + 16 + 13,
 .vtotal = 480 + 16 + 13 + 16,
};

static const struct panel_desc hitachi_tx23d38vm0caa = {
 .modes = &hitachi_tx23d38vm0caa_mode,
 .num_modes = 1,
 .bpc = 6,
 .size = {
  .width = 195,
  .height = 117,
 },
 .delay = {
  .enable = 160,
  .disable = 160,
 },
};

static const struct drm_display_mode innolux_at043tn24_mode = {
 .clock = 9000,
 .hdisplay = 480,
 .hsync_start = 480 + 2,
 .hsync_end = 480 + 2 + 41,
 .htotal = 480 + 2 + 41 + 2,
 .vdisplay = 272,
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=98 H=97 G=97

¤ Dauer der Verarbeitung: 0.20 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.