summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/bridge
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/bridge')
-rw-r--r--drivers/gpu/drm/bridge/Kconfig2
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c9
-rw-r--r--drivers/gpu/drm/bridge/cadence/Kconfig1
-rw-r--r--drivers/gpu/drm/bridge/ite-it66121.c29
-rw-r--r--drivers/gpu/drm/bridge/lontium-lt8912b.c22
-rw-r--r--drivers/gpu/drm/bridge/lvds-codec.c12
-rw-r--r--drivers/gpu/drm/bridge/panel.c18
-rw-r--r--drivers/gpu/drm/bridge/samsung-dsim.c20
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi.c2
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c2
10 files changed, 66 insertions, 51 deletions
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 44a660a4bdbf..ba82a1142adf 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -181,6 +181,7 @@ config DRM_NWL_MIPI_DSI
select DRM_KMS_HELPER
select DRM_MIPI_DSI
select DRM_PANEL_BRIDGE
+ select GENERIC_PHY
select GENERIC_PHY_MIPI_DPHY
select MFD_SYSCON
select MULTIPLEXER
@@ -227,6 +228,7 @@ config DRM_SAMSUNG_DSIM
select DRM_KMS_HELPER
select DRM_MIPI_DSI
select DRM_PANEL_BRIDGE
+ select GENERIC_PHY
select GENERIC_PHY_MIPI_DPHY
help
The Samsung MIPI DSIM bridge controller driver.
diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
index 800555aef97f..ad8241758896 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
@@ -1231,9 +1231,7 @@ static int anx78xx_i2c_probe(struct i2c_client *client)
mutex_init(&anx78xx->lock);
-#if IS_ENABLED(CONFIG_OF)
anx78xx->bridge.of_node = client->dev.of_node;
-#endif
anx78xx->client = client;
i2c_set_clientdata(client, anx78xx);
@@ -1367,12 +1365,6 @@ static void anx78xx_i2c_remove(struct i2c_client *client)
kfree(anx78xx->edid);
}
-static const struct i2c_device_id anx78xx_id[] = {
- { "anx7814", 0 },
- { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(i2c, anx78xx_id);
-
static const struct of_device_id anx78xx_match_table[] = {
{ .compatible = "analogix,anx7808", .data = anx7808_i2c_addresses },
{ .compatible = "analogix,anx7812", .data = anx781x_i2c_addresses },
@@ -1389,7 +1381,6 @@ static struct i2c_driver anx78xx_driver = {
},
.probe = anx78xx_i2c_probe,
.remove = anx78xx_i2c_remove,
- .id_table = anx78xx_id,
};
module_i2c_driver(anx78xx_driver);
diff --git a/drivers/gpu/drm/bridge/cadence/Kconfig b/drivers/gpu/drm/bridge/cadence/Kconfig
index ec35215a2003..cced81633ddc 100644
--- a/drivers/gpu/drm/bridge/cadence/Kconfig
+++ b/drivers/gpu/drm/bridge/cadence/Kconfig
@@ -4,6 +4,7 @@ config DRM_CDNS_DSI
select DRM_KMS_HELPER
select DRM_MIPI_DSI
select DRM_PANEL_BRIDGE
+ select GENERIC_PHY
select GENERIC_PHY_MIPI_DPHY
depends on OF
help
diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c
index 466641c77fe9..3c9b42c9d2ee 100644
--- a/drivers/gpu/drm/bridge/ite-it66121.c
+++ b/drivers/gpu/drm/bridge/ite-it66121.c
@@ -1447,10 +1447,14 @@ static int it66121_audio_get_eld(struct device *dev, void *data,
struct it66121_ctx *ctx = dev_get_drvdata(dev);
mutex_lock(&ctx->lock);
-
- memcpy(buf, ctx->connector->eld,
- min(sizeof(ctx->connector->eld), len));
-
+ if (!ctx->connector) {
+ /* Pass en empty ELD if connector not available */
+ dev_dbg(dev, "No connector present, passing empty EDID data");
+ memset(buf, 0, len);
+ } else {
+ memcpy(buf, ctx->connector->eld,
+ min(sizeof(ctx->connector->eld), len));
+ }
mutex_unlock(&ctx->lock);
return 0;
@@ -1501,7 +1505,6 @@ static const char * const it66121_supplies[] = {
static int it66121_probe(struct i2c_client *client)
{
- const struct i2c_device_id *id = i2c_client_get_device_id(client);
u32 revision_id, vendor_ids[2] = { 0 }, device_ids[2] = { 0 };
struct device_node *ep;
int ret;
@@ -1523,7 +1526,7 @@ static int it66121_probe(struct i2c_client *client)
ctx->dev = dev;
ctx->client = client;
- ctx->info = (const struct it66121_chip_info *) id->driver_data;
+ ctx->info = i2c_get_match_data(client);
of_property_read_u32(ep, "bus-width", &ctx->bus_width);
of_node_put(ep);
@@ -1609,13 +1612,6 @@ static void it66121_remove(struct i2c_client *client)
mutex_destroy(&ctx->lock);
}
-static const struct of_device_id it66121_dt_match[] = {
- { .compatible = "ite,it66121" },
- { .compatible = "ite,it6610" },
- { }
-};
-MODULE_DEVICE_TABLE(of, it66121_dt_match);
-
static const struct it66121_chip_info it66121_chip_info = {
.id = ID_IT66121,
.vid = 0x4954,
@@ -1628,6 +1624,13 @@ static const struct it66121_chip_info it6610_chip_info = {
.pid = 0x0611,
};
+static const struct of_device_id it66121_dt_match[] = {
+ { .compatible = "ite,it66121", &it66121_chip_info },
+ { .compatible = "ite,it6610", &it6610_chip_info },
+ { }
+};
+MODULE_DEVICE_TABLE(of, it66121_dt_match);
+
static const struct i2c_device_id it66121_id[] = {
{ "it66121", (kernel_ulong_t) &it66121_chip_info },
{ "it6610", (kernel_ulong_t) &it6610_chip_info },
diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c
index 4eaea67fb71c..03532efb893b 100644
--- a/drivers/gpu/drm/bridge/lontium-lt8912b.c
+++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c
@@ -45,7 +45,6 @@ struct lt8912 {
u8 data_lanes;
bool is_power_on;
- bool is_attached;
};
static int lt8912_write_init_config(struct lt8912 *lt)
@@ -559,6 +558,13 @@ static int lt8912_bridge_attach(struct drm_bridge *bridge,
struct lt8912 *lt = bridge_to_lt8912(bridge);
int ret;
+ ret = drm_bridge_attach(bridge->encoder, lt->hdmi_port, bridge,
+ DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+ if (ret < 0) {
+ dev_err(lt->dev, "Failed to attach next bridge (%d)\n", ret);
+ return ret;
+ }
+
if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
ret = lt8912_bridge_connector_init(bridge);
if (ret) {
@@ -575,8 +581,6 @@ static int lt8912_bridge_attach(struct drm_bridge *bridge,
if (ret)
goto error;
- lt->is_attached = true;
-
return 0;
error:
@@ -588,15 +592,10 @@ static void lt8912_bridge_detach(struct drm_bridge *bridge)
{
struct lt8912 *lt = bridge_to_lt8912(bridge);
- if (lt->is_attached) {
- lt8912_hard_power_off(lt);
-
- if (lt->hdmi_port->ops & DRM_BRIDGE_OP_HPD)
- drm_bridge_hpd_disable(lt->hdmi_port);
+ lt8912_hard_power_off(lt);
- drm_connector_unregister(&lt->connector);
- drm_connector_cleanup(&lt->connector);
- }
+ if (lt->connector.dev && lt->hdmi_port->ops & DRM_BRIDGE_OP_HPD)
+ drm_bridge_hpd_disable(lt->hdmi_port);
}
static enum drm_connector_status
@@ -750,7 +749,6 @@ static void lt8912_remove(struct i2c_client *client)
{
struct lt8912 *lt = i2c_get_clientdata(client);
- lt8912_bridge_detach(&lt->bridge);
drm_bridge_remove(&lt->bridge);
lt8912_free_i2c(lt);
lt8912_put_dt(lt);
diff --git a/drivers/gpu/drm/bridge/lvds-codec.c b/drivers/gpu/drm/bridge/lvds-codec.c
index 8c5668dca0c4..991732c4b629 100644
--- a/drivers/gpu/drm/bridge/lvds-codec.c
+++ b/drivers/gpu/drm/bridge/lvds-codec.c
@@ -5,6 +5,7 @@
*/
#include <linux/gpio/consumer.h>
+#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_graph.h>
@@ -71,12 +72,6 @@ static void lvds_codec_disable(struct drm_bridge *bridge)
"Failed to disable regulator \"vcc\": %d\n", ret);
}
-static const struct drm_bridge_funcs funcs = {
- .attach = lvds_codec_attach,
- .enable = lvds_codec_enable,
- .disable = lvds_codec_disable,
-};
-
#define MAX_INPUT_SEL_FORMATS 1
static u32 *
lvds_codec_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
@@ -102,7 +97,7 @@ lvds_codec_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
return input_fmts;
}
-static const struct drm_bridge_funcs funcs_decoder = {
+static const struct drm_bridge_funcs funcs = {
.attach = lvds_codec_attach,
.enable = lvds_codec_enable,
.disable = lvds_codec_disable,
@@ -184,8 +179,9 @@ static int lvds_codec_probe(struct platform_device *pdev)
return ret;
} else {
lvds_codec->bus_format = ret;
- lvds_codec->bridge.funcs = &funcs_decoder;
}
+ } else {
+ lvds_codec->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
}
/*
diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c
index 9316384b4474..e00d2e94c751 100644
--- a/drivers/gpu/drm/bridge/panel.c
+++ b/drivers/gpu/drm/bridge/panel.c
@@ -4,6 +4,8 @@
* Copyright (C) 2017 Broadcom
*/
+#include <linux/device.h>
+
#include <drm/drm_atomic_helper.h>
#include <drm/drm_bridge.h>
#include <drm/drm_connector.h>
@@ -19,6 +21,7 @@ struct panel_bridge {
struct drm_bridge bridge;
struct drm_connector connector;
struct drm_panel *panel;
+ struct device_link *link;
u32 connector_type;
};
@@ -60,6 +63,8 @@ static int panel_bridge_attach(struct drm_bridge *bridge,
{
struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
struct drm_connector *connector = &panel_bridge->connector;
+ struct drm_panel *panel = panel_bridge->panel;
+ struct drm_device *drm_dev = bridge->dev;
int ret;
if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
@@ -70,6 +75,14 @@ static int panel_bridge_attach(struct drm_bridge *bridge,
return -ENODEV;
}
+ panel_bridge->link = device_link_add(drm_dev->dev, panel->dev,
+ DL_FLAG_STATELESS);
+ if (!panel_bridge->link) {
+ DRM_ERROR("Failed to add device link between %s and %s\n",
+ dev_name(drm_dev->dev), dev_name(panel->dev));
+ return -EINVAL;
+ }
+
drm_connector_helper_add(connector,
&panel_bridge_connector_helper_funcs);
@@ -78,6 +91,7 @@ static int panel_bridge_attach(struct drm_bridge *bridge,
panel_bridge->connector_type);
if (ret) {
DRM_ERROR("Failed to initialize connector\n");
+ device_link_del(panel_bridge->link);
return ret;
}
@@ -100,6 +114,8 @@ static void panel_bridge_detach(struct drm_bridge *bridge)
struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
struct drm_connector *connector = &panel_bridge->connector;
+ device_link_del(panel_bridge->link);
+
/*
* Cleanup the connector if we know it was initialized.
*
@@ -302,9 +318,7 @@ struct drm_bridge *drm_panel_bridge_add_typed(struct drm_panel *panel,
panel_bridge->panel = panel;
panel_bridge->bridge.funcs = &panel_bridge_bridge_funcs;
-#ifdef CONFIG_OF
panel_bridge->bridge.of_node = panel->dev->of_node;
-#endif
panel_bridge->bridge.ops = DRM_BRIDGE_OP_MODES;
panel_bridge->bridge.type = connector_type;
diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c
index cf777bdb25d2..19bdb32dbc9a 100644
--- a/drivers/gpu/drm/bridge/samsung-dsim.c
+++ b/drivers/gpu/drm/bridge/samsung-dsim.c
@@ -385,7 +385,7 @@ static const unsigned int imx8mm_dsim_reg_values[] = {
[RESET_TYPE] = DSIM_SWRST,
[PLL_TIMER] = 500,
[STOP_STATE_CNT] = 0xf,
- [PHYCTRL_ULPS_EXIT] = 0,
+ [PHYCTRL_ULPS_EXIT] = DSIM_PHYCTRL_ULPS_EXIT(0xaf),
[PHYCTRL_VREG_LP] = 0,
[PHYCTRL_SLEW_UP] = 0,
[PHYTIMING_LPX] = DSIM_PHYTIMING_LPX(0x06),
@@ -413,6 +413,7 @@ static const struct samsung_dsim_driver_data exynos3_dsi_driver_data = {
.m_min = 41,
.m_max = 125,
.min_freq = 500,
+ .has_broken_fifoctrl_emptyhdr = 1,
};
static const struct samsung_dsim_driver_data exynos4_dsi_driver_data = {
@@ -429,6 +430,7 @@ static const struct samsung_dsim_driver_data exynos4_dsi_driver_data = {
.m_min = 41,
.m_max = 125,
.min_freq = 500,
+ .has_broken_fifoctrl_emptyhdr = 1,
};
static const struct samsung_dsim_driver_data exynos5_dsi_driver_data = {
@@ -1010,8 +1012,20 @@ static int samsung_dsim_wait_for_hdr_fifo(struct samsung_dsim *dsi)
do {
u32 reg = samsung_dsim_read(dsi, DSIM_FIFOCTRL_REG);
- if (reg & DSIM_SFR_HEADER_EMPTY)
- return 0;
+ if (!dsi->driver_data->has_broken_fifoctrl_emptyhdr) {
+ if (reg & DSIM_SFR_HEADER_EMPTY)
+ return 0;
+ } else {
+ if (!(reg & DSIM_SFR_HEADER_FULL)) {
+ /*
+ * Wait a little bit, so the pending data can
+ * actually leave the FIFO to avoid overflow.
+ */
+ if (!cond_resched())
+ usleep_range(950, 1050);
+ return 0;
+ }
+ }
if (!cond_resched())
usleep_range(950, 1050);
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 6c1d79474505..52d91a0df85e 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -3541,9 +3541,7 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
| DRM_BRIDGE_OP_HPD;
hdmi->bridge.interlace_allowed = true;
hdmi->bridge.ddc = hdmi->ddc;
-#ifdef CONFIG_OF
hdmi->bridge.of_node = pdev->dev.of_node;
-#endif
memset(&pdevinfo, 0, sizeof(pdevinfo));
pdevinfo.parent = dev;
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index 04d4a1a10698..a8dd2a2e7c7b 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -1182,9 +1182,7 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
dsi->bridge.driver_private = dsi;
dsi->bridge.funcs = &dw_mipi_dsi_bridge_funcs;
-#ifdef CONFIG_OF
dsi->bridge.of_node = pdev->dev.of_node;
-#endif
return dsi;
}