summaryrefslogtreecommitdiffstats
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/Kconfig1
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix_dp_core.c5
-rw-r--r--drivers/gpu/drm/bridge/analogix/anx7625.c22
-rw-r--r--drivers/gpu/drm/bridge/ite-it6505.c17
-rw-r--r--drivers/gpu/drm/bridge/lontium-lt8912b.c35
-rw-r--r--drivers/gpu/drm/bridge/lontium-lt9611uxc.c103
-rw-r--r--drivers/gpu/drm/bridge/nwl-dsi.c8
-rw-r--r--drivers/gpu/drm/bridge/nwl-dsi.h4
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c30
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi.c66
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c7
-rw-r--r--drivers/gpu/drm/bridge/tc358767.c45
12 files changed, 141 insertions, 202 deletions
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index c621be1a99a8..3eb955333c80 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -390,6 +390,7 @@ config DRM_TI_SN65DSI86
depends on OF
select DRM_DISPLAY_DP_HELPER
select DRM_DISPLAY_HELPER
+ select DRM_BRIDGE_CONNECTOR
select DRM_KMS_HELPER
select REGMAP_I2C
select DRM_PANEL
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index ddf1e4424ffd..bfa88409a7ff 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -36,11 +36,6 @@
static const bool verify_fast_training;
-struct bridge_init {
- struct i2c_client *client;
- struct device_node *node;
-};
-
static void analogix_dp_init_dp(struct analogix_dp_device *dp)
{
analogix_dp_reset(dp);
diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
index 88e4aa5830f3..a2e9bb485c36 100644
--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
+++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
@@ -1647,25 +1647,15 @@ static int anx7625_get_swing_setting(struct device *dev,
{
int num_regs;
- if (of_get_property(dev->of_node,
- "analogix,lane0-swing", &num_regs)) {
- if (num_regs > DP_TX_SWING_REG_CNT)
- num_regs = DP_TX_SWING_REG_CNT;
-
+ num_regs = of_property_read_variable_u8_array(dev->of_node, "analogix,lane0-swing",
+ pdata->lane0_reg_data, 1, DP_TX_SWING_REG_CNT);
+ if (num_regs > 0)
pdata->dp_lane0_swing_reg_cnt = num_regs;
- of_property_read_u8_array(dev->of_node, "analogix,lane0-swing",
- pdata->lane0_reg_data, num_regs);
- }
-
- if (of_get_property(dev->of_node,
- "analogix,lane1-swing", &num_regs)) {
- if (num_regs > DP_TX_SWING_REG_CNT)
- num_regs = DP_TX_SWING_REG_CNT;
+ num_regs = of_property_read_variable_u8_array(dev->of_node, "analogix,lane1-swing",
+ pdata->lane1_reg_data, 1, DP_TX_SWING_REG_CNT);
+ if (num_regs > 0)
pdata->dp_lane1_swing_reg_cnt = num_regs;
- of_property_read_u8_array(dev->of_node, "analogix,lane1-swing",
- pdata->lane1_reg_data, num_regs);
- }
return 0;
}
diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c
index 1e1c06fdf206..87b8545fccc0 100644
--- a/drivers/gpu/drm/bridge/ite-it6505.c
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
@@ -460,6 +460,8 @@ struct it6505 {
bool enable_drv_hold;
const struct drm_edid *cached_edid;
+
+ int irq;
};
struct it6505_step_train_para {
@@ -2624,6 +2626,8 @@ static int it6505_poweron(struct it6505 *it6505)
it6505_init(it6505);
it6505_lane_off(it6505);
+ enable_irq(it6505->irq);
+
return 0;
}
@@ -2640,6 +2644,8 @@ static int it6505_poweroff(struct it6505 *it6505)
return 0;
}
+ disable_irq_nosync(it6505->irq);
+
if (pdata->gpiod_reset)
gpiod_set_value_cansleep(pdata->gpiod_reset, 0);
@@ -3389,7 +3395,7 @@ static int it6505_i2c_probe(struct i2c_client *client)
struct it6505 *it6505;
struct device *dev = &client->dev;
struct extcon_dev *extcon;
- int err, intp_irq;
+ int err;
it6505 = devm_kzalloc(&client->dev, sizeof(*it6505), GFP_KERNEL);
if (!it6505)
@@ -3430,17 +3436,18 @@ static int it6505_i2c_probe(struct i2c_client *client)
it6505_parse_dt(it6505);
- intp_irq = client->irq;
+ it6505->irq = client->irq;
- if (!intp_irq) {
+ if (!it6505->irq) {
dev_err(dev, "Failed to get INTP IRQ");
err = -ENODEV;
return err;
}
- err = devm_request_threaded_irq(&client->dev, intp_irq, NULL,
+ err = devm_request_threaded_irq(&client->dev, it6505->irq, NULL,
it6505_int_threaded_handler,
- IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ IRQF_TRIGGER_LOW | IRQF_ONESHOT |
+ IRQF_NO_AUTOEN,
"it6505-intp", it6505);
if (err) {
dev_err(dev, "Failed to request INTP threaded IRQ: %d", err);
diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c
index 1a9defa15663..e265ab3c8c92 100644
--- a/drivers/gpu/drm/bridge/lontium-lt8912b.c
+++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c
@@ -422,22 +422,6 @@ static const struct drm_connector_funcs lt8912_connector_funcs = {
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
-static enum drm_mode_status
-lt8912_connector_mode_valid(struct drm_connector *connector,
- struct drm_display_mode *mode)
-{
- if (mode->clock > 150000)
- return MODE_CLOCK_HIGH;
-
- if (mode->hdisplay > 1920)
- return MODE_BAD_HVALUE;
-
- if (mode->vdisplay > 1080)
- return MODE_BAD_VVALUE;
-
- return MODE_OK;
-}
-
static int lt8912_connector_get_modes(struct drm_connector *connector)
{
const struct drm_edid *drm_edid;
@@ -463,7 +447,6 @@ static int lt8912_connector_get_modes(struct drm_connector *connector)
static const struct drm_connector_helper_funcs lt8912_connector_helper_funcs = {
.get_modes = lt8912_connector_get_modes,
- .mode_valid = lt8912_connector_mode_valid,
};
static void lt8912_bridge_mode_set(struct drm_bridge *bridge,
@@ -605,6 +588,23 @@ static void lt8912_bridge_detach(struct drm_bridge *bridge)
drm_bridge_hpd_disable(lt->hdmi_port);
}
+static enum drm_mode_status
+lt8912_bridge_mode_valid(struct drm_bridge *bridge,
+ const struct drm_display_info *info,
+ const struct drm_display_mode *mode)
+{
+ if (mode->clock > 150000)
+ return MODE_CLOCK_HIGH;
+
+ if (mode->hdisplay > 1920)
+ return MODE_BAD_HVALUE;
+
+ if (mode->vdisplay > 1080)
+ return MODE_BAD_VVALUE;
+
+ return MODE_OK;
+}
+
static enum drm_connector_status
lt8912_bridge_detect(struct drm_bridge *bridge)
{
@@ -635,6 +635,7 @@ static const struct drm_edid *lt8912_bridge_edid_read(struct drm_bridge *bridge,
static const struct drm_bridge_funcs lt8912_bridge_funcs = {
.attach = lt8912_bridge_attach,
.detach = lt8912_bridge_detach,
+ .mode_valid = lt8912_bridge_mode_valid,
.mode_set = lt8912_bridge_mode_set,
.enable = lt8912_bridge_enable,
.detect = lt8912_bridge_detect,
diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
index 4e802b54a1cb..4d1d40e1f1b4 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
@@ -23,6 +23,7 @@
#include <drm/drm_bridge.h>
#include <drm/drm_edid.h>
#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_of.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
@@ -34,7 +35,7 @@
struct lt9611uxc {
struct device *dev;
struct drm_bridge bridge;
- struct drm_connector connector;
+ struct drm_bridge *next_bridge;
struct regmap *regmap;
/* Protects all accesses to registers by stopping the on-chip MCU */
@@ -120,11 +121,6 @@ static struct lt9611uxc *bridge_to_lt9611uxc(struct drm_bridge *bridge)
return container_of(bridge, struct lt9611uxc, bridge);
}
-static struct lt9611uxc *connector_to_lt9611uxc(struct drm_connector *connector)
-{
- return container_of(connector, struct lt9611uxc, connector);
-}
-
static void lt9611uxc_lock(struct lt9611uxc *lt9611uxc)
{
mutex_lock(&lt9611uxc->ocm_lock);
@@ -171,20 +167,14 @@ static void lt9611uxc_hpd_work(struct work_struct *work)
struct lt9611uxc *lt9611uxc = container_of(work, struct lt9611uxc, work);
bool connected;
- if (lt9611uxc->connector.dev) {
- if (lt9611uxc->connector.dev->mode_config.funcs)
- drm_kms_helper_hotplug_event(lt9611uxc->connector.dev);
- } else {
-
- mutex_lock(&lt9611uxc->ocm_lock);
- connected = lt9611uxc->hdmi_connected;
- mutex_unlock(&lt9611uxc->ocm_lock);
+ mutex_lock(&lt9611uxc->ocm_lock);
+ connected = lt9611uxc->hdmi_connected;
+ mutex_unlock(&lt9611uxc->ocm_lock);
- drm_bridge_hpd_notify(&lt9611uxc->bridge,
- connected ?
- connector_status_connected :
- connector_status_disconnected);
- }
+ drm_bridge_hpd_notify(&lt9611uxc->bridge,
+ connected ?
+ connector_status_connected :
+ connector_status_disconnected);
}
static void lt9611uxc_reset(struct lt9611uxc *lt9611uxc)
@@ -289,82 +279,13 @@ static struct mipi_dsi_device *lt9611uxc_attach_dsi(struct lt9611uxc *lt9611uxc,
return dsi;
}
-static int lt9611uxc_connector_get_modes(struct drm_connector *connector)
-{
- struct lt9611uxc *lt9611uxc = connector_to_lt9611uxc(connector);
- const struct drm_edid *drm_edid;
- int count;
-
- drm_edid = drm_bridge_edid_read(&lt9611uxc->bridge, connector);
- drm_edid_connector_update(connector, drm_edid);
- count = drm_edid_connector_add_modes(connector);
- drm_edid_free(drm_edid);
-
- return count;
-}
-
-static enum drm_connector_status lt9611uxc_connector_detect(struct drm_connector *connector,
- bool force)
-{
- struct lt9611uxc *lt9611uxc = connector_to_lt9611uxc(connector);
-
- return lt9611uxc->bridge.funcs->detect(&lt9611uxc->bridge);
-}
-
-static enum drm_mode_status lt9611uxc_connector_mode_valid(struct drm_connector *connector,
- struct drm_display_mode *mode)
-{
- struct lt9611uxc_mode *lt9611uxc_mode = lt9611uxc_find_mode(mode);
-
- return lt9611uxc_mode ? MODE_OK : MODE_BAD;
-}
-
-static const struct drm_connector_helper_funcs lt9611uxc_bridge_connector_helper_funcs = {
- .get_modes = lt9611uxc_connector_get_modes,
- .mode_valid = lt9611uxc_connector_mode_valid,
-};
-
-static const struct drm_connector_funcs lt9611uxc_bridge_connector_funcs = {
- .fill_modes = drm_helper_probe_single_connector_modes,
- .detect = lt9611uxc_connector_detect,
- .destroy = drm_connector_cleanup,
- .reset = drm_atomic_helper_connector_reset,
- .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
- .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-};
-
-static int lt9611uxc_connector_init(struct drm_bridge *bridge, struct lt9611uxc *lt9611uxc)
-{
- int ret;
-
- lt9611uxc->connector.polled = DRM_CONNECTOR_POLL_HPD;
-
- drm_connector_helper_add(&lt9611uxc->connector,
- &lt9611uxc_bridge_connector_helper_funcs);
- ret = drm_connector_init(bridge->dev, &lt9611uxc->connector,
- &lt9611uxc_bridge_connector_funcs,
- DRM_MODE_CONNECTOR_HDMIA);
- if (ret) {
- DRM_ERROR("Failed to initialize connector with drm\n");
- return ret;
- }
-
- return drm_connector_attach_encoder(&lt9611uxc->connector, bridge->encoder);
-}
-
static int lt9611uxc_bridge_attach(struct drm_bridge *bridge,
enum drm_bridge_attach_flags flags)
{
struct lt9611uxc *lt9611uxc = bridge_to_lt9611uxc(bridge);
- int ret;
-
- if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
- ret = lt9611uxc_connector_init(bridge, lt9611uxc);
- if (ret < 0)
- return ret;
- }
- return 0;
+ return drm_bridge_attach(bridge->encoder, lt9611uxc->next_bridge,
+ bridge, flags);
}
static enum drm_mode_status
@@ -525,7 +446,7 @@ static int lt9611uxc_parse_dt(struct device *dev,
lt9611uxc->dsi1_node = of_graph_get_remote_node(dev->of_node, 1, -1);
- return 0;
+ return drm_of_find_panel_or_bridge(dev->of_node, 2, -1, NULL, &lt9611uxc->next_bridge);
}
static int lt9611uxc_gpio_init(struct lt9611uxc *lt9611uxc)
diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
index 8d54091ec66e..5f05647a3bea 100644
--- a/drivers/gpu/drm/bridge/nwl-dsi.c
+++ b/drivers/gpu/drm/bridge/nwl-dsi.c
@@ -289,13 +289,13 @@ static int nwl_dsi_config_dpi(struct nwl_dsi *dsi)
nwl_dsi_write(dsi, NWL_DSI_INTERFACE_COLOR_CODING, NWL_DSI_DPI_24_BIT);
nwl_dsi_write(dsi, NWL_DSI_PIXEL_FORMAT, color_format);
- /*
- * Adjusting input polarity based on the video mode results in
- * a black screen so always pick active low:
- */
nwl_dsi_write(dsi, NWL_DSI_VSYNC_POLARITY,
+ dsi->mode.flags & DRM_MODE_FLAG_PVSYNC ?
+ NWL_DSI_VSYNC_POLARITY_ACTIVE_HIGH :
NWL_DSI_VSYNC_POLARITY_ACTIVE_LOW);
nwl_dsi_write(dsi, NWL_DSI_HSYNC_POLARITY,
+ dsi->mode.flags & DRM_MODE_FLAG_PHSYNC ?
+ NWL_DSI_HSYNC_POLARITY_ACTIVE_HIGH :
NWL_DSI_HSYNC_POLARITY_ACTIVE_LOW);
burst_mode = (dsi->dsi_mode_flags & MIPI_DSI_MODE_VIDEO_BURST) &&
diff --git a/drivers/gpu/drm/bridge/nwl-dsi.h b/drivers/gpu/drm/bridge/nwl-dsi.h
index a247a8a11c7c..61e7d65cb1eb 100644
--- a/drivers/gpu/drm/bridge/nwl-dsi.h
+++ b/drivers/gpu/drm/bridge/nwl-dsi.h
@@ -30,11 +30,11 @@
#define NWL_DSI_PIXEL_FORMAT 0x20c
#define NWL_DSI_VSYNC_POLARITY 0x210
#define NWL_DSI_VSYNC_POLARITY_ACTIVE_LOW 0
-#define NWL_DSI_VSYNC_POLARITY_ACTIVE_HIGH BIT(1)
+#define NWL_DSI_VSYNC_POLARITY_ACTIVE_HIGH BIT(0)
#define NWL_DSI_HSYNC_POLARITY 0x214
#define NWL_DSI_HSYNC_POLARITY_ACTIVE_LOW 0
-#define NWL_DSI_HSYNC_POLARITY_ACTIVE_HIGH BIT(1)
+#define NWL_DSI_HSYNC_POLARITY_ACTIVE_HIGH BIT(0)
#define NWL_DSI_VIDEO_MODE 0x218
#define NWL_DSI_HFP 0x21c
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
index 67b8d17a722a..221e9a4edb40 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
@@ -8,6 +8,7 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/vmalloc.h>
#include <drm/bridge/dw_hdmi.h>
#include <drm/drm_edid.h>
@@ -388,15 +389,36 @@ static int dw_hdmi_close(struct snd_pcm_substream *substream)
static int dw_hdmi_hw_free(struct snd_pcm_substream *substream)
{
- return snd_pcm_lib_free_vmalloc_buffer(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ vfree(runtime->dma_area);
+ runtime->dma_area = NULL;
+ return 0;
}
static int dw_hdmi_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ size_t size = params_buffer_bytes(params);
+
/* Allocate the PCM runtime buffer, which is exposed to userspace. */
- return snd_pcm_lib_alloc_vmalloc_buffer(substream,
- params_buffer_bytes(params));
+ if (runtime->dma_area) {
+ if (runtime->dma_bytes >= size)
+ return 0; /* already large enough */
+ vfree(runtime->dma_area);
+ }
+ runtime->dma_area = vzalloc(size);
+ if (!runtime->dma_area)
+ return -ENOMEM;
+ runtime->dma_bytes = size;
+ return 1;
+}
+
+static struct page *dw_hdmi_get_page(struct snd_pcm_substream *substream,
+ unsigned long offset)
+{
+ return vmalloc_to_page(substream->runtime->dma_area + offset);
}
static int dw_hdmi_prepare(struct snd_pcm_substream *substream)
@@ -515,7 +537,7 @@ static const struct snd_pcm_ops snd_dw_hdmi_ops = {
.prepare = dw_hdmi_prepare,
.trigger = dw_hdmi_trigger,
.pointer = dw_hdmi_pointer,
- .page = snd_pcm_lib_get_vmalloc_page,
+ .page = dw_hdmi_get_page,
};
static int snd_dw_hdmi_probe(struct platform_device *pdev)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 9f2bc932c371..0031f3c54882 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -138,9 +138,6 @@ struct dw_hdmi {
struct platform_device *audio;
struct platform_device *cec;
struct device *dev;
- struct clk *isfr_clk;
- struct clk *iahb_clk;
- struct clk *cec_clk;
struct dw_hdmi_i2c *i2c;
struct hdmi_data_info hdmi_data;
@@ -3326,6 +3323,7 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
struct device_node *ddc_node;
struct dw_hdmi_cec_data cec;
struct dw_hdmi *hdmi;
+ struct clk *clk;
struct resource *iores = NULL;
int irq;
int ret;
@@ -3405,50 +3403,27 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
hdmi->regm = plat_data->regm;
}
- hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr");
- if (IS_ERR(hdmi->isfr_clk)) {
- ret = PTR_ERR(hdmi->isfr_clk);
+ clk = devm_clk_get_enabled(hdmi->dev, "isfr");
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
dev_err(hdmi->dev, "Unable to get HDMI isfr clk: %d\n", ret);
goto err_res;
}
- ret = clk_prepare_enable(hdmi->isfr_clk);
- if (ret) {
- dev_err(hdmi->dev, "Cannot enable HDMI isfr clock: %d\n", ret);
- goto err_res;
- }
-
- hdmi->iahb_clk = devm_clk_get(hdmi->dev, "iahb");
- if (IS_ERR(hdmi->iahb_clk)) {
- ret = PTR_ERR(hdmi->iahb_clk);
+ clk = devm_clk_get_enabled(hdmi->dev, "iahb");
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
dev_err(hdmi->dev, "Unable to get HDMI iahb clk: %d\n", ret);
- goto err_isfr;
- }
-
- ret = clk_prepare_enable(hdmi->iahb_clk);
- if (ret) {
- dev_err(hdmi->dev, "Cannot enable HDMI iahb clock: %d\n", ret);
- goto err_isfr;
+ goto err_res;
}
- hdmi->cec_clk = devm_clk_get(hdmi->dev, "cec");
- if (PTR_ERR(hdmi->cec_clk) == -ENOENT) {
- hdmi->cec_clk = NULL;
- } else if (IS_ERR(hdmi->cec_clk)) {
- ret = PTR_ERR(hdmi->cec_clk);
+ clk = devm_clk_get_optional_enabled(hdmi->dev, "cec");
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
if (ret != -EPROBE_DEFER)
dev_err(hdmi->dev, "Cannot get HDMI cec clock: %d\n",
ret);
-
- hdmi->cec_clk = NULL;
- goto err_iahb;
- } else {
- ret = clk_prepare_enable(hdmi->cec_clk);
- if (ret) {
- dev_err(hdmi->dev, "Cannot enable HDMI cec clock: %d\n",
- ret);
- goto err_iahb;
- }
+ goto err_res;
}
/* Product and revision IDs */
@@ -3462,12 +3437,12 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
dev_err(dev, "Unsupported HDMI controller (%04x:%02x:%02x)\n",
hdmi->version, prod_id0, prod_id1);
ret = -ENODEV;
- goto err_iahb;
+ goto err_res;
}
ret = dw_hdmi_detect_phy(hdmi);
if (ret < 0)
- goto err_iahb;
+ goto err_res;
dev_info(dev, "Detected HDMI TX controller v%x.%03x %s HDCP (%s)\n",
hdmi->version >> 12, hdmi->version & 0xfff,
@@ -3479,14 +3454,14 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
ret = irq;
- goto err_iahb;
+ goto err_res;
}
ret = devm_request_threaded_irq(dev, irq, dw_hdmi_hardirq,
dw_hdmi_irq, IRQF_SHARED,
dev_name(dev), hdmi);
if (ret)
- goto err_iahb;
+ goto err_res;
/*
* To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
@@ -3603,11 +3578,6 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
return hdmi;
-err_iahb:
- clk_disable_unprepare(hdmi->iahb_clk);
- clk_disable_unprepare(hdmi->cec_clk);
-err_isfr:
- clk_disable_unprepare(hdmi->isfr_clk);
err_res:
i2c_put_adapter(hdmi->ddc);
@@ -3627,10 +3597,6 @@ void dw_hdmi_remove(struct dw_hdmi *hdmi)
/* Disable all interrupts */
hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
- clk_disable_unprepare(hdmi->iahb_clk);
- clk_disable_unprepare(hdmi->isfr_clk);
- clk_disable_unprepare(hdmi->cec_clk);
-
if (hdmi->i2c)
i2c_del_adapter(&hdmi->i2c->adap);
else
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index c4e9d96933dc..0fb02e4e7f4e 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -722,7 +722,12 @@ static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi,
static void dw_mipi_dsi_packet_handler_config(struct dw_mipi_dsi *dsi)
{
- dsi_write(dsi, DSI_PCKHDL_CFG, CRC_RX_EN | ECC_RX_EN | BTA_EN);
+ u32 val = CRC_RX_EN | ECC_RX_EN | BTA_EN | EOTP_TX_EN;
+
+ if (dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET)
+ val &= ~EOTP_TX_EN;
+
+ dsi_write(dsi, DSI_PCKHDL_CFG, val);
}
static void dw_mipi_dsi_video_packet_config(struct dw_mipi_dsi *dsi,
diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c
index b8b7a227addf..290e2532fab1 100644
--- a/drivers/gpu/drm/bridge/tc358767.c
+++ b/drivers/gpu/drm/bridge/tc358767.c
@@ -241,6 +241,10 @@
/* Link Training */
#define DP0_SRCCTRL 0x06a0
+#define DP0_SRCCTRL_PRE1 GENMASK(29, 28)
+#define DP0_SRCCTRL_SWG1 GENMASK(25, 24)
+#define DP0_SRCCTRL_PRE0 GENMASK(21, 20)
+#define DP0_SRCCTRL_SWG0 GENMASK(17, 16)
#define DP0_SRCCTRL_SCRMBLDIS BIT(13)
#define DP0_SRCCTRL_EN810B BIT(12)
#define DP0_SRCCTRL_NOTP (0 << 8)
@@ -278,6 +282,8 @@
#define AUDIFDATA6 0x0720 /* DP0 Audio Info Frame Bytes 27 to 24 */
#define DP1_SRCCTRL 0x07a0 /* DP1 Control Register */
+#define DP1_SRCCTRL_PRE GENMASK(21, 20)
+#define DP1_SRCCTRL_SWG GENMASK(17, 16)
/* PHY */
#define DP_PHY_CTRL 0x0800
@@ -369,6 +375,7 @@ struct tc_data {
u32 rev;
u8 assr;
+ u8 pre_emphasis[2];
struct gpio_desc *sd_gpio;
struct gpio_desc *reset_gpio;
@@ -1090,13 +1097,17 @@ static int tc_main_link_enable(struct tc_data *tc)
return ret;
}
- ret = regmap_write(tc->regmap, DP0_SRCCTRL, tc_srcctrl(tc));
+ ret = regmap_write(tc->regmap, DP0_SRCCTRL,
+ tc_srcctrl(tc) |
+ FIELD_PREP(DP0_SRCCTRL_PRE0, tc->pre_emphasis[0]) |
+ FIELD_PREP(DP0_SRCCTRL_PRE1, tc->pre_emphasis[1]));
if (ret)
return ret;
/* SSCG and BW27 on DP1 must be set to the same as on DP0 */
ret = regmap_write(tc->regmap, DP1_SRCCTRL,
(tc->link.spread ? DP0_SRCCTRL_SSCG : 0) |
- ((tc->link.rate != 162000) ? DP0_SRCCTRL_BW27 : 0));
+ ((tc->link.rate != 162000) ? DP0_SRCCTRL_BW27 : 0) |
+ FIELD_PREP(DP1_SRCCTRL_PRE, tc->pre_emphasis[1]));
if (ret)
return ret;
@@ -1188,8 +1199,10 @@ static int tc_main_link_enable(struct tc_data *tc)
goto err_dpcd_write;
/* Reset voltage-swing & pre-emphasis */
- tmp[0] = tmp[1] = DP_TRAIN_VOLTAGE_SWING_LEVEL_0 |
- DP_TRAIN_PRE_EMPH_LEVEL_0;
+ tmp[0] = DP_TRAIN_VOLTAGE_SWING_LEVEL_0 |
+ FIELD_PREP(DP_TRAIN_PRE_EMPHASIS_MASK, tc->pre_emphasis[0]);
+ tmp[1] = DP_TRAIN_VOLTAGE_SWING_LEVEL_0 |
+ FIELD_PREP(DP_TRAIN_PRE_EMPHASIS_MASK, tc->pre_emphasis[1]);
ret = drm_dp_dpcd_write(aux, DP_TRAINING_LANE0_SET, tmp, 2);
if (ret < 0)
goto err_dpcd_write;
@@ -1213,7 +1226,9 @@ static int tc_main_link_enable(struct tc_data *tc)
ret = regmap_write(tc->regmap, DP0_SRCCTRL,
tc_srcctrl(tc) | DP0_SRCCTRL_SCRMBLDIS |
DP0_SRCCTRL_AUTOCORRECT |
- DP0_SRCCTRL_TP1);
+ DP0_SRCCTRL_TP1 |
+ FIELD_PREP(DP0_SRCCTRL_PRE0, tc->pre_emphasis[0]) |
+ FIELD_PREP(DP0_SRCCTRL_PRE1, tc->pre_emphasis[1]));
if (ret)
return ret;
@@ -1248,7 +1263,9 @@ static int tc_main_link_enable(struct tc_data *tc)
ret = regmap_write(tc->regmap, DP0_SRCCTRL,
tc_srcctrl(tc) | DP0_SRCCTRL_SCRMBLDIS |
DP0_SRCCTRL_AUTOCORRECT |
- DP0_SRCCTRL_TP2);
+ DP0_SRCCTRL_TP2 |
+ FIELD_PREP(DP0_SRCCTRL_PRE0, tc->pre_emphasis[0]) |
+ FIELD_PREP(DP0_SRCCTRL_PRE1, tc->pre_emphasis[1]));
if (ret)
return ret;
@@ -1274,7 +1291,9 @@ static int tc_main_link_enable(struct tc_data *tc)
/* Clear Training Pattern, set AutoCorrect Mode = 1 */
ret = regmap_write(tc->regmap, DP0_SRCCTRL, tc_srcctrl(tc) |
- DP0_SRCCTRL_AUTOCORRECT);
+ DP0_SRCCTRL_AUTOCORRECT |
+ FIELD_PREP(DP0_SRCCTRL_PRE0, tc->pre_emphasis[0]) |
+ FIELD_PREP(DP0_SRCCTRL_PRE1, tc->pre_emphasis[1]));
if (ret)
return ret;
@@ -2363,6 +2382,18 @@ static int tc_probe_bridge_endpoint(struct tc_data *tc)
return -EINVAL;
}
mode |= BIT(endpoint.port);
+
+ if (endpoint.port == 2) {
+ of_property_read_u8_array(node, "toshiba,pre-emphasis",
+ tc->pre_emphasis,
+ ARRAY_SIZE(tc->pre_emphasis));
+
+ if (tc->pre_emphasis[0] < 0 || tc->pre_emphasis[0] > 2 ||
+ tc->pre_emphasis[1] < 0 || tc->pre_emphasis[1] > 2) {
+ dev_err(dev, "Incorrect Pre-Emphasis setting, use either 0=0dB 1=3.5dB 2=6dB\n");
+ return -EINVAL;
+ }
+ }
}
if (mode == mode_dpi_to_edp || mode == mode_dpi_to_dp) {