summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/bridge/synopsys
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/bridge/synopsys')
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi.c95
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c210
2 files changed, 160 insertions, 145 deletions
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index a38db40ce990..ec8d0006ef7c 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -147,7 +147,6 @@ struct dw_hdmi {
int vic;
u8 edid[HDMI_EDID_LEN];
- bool cable_plugin;
struct {
const struct dw_hdmi_phy_ops *ops;
@@ -1037,19 +1036,21 @@ static void dw_hdmi_phy_enable_svsret(struct dw_hdmi *hdmi, u8 enable)
HDMI_PHY_CONF0_SVSRET_MASK);
}
-static void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable)
+void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable)
{
hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET,
HDMI_PHY_CONF0_GEN2_PDDQ_MASK);
}
+EXPORT_SYMBOL_GPL(dw_hdmi_phy_gen2_pddq);
-static void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable)
+void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable)
{
hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET,
HDMI_PHY_CONF0_GEN2_TXPWRON_MASK);
}
+EXPORT_SYMBOL_GPL(dw_hdmi_phy_gen2_txpwron);
static void dw_hdmi_phy_sel_data_en_pol(struct dw_hdmi *hdmi, u8 enable)
{
@@ -1065,6 +1066,22 @@ static void dw_hdmi_phy_sel_interface_control(struct dw_hdmi *hdmi, u8 enable)
HDMI_PHY_CONF0_SELDIPIF_MASK);
}
+void dw_hdmi_phy_reset(struct dw_hdmi *hdmi)
+{
+ /* PHY reset. The reset signal is active high on Gen2 PHYs. */
+ hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_PHYRSTZ, HDMI_MC_PHYRSTZ);
+ hdmi_writeb(hdmi, 0, HDMI_MC_PHYRSTZ);
+}
+EXPORT_SYMBOL_GPL(dw_hdmi_phy_reset);
+
+void dw_hdmi_phy_i2c_set_addr(struct dw_hdmi *hdmi, u8 address)
+{
+ hdmi_phy_test_clear(hdmi, 1);
+ hdmi_writeb(hdmi, address, HDMI_PHY_I2CM_SLAVE_ADDR);
+ hdmi_phy_test_clear(hdmi, 0);
+}
+EXPORT_SYMBOL_GPL(dw_hdmi_phy_i2c_set_addr);
+
static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
{
const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
@@ -1203,16 +1220,11 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
if (phy->has_svsret)
dw_hdmi_phy_enable_svsret(hdmi, 1);
- /* PHY reset. The reset signal is active high on Gen2 PHYs. */
- hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_PHYRSTZ, HDMI_MC_PHYRSTZ);
- hdmi_writeb(hdmi, 0, HDMI_MC_PHYRSTZ);
+ dw_hdmi_phy_reset(hdmi);
hdmi_writeb(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST);
- hdmi_phy_test_clear(hdmi, 1);
- hdmi_writeb(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2,
- HDMI_PHY_I2CM_SLAVE_ADDR);
- hdmi_phy_test_clear(hdmi, 0);
+ dw_hdmi_phy_i2c_set_addr(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2);
/* Write to the PHY as configured by the platform */
if (pdata->configure_phy)
@@ -1251,15 +1263,16 @@ static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi, void *data)
dw_hdmi_phy_power_off(hdmi);
}
-static enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi,
- void *data)
+enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi,
+ void *data)
{
return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
connector_status_connected : connector_status_disconnected;
}
+EXPORT_SYMBOL_GPL(dw_hdmi_phy_read_hpd);
-static void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data,
- bool force, bool disabled, bool rxsense)
+void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data,
+ bool force, bool disabled, bool rxsense)
{
u8 old_mask = hdmi->phy_mask;
@@ -1271,8 +1284,9 @@ static void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data,
if (old_mask != hdmi->phy_mask)
hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0);
}
+EXPORT_SYMBOL_GPL(dw_hdmi_phy_update_hpd);
-static void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi, void *data)
+void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi, void *data)
{
/*
* Configure the PHY RX SENSE and HPD interrupts polarities and clear
@@ -1291,6 +1305,7 @@ static void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi, void *data)
hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE),
HDMI_IH_MUTE_PHY_STAT0);
}
+EXPORT_SYMBOL_GPL(dw_hdmi_phy_setup_hpd);
static const struct dw_hdmi_phy_ops dw_hdmi_synopsys_phy_ops = {
.init = dw_hdmi_phy_init,
@@ -1634,9 +1649,12 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
* then write one of the FC registers several times.
*
* The number of iterations matters and depends on the HDMI TX revision
- * (and possibly on the platform). So far only i.MX6Q (v1.30a) and
- * i.MX6DL (v1.31a) have been identified as needing the workaround, with
- * 4 and 1 iterations respectively.
+ * (and possibly on the platform). So far i.MX6Q (v1.30a), i.MX6DL
+ * (v1.31a) and multiple Allwinner SoCs (v1.32a) have been identified
+ * as needing the workaround, with 4 iterations for v1.30a and 1
+ * iteration for others.
+ * The Amlogic Meson GX SoCs (v2.01a) have been identified as needing
+ * the workaround with a single iteration.
*/
switch (hdmi->version) {
@@ -1644,6 +1662,8 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
count = 4;
break;
case 0x131a:
+ case 0x132a:
+ case 0x201a:
count = 1;
break;
default:
@@ -1658,12 +1678,6 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF);
}
-static void hdmi_enable_overflow_interrupts(struct dw_hdmi *hdmi)
-{
- hdmi_writeb(hdmi, 0, HDMI_FC_MASK2);
- hdmi_writeb(hdmi, 0, HDMI_IH_MUTE_FC_STAT2);
-}
-
static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi)
{
hdmi_writeb(hdmi, HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK,
@@ -1753,8 +1767,6 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
hdmi_tx_hdcp_config(hdmi);
dw_hdmi_clear_overflow(hdmi);
- if (hdmi->cable_plugin && hdmi->sink_is_hdmi)
- hdmi_enable_overflow_interrupts(hdmi);
return 0;
}
@@ -2525,8 +2537,6 @@ __dw_hdmi_probe(struct platform_device *pdev,
if (hdmi->i2c)
dw_hdmi_i2c_init(hdmi);
- platform_set_drvdata(pdev, hdmi);
-
return hdmi;
err_iahb:
@@ -2576,25 +2586,23 @@ static void __dw_hdmi_remove(struct dw_hdmi *hdmi)
/* -----------------------------------------------------------------------------
* Probe/remove API, used from platforms based on the DRM bridge API.
*/
-int dw_hdmi_probe(struct platform_device *pdev,
- const struct dw_hdmi_plat_data *plat_data)
+struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
+ const struct dw_hdmi_plat_data *plat_data)
{
struct dw_hdmi *hdmi;
hdmi = __dw_hdmi_probe(pdev, plat_data);
if (IS_ERR(hdmi))
- return PTR_ERR(hdmi);
+ return hdmi;
drm_bridge_add(&hdmi->bridge);
- return 0;
+ return hdmi;
}
EXPORT_SYMBOL_GPL(dw_hdmi_probe);
-void dw_hdmi_remove(struct platform_device *pdev)
+void dw_hdmi_remove(struct dw_hdmi *hdmi)
{
- struct dw_hdmi *hdmi = platform_get_drvdata(pdev);
-
drm_bridge_remove(&hdmi->bridge);
__dw_hdmi_remove(hdmi);
@@ -2604,31 +2612,30 @@ EXPORT_SYMBOL_GPL(dw_hdmi_remove);
/* -----------------------------------------------------------------------------
* Bind/unbind API, used from platforms based on the component framework.
*/
-int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
- const struct dw_hdmi_plat_data *plat_data)
+struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev,
+ struct drm_encoder *encoder,
+ const struct dw_hdmi_plat_data *plat_data)
{
struct dw_hdmi *hdmi;
int ret;
hdmi = __dw_hdmi_probe(pdev, plat_data);
if (IS_ERR(hdmi))
- return PTR_ERR(hdmi);
+ return hdmi;
ret = drm_bridge_attach(encoder, &hdmi->bridge, NULL);
if (ret) {
- dw_hdmi_remove(pdev);
+ dw_hdmi_remove(hdmi);
DRM_ERROR("Failed to initialize bridge with drm\n");
- return ret;
+ return ERR_PTR(ret);
}
- return 0;
+ return hdmi;
}
EXPORT_SYMBOL_GPL(dw_hdmi_bind);
-void dw_hdmi_unbind(struct device *dev)
+void dw_hdmi_unbind(struct dw_hdmi *hdmi)
{
- struct dw_hdmi *hdmi = dev_get_drvdata(dev);
-
__dw_hdmi_remove(hdmi);
}
EXPORT_SYMBOL_GPL(dw_hdmi_unbind);
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index d9cca4fd66ec..226171a3ece1 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -29,7 +29,10 @@
#include <drm/bridge/dw_mipi_dsi.h>
#include <video/mipi_display.h>
+#define HWVER_131 0x31333100 /* IP version 1.31 */
+
#define DSI_VERSION 0x00
+#define VERSION GENMASK(31, 8)
#define DSI_PWR_UP 0x04
#define RESET 0
@@ -136,10 +139,6 @@
GEN_SW_0P_TX_LP)
#define DSI_GEN_HDR 0x6c
-/* TODO These 2 defines will be reworked thanks to mipi_dsi_create_packet() */
-#define GEN_HDATA(data) (((data) & 0xffff) << 8)
-#define GEN_HTYPE(type) (((type) & 0xff) << 0)
-
#define DSI_GEN_PLD_DATA 0x70
#define DSI_CMD_PKT_STATUS 0x74
@@ -169,11 +168,12 @@
#define PHY_CLKHS2LP_TIME(lbcc) (((lbcc) & 0x3ff) << 16)
#define PHY_CLKLP2HS_TIME(lbcc) ((lbcc) & 0x3ff)
-/* TODO Next register is slightly different between 1.30 & 1.31 IP version */
#define DSI_PHY_TMR_CFG 0x9c
#define PHY_HS2LP_TIME(lbcc) (((lbcc) & 0xff) << 24)
#define PHY_LP2HS_TIME(lbcc) (((lbcc) & 0xff) << 16)
#define MAX_RD_TIME(lbcc) ((lbcc) & 0x7fff)
+#define PHY_HS2LP_TIME_V131(lbcc) (((lbcc) & 0x3ff) << 16)
+#define PHY_LP2HS_TIME_V131(lbcc) ((lbcc) & 0x3ff)
#define DSI_PHY_RSTZ 0xa0
#define PHY_DISFORCEPLL 0
@@ -212,7 +212,9 @@
#define DSI_INT_ST1 0xc0
#define DSI_INT_MSK0 0xc4
#define DSI_INT_MSK1 0xc8
+
#define DSI_PHY_TMR_RD_CFG 0xf4
+#define MAX_RD_TIME_V131(lbcc) ((lbcc) & 0x7fff)
#define PHY_STATUS_TIMEOUT_US 10000
#define CMD_PKT_STATUS_TIMEOUT_US 20000
@@ -340,7 +342,7 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)
ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
val, !(val & GEN_CMD_FULL), 1000,
CMD_PKT_STATUS_TIMEOUT_US);
- if (ret < 0) {
+ if (ret) {
dev_err(dsi->dev, "failed to get available command FIFO\n");
return ret;
}
@@ -351,7 +353,7 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)
ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
val, (val & mask) == mask,
1000, CMD_PKT_STATUS_TIMEOUT_US);
- if (ret < 0) {
+ if (ret) {
dev_err(dsi->dev, "failed to write command FIFO\n");
return ret;
}
@@ -359,52 +361,23 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)
return 0;
}
-static int dw_mipi_dsi_dcs_short_write(struct dw_mipi_dsi *dsi,
- const struct mipi_dsi_msg *msg)
+static int dw_mipi_dsi_write(struct dw_mipi_dsi *dsi,
+ const struct mipi_dsi_packet *packet)
{
- const u8 *tx_buf = msg->tx_buf;
- u16 data = 0;
+ const u8 *tx_buf = packet->payload;
+ int len = packet->payload_length, pld_data_bytes = sizeof(u32), ret;
+ __le32 word;
u32 val;
- if (msg->tx_len > 0)
- data |= tx_buf[0];
- if (msg->tx_len > 1)
- data |= tx_buf[1] << 8;
-
- if (msg->tx_len > 2) {
- dev_err(dsi->dev, "too long tx buf length %zu for short write\n",
- msg->tx_len);
- return -EINVAL;
- }
-
- val = GEN_HDATA(data) | GEN_HTYPE(msg->type);
- return dw_mipi_dsi_gen_pkt_hdr_write(dsi, val);
-}
-
-static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,
- const struct mipi_dsi_msg *msg)
-{
- const u8 *tx_buf = msg->tx_buf;
- int len = msg->tx_len, pld_data_bytes = sizeof(u32), ret;
- u32 hdr_val = GEN_HDATA(msg->tx_len) | GEN_HTYPE(msg->type);
- u32 remainder;
- u32 val;
-
- if (msg->tx_len < 3) {
- dev_err(dsi->dev, "wrong tx buf length %zu for long write\n",
- msg->tx_len);
- return -EINVAL;
- }
-
- while (DIV_ROUND_UP(len, pld_data_bytes)) {
+ while (len) {
if (len < pld_data_bytes) {
- remainder = 0;
- memcpy(&remainder, tx_buf, len);
- dsi_write(dsi, DSI_GEN_PLD_DATA, remainder);
+ word = 0;
+ memcpy(&word, tx_buf, len);
+ dsi_write(dsi, DSI_GEN_PLD_DATA, le32_to_cpu(word));
len = 0;
} else {
- memcpy(&remainder, tx_buf, pld_data_bytes);
- dsi_write(dsi, DSI_GEN_PLD_DATA, remainder);
+ memcpy(&word, tx_buf, pld_data_bytes);
+ dsi_write(dsi, DSI_GEN_PLD_DATA, le32_to_cpu(word));
tx_buf += pld_data_bytes;
len -= pld_data_bytes;
}
@@ -412,47 +385,81 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,
ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
val, !(val & GEN_PLD_W_FULL), 1000,
CMD_PKT_STATUS_TIMEOUT_US);
- if (ret < 0) {
+ if (ret) {
dev_err(dsi->dev,
"failed to get available write payload FIFO\n");
return ret;
}
}
- return dw_mipi_dsi_gen_pkt_hdr_write(dsi, hdr_val);
+ word = 0;
+ memcpy(&word, packet->header, sizeof(packet->header));
+ return dw_mipi_dsi_gen_pkt_hdr_write(dsi, le32_to_cpu(word));
+}
+
+static int dw_mipi_dsi_read(struct dw_mipi_dsi *dsi,
+ const struct mipi_dsi_msg *msg)
+{
+ int i, j, ret, len = msg->rx_len;
+ u8 *buf = msg->rx_buf;
+ u32 val;
+
+ /* Wait end of the read operation */
+ ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
+ val, !(val & GEN_RD_CMD_BUSY),
+ 1000, CMD_PKT_STATUS_TIMEOUT_US);
+ if (ret) {
+ dev_err(dsi->dev, "Timeout during read operation\n");
+ return ret;
+ }
+
+ for (i = 0; i < len; i += 4) {
+ /* Read fifo must not be empty before all bytes are read */
+ ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
+ val, !(val & GEN_PLD_R_EMPTY),
+ 1000, CMD_PKT_STATUS_TIMEOUT_US);
+ if (ret) {
+ dev_err(dsi->dev, "Read payload FIFO is empty\n");
+ return ret;
+ }
+
+ val = dsi_read(dsi, DSI_GEN_PLD_DATA);
+ for (j = 0; j < 4 && j + i < len; j++)
+ buf[i + j] = val >> (8 * j);
+ }
+
+ return ret;
}
static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host,
const struct mipi_dsi_msg *msg)
{
struct dw_mipi_dsi *dsi = host_to_dsi(host);
- int ret;
+ struct mipi_dsi_packet packet;
+ int ret, nb_bytes;
+
+ ret = mipi_dsi_create_packet(&packet, msg);
+ if (ret) {
+ dev_err(dsi->dev, "failed to create packet: %d\n", ret);
+ return ret;
+ }
- /*
- * TODO dw drv improvements
- * use mipi_dsi_create_packet() instead of all following
- * functions and code (no switch cases, no
- * dw_mipi_dsi_dcs_short_write(), only the loop in long_write...)
- * and use packet.header...
- */
dw_mipi_message_config(dsi, msg);
- switch (msg->type) {
- case MIPI_DSI_DCS_SHORT_WRITE:
- case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
- case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
- ret = dw_mipi_dsi_dcs_short_write(dsi, msg);
- break;
- case MIPI_DSI_DCS_LONG_WRITE:
- ret = dw_mipi_dsi_dcs_long_write(dsi, msg);
- break;
- default:
- dev_err(dsi->dev, "unsupported message type 0x%02x\n",
- msg->type);
- ret = -EINVAL;
+ ret = dw_mipi_dsi_write(dsi, &packet);
+ if (ret)
+ return ret;
+
+ if (msg->rx_buf && msg->rx_len) {
+ ret = dw_mipi_dsi_read(dsi, msg);
+ if (ret)
+ return ret;
+ nb_bytes = msg->rx_len;
+ } else {
+ nb_bytes = packet.size;
}
- return ret;
+ return nb_bytes;
}
static const struct mipi_dsi_host_ops dw_mipi_dsi_host_ops = {
@@ -658,6 +665,8 @@ static void dw_mipi_dsi_vertical_timing_config(struct dw_mipi_dsi *dsi,
static void dw_mipi_dsi_dphy_timing_config(struct dw_mipi_dsi *dsi)
{
+ u32 hw_version;
+
/*
* TODO dw drv improvements
* data & clock lane timers should be computed according to panel
@@ -665,8 +674,17 @@ static void dw_mipi_dsi_dphy_timing_config(struct dw_mipi_dsi *dsi)
* note: DSI_PHY_TMR_CFG.MAX_RD_TIME should be in line with
* DSI_CMD_MODE_CFG.MAX_RD_PKT_SIZE_LP (see CMD_MODE_ALL_LP)
*/
- dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME(0x40)
- | PHY_LP2HS_TIME(0x40) | MAX_RD_TIME(10000));
+
+ hw_version = dsi_read(dsi, DSI_VERSION) & VERSION;
+
+ if (hw_version >= HWVER_131) {
+ dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME_V131(0x40) |
+ PHY_LP2HS_TIME_V131(0x40));
+ dsi_write(dsi, DSI_PHY_TMR_RD_CFG, MAX_RD_TIME_V131(10000));
+ } else {
+ dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME(0x40) |
+ PHY_LP2HS_TIME(0x40) | MAX_RD_TIME(10000));
+ }
dsi_write(dsi, DSI_PHY_TMR_LPCLK_CFG, PHY_CLKHS2LP_TIME(0x40)
| PHY_CLKLP2HS_TIME(0x40));
@@ -703,13 +721,13 @@ static void dw_mipi_dsi_dphy_enable(struct dw_mipi_dsi *dsi)
ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS, val,
val & PHY_LOCK, 1000, PHY_STATUS_TIMEOUT_US);
- if (ret < 0)
+ if (ret)
DRM_DEBUG_DRIVER("failed to wait phy lock state\n");
ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS,
val, val & PHY_STOP_STATE_CLK_LANE, 1000,
PHY_STATUS_TIMEOUT_US);
- if (ret < 0)
+ if (ret)
DRM_DEBUG_DRIVER("failed to wait phy clk lane stop state\n");
}
@@ -746,9 +764,9 @@ static void dw_mipi_dsi_bridge_post_disable(struct drm_bridge *bridge)
pm_runtime_put(dsi->dev);
}
-void dw_mipi_dsi_bridge_mode_set(struct drm_bridge *bridge,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
+static void dw_mipi_dsi_bridge_mode_set(struct drm_bridge *bridge,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
{
struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
const struct dw_mipi_dsi_phy_ops *phy_ops = dsi->plat_data->phy_ops;
@@ -922,8 +940,6 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
dsi->bridge.of_node = pdev->dev.of_node;
#endif
- dev_set_drvdata(dev, dsi);
-
return dsi;
}
@@ -935,23 +951,16 @@ static void __dw_mipi_dsi_remove(struct dw_mipi_dsi *dsi)
/*
* Probe/remove API, used from platforms based on the DRM bridge API.
*/
-int dw_mipi_dsi_probe(struct platform_device *pdev,
- const struct dw_mipi_dsi_plat_data *plat_data)
+struct dw_mipi_dsi *
+dw_mipi_dsi_probe(struct platform_device *pdev,
+ const struct dw_mipi_dsi_plat_data *plat_data)
{
- struct dw_mipi_dsi *dsi;
-
- dsi = __dw_mipi_dsi_probe(pdev, plat_data);
- if (IS_ERR(dsi))
- return PTR_ERR(dsi);
-
- return 0;
+ return __dw_mipi_dsi_probe(pdev, plat_data);
}
EXPORT_SYMBOL_GPL(dw_mipi_dsi_probe);
-void dw_mipi_dsi_remove(struct platform_device *pdev)
+void dw_mipi_dsi_remove(struct dw_mipi_dsi *dsi)
{
- struct dw_mipi_dsi *dsi = platform_get_drvdata(pdev);
-
mipi_dsi_host_unregister(&dsi->dsi_host);
__dw_mipi_dsi_remove(dsi);
@@ -961,31 +970,30 @@ EXPORT_SYMBOL_GPL(dw_mipi_dsi_remove);
/*
* Bind/unbind API, used from platforms based on the component framework.
*/
-int dw_mipi_dsi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
- const struct dw_mipi_dsi_plat_data *plat_data)
+struct dw_mipi_dsi *
+dw_mipi_dsi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
+ const struct dw_mipi_dsi_plat_data *plat_data)
{
struct dw_mipi_dsi *dsi;
int ret;
dsi = __dw_mipi_dsi_probe(pdev, plat_data);
if (IS_ERR(dsi))
- return PTR_ERR(dsi);
+ return dsi;
ret = drm_bridge_attach(encoder, &dsi->bridge, NULL);
if (ret) {
- dw_mipi_dsi_remove(pdev);
+ dw_mipi_dsi_remove(dsi);
DRM_ERROR("Failed to initialize bridge with drm\n");
- return ret;
+ return ERR_PTR(ret);
}
- return 0;
+ return dsi;
}
EXPORT_SYMBOL_GPL(dw_mipi_dsi_bind);
-void dw_mipi_dsi_unbind(struct device *dev)
+void dw_mipi_dsi_unbind(struct dw_mipi_dsi *dsi)
{
- struct dw_mipi_dsi *dsi = dev_get_drvdata(dev);
-
__dw_mipi_dsi_remove(dsi);
}
EXPORT_SYMBOL_GPL(dw_mipi_dsi_unbind);
OpenPOWER on IntegriCloud