Skip to content
This repository was archived by the owner on Apr 9, 2025. It is now read-only.
Open
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
181 changes: 137 additions & 44 deletions drivers/gpu/drm/bridge/ti/fpd_dp_ser_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ void fpd_dp_ser_set_up_variables(struct i2c_client *client)
fpd_dp_ser_write_reg(client, 0x70, FPD_DP_SER_RX_ADD_A);
fpd_dp_ser_write_reg(client, 0x78, FPD_DP_SER_RX_ADD_A);
fpd_dp_ser_write_reg(client, 0x88, 0x0);
fpd_dp_ser_write_reg(client, 0x3a, 0x88);
}

static void fpd_dp_ser_set_up_mcu(struct i2c_client *client)
Expand Down Expand Up @@ -463,7 +464,10 @@ int fpd_dp_ser_program_fpd_4_mode(struct i2c_client *client)
/* Disable FPD3 FIFO pass through */
fpd_dp_ser_write_reg(client, 0x5b, 0x23);
/* Force FPD4_TX single port 0 mode */
fpd_dp_ser_write_reg(client, 0x05,0x2c);
fpd_dp_ser_write_reg(client, 0x05, 0x2c);
fpd_dp_ser_write_reg(client, 0x01, 0x01);
msleep(30);

return 0;
}

Expand Down Expand Up @@ -556,13 +560,17 @@ int fpd_dp_set_fpd_4_983_pll(struct i2c_client *client)
fpd_dp_ser_write_reg(client, 0x42, 0x08);

/* Disable PLL1 */
fpd_dp_ser_write_reg(client, 0x40, 0x08);
fpd_dp_ser_write_reg(client, 0x41, 0x5b);
fpd_dp_ser_write_reg(client, 0x42, 0x08);

/* Enable mode overwrite*/
fpd_dp_ser_write_reg(client, 0x2, 0xd1);
fpd_dp_ser_write_reg(client, 0x2d, 0x1);

/* Select digital reg page */
fpd_dp_ser_write_reg(client, 0x42, 0x24);

/* Select PLL reg page */
fpd_dp_ser_write_reg(client, 0x40, 0x08);
/* Select Ncount Reg */
Expand Down Expand Up @@ -670,6 +678,9 @@ int fpd_dp_ser_configue_enable_983_plls(struct i2c_client *client)
fpd_dp_ser_debug("[FPD_DP] Configure and Enable PLLs\n");
fpd_dp_ser_debug("[FPD_DP] Set VCO\n");

/* Select PLL page */
fpd_dp_ser_write_reg(client, 0x40,0x08);

/* Select VCO reg */
fpd_dp_ser_write_reg(client, 0x41,0x0e);
/* Set VCO */
Expand All @@ -687,7 +698,7 @@ int fpd_dp_ser_configue_enable_983_plls(struct i2c_client *client)

/* soft reset Ser */
fpd_dp_ser_write_reg(client, 0x01,0x01);
msleep(40);
usleep_range(20000, 22000);

return 0;
}
Expand Down Expand Up @@ -720,8 +731,9 @@ int fpd_dp_deser_soft_983_reset(struct i2c_client *client)
{
u8 des_read = 0;

msleep(30);
fpd_dp_ser_write_reg(fpd_dp_priv->priv_dp_client[1], 0x01, 0x01);
msleep(50);
msleep(30);

/* Select write to port0 reg */
fpd_dp_ser_write_reg(fpd_dp_priv->priv_dp_client[0], 0x2d, 0x01);
Expand Down Expand Up @@ -1694,8 +1706,10 @@ int fpd_dp_deser_984_override_efuse(struct i2c_client *client)
fpd_dp_ser_write_reg(client, 0x41, 0x71);
fpd_dp_ser_write_reg(client, 0x42, 0x26);
/* Soft Reset DES */
/* Override DES 0 eFuse */
msleep(30);
fpd_dp_ser_write_reg(client, 0x1, 0x1);
msleep(50);
msleep(30);
}

return 0;
Expand Down Expand Up @@ -1890,6 +1904,12 @@ void fpd_dp_deser_984_enable_output(struct i2c_client *client)
fpd_dp_ser_write_reg(client, 0x4e, 0x0);
/* Enable INTB_IN */
fpd_dp_ser_write_reg(client, 0x44, 0x81);

/* i2c speed 400k */
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like that using 100k during initialization can impact cold boot time.

fpd_dp_ser_write_reg(fpd_dp_priv->priv_dp_client[0], 0x2b, 0x0a);
fpd_dp_ser_write_reg(fpd_dp_priv->priv_dp_client[0], 0x2c, 0x0b);
fpd_dp_ser_write_reg(fpd_dp_priv->priv_dp_client[1], 0x2b, 0x0a);
fpd_dp_ser_write_reg(fpd_dp_priv->priv_dp_client[1], 0x2c, 0x0b);
}

void fpd_dp_deser_984_enable(void)
Expand Down Expand Up @@ -2027,17 +2047,54 @@ static bool fpd_dp_ser_respond_dhu_startup_status(struct i2c_client *client)
return true;
}

static bool fpd_dp_ser_display_startup_reset(void)
{
unsigned char __iomem *gpio_cfg;
unsigned char data;

gpio_cfg = (unsigned char *)ioremap(PAD_CFG_DW0_GPPC_A_16, 0x1);
data = ioread8(gpio_cfg);
data = data & 0xFE;
iowrite8(data, gpio_cfg);
iounmap(gpio_cfg);
fpd_dp_ser_debug("[FPD_DP] gpio reset pull down 0x%02x reOK\n",
data);
/* Delay for VPs to sync to DP source */
msleep(500);

gpio_cfg = (unsigned char *)ioremap(PAD_CFG_DW0_GPPC_A_16, 0x1);
data = ioread8(gpio_cfg);
data = data | 1;
iowrite8(data, gpio_cfg);
iounmap(gpio_cfg);
fpd_dp_ser_debug("[FPD_DP] gpio reset pull up 0x%02x OK\n",
data);

/* Delay for VPs to sync to DP source */
msleep(100);

fpd_dp_ser_lock_global();

fpd_dp_ser_983_enable();

/* Check if VP is synchronized to DP input */
fpd_poll_984_training();

//WRITE_ONCE(deser_reset, 0);

fpd_dp_ser_set_up_mcu(fpd_dp_priv->priv_dp_client[0]);
fpd_dp_ser_unlock_global();

return true;
}

static bool fpd_dp_ser_read_display_startup_status(struct i2c_client *client)
{
bool status = false;
uint8_t rdata[5] = { 0 };
int ret, i;

fpd_dp_ser_lock_global();
if (!fpd_dp_ser_ready()) {
fpd_dp_ser_debug("%s: wait for serdes\n", __func__);
goto out;
}

ret = fpd_dp_mcu_read_reg(fpd_dp_priv->priv_dp_client[2],
FPD_DP_SER_RESPOND_DISPLAY_STARTUP_STATUS,
Expand All @@ -2055,6 +2112,10 @@ static bool fpd_dp_ser_read_display_startup_status(struct i2c_client *client)
if (rdata[3] == 1) {
fpd_dp_ser_info("[FPD_DP] RIB DP2 UB943 display startup status: done\n");
status = fpd_dp_ser_respond_dhu_startup_status(client);
if (status) {
WRITE_ONCE(deser_reset, 0);
fpd_dp_ser_set_ready(true);
}
} else {
fpd_dp_ser_info("[FPD_DP] RIB DP2 UB943 display startup status: not done\n");
}
Expand All @@ -2063,12 +2124,6 @@ static bool fpd_dp_ser_read_display_startup_status(struct i2c_client *client)
}

out:
/* i2c speed 400k */
fpd_dp_ser_write_reg(fpd_dp_priv->priv_dp_client[0], 0x2b, 0x0a);
fpd_dp_ser_write_reg(fpd_dp_priv->priv_dp_client[0], 0x2c, 0x0b);
fpd_dp_ser_write_reg(fpd_dp_priv->priv_dp_client[1], 0x2b, 0x0a);
fpd_dp_ser_write_reg(fpd_dp_priv->priv_dp_client[1], 0x2c, 0x0b);

fpd_dp_ser_unlock_global();
return status;
}
Expand All @@ -2082,8 +2137,11 @@ static bool wait_display_startup_done(struct i2c_client *client)

while (++n < 100)
{
if (fpd_dp_ser_read_display_startup_status(client))
if (fpd_dp_ser_read_display_startup_status(client)) {
return true;
} else {
fpd_dp_ser_info("[FPD_DP] RIB DP2 UB943 display startup reset\n");
}
usleep_range(5000, 5200);
}

Expand All @@ -2106,11 +2164,8 @@ bool fpd_dp_ser_init(void)
/* Check if VP is synchronized to DP input */
fpd_poll_984_training();

WRITE_ONCE(deser_reset, 0);

fpd_dp_ser_set_up_mcu(fpd_dp_priv->priv_dp_client[0]);

fpd_dp_ser_set_ready(true);
fpd_dp_ser_unlock_global();

queue_work(fpd_dp_priv->motor_setup_wq, &fpd_dp_priv->motor_setup_work);
Expand Down Expand Up @@ -2145,8 +2200,8 @@ static int fpd_dp_ser_probe(struct platform_device *pdev)
}

/* retries when i2c timeout */
i2c_adap->retries = 5;
i2c_adap->timeout = msecs_to_jiffies(5 * 10);
i2c_adap->retries = 10;
i2c_adap->timeout = msecs_to_jiffies(10 * 10);
priv->i2c_adap = i2c_adap;

i2c_adap_mcu = i2c_adap;
Expand Down Expand Up @@ -2186,6 +2241,8 @@ static int fpd_dp_ser_probe(struct platform_device *pdev)
gpio_cfg = (unsigned char *)ioremap(PAD_CFG_DW0_GPPC_A_16, 0x1);
data = ioread8(gpio_cfg);
data = data | 1;
fpd_dp_ser_debug("[FPD_DP] gpio 0x%02x OK\n",
data);
iowrite8(data, gpio_cfg);
iounmap(gpio_cfg);
/* Delay for VPs to sync to DP source */
Expand Down Expand Up @@ -2235,6 +2292,29 @@ static int fpd_dp_ser_remove(struct platform_device *pdev) {
return 0;
}

static void fpd_dp_ser_shutdown(struct platform_device *pdev) {
unsigned char __iomem *gpio_cfg;
unsigned char data;

fpd_dp_ser_debug("[FPD_DP] [-%s-%s-%d-]\n", __FILE__, __func__, __LINE__);

/* Map GPIO IO address to virtual address */
gpio_cfg = (unsigned char *)ioremap(PAD_CFG_DW0_GPPC_A_16, 0x1);
if (!gpio_cfg) {
fpd_dp_ser_debug("Ioremap fail in fpd_dp_ser_shutdown\n");
return;
}

data = ioread8(gpio_cfg);

/* Set Serdes DP3 last bit of GPIO IO address to 1 for pulling up DP3 */
data = data & 0xFE;
iowrite8(data, gpio_cfg);
iounmap(gpio_cfg);

return;
}

#ifdef CONFIG_PM

static int fpd_dp_ser_suspend(struct device *dev)
Expand All @@ -2244,21 +2324,6 @@ static int fpd_dp_ser_suspend(struct device *dev)

fpd_dp_ser_lock_global();
fpd_dp_ser_set_ready(false);
/* first des reset, and then ser reset */
fpd_dp_ser_write_reg(priv->priv_dp_client[1], 0x01, 0x01);

/* after reset, wait 20ms to avoid ser/des read/write fail */
usleep_range(20000, 22000);
/* i2c speed reset */
fpd_dp_ser_write_reg(priv->priv_dp_client[1], 0x2b, 0x7f);
fpd_dp_ser_write_reg(priv->priv_dp_client[1], 0x2c, 0x7f);

fpd_dp_ser_reset(priv->priv_dp_client[0]);

/* i2c speed reset */
fpd_dp_ser_write_reg(priv->priv_dp_client[0], 0x2b, 0x7f);
fpd_dp_ser_write_reg(priv->priv_dp_client[0], 0x2c, 0x7f);
usleep_range(20000, 22000);
fpd_dp_ser_unlock_global();

fpd_dp_ser_debug("[FPD_DP] [-%s-%s-%d-]\n", __FILE__, __func__, __LINE__);
Expand All @@ -2267,16 +2332,7 @@ static int fpd_dp_ser_suspend(struct device *dev)

static int fpd_dp_ser_resume(struct device *dev)
{
bool result;

fpd_dp_ser_debug("[FPD_DP] [-%s-%s-%d-]\n", __FILE__, __func__, __LINE__);

result = fpd_dp_ser_init();
if (!result) {
fpd_dp_ser_debug("Serdes enable fail in fpd_dp_ser_resume\n");
return -EIO;
}

return 0;
}

Expand All @@ -2297,10 +2353,36 @@ static int fpd_dp_ser_runtime_resume(struct device *dev)
return 0;
}

static int fpd_dp_ser_suspend_late(struct device *dev)
{
unsigned char __iomem *gpio_cfg;
unsigned char data;

fpd_dp_ser_debug("[FPD_DP] [-%s-%s-%d-]\n", __FILE__, __func__, __LINE__);

/* Map GPIO IO address to virtual address */
gpio_cfg = (unsigned char *)ioremap(PAD_CFG_DW0_GPPC_A_16, 0x1);
if (!gpio_cfg) {
fpd_dp_ser_debug("Ioremap fail in fpd_dp_ser_resume_early\n");
return -ENOMEM;
}

data = ioread8(gpio_cfg);

/* Set Serdes DP3 last bit of GPIO IO address to 1 for pulling up DP3 */
data = data & 0xFE;
iowrite8(data, gpio_cfg);
iounmap(gpio_cfg);

return 0;
}


static int fpd_dp_ser_resume_early(struct device *dev)
{
unsigned char __iomem *gpio_cfg;
unsigned char data;
bool result;

fpd_dp_ser_debug("[FPD_DP] [-%s-%s-%d-]\n", __FILE__, __func__, __LINE__);

Expand All @@ -2318,6 +2400,15 @@ static int fpd_dp_ser_resume_early(struct device *dev)
iowrite8(data, gpio_cfg);
iounmap(gpio_cfg);

/* Delay for VPs to sync to DP source */
msleep(100);

result = fpd_dp_ser_init();
if (!result) {
fpd_dp_ser_debug("Serdes enable fail in fpd_dp_ser_resume\n");
return -EIO;
}

return 0;
}

Expand All @@ -2326,6 +2417,7 @@ static const struct dev_pm_ops fdp_dp_ser_pmops = {
.resume = fpd_dp_ser_resume,
.runtime_suspend = fpd_dp_ser_runtime_suspend,
.runtime_resume = fpd_dp_ser_runtime_resume,
.suspend_late = fpd_dp_ser_suspend_late,
.resume_early = fpd_dp_ser_resume_early,
};

Expand All @@ -2349,6 +2441,7 @@ static const struct i2c_device_id fpd_dp_ser_i2c_id_table[] = {
static struct platform_driver fpd_dp_ser_driver = {
.probe = fpd_dp_ser_probe,
.remove = fpd_dp_ser_remove,
.shutdown = fpd_dp_ser_shutdown,
.driver = {
.name = DEV_NAME,
.owner = THIS_MODULE,
Expand Down
12 changes: 0 additions & 12 deletions drivers/gpu/drm/i915/display/intel_dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -5612,18 +5612,6 @@ static void mcu_set_backlight(const struct drm_connector_state *conn_state, u32
fpd_dp_ser_lock_global();

if (fpd_dp_ser_ready()) {
if (!READ_ONCE(deser_reset)) {
/*
* TODO: 984 reset to avoid serdes panel black screen,
* the following should handle 984 reset accoding to panel
* status
*/
intel_dp_ser_write_reg(dev, i2c_adap_mcu, 0x01, 0x01);
msleep(50);
WRITE_ONCE(deser_reset, 1);
drm_dbg_kms(dev, "[FPD_DP] 984 reset");
}

drm_dbg_kms(dev, "[CONNECTOR:%d:%s] backlight level = 0x%2x\n",
to_intel_connector(conn_state->connector)->base.base.id,
to_intel_connector(conn_state->connector)->base.name,
Expand Down