Skip to content
Snippets Groups Projects
Commit d716c48f authored by Liu Ying's avatar Liu Ying Committed by Leonard Crestez
Browse files

MLK-16015-6 drm/imx: ldb: Add pixel link validate/invalidate logics


To enable or disable a display safely, we need to validate pixel link
after the relevant ldb channel is enabled and invalidate pixel link
before the channel is disabled.  These operations are recommended
by the design team.

Signed-off-by: default avatarLiu Ying <victor.liu@nxp.com>
(cherry picked from commit 5fab9a74)
parent 1836cd48
No related merge requests found
...@@ -115,6 +115,7 @@ struct devtype { ...@@ -115,6 +115,7 @@ struct devtype {
bool use_mixel_combo_phy; bool use_mixel_combo_phy;
bool padding_quirks; bool padding_quirks;
bool pixel_link_init_quirks; bool pixel_link_init_quirks;
bool pixel_link_valid_quirks;
/* pixel rate in KHz */ /* pixel rate in KHz */
unsigned int max_prate_single_mode; unsigned int max_prate_single_mode;
...@@ -143,6 +144,7 @@ struct imx_ldb { ...@@ -143,6 +144,7 @@ struct imx_ldb {
bool use_mixel_combo_phy; bool use_mixel_combo_phy;
bool padding_quirks; bool padding_quirks;
bool pixel_link_init_quirks; bool pixel_link_init_quirks;
bool pixel_link_valid_quirks;
/* pixel rate in KHz */ /* pixel rate in KHz */
unsigned int max_prate_single_mode; unsigned int max_prate_single_mode;
...@@ -277,6 +279,100 @@ static void imx_ldb_set_clock(struct imx_ldb *ldb, int mux, int chno, ...@@ -277,6 +279,100 @@ static void imx_ldb_set_clock(struct imx_ldb *ldb, int mux, int chno,
chno); chno);
} }
#ifndef CONFIG_HAVE_IMX8_SOC
static void dpu_pixel_link_validate(int dpu_id, int stream_id) {}
static void dpu_pixel_link_invalidate(int dpu_id, int stream_id) {}
#else
/* FIXME: validate pixel link in a proper manner */
static void dpu_pixel_link_validate(int dpu_id, int stream_id)
{
sc_err_t sciErr;
sc_ipc_t ipcHndl = 0;
u32 mu_id;
sciErr = sc_ipc_getMuID(&mu_id);
if (sciErr != SC_ERR_NONE) {
pr_err("Cannot obtain MU ID\n");
return;
}
sciErr = sc_ipc_open(&ipcHndl, mu_id);
if (sciErr != SC_ERR_NONE) {
pr_err("sc_ipc_open failed! (sciError = %d)\n", sciErr);
return;
}
if (dpu_id == 0) {
sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_0,
stream_id ? SC_C_PXL_LINK_MST2_VLD : SC_C_PXL_LINK_MST1_VLD, 1);
if (sciErr != SC_ERR_NONE)
pr_err("SC_R_DC_0:SC_C_PXL_LINK_MST%d_VLD sc_misc_set_control failed! (sciError = %d)\n", stream_id + 1, sciErr);
sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_0,
stream_id ? SC_C_SYNC_CTRL1 : SC_C_SYNC_CTRL0, 1);
if (sciErr != SC_ERR_NONE)
pr_err("SC_R_DC_0:SC_C_SYNC_CTRL%d sc_misc_set_control failed! (sciError = %d)\n", stream_id, sciErr);
} else if (dpu_id == 1) {
sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_1,
stream_id ? SC_C_PXL_LINK_MST2_VLD : SC_C_PXL_LINK_MST1_VLD, 1);
if (sciErr != SC_ERR_NONE)
pr_err("SC_R_DC_1:SC_C_PXL_LINK_MST%d_VLD sc_misc_set_control failed! (sciError = %d)\n", stream_id + 1, sciErr);
sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_1,
stream_id ? SC_C_SYNC_CTRL1 : SC_C_SYNC_CTRL0, 1);
if (sciErr != SC_ERR_NONE)
pr_err("SC_R_DC_1:SC_C_SYNC_CTRL%d sc_misc_set_control failed! (sciError = %d)\n", stream_id, sciErr);
}
sc_ipc_close(mu_id);
}
/* FIXME: invalidate pixel link in a proper manner */
static void dpu_pixel_link_invalidate(int dpu_id, int stream_id)
{
sc_err_t sciErr;
sc_ipc_t ipcHndl = 0;
u32 mu_id;
sciErr = sc_ipc_getMuID(&mu_id);
if (sciErr != SC_ERR_NONE) {
pr_err("Cannot obtain MU ID\n");
return;
}
sciErr = sc_ipc_open(&ipcHndl, mu_id);
if (sciErr != SC_ERR_NONE) {
pr_err("sc_ipc_open failed! (sciError = %d)\n", sciErr);
return;
}
if (dpu_id == 0) {
sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_0,
stream_id ? SC_C_SYNC_CTRL1 : SC_C_SYNC_CTRL0, 0);
if (sciErr != SC_ERR_NONE)
pr_err("SC_R_DC_0:SC_C_SYNC_CTRL%d sc_misc_set_control failed! (sciError = %d)\n", stream_id, sciErr);
sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_0,
stream_id ? SC_C_PXL_LINK_MST2_VLD : SC_C_PXL_LINK_MST1_VLD, 0);
if (sciErr != SC_ERR_NONE)
pr_err("SC_R_DC_0:SC_C_PXL_LINK_MST%d_VLD sc_misc_set_control failed! (sciError = %d)\n", stream_id + 1, sciErr);
} else if (dpu_id == 1) {
sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_1,
stream_id ? SC_C_SYNC_CTRL1 : SC_C_SYNC_CTRL0, 0);
if (sciErr != SC_ERR_NONE)
pr_err("SC_R_DC_1:SC_C_SYNC_CTRL%d sc_misc_set_control failed! (sciError = %d)\n", stream_id, sciErr);
sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_1,
stream_id ? SC_C_PXL_LINK_MST2_VLD : SC_C_PXL_LINK_MST1_VLD, 0);
if (sciErr != SC_ERR_NONE)
pr_err("SC_R_DC_1:SC_C_PXL_LINK_MST%d_VLD sc_misc_set_control failed! (sciError = %d)\n", stream_id + 1, sciErr);
}
sc_ipc_close(mu_id);
}
#endif
static void imx_ldb_encoder_enable(struct drm_encoder *encoder) static void imx_ldb_encoder_enable(struct drm_encoder *encoder)
{ {
struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
...@@ -345,6 +441,13 @@ static void imx_ldb_encoder_enable(struct drm_encoder *encoder) ...@@ -345,6 +441,13 @@ static void imx_ldb_encoder_enable(struct drm_encoder *encoder)
imx_ldb_ch->phy_is_on = true; imx_ldb_ch->phy_is_on = true;
} }
if (ldb->pixel_link_valid_quirks) {
if (ldb->use_mixel_phy)
dpu_pixel_link_validate(ldb->id, 1);
else if (ldb->use_mixel_combo_phy)
dpu_pixel_link_validate(0, ldb->id);
}
drm_panel_enable(imx_ldb_ch->panel); drm_panel_enable(imx_ldb_ch->panel);
} }
...@@ -519,6 +622,13 @@ static void imx_ldb_encoder_disable(struct drm_encoder *encoder) ...@@ -519,6 +622,13 @@ static void imx_ldb_encoder_disable(struct drm_encoder *encoder)
drm_panel_disable(imx_ldb_ch->panel); drm_panel_disable(imx_ldb_ch->panel);
if (ldb->pixel_link_valid_quirks) {
if (ldb->use_mixel_phy)
dpu_pixel_link_invalidate(ldb->id, 1);
else if (ldb->use_mixel_combo_phy)
dpu_pixel_link_invalidate(0, ldb->id);
}
if (dual) { if (dual) {
phy_power_off(ldb->channel[0].phy); phy_power_off(ldb->channel[0].phy);
phy_power_off(ldb->channel[1].phy); phy_power_off(ldb->channel[1].phy);
...@@ -813,6 +923,7 @@ static struct devtype imx8qm_ldb_devtype = { ...@@ -813,6 +923,7 @@ static struct devtype imx8qm_ldb_devtype = {
.is_imx8 = true, .is_imx8 = true,
.use_mixel_phy = true, .use_mixel_phy = true,
.padding_quirks = true, .padding_quirks = true,
.pixel_link_valid_quirks = true,
.max_prate_single_mode = 150000, .max_prate_single_mode = 150000,
.max_prate_dual_mode = 300000, .max_prate_dual_mode = 300000,
}; };
...@@ -826,6 +937,7 @@ static struct devtype imx8qxp_ldb_devtype = { ...@@ -826,6 +937,7 @@ static struct devtype imx8qxp_ldb_devtype = {
.use_mixel_combo_phy = true, .use_mixel_combo_phy = true,
.padding_quirks = true, .padding_quirks = true,
.pixel_link_init_quirks = true, .pixel_link_init_quirks = true,
.pixel_link_valid_quirks = true,
.max_prate_single_mode = 150000, .max_prate_single_mode = 150000,
.max_prate_dual_mode = 300000, .max_prate_dual_mode = 300000,
}; };
...@@ -968,6 +1080,7 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) ...@@ -968,6 +1080,7 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
imx_ldb->use_mixel_combo_phy = devtype->use_mixel_combo_phy; imx_ldb->use_mixel_combo_phy = devtype->use_mixel_combo_phy;
imx_ldb->padding_quirks = devtype->padding_quirks; imx_ldb->padding_quirks = devtype->padding_quirks;
imx_ldb->pixel_link_init_quirks = devtype->pixel_link_init_quirks; imx_ldb->pixel_link_init_quirks = devtype->pixel_link_init_quirks;
imx_ldb->pixel_link_valid_quirks = devtype->pixel_link_valid_quirks;
imx_ldb->max_prate_single_mode = devtype->max_prate_single_mode; imx_ldb->max_prate_single_mode = devtype->max_prate_single_mode;
imx_ldb->max_prate_dual_mode = devtype->max_prate_dual_mode; imx_ldb->max_prate_dual_mode = devtype->max_prate_dual_mode;
...@@ -1125,10 +1238,12 @@ get_phy: ...@@ -1125,10 +1238,12 @@ get_phy:
dev_set_drvdata(dev, imx_ldb); dev_set_drvdata(dev, imx_ldb);
if (imx_ldb->pixel_link_init_quirks) { if (imx_ldb->pixel_link_valid_quirks ||
imx_ldb->pixel_link_init_quirks)
imx_ldb->id = of_alias_get_id(np, "ldb"); imx_ldb->id = of_alias_get_id(np, "ldb");
if (imx_ldb->pixel_link_init_quirks)
ldb_pixel_link_init(imx_ldb->id); ldb_pixel_link_init(imx_ldb->id);
}
return 0; return 0;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment