diff --git a/drivers/gpu/drm/bridge/ti/fpd_dp_ser_drv.c b/drivers/gpu/drm/bridge/ti/fpd_dp_ser_drv.c index 3827caf078224..bc8789d284859 100644 --- a/drivers/gpu/drm/bridge/ti/fpd_dp_ser_drv.c +++ b/drivers/gpu/drm/bridge/ti/fpd_dp_ser_drv.c @@ -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) @@ -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; } @@ -556,6 +560,7 @@ 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); @@ -563,6 +568,9 @@ int fpd_dp_set_fpd_4_983_pll(struct i2c_client *client) 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 */ @@ -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 */ @@ -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; } @@ -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); @@ -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; @@ -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 */ + 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) @@ -2027,6 +2047,47 @@ 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; @@ -2034,10 +2095,6 @@ static bool fpd_dp_ser_read_display_startup_status(struct i2c_client *client) 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, @@ -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"); } @@ -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; } @@ -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); } @@ -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); @@ -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; @@ -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 */ @@ -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) @@ -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__); @@ -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; } @@ -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__); @@ -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; } @@ -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, }; @@ -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, diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 07b2a76187fcb..5e501fdca2b5f 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -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,