From f36bd33120a3e76e8bc1bbfe5414475f1b7ba404 Mon Sep 17 00:00:00 2001 From: Evoke Zhang Date: Thu, 10 Jan 2019 12:56:06 +0800 Subject: [PATCH] lcd: tcon: add chpi bbc init support for tl1 [1/1] PD#SWPL-3739 Problem: need bbc flow to init channel for tcon chpi Solution: add bbc flow support Verify: x301 Change-Id: I15a3e9a85fdf62359768ce8931374f9c730b49d1 Signed-off-by: Evoke Zhang Conflicts: drivers/amlogic/media/vout/lcd/lcd_tv/lcd_drv.c --- .../boot/dts/amlogic/mesontl1_t309-panel.dtsi | 12 +- .../boot/dts/amlogic/mesontl1_x301-panel.dtsi | 12 +- .../amlogic/mesontm2_t962x3_ab309-panel.dtsi | 12 +- .../boot/dts/amlogic/mesontl1_t309-panel.dtsi | 12 +- .../boot/dts/amlogic/mesontl1_x301-panel.dtsi | 12 +- .../amlogic/mesontm2_t962x3_ab309-panel.dtsi | 12 +- .../amlogic/media/vout/lcd/lcd_clk_config.c | 113 ++++-------------- drivers/amlogic/media/vout/lcd/lcd_clk_ctrl.h | 3 + drivers/amlogic/media/vout/lcd/lcd_common.h | 3 +- drivers/amlogic/media/vout/lcd/lcd_debug.c | 72 +++++++++-- .../amlogic/media/vout/lcd/lcd_phy_config.c | 13 +- drivers/amlogic/media/vout/lcd/lcd_reg.h | 7 +- .../media/vout/lcd/lcd_tablet/lcd_drv.c | 20 +--- drivers/amlogic/media/vout/lcd/lcd_tcon.c | 72 +++++++++-- .../amlogic/media/vout/lcd/lcd_tv/lcd_drv.c | 64 +++++----- 15 files changed, 234 insertions(+), 205 deletions(-) diff --git a/arch/arm/boot/dts/amlogic/mesontl1_t309-panel.dtsi b/arch/arm/boot/dts/amlogic/mesontl1_t309-panel.dtsi index 7e87a902df23..4ed977ea70a0 100644 --- a/arch/arm/boot/dts/amlogic/mesontl1_t309-panel.dtsi +++ b/arch/arm/boot/dts/amlogic/mesontl1_t309-panel.dtsi @@ -623,9 +623,9 @@ 0>; /*pixel_clk(unit in Hz)*/ minilvds_attr = < 6 /* channel_num */ - 0x12304567 /* channel_sel0 */ - 0x0 /* channel_sel1 */ - 0xaa0 /* clk_phase */ + 0x76543210 /* channel_sel0 */ + 0xba98 /* channel_sel1 */ + 0x660 /* clk_phase */ 0 /* pn_swap */ 0>; /* bit_swap */ phy_attr=<0xf 0>; /* vswing_level, preem_level */ @@ -668,9 +668,9 @@ 0>; /*pixel_clk(unit in Hz)*/ minilvds_attr = < 6 /* channel_num */ - 0x45603012 /* channel_sel0 */ - 0x0 /* channel_sel1 */ - 0xaa0 /* clk_phase */ + 0x76543210 /* channel_sel0 */ + 0xba98 /* channel_sel1 */ + 0x660 /* clk_phase */ 0 /* pn_swap */ 0>; /* bit_swap */ phy_attr=<0xf 0>; /* vswing_level, preem_level */ diff --git a/arch/arm/boot/dts/amlogic/mesontl1_x301-panel.dtsi b/arch/arm/boot/dts/amlogic/mesontl1_x301-panel.dtsi index 309b6138b82b..d3f8d73e3563 100644 --- a/arch/arm/boot/dts/amlogic/mesontl1_x301-panel.dtsi +++ b/arch/arm/boot/dts/amlogic/mesontl1_x301-panel.dtsi @@ -627,9 +627,9 @@ 0>; /*pixel_clk(unit in Hz)*/ minilvds_attr = < 6 /* channel_num */ - 0x12304567 /* channel_sel0 */ - 0x0 /* channel_sel1 */ - 0xaa0 /* clk_phase */ + 0x76543210 /* channel_sel0 */ + 0xba98 /* channel_sel1 */ + 0x660 /* clk_phase */ 0 /* pn_swap */ 0>; /* bit_swap */ phy_attr=<0xf 0>; /* vswing_level, preem_level */ @@ -672,9 +672,9 @@ 0>; /*pixel_clk(unit in Hz)*/ minilvds_attr = < 6 /* channel_num */ - 0x45603012 /* channel_sel0 */ - 0x0 /* channel_sel1 */ - 0xaa0 /* clk_phase */ + 0x76543210 /* channel_sel0 */ + 0xba98 /* channel_sel1 */ + 0x660 /* clk_phase */ 0 /* pn_swap */ 0>; /* bit_swap */ phy_attr=<0xf 0>; /* vswing_level, preem_level */ diff --git a/arch/arm/boot/dts/amlogic/mesontm2_t962x3_ab309-panel.dtsi b/arch/arm/boot/dts/amlogic/mesontm2_t962x3_ab309-panel.dtsi index 4a6b224c157d..4bf042efe1bc 100644 --- a/arch/arm/boot/dts/amlogic/mesontm2_t962x3_ab309-panel.dtsi +++ b/arch/arm/boot/dts/amlogic/mesontm2_t962x3_ab309-panel.dtsi @@ -421,9 +421,9 @@ 0>; /*pixel_clk(unit in Hz)*/ minilvds_attr = < 6 /* channel_num */ - 0x12304567 /* channel_sel0 */ - 0x0 /* channel_sel1 */ - 0xaa0 /* clk_phase */ + 0x76543210 /* channel_sel0 */ + 0xba98 /* channel_sel1 */ + 0x660 /* clk_phase */ 0 /* pn_swap */ 0>; /* bit_swap */ phy_attr=<0xf 0>; /* vswing_level, preem_level */ @@ -464,9 +464,9 @@ 0>; /*pixel_clk(unit in Hz)*/ minilvds_attr = < 6 /* channel_num */ - 0x45603012 /* channel_sel0 */ - 0x0 /* channel_sel1 */ - 0xaa0 /* clk_phase */ + 0x76543210 /* channel_sel0 */ + 0xba98 /* channel_sel1 */ + 0x660 /* clk_phase */ 0 /* pn_swap */ 0>; /* bit_swap */ phy_attr=<0xf 0>; /* vswing_level, preem_level */ diff --git a/arch/arm64/boot/dts/amlogic/mesontl1_t309-panel.dtsi b/arch/arm64/boot/dts/amlogic/mesontl1_t309-panel.dtsi index 36852e1d3f90..a902618fa296 100644 --- a/arch/arm64/boot/dts/amlogic/mesontl1_t309-panel.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesontl1_t309-panel.dtsi @@ -623,9 +623,9 @@ 0>; /*pixel_clk(unit in Hz)*/ minilvds_attr = < 6 /* channel_num */ - 0x12304567 /* channel_sel0 */ - 0x0 /* channel_sel1 */ - 0xaa0 /* clk_phase */ + 0x76543210 /* channel_sel0 */ + 0xba98 /* channel_sel1 */ + 0x660 /* clk_phase */ 0 /* pn_swap */ 0>; /* bit_swap */ phy_attr=<0xf 0>; /* vswing_level, preem_level */ @@ -668,9 +668,9 @@ 0>; /*pixel_clk(unit in Hz)*/ minilvds_attr = < 6 /* channel_num */ - 0x45603012 /* channel_sel0 */ - 0x0 /* channel_sel1 */ - 0xaa0 /* clk_phase */ + 0x76543210 /* channel_sel0 */ + 0xba98 /* channel_sel1 */ + 0x660 /* clk_phase */ 0 /* pn_swap */ 0>; /* bit_swap */ phy_attr=<0xf 0>; /* vswing_level, preem_level */ diff --git a/arch/arm64/boot/dts/amlogic/mesontl1_x301-panel.dtsi b/arch/arm64/boot/dts/amlogic/mesontl1_x301-panel.dtsi index 2e38f339e816..9c7fd79eccae 100644 --- a/arch/arm64/boot/dts/amlogic/mesontl1_x301-panel.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesontl1_x301-panel.dtsi @@ -626,9 +626,9 @@ 0>; /*pixel_clk(unit in Hz)*/ minilvds_attr = < 6 /* channel_num */ - 0x12304567 /* channel_sel0 */ - 0x0 /* channel_sel1 */ - 0xaa0 /* clk_phase */ + 0x76543210 /* channel_sel0 */ + 0xba98 /* channel_sel1 */ + 0x660 /* clk_phase */ 0 /* pn_swap */ 0>; /* bit_swap */ phy_attr=<0xf 0>; /* vswing_level, preem_level */ @@ -671,9 +671,9 @@ 0>; /*pixel_clk(unit in Hz)*/ minilvds_attr = < 6 /* channel_num */ - 0x45603012 /* channel_sel0 */ - 0x0 /* channel_sel1 */ - 0xaa0 /* clk_phase */ + 0x76543210 /* channel_sel0 */ + 0xba98 /* channel_sel1 */ + 0x660 /* clk_phase */ 0 /* pn_swap */ 0>; /* bit_swap */ phy_attr=<0xf 0>; /* vswing_level, preem_level */ diff --git a/arch/arm64/boot/dts/amlogic/mesontm2_t962x3_ab309-panel.dtsi b/arch/arm64/boot/dts/amlogic/mesontm2_t962x3_ab309-panel.dtsi index 42191edb6668..6f74572fb3b0 100644 --- a/arch/arm64/boot/dts/amlogic/mesontm2_t962x3_ab309-panel.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesontm2_t962x3_ab309-panel.dtsi @@ -421,9 +421,9 @@ 0>; /*pixel_clk(unit in Hz)*/ minilvds_attr = < 6 /* channel_num */ - 0x12304567 /* channel_sel0 */ - 0x0 /* channel_sel1 */ - 0xaa0 /* clk_phase */ + 0x76543210 /* channel_sel0 */ + 0xba98 /* channel_sel1 */ + 0x660 /* clk_phase */ 0 /* pn_swap */ 0>; /* bit_swap */ phy_attr=<0xf 0>; /* vswing_level, preem_level */ @@ -464,9 +464,9 @@ 0>; /*pixel_clk(unit in Hz)*/ minilvds_attr = < 6 /* channel_num */ - 0x45603012 /* channel_sel0 */ - 0x0 /* channel_sel1 */ - 0xaa0 /* clk_phase */ + 0x76543210 /* channel_sel0 */ + 0xba98 /* channel_sel1 */ + 0x660 /* clk_phase */ 0 /* pn_swap */ 0>; /* bit_swap */ phy_attr=<0xf 0>; /* vswing_level, preem_level */ diff --git a/drivers/amlogic/media/vout/lcd/lcd_clk_config.c b/drivers/amlogic/media/vout/lcd/lcd_clk_config.c index f027f80b9c4d..dddf40625884 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_clk_config.c +++ b/drivers/amlogic/media/vout/lcd/lcd_clk_config.c @@ -511,7 +511,6 @@ static void lcd_set_pll_ss_advance_tl1(unsigned int freq, unsigned int mode) static void lcd_set_pll_tl1(struct lcd_clk_config_s *cConf) { -#if 1 unsigned int pll_ctrl, pll_ctrl1; unsigned int tcon_div[5][3] = { /* div_mux, div2/4_sel, div4_bypass */ @@ -551,101 +550,16 @@ static void lcd_set_pll_tl1(struct lcd_clk_config_s *cConf) udelay(10); lcd_hiu_write(HHI_TCON_PLL_CNTL3, 0x10051400); udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL4, 0x000100c0); + lcd_hiu_setb(HHI_TCON_PLL_CNTL4, 0x0100c0, 0, 24); udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL4, 0x008300c0); + lcd_hiu_setb(HHI_TCON_PLL_CNTL4, 0x8300c0, 0, 24); udelay(10); lcd_hiu_setb(HHI_TCON_PLL_CNTL0, 1, 26, 1); udelay(10); lcd_hiu_setb(HHI_TCON_PLL_CNTL0, 0, LCD_PLL_RST_TL1, 1); udelay(10); lcd_hiu_write(HHI_TCON_PLL_CNTL2, 0x00003008); -#else - struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver(); - int ret; - switch (lcd_drv->lcd_config->lcd_basic.lcd_type) { - case LCD_LVDS: - lcd_hiu_write(HHI_TCON_PLL_CNTL0, 0x000704ad); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL0, 0x200704ad); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL0, 0x300704ad); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL1, 0x10508000); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL2, 0x00001108); - udelay(10); - //lcd_hiu_write(HHI_TCON_PLL_CNTL3, 0x10058f30); - lcd_hiu_write(HHI_TCON_PLL_CNTL3, 0x10051400); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL4, 0x010100c0); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL4, 0x038300c0); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL0, 0x340704ad); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL0, 0x142e04ad); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL2, 0x00003008); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL4, 0x0b8300c0); - udelay(10); - break; - case LCD_VBYONE: - lcd_hiu_write(HHI_TCON_PLL_CNTL0, 0x000f04f7); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL0, 0x200f04f7); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL0, 0x300f04f7); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL1, 0x10110000); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL2, 0x00001108); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL3, 0x10051400); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL4, 0x010100c0); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL4, 0x038300c0); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL0, 0x340f04f7); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL0, 0x140f04f7); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL2, 0x00003008); - udelay(10); - break; - case LCD_P2P: - lcd_hiu_write(HHI_TCON_PLL_CNTL0, 0x000f04e1); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL0, 0x200604e1); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL0, 0x300604e1); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL1, 0x10208000); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL2, 0x00001108); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL3, 0x10058f30); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL4, 0x010100c0); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL4, 0x038300c0); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL0, 0x340604e1); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL0, 0x14af04e1); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL2, 0x00003008); - udelay(10); - lcd_hiu_write(HHI_TCON_PLL_CNTL4, 0x0b8300c0); - udelay(10); - break; - default: - break; - } -#endif ret = lcd_pll_wait_lock(HHI_TCON_PLL_CNTL0, LCD_PLL_LOCK_TL1); if (ret) { LCDERR("hpll lock failed\n"); @@ -746,11 +660,28 @@ static void lcd_set_dsi_phy_clk(int sel) static void lcd_set_tcon_clk(struct lcd_config_s *pconf) { + unsigned int freq, val; + if (lcd_debug_print_flag == 2) LCDPR("%s\n", __func__); switch (pconf->lcd_basic.lcd_type) { case LCD_MLVDS: + val = pconf->lcd_control.mlvds_config->clk_phase & 0xfff; + lcd_hiu_setb(HHI_TCON_PLL_CNTL1, (val & 0xf), 24, 4); + lcd_hiu_setb(HHI_TCON_PLL_CNTL4, ((val >> 4) & 0xf), 28, 4); + lcd_hiu_setb(HHI_TCON_PLL_CNTL4, ((val >> 8) & 0xf), 24, 4); + + /* tcon_clk */ + if (pconf->lcd_timing.lcd_clk >= 100000000) /* 25M */ + freq = 25000000; + else /* 12.5M */ + freq = 12500000; + if (!IS_ERR_OR_NULL(lcd_clktree.tcon_clk)) { + clk_set_rate(lcd_clktree.tcon_clk, freq); + clk_prepare_enable(lcd_clktree.tcon_clk); + } + break; case LCD_P2P: if (!IS_ERR_OR_NULL(lcd_clktree.tcon_clk)) { clk_set_rate(lcd_clktree.tcon_clk, 50000000); @@ -867,6 +798,12 @@ static unsigned int clk_vid_pll_div_calc(unsigned int clk, else clk_ret = clk * 5 / 2; break; + case CLK_DIV_SEL_4p67: + if (dir == CLK_DIV_I2O) + clk_ret = clk * 3 / 14; + else + clk_ret = clk * 14 / 3; + break; default: clk_ret = clk; LCDERR("clk_div_sel: Invalid parameter\n"); diff --git a/drivers/amlogic/media/vout/lcd/lcd_clk_ctrl.h b/drivers/amlogic/media/vout/lcd/lcd_clk_ctrl.h index 041b3b292590..cfbdd410a857 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_clk_ctrl.h +++ b/drivers/amlogic/media/vout/lcd/lcd_clk_ctrl.h @@ -410,6 +410,7 @@ static char *lcd_clk_div_sel_table[] = { "14", "15", "2.5", + "4.67", "invalid", }; @@ -432,6 +433,7 @@ enum div_sel_e { CLK_DIV_SEL_14, /* 12 */ CLK_DIV_SEL_15, /* 13 */ CLK_DIV_SEL_2p5, /* 14 */ + CLK_DIV_SEL_4p67, /* 15 */ CLK_DIV_SEL_MAX, }; @@ -452,6 +454,7 @@ static unsigned int lcd_clk_div_table[][3] = { {CLK_DIV_SEL_14, 0x3f80, 1,}, {CLK_DIV_SEL_15, 0x7f80, 2,}, {CLK_DIV_SEL_2p5, 0x5294, 2,}, + {CLK_DIV_SEL_4p67, 0x0ccc, 1,}, {CLK_DIV_SEL_MAX, 0xffff, 0,}, }; diff --git a/drivers/amlogic/media/vout/lcd/lcd_common.h b/drivers/amlogic/media/vout/lcd/lcd_common.h index 398a1a408642..419551066a40 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_common.h +++ b/drivers/amlogic/media/vout/lcd/lcd_common.h @@ -36,7 +36,8 @@ /* 20181212: tl1 update p2p config and pll setting */ /* 20181225: update phy config */ /* 20190108: tl1 support tablet mode */ -#define LCD_DRV_VERSION "20190108" +/* 20190115: tl1 tcon all interface support */ +#define LCD_DRV_VERSION "20190115" #define VPP_OUT_SATURATE (1 << 0) diff --git a/drivers/amlogic/media/vout/lcd/lcd_debug.c b/drivers/amlogic/media/vout/lcd/lcd_debug.c index 63dc64b035fc..e8d023eabb0b 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_debug.c +++ b/drivers/amlogic/media/vout/lcd/lcd_debug.c @@ -428,7 +428,7 @@ static int lcd_info_print_mlvds(char *buf, int offset) n = lcd_debug_info_len(len + offset); len += snprintf((buf+len), n, "channel_num %d\n" - "channel_sel1 0x%08x\n" + "channel_sel0 0x%08x\n" "channel_sel1 0x%08x\n" "clk_phase 0x%04x\n" "pn_swap %u\n" @@ -472,7 +472,7 @@ static int lcd_info_print_p2p(char *buf, int offset) len += snprintf((buf+len), n, "p2p_type %d\n" "lane_num %d\n" - "channel_sel1 0x%08x\n" + "channel_sel0 0x%08x\n" "channel_sel1 0x%08x\n" "pn_swap %u\n" "bit_swap %u\n" @@ -971,9 +971,9 @@ static int lcd_reg_print_mlvds(char *buf, int offset) len += snprintf((buf+len), n, "TCON_INTR_MASKN [0x%04x] = 0x%08x\n", reg, lcd_tcon_read(reg)); - reg = TCON_INTR; + reg = TCON_INTR_RO; len += snprintf((buf+len), n, - "TCON_INTR [0x%04x] = 0x%08x\n", + "TCON_INTR_RO [0x%04x] = 0x%08x\n", reg, lcd_tcon_read(reg)); return len; @@ -1069,9 +1069,9 @@ static int lcd_reg_print_p2p(char *buf, int offset) len += snprintf((buf+len), n, "TCON_INTR_MASKN [0x%04x] = 0x%08x\n", reg, lcd_tcon_read(reg)); - reg = TCON_INTR; + reg = TCON_INTR_RO; len += snprintf((buf+len), n, - "TCON_INTR [0x%04x] = 0x%08x\n", + "TCON_INTR_RO [0x%04x] = 0x%08x\n", reg, lcd_tcon_read(reg)); return len; @@ -3619,11 +3619,6 @@ static void lcd_phy_config_update(unsigned int *para, int cnt) struct lcd_config_s *pconf; struct lvds_config_s *lvds_conf; - if (lcd_drv->data->chip_type == LCD_CHIP_TL1) { - LCDPR("%s: not support yet\n", __func__); - return; - } - pconf = lcd_drv->lcd_config; switch (pconf->lcd_basic.lcd_type) { case LCD_LVDS: @@ -3891,6 +3886,61 @@ static ssize_t lcd_tcon_debug_store(struct class *class, lcd_tcon_reg_save(parm[2], size); else pr_info("invalid save path\n"); + } else if (strcmp(parm[1], "rb") == 0) { + if (parm[2] != NULL) { + ret = kstrtouint(parm[2], 16, &temp); + if (ret) { + pr_info("invalid parameters\n"); + goto lcd_tcon_debug_store_err; + } + pr_info("read tcon byte [0x%04x] = 0x%02x\n", + temp, lcd_tcon_read_byte(temp)); + } + } else if (strcmp(parm[1], "wb") == 0) { + if (parm[3] != NULL) { + ret = kstrtouint(parm[2], 16, &temp); + if (ret) { + pr_info("invalid parameters\n"); + goto lcd_tcon_debug_store_err; + } + ret = kstrtouint(parm[3], 16, &val); + if (ret) { + pr_info("invalid parameters\n"); + goto lcd_tcon_debug_store_err; + } + data = (unsigned char)val; + lcd_tcon_write_byte(temp, data); + pr_info( + "write tcon byte [0x%04x] = 0x%02x, readback 0x%02x\n", + temp, data, lcd_tcon_read_byte(temp)); + } + } else if (strcmp(parm[1], "r") == 0) { + if (parm[2] != NULL) { + ret = kstrtouint(parm[2], 16, &temp); + if (ret) { + pr_info("invalid parameters\n"); + goto lcd_tcon_debug_store_err; + } + pr_info("read tcon [0x%04x] = 0x%08x\n", + temp, lcd_tcon_read(temp)); + } + } else if (strcmp(parm[1], "w") == 0) { + if (parm[3] != NULL) { + ret = kstrtouint(parm[2], 16, &temp); + if (ret) { + pr_info("invalid parameters\n"); + goto lcd_tcon_debug_store_err; + } + ret = kstrtouint(parm[3], 16, &val); + if (ret) { + pr_info("invalid parameters\n"); + goto lcd_tcon_debug_store_err; + } + lcd_tcon_write(temp, val); + pr_info( + "write tcon [0x%04x] = 0x%08x, readback 0x%08x\n", + temp, val, lcd_tcon_read(temp)); + } } } else if (strcmp(parm[0], "table") == 0) { if (parm[1] == NULL) { diff --git a/drivers/amlogic/media/vout/lcd/lcd_phy_config.c b/drivers/amlogic/media/vout/lcd/lcd_phy_config.c index ad9ac39337d1..bdc31b171ab5 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_phy_config.c +++ b/drivers/amlogic/media/vout/lcd/lcd_phy_config.c @@ -309,7 +309,7 @@ void lcd_vbyone_phy_set(struct lcd_config_s *pconf, int status) void lcd_mlvds_phy_set(struct lcd_config_s *pconf, int status) { unsigned int vswing, preem; - unsigned int data32, size; + unsigned int data32, size, cntl16; struct mlvds_config_s *mlvds_conf; if (lcd_debug_print_flag) @@ -333,7 +333,9 @@ void lcd_mlvds_phy_set(struct lcd_config_s *pconf, int status) lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL14, 0xff2027e0 | vswing); lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL15, 0); - lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL16, 0x80000000); + cntl16 = (mlvds_conf->pi_clk_sel << 12); + cntl16 |= 0x80000000; + lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL16, cntl16); lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL8, 0); lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL1, data32); lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL9, 0); @@ -422,11 +424,10 @@ void lcd_p2p_phy_set(struct lcd_config_s *pconf, int status) preem = 0x1; } data32 = p2p_low_common_phy_preem_tl1[preem]; + cntl16 = 0x80000000; if (p2p_conf->p2p_type == P2P_CHPI) { - /* cntl[30]=1, weakly pull down */ - cntl16 = 0x80000000; - } else { - cntl16 = 0x80000000; + /* weakly pull down */ + data32 &= ~((1 << 19) | (1 << 3)); } lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL14, 0xfe60027f); lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL15, 0); diff --git a/drivers/amlogic/media/vout/lcd/lcd_reg.h b/drivers/amlogic/media/vout/lcd/lcd_reg.h index ab3ee4f03f63..c3ca21e03af1 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_reg.h +++ b/drivers/amlogic/media/vout/lcd/lcd_reg.h @@ -981,8 +981,13 @@ #define TCON_GPO_CTRL0 0x2015 #define TCON_GPO_CTRL1 0x2016 #define TCON_GPO_CTRL2 0x2017 +#define TCON_INTR_WR 0x2020 +#define TCON_INTR_CLR 0x2021 #define TCON_INTR_MASKN 0x2022 -#define TCON_INTR 0x2023 /* read only */ +#define TCON_INTR_RO 0x2023 /* read only */ + +#define P2P_CH_SWAP0 0x4200 +#define P2P_CH_SWAP1 0x4201 /* ******************************** * Video post-processing: VPP_VCBUS_BASE = 0x1d diff --git a/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_drv.c b/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_drv.c index 7d62f25f515b..16682e91c15f 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_drv.c +++ b/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_drv.c @@ -278,7 +278,6 @@ static void lcd_lvds_control_set(struct lcd_config_s *pconf) unsigned int pn_swap, port_swap, lane_reverse; unsigned int dual_port, fifo_mode; unsigned int lvds_repack = 1; - unsigned int ch_swap0, ch_swap1, ch_swap2; if (lcd_debug_print_flag) LCDPR("%s\n", __func__); @@ -327,12 +326,8 @@ static void lcd_lvds_control_set(struct lcd_config_s *pconf) switch (lcd_drv->data->chip_type) { case LCD_CHIP_TL1: - ch_swap0 = 0x3210; - ch_swap1 = 0x7654; - ch_swap2 = 0xba98; - lcd_vcbus_write(LVDS_CH_SWAP0, ch_swap0); - lcd_vcbus_write(LVDS_CH_SWAP1, ch_swap1); - lcd_vcbus_write(LVDS_CH_SWAP2, ch_swap2); + lcd_vcbus_write(P2P_CH_SWAP0, 0x76543210); + lcd_vcbus_write(P2P_CH_SWAP1, 0xba98); break; default: lcd_vcbus_setb(LCD_PORT_SWAP, port_swap, 12, 1); @@ -419,7 +414,6 @@ static void lcd_vbyone_clk_util_set(struct lcd_config_s *pconf) static int lcd_vbyone_lanes_set(int lane_num, int byte_mode, int region_num, int hsize, int vsize) { - struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver(); int sublane_num; int region_size[4]; int tmp; @@ -483,16 +477,6 @@ static int lcd_vbyone_lanes_set(int lane_num, int byte_mode, int region_num, lcd_vcbus_setb(VBO_CTRL_H, 0x1, 9, 1); /* lcd_vcbus_setb(VBO_CTRL_L,enable,0,1); */ - switch (lcd_drv->data->chip_type) { /* pn swap */ - case LCD_CHIP_TL1: - lcd_vcbus_write(LVDS_CH_SWAP0, 0x3210); - lcd_vcbus_write(LVDS_CH_SWAP1, 0x7654); - lcd_vcbus_write(LVDS_CH_SWAP2, 0xba98); - break; - default: - break; - } - return 0; } diff --git a/drivers/amlogic/media/vout/lcd/lcd_tcon.c b/drivers/amlogic/media/vout/lcd/lcd_tcon.c index ed6e1f7ca016..c8039f2499f9 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_tcon.c +++ b/drivers/amlogic/media/vout/lcd/lcd_tcon.c @@ -163,7 +163,7 @@ void lcd_tcon_core_reg_update(void) } } -static int lcd_tcon_top_set_tl1(void) +static int lcd_tcon_top_set_tl1(struct lcd_config_s *pconf) { unsigned int axi_reg[3] = { TCON_AXI_OFST0, TCON_AXI_OFST1, TCON_AXI_OFST2 @@ -188,7 +188,18 @@ static int lcd_tcon_top_set_tl1(void) } lcd_tcon_write(TCON_CLK_CTRL, 0x001f); - lcd_tcon_write(TCON_TOP_CTRL, 0x8999); + if (pconf->lcd_basic.lcd_type == LCD_P2P) { + switch (pconf->lcd_control.p2p_config->p2p_type) { + case P2P_CHPI: + lcd_tcon_write(TCON_TOP_CTRL, 0x8199); + break; + default: + lcd_tcon_write(TCON_TOP_CTRL, 0x8999); + break; + } + } else { + lcd_tcon_write(TCON_TOP_CTRL, 0x8999); + } lcd_tcon_write(TCON_PLLLOCK_CNTL, 0x0037); lcd_tcon_write(TCON_RST_CTRL, 0x003f); lcd_tcon_write(TCON_RST_CTRL, 0x0000); @@ -198,8 +209,46 @@ static int lcd_tcon_top_set_tl1(void) return 0; } +static void lcd_tcon_chpi_bbc_init_tl1(int delay) +{ + unsigned int data32; + + udelay(delay); + lcd_hiu_setb(HHI_DIF_CSI_PHY_CNTL1, 1, 3, 1); + lcd_hiu_setb(HHI_DIF_CSI_PHY_CNTL1, 1, 19, 1); + lcd_hiu_setb(HHI_DIF_CSI_PHY_CNTL2, 1, 3, 1); + lcd_hiu_setb(HHI_DIF_CSI_PHY_CNTL2, 1, 19, 1); + lcd_hiu_setb(HHI_DIF_CSI_PHY_CNTL3, 1, 3, 1); + lcd_hiu_setb(HHI_DIF_CSI_PHY_CNTL3, 1, 19, 1); + lcd_hiu_setb(HHI_DIF_CSI_PHY_CNTL4, 1, 3, 1); + lcd_hiu_setb(HHI_DIF_CSI_PHY_CNTL4, 1, 19, 1); + lcd_hiu_setb(HHI_DIF_CSI_PHY_CNTL6, 1, 3, 1); + lcd_hiu_setb(HHI_DIF_CSI_PHY_CNTL6, 1, 19, 1); + lcd_hiu_setb(HHI_DIF_CSI_PHY_CNTL7, 1, 3, 1); + lcd_hiu_setb(HHI_DIF_CSI_PHY_CNTL7, 1, 19, 1); + LCDPR("%s: delay: %dus\n", __func__, delay); + + data32 = 0x06020602; + lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL14, 0xff2027ef); + lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL15, 0); + lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL16, 0x80000000); + lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL8, 0); + lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL1, data32); + lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL9, 0); + lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL2, data32); + lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL10, 0); + lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL3, data32); + lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL11, 0); + lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL4, data32); + lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL12, 0); + lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL6, data32); + lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL13, 0); + lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL7, data32); +} + static int lcd_tcon_enable_tl1(struct lcd_config_s *pconf) { + unsigned int n = 10; int ret; ret = lcd_tcon_valid_check(); @@ -207,16 +256,23 @@ static int lcd_tcon_enable_tl1(struct lcd_config_s *pconf) return -1; /* step 1: tcon top */ - lcd_tcon_top_set_tl1(); + lcd_tcon_top_set_tl1(pconf); /* step 2: tcon_core_reg_update */ lcd_tcon_core_reg_update(); + if (pconf->lcd_basic.lcd_type == LCD_P2P) { + switch (pconf->lcd_control.p2p_config->p2p_type) { + case P2P_CHPI: + lcd_tcon_chpi_bbc_init_tl1(n); + break; + default: + break; + } + } /* step 3: tcon_top_output_set */ - lcd_tcon_write(TCON_OUT_CH_SEL1, 0xba98); /* out swap for ch8~11 */ - LCDPR("set tcon ch_sel: 0x%08x, 0x%08x\n", - lcd_tcon_read(TCON_OUT_CH_SEL0), - lcd_tcon_read(TCON_OUT_CH_SEL1)); + lcd_tcon_write(TCON_OUT_CH_SEL0, 0x76543210); + lcd_tcon_write(TCON_OUT_CH_SEL1, 0xba98); /* step 4: tcon_intr_mask */ lcd_tcon_write(TCON_INTR_MASKN, TCON_INTR_MASKN_VAL); @@ -232,7 +288,7 @@ static irqreturn_t lcd_tcon_isr(int irq, void *dev_id) if ((lcd_drv->lcd_status & LCD_STATUS_IF_ON) == 0) return IRQ_HANDLED; - temp = lcd_tcon_read(TCON_INTR); + temp = lcd_tcon_read(TCON_INTR_RO); if (temp & 0x2) { LCDPR("%s: tcon sw_reset triggered\n", __func__); lcd_tcon_core_reg_update(); diff --git a/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_drv.c b/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_drv.c index bdf87ca12ee5..71c4bc579490 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_drv.c +++ b/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_drv.c @@ -252,7 +252,6 @@ static void lcd_lvds_control_set(struct lcd_config_s *pconf) unsigned int pn_swap, port_swap, lane_reverse; unsigned int dual_port, fifo_mode; unsigned int lvds_repack = 1; - unsigned int ch_swap0, ch_swap1, ch_swap2; if (lcd_debug_print_flag) LCDPR("%s\n", __func__); @@ -301,7 +300,6 @@ static void lcd_lvds_control_set(struct lcd_config_s *pconf) switch (lcd_drv->data->chip_type) { case LCD_CHIP_TL1: - case LCD_CHIP_TM2: lcd_vcbus_write(P2P_CH_SWAP0, 0x76543210); lcd_vcbus_write(P2P_CH_SWAP1, 0xba98); break; @@ -356,12 +354,10 @@ static void lcd_mlvds_control_set(struct lcd_config_s *pconf) /* fifo write enable[31] */ lcd_hiu_setb(HHI_LVDS_TX_PHY_CNTL1_TL1, 1, 31, 1); - /* channel swap default no swap */ channel_sel0 = pconf->lcd_control.mlvds_config->channel_sel0; channel_sel1 = pconf->lcd_control.mlvds_config->channel_sel1; - lcd_vcbus_write(LVDS_CH_SWAP0, (channel_sel0 & 0xff)); - lcd_vcbus_write(LVDS_CH_SWAP1, ((channel_sel0 >> 8) & 0xff)); - lcd_vcbus_write(LVDS_CH_SWAP2, (channel_sel1 & 0xff)); + lcd_vcbus_write(P2P_CH_SWAP0, channel_sel0); + lcd_vcbus_write(P2P_CH_SWAP1, channel_sel1); lcd_tcon_enable(pconf); } @@ -452,7 +448,6 @@ static void lcd_vbyone_clk_util_set(struct lcd_config_s *pconf) static int lcd_vbyone_lanes_set(int lane_num, int byte_mode, int region_num, int hsize, int vsize) { - struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver(); int sublane_num; int region_size[4]; int tmp; @@ -516,16 +511,6 @@ static int lcd_vbyone_lanes_set(int lane_num, int byte_mode, int region_num, lcd_vcbus_setb(VBO_CTRL_H, 0x1, 9, 1); /* lcd_vcbus_setb(VBO_CTRL_L,enable,0,1); */ - switch (lcd_drv->data->chip_type) { /* pn swap */ - case LCD_CHIP_TL1: - lcd_vcbus_write(LVDS_CH_SWAP0, 0x3210); - lcd_vcbus_write(LVDS_CH_SWAP1, 0x7654); - lcd_vcbus_write(LVDS_CH_SWAP2, 0xba98); - break; - default: - break; - } - return 0; } @@ -1265,12 +1250,10 @@ static void lcd_p2p_control_set(struct lcd_config_s *pconf) /* fifo write enable[31] */ lcd_hiu_setb(reg_cntl1, 1, 31, 1); - /* channel swap default no swap */ channel_sel0 = pconf->lcd_control.p2p_config->channel_sel0; channel_sel1 = pconf->lcd_control.p2p_config->channel_sel1; - lcd_vcbus_write(LVDS_CH_SWAP0, (channel_sel0 & 0xff)); - lcd_vcbus_write(LVDS_CH_SWAP1, ((channel_sel0 >> 8) & 0xff)); - lcd_vcbus_write(LVDS_CH_SWAP2, (channel_sel1 & 0xff)); + lcd_vcbus_write(P2P_CH_SWAP0, channel_sel0); + lcd_vcbus_write(P2P_CH_SWAP1, channel_sel1); lcd_tcon_enable(pconf); } @@ -1353,7 +1336,7 @@ static void lcd_mlvds_config_set(struct lcd_config_s *pconf) { unsigned int bit_rate, pclk; unsigned int lcd_bits, channel_num; - unsigned int channel_sel0, channel_sel1, pi_clk_sel; + unsigned int channel_sel0, channel_sel1, pi_clk_sel = 0; unsigned int i, temp; if (lcd_debug_print_flag) @@ -1373,27 +1356,30 @@ static void lcd_mlvds_config_set(struct lcd_config_s *pconf) } /* pi_clk select */ - /* mlvds channel: //tx 10 channels - * 0: d0_a - * 1: d1_a - * 2: d2_a - * 3: clk_a - * 4: d0_b - * 5: d1_b - * 6: d2_b - * 7: clk_b - */ channel_sel0 = pconf->lcd_control.mlvds_config->channel_sel0; channel_sel1 = pconf->lcd_control.mlvds_config->channel_sel1; - pi_clk_sel = 0; + /* mlvds channel: //tx 12 channels + * 0: clk_a + * 1: d0_a + * 2: d1_a + * 3: d2_a + * 4: d3_a + * 5: d4_a + * 6: clk_b + * 7: d0_b + * 8: d1_b + * 9: d2_b + * 10: d3_b + * 11: d4_b + */ for (i = 0; i < 8; i++) { temp = (channel_sel0 >> (i*4)) & 0xf; - if ((temp == 3) || (temp == 7)) + if ((temp == 0) || (temp == 6)) pi_clk_sel |= (1 << i); } - for (i = 0; i < 2; i++) { + for (i = 0; i < 4; i++) { temp = (channel_sel1 >> (i*4)) & 0xf; - if ((temp == 3) || (temp == 7)) + if ((temp == 0) || (temp == 6)) pi_clk_sel |= (1 << (i + 8)); } pconf->lcd_control.mlvds_config->pi_clk_sel = pi_clk_sel; @@ -1416,6 +1402,12 @@ static void lcd_p2p_config_set(struct lcd_config_s *pconf) lane_num = pconf->lcd_control.p2p_config->lane_num; pclk = pconf->lcd_timing.lcd_clk / 1000; switch (pconf->lcd_control.p2p_config->p2p_type) { + case P2P_CEDS: + if (pclk >= 600000) + bit_rate = pclk * 3 * lcd_bits / lane_num; + else + bit_rate = pclk * (3 * lcd_bits + 4) / lane_num; + break; case P2P_CHPI: /* 8/10 coding */ bit_rate = (pclk * 3 * lcd_bits * 10 / 8) / lane_num; break;