drm-misc-next for $kernel-version:

UAPI Changes:
 
 Cross-subsystem Changes:
 
 Core Changes:
 
  * crtc: Remove unnessary include statements from drm_crtc.h, plus
    fallout in drivers
 
  * edid: More use of struct drm_edid; implement HF-EEODB extension
 
 Driver Changes:
 
  * bridge:
    * anx7625: Implement HDP timeout via callback; Cleanups
    * fsl-ldb: Drop DE flip; Modesetting fixes
    * imx: Depend on ARCH_MXC
    * sil8620: Fix off-by-one
    * ti-sn65dsi86: Convert to atomic modesetting
 
  * ingenic: Fix display at maximum resolution
 
  * panel:
    * simple: Add support for HannStar HSD101PWW2, plus DT bindings; Add
      support for ETML0700Y5DHA, plus DT bindings
 
  * rockchip: Fixes
 
  * vc4: Cleanups
 
  * vmwgfx: Cleanups
 -----BEGIN PGP SIGNATURE-----
 
 iQEyBAABCAAdFiEEchf7rIzpz2NEoWjlaA3BHVMLeiMFAmLGh3kACgkQaA3BHVML
 eiOingf3S+CwFdW3Gw3qvz7XtJiEOjEdakM8y+cmSwCRVjvdhdnpIvqfl2fy/DRb
 uDmkMvn94awr64JNs90X/e7sHDh09USgidR/zuIXxycCGYA1dJaqMjwptJDUgK5s
 C6mo8jv67cw6NRvgRFQsgZ6/nM1VhDE0fwZIOg2IHGISmFJWj9XCFcpRR6SNwDJt
 mD735MQt90HD7rFcCaQA4AkRLel2Imas4+6LZ+UcMfYiUVBX5dqAVdnyXzamVMf9
 KfEYLOAoOZOTqaW/y2qh/vGSX6v8bkTL3q6k0mqC8iCfLAxHHmIJwyPkcqHNYdcu
 9z9eZs9yy6Jh9qTpIez330wqthah
 =SP8k
 -----END PGP SIGNATURE-----

Merge tag 'drm-misc-next-2022-07-07' of git://anongit.freedesktop.org/drm/drm-misc into drm-next

drm-misc-next for $kernel-version:

UAPI Changes:

Cross-subsystem Changes:

Core Changes:

 * crtc: Remove unnessary include statements from drm_crtc.h, plus
   fallout in drivers

 * edid: More use of struct drm_edid; implement HF-EEODB extension

Driver Changes:

 * bridge:
   * anx7625: Implement HDP timeout via callback; Cleanups
   * fsl-ldb: Drop DE flip; Modesetting fixes
   * imx: Depend on ARCH_MXC
   * sil8620: Fix off-by-one
   * ti-sn65dsi86: Convert to atomic modesetting

 * ingenic: Fix display at maximum resolution

 * panel:
   * simple: Add support for HannStar HSD101PWW2, plus DT bindings; Add
     support for ETML0700Y5DHA, plus DT bindings

 * rockchip: Fixes

 * vc4: Cleanups

 * vmwgfx: Cleanups

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patchwork.freedesktop.org/patch/msgid/YsaHq1pvE699NtOM@linux-uq9g
This commit is contained in:
Dave Airlie 2022-07-12 13:27:47 +10:00
commit b45b4f880f
95 changed files with 644 additions and 300 deletions

View File

@ -141,6 +141,8 @@ properties:
# Emerging Display Technology Corp. WVGA TFT Display with capacitive touch
- edt,etm0700g0dh6
- edt,etm0700g0edh6
# Emerging Display Technology Corp. LVDS WSVGA TFT Display with capacitive touch
- edt,etml0700y5dha
# Emerging Display Technology Corp. 5.7" VGA TFT LCD panel with
# capacitive touch
- edt,etmv570g2dhu
@ -162,6 +164,8 @@ properties:
- hannstar,hsd070pww1
# HannStar Display Corp. HSD100PXN1 10.1" XGA LVDS panel
- hannstar,hsd100pxn1
# HannStar Display Corp. HSD101PWW2 10.1" WXGA (1280x800) LVDS panel
- hannstar,hsd101pww2
# Hitachi Ltd. Corporation 9" WVGA (800x480) TFT LCD panel
- hit,tx23d38vm0caa
# InfoVision Optoelectronics M133NWF4 R0 13.3" FHD (1920x1080) TFT LCD panel

View File

@ -30,7 +30,12 @@ allOf:
properties:
compatible:
const: sharp,lq101r1sx01
oneOf:
- items:
- const: sharp,lq101r1sx03
- const: sharp,lq101r1sx01
- items:
- const: sharp,lq101r1sx01
reg: true
power-supply: true

View File

@ -4,6 +4,8 @@
* Author: James.Qian.Wang <james.qian.wang@arm.com>
*
*/
#include <linux/of.h>
#include <drm/drm_print.h>
#include "komeda_dev.h"

View File

@ -6,6 +6,7 @@
*/
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/of.h>
#include <drm/drm_probe_helper.h>
#include "armada_crtc.h"
#include "armada_drm.h"

View File

@ -8,6 +8,7 @@
*/
#include <linux/clk.h>
#include <linux/media-bus-format.h>
#include <linux/mfd/atmel-hlcdc.h>
#include <linux/pinctrl/consumer.h>
#include <linux/pm.h>

View File

@ -9,6 +9,7 @@
*/
#include <linux/media-bus-format.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <drm/drm_bridge.h>

View File

@ -1443,23 +1443,24 @@ static int anx7625_read_hpd_status_p0(struct anx7625_data *ctx)
return anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS);
}
static void anx7625_hpd_polling(struct anx7625_data *ctx)
static int _anx7625_hpd_polling(struct anx7625_data *ctx,
unsigned long wait_us)
{
int ret, val;
struct device *dev = &ctx->client->dev;
/* Interrupt mode, no need poll HPD status, just return */
if (ctx->pdata.intp_irq)
return;
return 0;
ret = readx_poll_timeout(anx7625_read_hpd_status_p0,
ctx, val,
((val & HPD_STATUS) || (val < 0)),
5000,
5000 * 100);
wait_us / 100,
wait_us);
if (ret) {
DRM_DEV_ERROR(dev, "no hpd.\n");
return;
return ret;
}
DRM_DEV_DEBUG_DRIVER(dev, "system status: 0x%x. HPD raise up.\n", val);
@ -1472,6 +1473,23 @@ static void anx7625_hpd_polling(struct anx7625_data *ctx)
if (!ctx->pdata.panel_bridge && ctx->bridge_attached)
drm_helper_hpd_irq_event(ctx->bridge.dev);
return 0;
}
static int anx7625_wait_hpd_asserted(struct drm_dp_aux *aux,
unsigned long wait_us)
{
struct anx7625_data *ctx = container_of(aux, struct anx7625_data, aux);
struct device *dev = &ctx->client->dev;
int ret;
pm_runtime_get_sync(dev);
ret = _anx7625_hpd_polling(ctx, wait_us);
pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);
return ret;
}
static void anx7625_remove_edid(struct anx7625_data *ctx)
@ -1741,6 +1759,7 @@ static struct edid *anx7625_get_edid(struct anx7625_data *ctx)
}
pm_runtime_get_sync(dev);
_anx7625_hpd_polling(ctx, 5000 * 100);
edid_num = sp_tx_edid_read(ctx, p_edid->edid_raw_data);
pm_runtime_put_sync(dev);
@ -2378,6 +2397,7 @@ static void anx7625_bridge_atomic_enable(struct drm_bridge *bridge,
ctx->connector = connector;
pm_runtime_get_sync(dev);
_anx7625_hpd_polling(ctx, 5000 * 100);
anx7625_dp_start(ctx);
}
@ -2436,82 +2456,44 @@ static const struct drm_bridge_funcs anx7625_bridge_funcs = {
static int anx7625_register_i2c_dummy_clients(struct anx7625_data *ctx,
struct i2c_client *client)
{
int err = 0;
struct device *dev = &ctx->client->dev;
ctx->i2c.tx_p0_client = i2c_new_dummy_device(client->adapter,
TX_P0_ADDR >> 1);
ctx->i2c.tx_p0_client = devm_i2c_new_dummy_device(dev, client->adapter,
TX_P0_ADDR >> 1);
if (IS_ERR(ctx->i2c.tx_p0_client))
return PTR_ERR(ctx->i2c.tx_p0_client);
ctx->i2c.tx_p1_client = i2c_new_dummy_device(client->adapter,
TX_P1_ADDR >> 1);
if (IS_ERR(ctx->i2c.tx_p1_client)) {
err = PTR_ERR(ctx->i2c.tx_p1_client);
goto free_tx_p0;
}
ctx->i2c.tx_p1_client = devm_i2c_new_dummy_device(dev, client->adapter,
TX_P1_ADDR >> 1);
if (IS_ERR(ctx->i2c.tx_p1_client))
return PTR_ERR(ctx->i2c.tx_p1_client);
ctx->i2c.tx_p2_client = i2c_new_dummy_device(client->adapter,
TX_P2_ADDR >> 1);
if (IS_ERR(ctx->i2c.tx_p2_client)) {
err = PTR_ERR(ctx->i2c.tx_p2_client);
goto free_tx_p1;
}
ctx->i2c.tx_p2_client = devm_i2c_new_dummy_device(dev, client->adapter,
TX_P2_ADDR >> 1);
if (IS_ERR(ctx->i2c.tx_p2_client))
return PTR_ERR(ctx->i2c.tx_p2_client);
ctx->i2c.rx_p0_client = i2c_new_dummy_device(client->adapter,
RX_P0_ADDR >> 1);
if (IS_ERR(ctx->i2c.rx_p0_client)) {
err = PTR_ERR(ctx->i2c.rx_p0_client);
goto free_tx_p2;
}
ctx->i2c.rx_p0_client = devm_i2c_new_dummy_device(dev, client->adapter,
RX_P0_ADDR >> 1);
if (IS_ERR(ctx->i2c.rx_p0_client))
return PTR_ERR(ctx->i2c.rx_p0_client);
ctx->i2c.rx_p1_client = i2c_new_dummy_device(client->adapter,
RX_P1_ADDR >> 1);
if (IS_ERR(ctx->i2c.rx_p1_client)) {
err = PTR_ERR(ctx->i2c.rx_p1_client);
goto free_rx_p0;
}
ctx->i2c.rx_p1_client = devm_i2c_new_dummy_device(dev, client->adapter,
RX_P1_ADDR >> 1);
if (IS_ERR(ctx->i2c.rx_p1_client))
return PTR_ERR(ctx->i2c.rx_p1_client);
ctx->i2c.rx_p2_client = i2c_new_dummy_device(client->adapter,
RX_P2_ADDR >> 1);
if (IS_ERR(ctx->i2c.rx_p2_client)) {
err = PTR_ERR(ctx->i2c.rx_p2_client);
goto free_rx_p1;
}
ctx->i2c.rx_p2_client = devm_i2c_new_dummy_device(dev, client->adapter,
RX_P2_ADDR >> 1);
if (IS_ERR(ctx->i2c.rx_p2_client))
return PTR_ERR(ctx->i2c.rx_p2_client);
ctx->i2c.tcpc_client = i2c_new_dummy_device(client->adapter,
TCPC_INTERFACE_ADDR >> 1);
if (IS_ERR(ctx->i2c.tcpc_client)) {
err = PTR_ERR(ctx->i2c.tcpc_client);
goto free_rx_p2;
}
ctx->i2c.tcpc_client = devm_i2c_new_dummy_device(dev, client->adapter,
TCPC_INTERFACE_ADDR >> 1);
if (IS_ERR(ctx->i2c.tcpc_client))
return PTR_ERR(ctx->i2c.tcpc_client);
return 0;
free_rx_p2:
i2c_unregister_device(ctx->i2c.rx_p2_client);
free_rx_p1:
i2c_unregister_device(ctx->i2c.rx_p1_client);
free_rx_p0:
i2c_unregister_device(ctx->i2c.rx_p0_client);
free_tx_p2:
i2c_unregister_device(ctx->i2c.tx_p2_client);
free_tx_p1:
i2c_unregister_device(ctx->i2c.tx_p1_client);
free_tx_p0:
i2c_unregister_device(ctx->i2c.tx_p0_client);
return err;
}
static void anx7625_unregister_i2c_dummy_clients(struct anx7625_data *ctx)
{
i2c_unregister_device(ctx->i2c.tx_p0_client);
i2c_unregister_device(ctx->i2c.tx_p1_client);
i2c_unregister_device(ctx->i2c.tx_p2_client);
i2c_unregister_device(ctx->i2c.rx_p0_client);
i2c_unregister_device(ctx->i2c.rx_p1_client);
i2c_unregister_device(ctx->i2c.rx_p2_client);
i2c_unregister_device(ctx->i2c.tcpc_client);
}
static int __maybe_unused anx7625_runtime_pm_suspend(struct device *dev)
@ -2535,45 +2517,15 @@ static int __maybe_unused anx7625_runtime_pm_resume(struct device *dev)
mutex_lock(&ctx->lock);
anx7625_power_on_init(ctx);
anx7625_hpd_polling(ctx);
mutex_unlock(&ctx->lock);
return 0;
}
static int __maybe_unused anx7625_resume(struct device *dev)
{
struct anx7625_data *ctx = dev_get_drvdata(dev);
if (!ctx->pdata.intp_irq)
return 0;
if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) {
enable_irq(ctx->pdata.intp_irq);
anx7625_runtime_pm_resume(dev);
}
return 0;
}
static int __maybe_unused anx7625_suspend(struct device *dev)
{
struct anx7625_data *ctx = dev_get_drvdata(dev);
if (!ctx->pdata.intp_irq)
return 0;
if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) {
anx7625_runtime_pm_suspend(dev);
disable_irq(ctx->pdata.intp_irq);
}
return 0;
}
static const struct dev_pm_ops anx7625_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(anx7625_suspend, anx7625_resume)
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
pm_runtime_force_resume)
SET_RUNTIME_PM_OPS(anx7625_runtime_pm_suspend,
anx7625_runtime_pm_resume, NULL)
};
@ -2656,15 +2608,8 @@ static int anx7625_i2c_probe(struct i2c_client *client,
platform->aux.name = "anx7625-aux";
platform->aux.dev = dev;
platform->aux.transfer = anx7625_aux_transfer;
platform->aux.wait_hpd_asserted = anx7625_wait_hpd_asserted;
drm_dp_aux_init(&platform->aux);
devm_of_dp_aux_populate_ep_devices(&platform->aux);
ret = anx7625_parse_dt(dev, pdata);
if (ret) {
if (ret != -EPROBE_DEFER)
DRM_DEV_ERROR(dev, "fail to parse DT : %d\n", ret);
goto free_wq;
}
if (anx7625_register_i2c_dummy_clients(platform, client) != 0) {
ret = -ENOMEM;
@ -2680,9 +2625,19 @@ static int anx7625_i2c_probe(struct i2c_client *client,
if (ret)
goto free_wq;
devm_of_dp_aux_populate_ep_devices(&platform->aux);
ret = anx7625_parse_dt(dev, pdata);
if (ret) {
if (ret != -EPROBE_DEFER)
DRM_DEV_ERROR(dev, "fail to parse DT : %d\n", ret);
goto free_wq;
}
if (!platform->pdata.low_power_mode) {
anx7625_disable_pd_protocol(platform);
pm_runtime_get_sync(dev);
_anx7625_hpd_polling(platform, 5000 * 100);
}
/* Add work function */
@ -2723,8 +2678,6 @@ unregister_bridge:
if (!platform->pdata.low_power_mode)
pm_runtime_put_sync_suspend(&client->dev);
anx7625_unregister_i2c_dummy_clients(platform);
free_wq:
if (platform->workqueue)
destroy_workqueue(platform->workqueue);
@ -2754,8 +2707,6 @@ static int anx7625_i2c_remove(struct i2c_client *client)
if (!platform->pdata.low_power_mode)
pm_runtime_put_sync_suspend(&client->dev);
anx7625_unregister_i2c_dummy_clients(platform);
if (platform->pdata.audio_en)
anx7625_unregister_audio(platform);

View File

@ -26,6 +26,7 @@
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/irq.h>
#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>

View File

@ -14,6 +14,7 @@
#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/regmap.h>

View File

@ -6,6 +6,7 @@
*/
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/regmap.h>

View File

@ -6,6 +6,7 @@
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>

View File

@ -4,6 +4,7 @@
*/
#include <linux/clk.h>
#include <linux/media-bus-format.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
@ -74,22 +75,6 @@ static int fsl_ldb_attach(struct drm_bridge *bridge,
bridge, flags);
}
static int fsl_ldb_atomic_check(struct drm_bridge *bridge,
struct drm_bridge_state *bridge_state,
struct drm_crtc_state *crtc_state,
struct drm_connector_state *conn_state)
{
/* Invert DE signal polarity. */
bridge_state->input_bus_cfg.flags &= ~(DRM_BUS_FLAG_DE_LOW |
DRM_BUS_FLAG_DE_HIGH);
if (bridge_state->output_bus_cfg.flags & DRM_BUS_FLAG_DE_LOW)
bridge_state->input_bus_cfg.flags |= DRM_BUS_FLAG_DE_HIGH;
else if (bridge_state->output_bus_cfg.flags & DRM_BUS_FLAG_DE_HIGH)
bridge_state->input_bus_cfg.flags |= DRM_BUS_FLAG_DE_LOW;
return 0;
}
static void fsl_ldb_atomic_enable(struct drm_bridge *bridge,
struct drm_bridge_state *old_bridge_state)
{
@ -153,7 +138,7 @@ static void fsl_ldb_atomic_enable(struct drm_bridge *bridge,
reg = LDB_CTRL_CH0_ENABLE;
if (fsl_ldb->lvds_dual_link)
reg |= LDB_CTRL_CH1_ENABLE;
reg |= LDB_CTRL_CH1_ENABLE | LDB_CTRL_SPLIT_MODE;
if (lvds_format_24bpp) {
reg |= LDB_CTRL_CH0_DATA_WIDTH;
@ -233,7 +218,7 @@ fsl_ldb_mode_valid(struct drm_bridge *bridge,
{
struct fsl_ldb *fsl_ldb = to_fsl_ldb(bridge);
if (mode->clock > (fsl_ldb->lvds_dual_link ? 80000 : 160000))
if (mode->clock > (fsl_ldb->lvds_dual_link ? 160000 : 80000))
return MODE_CLOCK_HIGH;
return MODE_OK;
@ -241,7 +226,6 @@ fsl_ldb_mode_valid(struct drm_bridge *bridge,
static const struct drm_bridge_funcs funcs = {
.attach = fsl_ldb_attach,
.atomic_check = fsl_ldb_atomic_check,
.atomic_enable = fsl_ldb_atomic_enable,
.atomic_disable = fsl_ldb_atomic_disable,
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,

View File

@ -1,3 +1,5 @@
if ARCH_MXC || COMPILE_TEST
config DRM_IMX8QM_LDB
tristate "Freescale i.MX8QM LVDS display bridge"
depends on OF
@ -41,3 +43,5 @@ config DRM_IMX8QXP_PIXEL_LINK_TO_DPI
help
Choose this to enable pixel link to display pixel interface(PXL2DPI)
found in Freescale i.MX8qxp processor.
endif # ARCH_MXC || COMPILE_TEST

View File

@ -4,6 +4,7 @@
* Copyright 2019,2020,2022 NXP
*/
#include <linux/media-bus-format.h>
#include <linux/mfd/syscon.h>
#include <linux/of.h>
#include <linux/regmap.h>

View File

@ -5,6 +5,7 @@
*/
#include <linux/clk.h>
#include <linux/media-bus-format.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>

View File

@ -5,6 +5,7 @@
*/
#include <linux/clk.h>
#include <linux/media-bus-format.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>

View File

@ -7,6 +7,8 @@
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_graph.h>

View File

@ -5,6 +5,7 @@
*/
#include <linux/firmware/imx/svc/misc.h>
#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_graph.h>

View File

@ -5,6 +5,7 @@
*/
#include <linux/firmware/imx/svc/misc.h>
#include <linux/media-bus-format.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>

View File

@ -7,6 +7,7 @@
*
*/
#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/interrupt.h>

View File

@ -7,6 +7,7 @@
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/media-bus-format.h>
#include <linux/regmap.h>
#include <drm/drm_probe_helper.h>

View File

@ -14,6 +14,7 @@
#include <linux/clk.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_graph.h>

View File

@ -5,7 +5,9 @@
*/
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/of_graph.h>
#include <linux/platform_device.h>

View File

@ -6,6 +6,7 @@
#include <linux/firmware.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/mutex.h>

View File

@ -12,6 +12,7 @@
#include <linux/irq.h>
#include <linux/math64.h>
#include <linux/mfd/syscon.h>
#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/mux/consumer.h>
#include <linux/of.h>

View File

@ -15,6 +15,7 @@
#include <linux/gpio/consumer.h>
#include <linux/i2c-mux.h>
#include <linux/i2c.h>
#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>

View File

@ -605,7 +605,7 @@ static void *sii8620_burst_get_tx_buf(struct sii8620 *ctx, int len)
u8 *buf = &ctx->burst.tx_buf[ctx->burst.tx_count];
int size = len + 2;
if (ctx->burst.tx_count + size > ARRAY_SIZE(ctx->burst.tx_buf)) {
if (ctx->burst.tx_count + size >= ARRAY_SIZE(ctx->burst.tx_buf)) {
dev_err(ctx->dev, "TX-BLK buffer exhausted\n");
ctx->error = -EINVAL;
return NULL;
@ -622,7 +622,7 @@ static u8 *sii8620_burst_get_rx_buf(struct sii8620 *ctx, int len)
u8 *buf = &ctx->burst.rx_buf[ctx->burst.rx_count];
int size = len + 1;
if (ctx->burst.tx_count + size > ARRAY_SIZE(ctx->burst.tx_buf)) {
if (ctx->burst.rx_count + size >= ARRAY_SIZE(ctx->burst.rx_buf)) {
dev_err(ctx->dev, "RX-BLK buffer exhausted\n");
ctx->error = -EINVAL;
return NULL;

View File

@ -10,6 +10,7 @@
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/hdmi.h>
#include <linux/i2c.h>
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/mutex.h>

View File

@ -9,6 +9,7 @@
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of_graph.h>
#include <linux/regulator/consumer.h>

View File

@ -24,6 +24,7 @@
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/slab.h>

View File

@ -13,6 +13,7 @@
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>

View File

@ -16,6 +16,7 @@
#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/regmap.h>
#include <linux/regulator/consumer.h>

View File

@ -29,6 +29,7 @@
#include <linux/clk.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_graph.h>

View File

@ -752,7 +752,8 @@ ti_sn_bridge_mode_valid(struct drm_bridge *bridge,
return MODE_OK;
}
static void ti_sn_bridge_disable(struct drm_bridge *bridge)
static void ti_sn_bridge_atomic_disable(struct drm_bridge *bridge,
struct drm_bridge_state *old_bridge_state)
{
struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);
@ -1011,7 +1012,8 @@ exit:
return ret;
}
static void ti_sn_bridge_enable(struct drm_bridge *bridge)
static void ti_sn_bridge_atomic_enable(struct drm_bridge *bridge,
struct drm_bridge_state *old_bridge_state)
{
struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);
const char *last_err_str = "No supported DP rate";
@ -1080,7 +1082,8 @@ static void ti_sn_bridge_enable(struct drm_bridge *bridge)
VSTREAM_ENABLE);
}
static void ti_sn_bridge_pre_enable(struct drm_bridge *bridge)
static void ti_sn_bridge_atomic_pre_enable(struct drm_bridge *bridge,
struct drm_bridge_state *old_bridge_state)
{
struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);
@ -1093,7 +1096,8 @@ static void ti_sn_bridge_pre_enable(struct drm_bridge *bridge)
usleep_range(100, 110);
}
static void ti_sn_bridge_post_disable(struct drm_bridge *bridge)
static void ti_sn_bridge_atomic_post_disable(struct drm_bridge *bridge,
struct drm_bridge_state *old_bridge_state)
{
struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);
@ -1114,10 +1118,13 @@ static const struct drm_bridge_funcs ti_sn_bridge_funcs = {
.attach = ti_sn_bridge_attach,
.detach = ti_sn_bridge_detach,
.mode_valid = ti_sn_bridge_mode_valid,
.pre_enable = ti_sn_bridge_pre_enable,
.enable = ti_sn_bridge_enable,
.disable = ti_sn_bridge_disable,
.post_disable = ti_sn_bridge_post_disable,
.atomic_pre_enable = ti_sn_bridge_atomic_pre_enable,
.atomic_enable = ti_sn_bridge_atomic_enable,
.atomic_disable = ti_sn_bridge_atomic_disable,
.atomic_post_disable = ti_sn_bridge_atomic_post_disable,
.atomic_reset = drm_atomic_helper_bridge_reset,
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
};
static void ti_sn_bridge_parse_lanes(struct ti_sn65dsi86 *pdata,

View File

@ -6,6 +6,7 @@
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/of_graph.h>
#include <linux/platform_device.h>

View File

@ -20,6 +20,7 @@
* OF THIS SOFTWARE.
*/
#include <linux/backlight.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/i2c.h>

View File

@ -22,6 +22,7 @@
*/
#include <linux/err.h>
#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/mutex.h>

View File

@ -32,6 +32,7 @@
#include <drm/drm_privacy_screen_consumer.h>
#include <drm/drm_sysfs.h>
#include <linux/fb.h>
#include <linux/uaccess.h>
#include "drm_crtc_internal.h"
@ -2077,80 +2078,6 @@ int drm_connector_set_tile_property(struct drm_connector *connector)
}
EXPORT_SYMBOL(drm_connector_set_tile_property);
/**
* drm_connector_update_edid_property - update the edid property of a connector
* @connector: drm connector
* @edid: new value of the edid property
*
* This function creates a new blob modeset object and assigns its id to the
* connector's edid property.
* Since we also parse tile information from EDID's displayID block, we also
* set the connector's tile property here. See drm_connector_set_tile_property()
* for more details.
*
* Returns:
* Zero on success, negative errno on failure.
*/
int drm_connector_update_edid_property(struct drm_connector *connector,
const struct edid *edid)
{
struct drm_device *dev = connector->dev;
size_t size = 0;
int ret;
const struct edid *old_edid;
/* ignore requests to set edid when overridden */
if (connector->override_edid)
return 0;
if (edid)
size = EDID_LENGTH * (1 + edid->extensions);
/* Set the display info, using edid if available, otherwise
* resetting the values to defaults. This duplicates the work
* done in drm_add_edid_modes, but that function is not
* consistently called before this one in all drivers and the
* computation is cheap enough that it seems better to
* duplicate it rather than attempt to ensure some arbitrary
* ordering of calls.
*/
if (edid)
drm_add_display_info(connector, edid);
else
drm_reset_display_info(connector);
drm_update_tile_info(connector, edid);
if (connector->edid_blob_ptr) {
old_edid = (const struct edid *)connector->edid_blob_ptr->data;
if (old_edid) {
if (!drm_edid_are_equal(edid, old_edid)) {
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Edid was changed.\n",
connector->base.id, connector->name);
connector->epoch_counter += 1;
DRM_DEBUG_KMS("Updating change counter to %llu\n",
connector->epoch_counter);
}
}
}
drm_object_property_set_value(&connector->base,
dev->mode_config.non_desktop_property,
connector->display_info.non_desktop);
ret = drm_property_replace_global_blob(dev,
&connector->edid_blob_ptr,
size,
edid,
&connector->base,
dev->mode_config.edid_property);
if (ret)
return ret;
return drm_connector_set_tile_property(connector);
}
EXPORT_SYMBOL(drm_connector_update_edid_property);
/**
* drm_connector_set_link_status_property - Set link status property of a connector
* @connector: drm connector

View File

@ -286,6 +286,5 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
/* drm_edid.c */
void drm_mode_fixup_1366x768(struct drm_display_mode *mode);
void drm_reset_display_info(struct drm_connector *connector);
u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edid);
void drm_update_tile_info(struct drm_connector *connector, const struct edid *edid);
int drm_edid_override_set(struct drm_connector *connector, const void *edid, size_t size);
int drm_edid_override_reset(struct drm_connector *connector);

View File

@ -350,31 +350,20 @@ static ssize_t edid_write(struct file *file, const char __user *ubuf,
struct seq_file *m = file->private_data;
struct drm_connector *connector = m->private;
char *buf;
struct edid *edid;
int ret;
buf = memdup_user(ubuf, len);
if (IS_ERR(buf))
return PTR_ERR(buf);
edid = (struct edid *) buf;
if (len == 5 && !strncmp(buf, "reset", 5)) {
connector->override_edid = false;
ret = drm_connector_update_edid_property(connector, NULL);
} else if (len < EDID_LENGTH ||
EDID_LENGTH * (1 + edid->extensions) > len)
ret = -EINVAL;
else {
connector->override_edid = false;
ret = drm_connector_update_edid_property(connector, edid);
if (!ret)
connector->override_edid = true;
}
if (len == 5 && !strncmp(buf, "reset", 5))
ret = drm_edid_override_reset(connector);
else
ret = drm_edid_override_set(connector, buf, len);
kfree(buf);
return (ret) ? ret : len;
return ret ? ret : len;
}
/*

View File

@ -1581,6 +1581,15 @@ static bool version_greater(const struct drm_edid *drm_edid,
(edid->version == version && edid->revision > revision);
}
static int edid_hfeeodb_extension_block_count(const struct edid *edid);
static int edid_hfeeodb_block_count(const struct edid *edid)
{
int eeodb = edid_hfeeodb_extension_block_count(edid);
return eeodb ? eeodb + 1 : 0;
}
static int edid_extension_block_count(const struct edid *edid)
{
return edid->extensions;
@ -1620,6 +1629,19 @@ static int drm_edid_block_count(const struct drm_edid *drm_edid)
/* Starting point */
num_blocks = edid_block_count(drm_edid->edid);
/* HF-EEODB override */
if (drm_edid->size >= edid_size_by_blocks(2)) {
int eeodb;
/*
* Note: HF-EEODB may specify a smaller extension count than the
* regular one. Unlike in buffer allocation, here we can use it.
*/
eeodb = edid_hfeeodb_block_count(drm_edid->edid);
if (eeodb)
num_blocks = eeodb;
}
/* Limit by allocated size */
num_blocks = min(num_blocks, (int)drm_edid->size / EDID_LENGTH);
@ -2020,33 +2042,42 @@ bool drm_edid_is_valid(struct edid *edid)
}
EXPORT_SYMBOL(drm_edid_is_valid);
static struct edid *edid_filter_invalid_blocks(const struct edid *edid,
int invalid_blocks,
static struct edid *edid_filter_invalid_blocks(struct edid *edid,
size_t *alloc_size)
{
struct edid *new, *dest_block;
int valid_extensions = edid->extensions - invalid_blocks;
int i;
struct edid *new;
int i, valid_blocks = 0;
*alloc_size = edid_size_by_blocks(valid_extensions + 1);
new = kmalloc(*alloc_size, GFP_KERNEL);
if (!new)
goto out;
dest_block = new;
/*
* Note: If the EDID uses HF-EEODB, but has invalid blocks, we'll revert
* back to regular extension count here. We don't want to start
* modifying the HF-EEODB extension too.
*/
for (i = 0; i < edid_block_count(edid); i++) {
const void *block = edid_block_data(edid, i);
const void *src_block = edid_block_data(edid, i);
if (edid_block_valid(block, i == 0))
memcpy(dest_block++, block, EDID_LENGTH);
if (edid_block_valid(src_block, i == 0)) {
void *dst_block = (void *)edid_block_data(edid, valid_blocks);
memmove(dst_block, src_block, EDID_LENGTH);
valid_blocks++;
}
}
new->extensions = valid_extensions;
new->checksum = edid_block_compute_checksum(new);
/* We already trusted the base block to be valid here... */
if (WARN_ON(!valid_blocks)) {
kfree(edid);
return NULL;
}
out:
kfree(edid);
edid->extensions = valid_blocks - 1;
edid->checksum = edid_block_compute_checksum(edid);
*alloc_size = edid_size_by_blocks(valid_blocks);
new = krealloc(edid, *alloc_size, GFP_KERNEL);
if (!new)
kfree(edid);
return new;
}
@ -2161,6 +2192,32 @@ static struct edid *drm_get_override_edid(struct drm_connector *connector,
return IS_ERR(override) ? NULL : override;
}
/* For debugfs edid_override implementation */
int drm_edid_override_set(struct drm_connector *connector, const void *edid,
size_t size)
{
int ret;
if (size < EDID_LENGTH || edid_size(edid) > size)
return -EINVAL;
connector->override_edid = false;
ret = drm_connector_update_edid_property(connector, edid);
if (!ret)
connector->override_edid = true;
return ret;
}
/* For debugfs edid_override implementation */
int drm_edid_override_reset(struct drm_connector *connector)
{
connector->override_edid = false;
return drm_connector_update_edid_property(connector, NULL);
}
/**
* drm_add_override_edid_modes - add modes from override/firmware EDID
* @connector: connector we're probing
@ -2231,7 +2288,7 @@ static struct edid *_drm_do_get_edid(struct drm_connector *connector,
size_t *size)
{
enum edid_block_status status;
int i, invalid_blocks = 0;
int i, num_blocks, invalid_blocks = 0;
struct edid *edid, *new;
size_t alloc_size = EDID_LENGTH;
@ -2273,7 +2330,8 @@ static struct edid *_drm_do_get_edid(struct drm_connector *connector,
goto fail;
edid = new;
for (i = 1; i < edid_block_count(edid); i++) {
num_blocks = edid_block_count(edid);
for (i = 1; i < num_blocks; i++) {
void *block = (void *)edid_block_data(edid, i);
status = edid_block_read(block, i, read_block, context);
@ -2284,14 +2342,33 @@ static struct edid *_drm_do_get_edid(struct drm_connector *connector,
if (status == EDID_BLOCK_READ_FAIL)
goto fail;
invalid_blocks++;
} else if (i == 1) {
/*
* If the first EDID extension is a CTA extension, and
* the first Data Block is HF-EEODB, override the
* extension block count.
*
* Note: HF-EEODB could specify a smaller extension
* count too, but we can't risk allocating a smaller
* amount.
*/
int eeodb = edid_hfeeodb_block_count(edid);
if (eeodb > num_blocks) {
num_blocks = eeodb;
alloc_size = edid_size_by_blocks(num_blocks);
new = krealloc(edid, alloc_size, GFP_KERNEL);
if (!new)
goto fail;
edid = new;
}
}
}
if (invalid_blocks) {
connector_bad_edid(connector, edid, edid_block_count(edid));
connector_bad_edid(connector, edid, num_blocks);
edid = edid_filter_invalid_blocks(edid, invalid_blocks,
&alloc_size);
edid = edid_filter_invalid_blocks(edid, &alloc_size);
}
ok:
@ -2333,6 +2410,32 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
}
EXPORT_SYMBOL_GPL(drm_do_get_edid);
/**
* drm_edid_raw - Get a pointer to the raw EDID data.
* @drm_edid: drm_edid container
*
* Get a pointer to the raw EDID data.
*
* This is for transition only. Avoid using this like the plague.
*
* Return: Pointer to raw EDID data.
*/
const struct edid *drm_edid_raw(const struct drm_edid *drm_edid)
{
if (!drm_edid || !drm_edid->size)
return NULL;
/*
* Do not return pointers where relying on EDID extension count would
* lead to buffer overflow.
*/
if (WARN_ON(edid_size(drm_edid->edid) > drm_edid->size))
return NULL;
return drm_edid->edid;
}
EXPORT_SYMBOL(drm_edid_raw);
/* Allocate struct drm_edid container *without* duplicating the edid data */
static const struct drm_edid *_drm_edid_alloc(const void *edid, size_t size)
{
@ -3796,6 +3899,7 @@ static int add_detailed_modes(struct drm_connector *connector,
#define CTA_EXT_DB_HDR_STATIC_METADATA 6
#define CTA_EXT_DB_420_VIDEO_DATA 14
#define CTA_EXT_DB_420_VIDEO_CAP_MAP 15
#define CTA_EXT_DB_HF_EEODB 0x78
#define CTA_EXT_DB_HF_SCDB 0x79
#define EDID_BASIC_AUDIO (1 << 6)
@ -4855,6 +4959,12 @@ static bool cea_db_is_hdmi_forum_vsdb(const struct cea_db *db)
cea_db_payload_len(db) >= 7;
}
static bool cea_db_is_hdmi_forum_eeodb(const void *db)
{
return cea_db_is_extended_tag(db, CTA_EXT_DB_HF_EEODB) &&
cea_db_payload_len(db) >= 2;
}
static bool cea_db_is_microsoft_vsdb(const struct cea_db *db)
{
return cea_db_is_vendor(db, MICROSOFT_IEEE_OUI) &&
@ -4889,6 +4999,47 @@ static bool cea_db_is_hdmi_hdr_metadata_block(const struct cea_db *db)
cea_db_payload_len(db) >= 3;
}
/*
* Get the HF-EEODB override extension block count from EDID.
*
* The passed in EDID may be partially read, as long as it has at least two
* blocks (base block and one extension block) if EDID extension count is > 0.
*
* Note that this is *not* how you should parse CTA Data Blocks in general; this
* is only to handle partially read EDIDs. Normally, use the CTA Data Block
* iterators instead.
*
* References:
* - HDMI 2.1 section 10.3.6 HDMI Forum EDID Extension Override Data Block
*/
static int edid_hfeeodb_extension_block_count(const struct edid *edid)
{
const u8 *cta;
/* No extensions according to base block, no HF-EEODB. */
if (!edid_extension_block_count(edid))
return 0;
/* HF-EEODB is always in the first EDID extension block only */
cta = edid_extension_block_data(edid, 0);
if (edid_block_tag(cta) != CEA_EXT || cea_revision(cta) < 3)
return 0;
/* Need to have the data block collection, and at least 3 bytes. */
if (cea_db_collection_size(cta) < 3)
return 0;
/*
* Sinks that include the HF-EEODB in their E-EDID shall include one and
* only one instance of the HF-EEODB in the E-EDID, occupying bytes 4
* through 6 of Block 1 of the E-EDID.
*/
if (!cea_db_is_hdmi_forum_eeodb(&cta[4]))
return 0;
return cta[4 + 2];
}
static void drm_parse_y420cmdb_bitmap(struct drm_connector *connector,
const u8 *db)
{
@ -5928,8 +6079,7 @@ static void drm_update_mso(struct drm_connector *connector,
/* A connector has no EDID information, so we've got no EDID to compute quirks from. Reset
* all of the values which would have been set from EDID
*/
void
drm_reset_display_info(struct drm_connector *connector)
static void drm_reset_display_info(struct drm_connector *connector)
{
struct drm_display_info *info = &connector->display_info;
@ -6043,14 +6193,6 @@ out:
return quirks;
}
u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edid)
{
struct drm_edid drm_edid;
return update_display_info(connector,
drm_edid_legacy_init(&drm_edid, edid));
}
static struct drm_display_mode *drm_mode_displayid_detailed(struct drm_device *dev,
struct displayid_detailed_timings_1 *timings,
bool type_7)
@ -6143,8 +6285,8 @@ static int add_displayid_detailed_modes(struct drm_connector *connector,
return num_modes;
}
static int drm_edid_connector_update(struct drm_connector *connector,
const struct drm_edid *drm_edid)
static int _drm_edid_connector_update(struct drm_connector *connector,
const struct drm_edid *drm_edid)
{
int num_modes = 0;
u32 quirks;
@ -6207,6 +6349,156 @@ static int drm_edid_connector_update(struct drm_connector *connector,
return num_modes;
}
static void _drm_update_tile_info(struct drm_connector *connector,
const struct drm_edid *drm_edid);
static int _drm_edid_connector_property_update(struct drm_connector *connector,
const struct drm_edid *drm_edid)
{
struct drm_device *dev = connector->dev;
int ret;
if (connector->edid_blob_ptr) {
const struct edid *old_edid = connector->edid_blob_ptr->data;
if (old_edid) {
if (!drm_edid_are_equal(drm_edid ? drm_edid->edid : NULL, old_edid)) {
connector->epoch_counter++;
drm_dbg_kms(dev, "[CONNECTOR:%d:%s] EDID changed, epoch counter %llu\n",
connector->base.id, connector->name,
connector->epoch_counter);
}
}
}
ret = drm_property_replace_global_blob(dev,
&connector->edid_blob_ptr,
drm_edid ? drm_edid->size : 0,
drm_edid ? drm_edid->edid : NULL,
&connector->base,
dev->mode_config.edid_property);
if (ret) {
drm_dbg_kms(dev, "[CONNECTOR:%d:%s] EDID property update failed (%d)\n",
connector->base.id, connector->name, ret);
goto out;
}
ret = drm_object_property_set_value(&connector->base,
dev->mode_config.non_desktop_property,
connector->display_info.non_desktop);
if (ret) {
drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Non-desktop property update failed (%d)\n",
connector->base.id, connector->name, ret);
goto out;
}
ret = drm_connector_set_tile_property(connector);
if (ret) {
drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Tile property update failed (%d)\n",
connector->base.id, connector->name, ret);
goto out;
}
out:
return ret;
}
/**
* drm_edid_connector_update - Update connector information from EDID
* @connector: Connector
* @drm_edid: EDID
*
* Update the connector mode list, display info, ELD, HDR metadata, relevant
* properties, etc. from the passed in EDID.
*
* If EDID is NULL, reset the information.
*
* Return: The number of modes added or 0 if we couldn't find any.
*/
int drm_edid_connector_update(struct drm_connector *connector,
const struct drm_edid *drm_edid)
{
int count;
/*
* FIXME: Reconcile the differences in override_edid handling between
* this and drm_connector_update_edid_property().
*
* If override_edid is set, and the EDID passed in here originates from
* drm_edid_read() and friends, it will be the override EDID, and there
* are no issues. drm_connector_update_edid_property() ignoring requests
* to set the EDID dates back to a time when override EDID was not
* handled at the low level EDID read.
*
* The only way the EDID passed in here can be different from the
* override EDID is when a driver passes in an EDID that does *not*
* originate from drm_edid_read() and friends, or passes in a stale
* cached version. This, in turn, is a question of when an override EDID
* set via debugfs should take effect.
*/
count = _drm_edid_connector_update(connector, drm_edid);
_drm_update_tile_info(connector, drm_edid);
/* Note: Ignore errors for now. */
_drm_edid_connector_property_update(connector, drm_edid);
return count;
}
EXPORT_SYMBOL(drm_edid_connector_update);
static int _drm_connector_update_edid_property(struct drm_connector *connector,
const struct drm_edid *drm_edid)
{
/* ignore requests to set edid when overridden */
if (connector->override_edid)
return 0;
/*
* Set the display info, using edid if available, otherwise resetting
* the values to defaults. This duplicates the work done in
* drm_add_edid_modes, but that function is not consistently called
* before this one in all drivers and the computation is cheap enough
* that it seems better to duplicate it rather than attempt to ensure
* some arbitrary ordering of calls.
*/
if (drm_edid)
update_display_info(connector, drm_edid);
else
drm_reset_display_info(connector);
_drm_update_tile_info(connector, drm_edid);
return _drm_edid_connector_property_update(connector, drm_edid);
}
/**
* drm_connector_update_edid_property - update the edid property of a connector
* @connector: drm connector
* @edid: new value of the edid property
*
* This function creates a new blob modeset object and assigns its id to the
* connector's edid property.
* Since we also parse tile information from EDID's displayID block, we also
* set the connector's tile property here. See drm_connector_set_tile_property()
* for more details.
*
* This function is deprecated. Use drm_edid_connector_update() instead.
*
* Returns:
* Zero on success, negative errno on failure.
*/
int drm_connector_update_edid_property(struct drm_connector *connector,
const struct edid *edid)
{
struct drm_edid drm_edid;
return _drm_connector_update_edid_property(connector,
drm_edid_legacy_init(&drm_edid, edid));
}
EXPORT_SYMBOL(drm_connector_update_edid_property);
/**
* drm_add_edid_modes - add modes from EDID data, if available
* @connector: connector we're probing
@ -6216,6 +6508,8 @@ static int drm_edid_connector_update(struct drm_connector *connector,
* &drm_display_info structure and ELD in @connector with any information which
* can be derived from the edid.
*
* This function is deprecated. Use drm_edid_connector_update() instead.
*
* Return: The number of modes added or 0 if we couldn't find any.
*/
int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
@ -6228,8 +6522,8 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
edid = NULL;
}
return drm_edid_connector_update(connector,
drm_edid_legacy_init(&drm_edid, edid));
return _drm_edid_connector_update(connector,
drm_edid_legacy_init(&drm_edid, edid));
}
EXPORT_SYMBOL(drm_add_edid_modes);
@ -6644,11 +6938,3 @@ static void _drm_update_tile_info(struct drm_connector *connector,
connector->tile_group = NULL;
}
}
void drm_update_tile_info(struct drm_connector *connector,
const struct edid *edid)
{
struct drm_edid drm_edid;
_drm_update_tile_info(connector, drm_edid_legacy_init(&drm_edid, edid));
}

View File

@ -5,6 +5,7 @@
* Copyright 2016 Noralf Trønnes
*/
#include <linux/backlight.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>

View File

@ -34,6 +34,7 @@
#include <linux/list.h>
#include <linux/list_sort.h>
#include <linux/export.h>
#include <linux/fb.h>
#include <video/of_display_timing.h>
#include <video/of_videomode.h>

View File

@ -2,6 +2,8 @@
#include <linux/component.h>
#include <linux/export.h>
#include <linux/list.h>
#include <linux/media-bus-format.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <drm/drm_bridge.h>

View File

@ -1049,3 +1049,37 @@ int drm_connector_helper_get_modes_from_ddc(struct drm_connector *connector)
return count;
}
EXPORT_SYMBOL(drm_connector_helper_get_modes_from_ddc);
/**
* drm_connector_helper_get_modes - Read EDID and update connector.
* @connector: The connector
*
* Read the EDID using drm_edid_read() (which requires that connector->ddc is
* set), and update the connector using the EDID.
*
* This can be used as the "default" connector helper .get_modes() hook if the
* driver does not need any special processing. This is sets the example what
* custom .get_modes() hooks should do regarding EDID read and connector update.
*
* Returns: Number of modes.
*/
int drm_connector_helper_get_modes(struct drm_connector *connector)
{
const struct drm_edid *drm_edid;
int count;
drm_edid = drm_edid_read(connector);
/*
* Unconditionally update the connector. If the EDID was read
* successfully, fill in the connector information derived from the
* EDID. Otherwise, if the EDID is NULL, clear the connector
* information.
*/
count = drm_edid_connector_update(connector, drm_edid);
drm_edid_free(drm_edid);
return count;
}
EXPORT_SYMBOL(drm_connector_helper_get_modes);

View File

@ -10,6 +10,7 @@
#include <linux/component.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>

View File

@ -7,6 +7,7 @@
* Contacts: Andrzej Hajda <a.hajda@samsung.com>
*/
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/regulator/consumer.h>

View File

@ -14,6 +14,7 @@
#include <linux/clk.h>
#include <linux/component.h>
#include <linux/delay.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>

View File

@ -7,6 +7,7 @@
#include <linux/component.h>
#include <linux/gpio/consumer.h>
#include <linux/hdmi.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/platform_data/tda9950.h>
#include <linux/irq.h>

View File

@ -3,6 +3,7 @@
* Copyright © 2021 Intel Corporation
*/
#include <linux/backlight.h>
#include <linux/kernel.h>
#include <linux/pwm.h>
#include <linux/string_helpers.h>

View File

@ -5,6 +5,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <drm/drm_module.h>
#include <drm/drm_of.h>

View File

@ -7,6 +7,7 @@
#include <linux/clk.h>
#include <linux/component.h>
#include <linux/media-bus-format.h>
#include <linux/mfd/syscon.h>
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
#include <linux/module.h>

View File

@ -6,6 +6,7 @@
*/
#include <linux/component.h>
#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/videodev2.h>

View File

@ -11,6 +11,7 @@
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of_device.h>
@ -70,6 +71,7 @@ struct jz_soc_info {
bool map_noncoherent;
bool use_extended_hwdesc;
bool plane_f0_not_working;
u32 max_burst;
unsigned int max_width, max_height;
const u32 *formats_f0, *formats_f1;
unsigned int num_formats_f0, num_formats_f1;
@ -319,8 +321,9 @@ static void ingenic_drm_crtc_update_timings(struct ingenic_drm *priv,
regmap_write(priv->map, JZ_REG_LCD_REV, mode->htotal << 16);
}
regmap_set_bits(priv->map, JZ_REG_LCD_CTRL,
JZ_LCD_CTRL_OFUP | JZ_LCD_CTRL_BURST_16);
regmap_update_bits(priv->map, JZ_REG_LCD_CTRL,
JZ_LCD_CTRL_OFUP | JZ_LCD_CTRL_BURST_MASK,
JZ_LCD_CTRL_OFUP | priv->soc_info->max_burst);
/*
* IPU restart - specify how much time the LCDC will wait before
@ -1519,6 +1522,7 @@ static const struct jz_soc_info jz4740_soc_info = {
.map_noncoherent = false,
.max_width = 800,
.max_height = 600,
.max_burst = JZ_LCD_CTRL_BURST_16,
.formats_f1 = jz4740_formats,
.num_formats_f1 = ARRAY_SIZE(jz4740_formats),
/* JZ4740 has only one plane */
@ -1530,6 +1534,7 @@ static const struct jz_soc_info jz4725b_soc_info = {
.map_noncoherent = false,
.max_width = 800,
.max_height = 600,
.max_burst = JZ_LCD_CTRL_BURST_16,
.formats_f1 = jz4725b_formats_f1,
.num_formats_f1 = ARRAY_SIZE(jz4725b_formats_f1),
.formats_f0 = jz4725b_formats_f0,
@ -1542,6 +1547,7 @@ static const struct jz_soc_info jz4770_soc_info = {
.map_noncoherent = true,
.max_width = 1280,
.max_height = 720,
.max_burst = JZ_LCD_CTRL_BURST_64,
.formats_f1 = jz4770_formats_f1,
.num_formats_f1 = ARRAY_SIZE(jz4770_formats_f1),
.formats_f0 = jz4770_formats_f0,
@ -1556,6 +1562,7 @@ static const struct jz_soc_info jz4780_soc_info = {
.plane_f0_not_working = true, /* REVISIT */
.max_width = 4096,
.max_height = 2048,
.max_burst = JZ_LCD_CTRL_BURST_64,
.formats_f1 = jz4770_formats_f1,
.num_formats_f1 = ARRAY_SIZE(jz4770_formats_f1),
.formats_f0 = jz4770_formats_f0,

View File

@ -106,6 +106,9 @@
#define JZ_LCD_CTRL_BURST_4 (0x0 << 28)
#define JZ_LCD_CTRL_BURST_8 (0x1 << 28)
#define JZ_LCD_CTRL_BURST_16 (0x2 << 28)
#define JZ_LCD_CTRL_BURST_32 (0x3 << 28)
#define JZ_LCD_CTRL_BURST_64 (0x4 << 28)
#define JZ_LCD_CTRL_BURST_MASK (0x7 << 28)
#define JZ_LCD_CTRL_RGB555 BIT(27)
#define JZ_LCD_CTRL_OFUP BIT(26)
#define JZ_LCD_CTRL_FRC_GRAYSCALE_16 (0x0 << 24)

View File

@ -5,6 +5,7 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/mfd/syscon.h>
#include <linux/platform_device.h>

View File

@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/regulator/consumer.h>
#include "mcde_drm.h"

View File

@ -8,6 +8,7 @@
#include <linux/component.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/media-bus-format.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>

View File

@ -8,6 +8,7 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/media-bus-format.h>
#include <linux/pm_runtime.h>
#include <linux/spinlock.h>

View File

@ -11,6 +11,7 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/media-bus-format.h>
#include <linux/pm_runtime.h>
#include <linux/spinlock.h>

View File

@ -17,6 +17,7 @@
#include <linux/list.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h> /* platform_device() */
#include <linux/sched.h>
#include <linux/seq_file.h>

View File

@ -45,6 +45,7 @@
#include <linux/err.h>
#include <linux/fb.h>
#include <linux/i2c.h>
#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>

View File

@ -8,6 +8,7 @@
#include <linux/backlight.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/regulator/consumer.h>

View File

@ -7,6 +7,7 @@
*/
#include <linux/delay.h>
#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>

View File

@ -23,6 +23,8 @@
#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_platform.h>
#include <linux/platform_device.h>
@ -1753,6 +1755,32 @@ static const struct panel_desc edt_etm0700g0bdh6 = {
.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 drm_display_mode edt_etmv570g2dhu_mode = {
.clock = 25175,
.hdisplay = 640,
@ -2021,6 +2049,31 @@ static const struct panel_desc hannstar_hsd100pxn1 = {
.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,
@ -3942,6 +3995,9 @@ static const struct of_device_id platform_of_match[] = {
}, {
.compatible = "edt,etm0700g0edh6",
.data = &edt_etm0700g0bdh6,
}, {
.compatible = "edt,etml0700y5dha",
.data = &edt_etml0700y5dha,
}, {
.compatible = "edt,etmv570g2dhu",
.data = &edt_etmv570g2dhu,
@ -3972,6 +4028,9 @@ static const struct of_device_id platform_of_match[] = {
}, {
.compatible = "hannstar,hsd100pxn1",
.data = &hannstar_hsd100pxn1,
}, {
.compatible = "hannstar,hsd101pww2",
.data = &hannstar_hsd101pww2,
}, {
.compatible = "hit,tx23d38vm0caa",
.data = &hitachi_tx23d38vm0caa

View File

@ -12,6 +12,7 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/dma-buf.h>
#include <linux/media-bus-format.h>
#include <linux/of_graph.h>
#include <drm/drm_fb_cma_helper.h>

View File

@ -8,6 +8,7 @@
*/
#include <linux/export.h>
#include <linux/of.h>
#include <linux/slab.h>
#include <drm/drm_bridge.h>

View File

@ -10,6 +10,7 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>

View File

@ -408,7 +408,15 @@ static int rockchip_dp_probe(struct platform_device *pdev)
if (IS_ERR(dp->adp))
return PTR_ERR(dp->adp);
return component_add(dev, &rockchip_dp_component_ops);
ret = component_add(dev, &rockchip_dp_component_ops);
if (ret)
goto err_dp_remove;
return 0;
err_dp_remove:
analogix_dp_remove(dp->adp);
return ret;
}
static int rockchip_dp_remove(struct platform_device *pdev)

View File

@ -1572,6 +1572,9 @@ static struct drm_crtc_state *vop_crtc_duplicate_state(struct drm_crtc *crtc)
{
struct rockchip_crtc_state *rockchip_state;
if (WARN_ON(!crtc->state))
return NULL;
rockchip_state = kzalloc(sizeof(*rockchip_state), GFP_KERNEL);
if (!rockchip_state)
return NULL;

View File

@ -9,6 +9,7 @@
#include <linux/delay.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/media-bus-format.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>

View File

@ -6,6 +6,7 @@
*/
#include <linux/component.h>
#include <linux/media-bus-format.h>
#include <linux/of_graph.h>
#include <drm/display/drm_dp_helper.h>

View File

@ -9,6 +9,7 @@
#include <linux/component.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/reset.h>

View File

@ -7,6 +7,7 @@
*/
#include <linux/dma-mapping.h>
#include <linux/of.h>
#include <linux/seq_file.h>
#include <drm/drm_atomic.h>

View File

@ -7,6 +7,7 @@
#include <linux/clk.h>
#include <linux/component.h>
#include <linux/io.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/seq_file.h>

View File

@ -8,6 +8,7 @@
#include <linux/component.h>
#include <linux/debugfs.h>
#include <linux/hdmi.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/platform_device.h>

View File

@ -10,6 +10,7 @@
#include <linux/firmware.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/reset.h>
#include <linux/seq_file.h>

View File

@ -12,6 +12,7 @@
#include <linux/component.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_graph.h>

View File

@ -7,6 +7,7 @@
#include <linux/clk.h>
#include <linux/component.h>
#include <linux/i2c.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/of_device.h>

View File

@ -8,6 +8,7 @@
#include <linux/component.h>
#include <linux/ioport.h>
#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_device.h>

View File

@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/mod_devicetable.h>
#include <linux/reset.h>
#define SUN4I_TCON_GCTL_REG 0x0

View File

@ -11,6 +11,7 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/mfd/syscon.h>
#include <linux/of.h>

View File

@ -4,6 +4,7 @@
* Author: Rob Clark <robdclark@gmail.com>
*/
#include <linux/backlight.h>
#include <linux/gpio/consumer.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>

View File

@ -20,6 +20,7 @@
#include <drm/drm_simple_kms_helper.h>
#include <linux/clk.h>
#include <linux/component.h>
#include <linux/media-bus-format.h>
#include <linux/of_graph.h>
#include <linux/of_platform.h>
#include "vc4_drv.h"

View File

@ -209,7 +209,7 @@ static void vc4_match_add_drivers(struct device *dev,
}
}
const struct of_device_id vc4_dma_range_matches[] = {
static const struct of_device_id vc4_dma_range_matches[] = {
{ .compatible = "brcm,bcm2711-hvs" },
{ .compatible = "brcm,bcm2835-hvs" },
{ .compatible = "brcm,bcm2835-v3d" },

View File

@ -6,6 +6,7 @@
#define _VC4_DRV_H_
#include <linux/delay.h>
#include <linux/of.h>
#include <linux/refcount.h>
#include <linux/uaccess.h>

View File

@ -26,6 +26,7 @@
*
**************************************************************************/
#include <linux/fb.h>
#include <linux/pci.h>
#include <drm/drm_fourcc.h>

View File

@ -252,7 +252,7 @@ static void vmw_cursor_update_position(struct vmw_private *dev_priv,
vmw_write(dev_priv, SVGA_REG_CURSOR4_Y, y);
vmw_write(dev_priv, SVGA_REG_CURSOR4_SCREEN_ID, SVGA3D_INVALID_ID);
vmw_write(dev_priv, SVGA_REG_CURSOR4_ON, svga_cursor_on);
vmw_write(dev_priv, SVGA_REG_CURSOR4_SUBMIT, TRUE);
vmw_write(dev_priv, SVGA_REG_CURSOR4_SUBMIT, 1);
} else if (vmw_is_cursor_bypass3_enabled(dev_priv)) {
vmw_fifo_mem_write(dev_priv, SVGA_FIFO_CURSOR_ON, svga_cursor_on);
vmw_fifo_mem_write(dev_priv, SVGA_FIFO_CURSOR_X, x);

View File

@ -25,6 +25,7 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>

View File

@ -1527,7 +1527,11 @@ struct drm_connector {
struct drm_cmdline_mode cmdline_mode;
/** @force: a DRM_FORCE_<foo> state for forced mode sets */
enum drm_connector_force force;
/** @override_edid: has the EDID been overwritten through debugfs for testing? */
/**
* @override_edid: has the EDID been overwritten through debugfs for
* testing? Do not modify outside of drm_edid_override_set() and
* drm_edid_override_reset().
*/
bool override_edid;
/** @epoch_counter: used to detect any other changes in connector, besides status */
u64 epoch_counter;

View File

@ -25,22 +25,13 @@
#ifndef __DRM_CRTC_H__
#define __DRM_CRTC_H__
#include <linux/i2c.h>
#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/fb.h>
#include <linux/hdmi.h>
#include <linux/media-bus-format.h>
#include <uapi/drm/drm_mode.h>
#include <uapi/drm/drm_fourcc.h>
#include <drm/drm_modeset_lock.h>
#include <drm/drm_rect.h>
#include <drm/drm_mode_object.h>
#include <drm/drm_modes.h>
#include <drm/drm_device.h>
#include <drm/drm_property.h>
#include <drm/drm_plane.h>
#include <drm/drm_color_mgmt.h>
#include <drm/drm_debugfs_crc.h>
#include <drm/drm_mode_config.h>
@ -49,11 +40,9 @@ struct drm_device;
struct drm_framebuffer;
struct drm_mode_set;
struct drm_file;
struct drm_clip_rect;
struct drm_printer;
struct drm_self_refresh_data;
struct device_node;
struct dma_fence;
struct edid;
static inline int64_t U642I64(uint64_t val)

View File

@ -597,12 +597,15 @@ drm_display_mode_from_cea_vic(struct drm_device *dev,
const struct drm_edid *drm_edid_alloc(const void *edid, size_t size);
const struct drm_edid *drm_edid_dup(const struct drm_edid *drm_edid);
void drm_edid_free(const struct drm_edid *drm_edid);
const struct edid *drm_edid_raw(const struct drm_edid *drm_edid);
const struct drm_edid *drm_edid_read(struct drm_connector *connector);
const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
struct i2c_adapter *adapter);
const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector,
int (*read_block)(void *context, u8 *buf, unsigned int block, size_t len),
void *context);
int drm_edid_connector_update(struct drm_connector *connector,
const struct drm_edid *edid);
const u8 *drm_find_edid_extension(const struct drm_edid *drm_edid,
int ext_id, int *ext_index);

View File

@ -27,6 +27,8 @@
#ifndef __DRM_ENCODER_SLAVE_H__
#define __DRM_ENCODER_SLAVE_H__
#include <linux/i2c.h>
#include <drm/drm_crtc.h>
#include <drm/drm_encoder.h>

View File

@ -35,6 +35,7 @@ struct drm_fb_helper;
#include <drm/drm_client.h>
#include <drm/drm_crtc.h>
#include <drm/drm_device.h>
#include <linux/fb.h>
#include <linux/kgdb.h>
enum mode_set_atomic {

View File

@ -27,5 +27,6 @@ void drm_kms_helper_poll_enable(struct drm_device *dev);
bool drm_kms_helper_is_poll_worker(void);
int drm_connector_helper_get_modes_from_ddc(struct drm_connector *connector);
int drm_connector_helper_get_modes(struct drm_connector *connector);
#endif