Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ struct dw_mipi_dsi {
} vpg_defs;
#endif /* CONFIG_DEBUG_FS */

struct dw_mipi_dsi *dsi0;
struct dw_mipi_dsi *master; /* dual-dsi master ptr */
struct dw_mipi_dsi *slave; /* dual-dsi slave ptr */

Expand Down Expand Up @@ -408,6 +409,7 @@ static void dw_mipi_message_config(struct dw_mipi_dsi *dsi,
ctrl |= PHY_TXREQUESTCLKHS;
}

ctrl |= PHY_TXREQUESTCLKHS;
dsi_write(dsi, DSI_VID_MODE_CFG, val);
dsi_write(dsi, DSI_LPCLK_CTRL, ctrl);
}
Expand Down Expand Up @@ -586,6 +588,7 @@ static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi)
static void dw_mipi_dsi_set_mode(struct dw_mipi_dsi *dsi,
unsigned long mode_flags)
{
u32 val = 0;
dsi_write(dsi, DSI_PWR_UP, RESET);

if (mode_flags & MIPI_DSI_MODE_VIDEO) {
Expand All @@ -595,6 +598,15 @@ static void dw_mipi_dsi_set_mode(struct dw_mipi_dsi *dsi,
dsi_write(dsi, DSI_MODE_CFG, ENABLE_CMD_MODE);
}

/* The high-speed clock is started before that the
* high-speed data is sent via the data lanes.
*/
val = dsi_read(dsi, DSI_LPCLK_CTRL);
if(((val & PHY_TXREQUESTCLKHS) != PHY_TXREQUESTCLKHS)
&& (mode_flags & MIPI_DSI_MODE_VIDEO))
val |= PHY_TXREQUESTCLKHS;
val |= PHY_TXREQUESTCLKHS;

dsi_write(dsi, DSI_PWR_UP, POWERUP);
}

Expand All @@ -605,6 +617,8 @@ static void dw_mipi_dsi_disable(struct dw_mipi_dsi *dsi)
dw_mipi_dsi_set_mode(dsi, 0);
if (dsi->slave)
dw_mipi_dsi_disable(dsi->slave);
if (dsi->dsi0)
dw_mipi_dsi_disable(dsi->dsi0);
}

static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi)
Expand Down Expand Up @@ -871,6 +885,8 @@ static void dw_mipi_dsi_post_disable(struct dw_mipi_dsi *dsi)

if (dsi->slave)
dw_mipi_dsi_post_disable(dsi->slave);
if (dsi->dsi0)
dw_mipi_dsi_set_mode(dsi->dsi0, 0);
}

static void dw_mipi_dsi_bridge_post_atomic_disable(struct drm_bridge *bridge,
Expand Down Expand Up @@ -927,6 +943,8 @@ static void dw_mipi_dsi_bridge_mode_set(struct drm_bridge *bridge,

if (dsi->slave)
drm_mode_copy(&dsi->slave->mode, adjusted_mode);
if (dsi->dsi0)
drm_mode_copy(&dsi->dsi0->mode, adjusted_mode);
}

static void dw_mipi_dsi_pre_enable(struct dw_mipi_dsi *dsi)
Expand All @@ -937,6 +955,8 @@ static void dw_mipi_dsi_pre_enable(struct dw_mipi_dsi *dsi)
int ret;
u32 lanes = dw_mipi_dsi_get_lanes(dsi);

if (dsi->dsi0)
dw_mipi_dsi_pre_enable(dsi->dsi0);
if (dsi->apb_rst) {
reset_control_assert(dsi->apb_rst);
usleep_range(10, 20);
Expand Down Expand Up @@ -1002,6 +1022,8 @@ static void dw_mipi_dsi_enable(struct dw_mipi_dsi *dsi)
u32 val;

val = PHY_TXREQUESTCLKHS;
if (dsi->dsi0)
dw_mipi_dsi_enable(dsi->dsi0);
if (dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)
val |= AUTO_CLKLANE_CTRL;

Expand Down Expand Up @@ -1264,6 +1286,19 @@ void dw_mipi_dsi_set_slave(struct dw_mipi_dsi *dsi, struct dw_mipi_dsi *slave)
}
EXPORT_SYMBOL_GPL(dw_mipi_dsi_set_slave);

void dw_mipi_dsi_set_dsi0(struct dw_mipi_dsi *dsi, struct dw_mipi_dsi *dsi0)
{
/* introduce controllers to each other */
dsi->dsi0 = dsi0;

/* migrate settings for already attached displays */
dsi->dsi0->lanes = dsi->lanes;
dsi->dsi0->channel = dsi->channel;
dsi->dsi0->format = dsi->format;
dsi->dsi0->mode_flags = dsi->mode_flags;
}
EXPORT_SYMBOL_GPL(dw_mipi_dsi_set_dsi0);

/*
* Probe/remove API, used from platforms based on the DRM bridge API.
*/
Expand Down
53 changes: 53 additions & 0 deletions drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,8 @@ struct dw_mipi_dsi_rockchip {

/* dual-channel */
bool is_slave;
bool is_dsi0;
struct dw_mipi_dsi_rockchip *dsi0;
struct dw_mipi_dsi_rockchip *slave;
bool data_swap;

Expand Down Expand Up @@ -883,6 +885,9 @@ static void dw_mipi_dsi_encoder_disable(struct drm_encoder *encoder)

static void dw_mipi_dsi_rockchip_loader_protect(struct dw_mipi_dsi_rockchip *dsi, bool on)
{
if (dsi->dsi0)
dw_mipi_dsi_rockchip_loader_protect(dsi->dsi0, on);

if (on) {
pm_runtime_get_sync(dsi->dev);
phy_init(dsi->phy);
Expand Down Expand Up @@ -986,6 +991,31 @@ static struct device
return NULL;
}

static struct device
*dw_mipi_dsi_rockchip_find_dsi0(struct dw_mipi_dsi_rockchip *dsi)
{
struct device_node *node = NULL;
struct platform_device *pdev;
struct dw_mipi_dsi_rockchip *dsi2;

node = of_parse_phandle(dsi->dev->of_node, "rockchip,dsi-dsi0", 0);
if (node) {
pdev = of_find_device_by_node(node);
if (!pdev)
return ERR_PTR(-EPROBE_DEFER);

dsi2 = platform_get_drvdata(pdev);
if (!dsi2) {
platform_device_put(pdev);
return ERR_PTR(-EPROBE_DEFER);
}

return &pdev->dev;
}

return NULL;
}

static int dw_mipi_dsi_get_dsc_info_from_sink(struct dw_mipi_dsi_rockchip *dsi,
struct drm_panel *panel,
struct drm_bridge *bridge)
Expand Down Expand Up @@ -1075,6 +1105,27 @@ static int dw_mipi_dsi_rockchip_bind(struct device *dev,
dw_mipi_dsi_set_slave(dsi->dmd, dsi->slave->dmd);
put_device(second);
}
if(!second){
second = dw_mipi_dsi_rockchip_find_dsi0(dsi);
if (IS_ERR(second))
return PTR_ERR(second);

if (second) {
/* we are the slave in dual-DSI */
dsi->dsi0 = dev_get_drvdata(second);
if (!dsi->dsi0) {
DRM_DEV_ERROR(dev, "could not get dsi0 data\n");
return -ENODEV;
}

dsi->dsi0->is_dsi0 = true;
dw_mipi_dsi_set_dsi0(dsi->dmd, dsi->dsi0->dmd);
put_device(second);
} else
dsi->is_dsi0 = of_property_read_bool(dev->of_node, "dsi1-only");
}
if (dsi->is_dsi0)
return 0;

if (dsi->is_slave)
return 0;
Expand Down Expand Up @@ -1123,6 +1174,8 @@ static void dw_mipi_dsi_rockchip_unbind(struct device *dev,
{
struct dw_mipi_dsi_rockchip *dsi = dev_get_drvdata(dev);

if (dsi->is_dsi0)
return;
if (dsi->is_slave)
return;

Expand Down
1 change: 1 addition & 0 deletions include/drm/bridge/dw_mipi_dsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ void dw_mipi_dsi_remove(struct dw_mipi_dsi *dsi);
int dw_mipi_dsi_bind(struct dw_mipi_dsi *dsi, struct drm_encoder *encoder);
void dw_mipi_dsi_unbind(struct dw_mipi_dsi *dsi);
void dw_mipi_dsi_set_slave(struct dw_mipi_dsi *dsi, struct dw_mipi_dsi *slave);
void dw_mipi_dsi_set_dsi0(struct dw_mipi_dsi *dsi, struct dw_mipi_dsi *slave);
struct drm_connector *dw_mipi_dsi_get_connector(struct dw_mipi_dsi *dsi);

#endif /* __DW_MIPI_DSI__ */