lcd: update p2p config and pll setting for tl1 [1/1]

PD#SWPL-3108

Problem:
1. tcon pll don't support spread spectrum yet
2. no p2p parameters config

Solution:
1. add p2p config parameters
2. enable tl1 clk parameters auto generate
3. add tl1 tcon_pll spread spectrum support
4. update clk spread spectrum api:
   set ss_level(hex val):
       echo level <val> >/sys/class/lcd/ss
   set ss_freq(hex val):
       echo freq <val> >/sys/class/lcd/ss
   set ss_mode(hex val):
       echo mode <val> >/sys/class/lcd/ss
   set ss advance(hex val, [15:12]=mode, [11:8]=freq, [7:0]=level):
       echo <val> >/sys/class/lcd/ss
   show ss_level, ss_freq, ss_mode:
       cat /sys/class/lcd/ss

Verify:
x301

Change-Id: I99eeca84290403fe766b17673ba9b0f7429fae26
Signed-off-by: Evoke Zhang <evoke.zhang@amlogic.com>

Conflicts:
	arch/arm/boot/dts/amlogic/mesontl1_t309-panel.dtsi
	arch/arm/boot/dts/amlogic/mesontl1_x301-panel.dtsi
	arch/arm/boot/dts/amlogic/mesontm2_t962x3_ab309-panel.dtsi
	drivers/amlogic/media/vout/lcd/lcd_clk_config.c
	drivers/amlogic/media/vout/lcd/lcd_common.h
	drivers/amlogic/media/vout/lcd/lcd_debug.c
	drivers/amlogic/media/vout/lcd/lcd_tv/lcd_drv.c
	drivers/amlogic/media/vout/lcd/lcd_vout.c
	include/linux/amlogic/media/vout/lcd/lcd_vout.h
This commit is contained in:
Evoke Zhang
2018-12-12 16:33:29 +08:00
committed by Dongjin Kim
parent 6f911494ca
commit d0533b8c2b
14 changed files with 748 additions and 628 deletions

View File

@@ -205,7 +205,7 @@
*(0=clk, 1=htotal, 2=vtotal, 3=auto_range,
* 4=hdmi_mode)
*/
3 /*clk_ss_level*/
0 /*clk_ss_level*/
1 /*clk_auto_generate*/
0>; /*pixel_clk(unit in Hz)*/
vbyone_attr = <
@@ -216,7 +216,7 @@
vbyone_intr_enable = <
1 /*vbyone_intr_enable */
3>; /*vbyone_vsync_intr_enable*/
phy_attr=<0xf 1>; /* vswing_level, preem_level */
phy_attr=<3 0>; /* vswing_level, preem_level */
/* power step: type, index, value, delay(ms) */
power_on_step = <0 0 1 50 /*panel power on*/
@@ -247,7 +247,7 @@
*(0=clk, 1=htotal, 2=vtotal, 3=auto_range,
* 4=hdmi_mode)
*/
3 /*clk_ss_level*/
0 /*clk_ss_level*/
1 /*clk_auto_generate*/
0>; /*pixel_clk(unit in Hz)*/
vbyone_attr = <
@@ -258,7 +258,7 @@
vbyone_intr_enable = <
1 /*vbyone_intr_enable*/
3>; /*vbyone_vsync_intr_enable*/
phy_attr=<0xf 1>; /* vswing_level, preem_level */
phy_attr=<3 0>; /*vswing_level, preem_level*/
/* power step: type, index, value, delay(ms) */
power_on_step = <
@@ -302,7 +302,7 @@
vbyone_intr_enable = <
1 /*vbyone_intr_enable*/
3>; /*vbyone_vsync_intr_enable*/
phy_attr=<0xf 1>; /* vswing_level, preem_level */
phy_attr=<3 0>; /*vswing_level, preem_level*/
/* power step: type, index, value, delay(ms) */
power_on_step = <
@@ -335,7 +335,7 @@
*(0=clk, 1=htotal, 2=vtotal, 3=auto_range,
* 4=hdmi_mode)
*/
3 /*clk_ss_level*/
0 /*clk_ss_level*/
1 /*clk_auto_generate*/
0>; /*pixel_clk(unit in Hz)*/
vbyone_attr = <
@@ -346,7 +346,7 @@
vbyone_intr_enable = <
1 /*vbyone_intr_enable*/
3>; /*vbyone_vsync_intr_enable*/
phy_attr=<0xf 1>; /* vswing_level, preem_level */
phy_attr=<3 0>; /*vswing_level, preem_level*/
/* power step: type, index, value, delay(ms) */
power_on_step = <
@@ -381,7 +381,7 @@
*(0=clk, 1=htotal, 2=vtotal, 3=auto_range,
* 4=hdmi_mode)
*/
3 /*clk_ss_level*/
1 /*clk_ss_level*/
1 /*clk_auto_generate*/
0>; /*pixel_clk(unit in Hz)*/
vbyone_attr = <
@@ -392,7 +392,7 @@
vbyone_intr_enable = <
1 /*vbyone_intr_enable*/
3>; /*vbyone_vsync_intr_enable*/
phy_attr=<0xf 1>; /* vswing_level, preem_level */
phy_attr=<3 0>; /*vswing_level, preem_level*/
/* power step: type, index, value, delay(ms) */
power_on_step = <
@@ -407,7 +407,7 @@
0xff 0 0 0>; /*ending*/
backlight_index = <2>;
};
p2p_0{
p2p{
model_name = "p2p_ceds";
interface = "p2p"; /*lcd_interface
*(lvds, vbyone, minilvds, p2p)
@@ -433,16 +433,15 @@
1 /*clk_auto_generate*/
0>; /*pixel_clk(unit in Hz)*/
p2p_attr = <
0x0 /* p2p_teyp:
* 0x0=ceds, 0x1=cmpi, 0x2=isp, 0x3=epi,
* 0x10=chpi, 0x11=cspi, 0x12=usit
*/
0 /* teyp: 0=ceds, 1=cspi, 2=cmpi, 3=isp,
* 4=chpi
*/
12 /* channel_num */
0x76543210 /* channel_sel0 */
0xba98 /* channel_sel1 */
0 /* pn_swap */
0>; /* bit_swap */
phy_attr=<0xf 1>; /* vswing_level, preem_level */
phy_attr=<3 0>; /*vswing_level, preem_level*/
/* power step: type, index, value, delay(ms) */
power_on_step = <
@@ -459,7 +458,7 @@
p2p_1{
model_name = "p2p_ceds";
interface = "p2p"; /*lcd_interface
*(lvds, vbyone, minilvds, p2p)
*(lvds, vbyone, mlvds, p2p)
*/
basic_setting = <
3840 2160 /*h_active, v_active*/
@@ -478,20 +477,19 @@
*(0=clk, 1=htotal, 2=vtotal, 3=auto_range,
* 4=hdmi_mode)
*/
3 /*clk_ss_level*/
0 /*clk_ss_level*/
1 /*clk_auto_generate*/
0>; /*pixel_clk(unit in Hz)*/
p2p_attr = <
0x0 /* p2p_teyp:
* 0x0=ceds, 0x1=cmpi, 0x2=isp, 0x3=epi,
* 0x10=chpi, 0x11=cspi, 0x12=usit
*/
0 /* teyp: 0=ceds, 1=cspi, 2=cmpi, 3=isp,
* 4=chpi
*/
6 /* channel_num */
0x76543210 /* channel_sel0 */
0xba98 /* channel_sel1 */
0 /* pn_swap */
0>; /* bit_swap */
phy_attr=<0xf 1>; /* vswing_level, preem_level */
phy_attr=<3 0>; /*vswing_level, preem_level*/
/* power step: type, index, value, delay(ms) */
power_on_step = <
@@ -507,7 +505,7 @@
p2p_2{
model_name = "p2p_chpi";
interface = "p2p"; /*lcd_interface
*(lvds, vbyone, minilvds, p2p)
*(lvds, vbyone, mlvds, p2p)
*/
basic_setting = <
3840 2160 /*h_active, v_active*/
@@ -526,20 +524,19 @@
*(0=clk, 1=htotal, 2=vtotal, 3=auto_range,
* 4=hdmi_mode)
*/
3 /*clk_ss_level*/
0 /*clk_ss_level*/
1 /*clk_auto_generate*/
0>; /*pixel_clk(unit in Hz)*/
p2p_attr = <
0x10 /* p2p_teyp:
* 0x0=ceds, 0x1=cmpi, 0x2=isp, 0x3=epi,
* 0x10=chpi, 0x11=cspi, 0x12=usit
*/
4 /* teyp: 0=ceds, 1=cspi, 2=cmpi, 3=isp,
* 4=chpi
*/
6 /* channel_num */
0x76543210 /* channel_sel0 */
0xba98 /* channel_sel1 */
0 /* pn_swap */
0>; /* bit_swap */
phy_attr=<0xf 1>; /* vswing_level, preem_level */
phy_attr=<3 0>; /*vswing_level, preem_level*/
/* power step: type, index, value, delay(ms) */
power_on_step = <
@@ -555,7 +552,7 @@
p2p_3{
model_name = "p2p_chpi";
interface = "p2p"; /*lcd_interface
*(lvds, vbyone, minilvds, p2p)
*(lvds, vbyone, mlvds, p2p)
*/
basic_setting = <
3840 2160 /*h_active, v_active*/
@@ -574,110 +571,20 @@
*(0=clk, 1=htotal, 2=vtotal, 3=auto_range,
* 4=hdmi_mode)
*/
3 /*clk_ss_level*/
0 /*clk_ss_level*/
1 /*clk_auto_generate*/
0>; /*pixel_clk(unit in Hz)*/
p2p_attr = <
0x10 /* p2p_teyp:
* 0x0=ceds, 0x1=cmpi, 0x2=isp, 0x3=epi,
* 0x10=chpi, 0x11=cspi, 0x12=usit
*/
4 /* teyp: 0=ceds, 1=cspi, 2=cmpi, 3=isp,
* 4=chpi
*/
12 /* channel_num */
0x76543210 /* channel_sel0 */
0xba98 /* channel_sel1 */
0 /* pn_swap */
0>; /* bit_swap */
phy_attr=<0xf 1>; /* vswing_level, preem_level */
/* power step: type, index, value, delay(ms) */
power_on_step = <
0 0 1 20 /*panel power on*/
2 0 0 10 /*signal enable*/
0xff 0 0 0>; /*ending*/
power_off_step = <
2 0 0 10 /*signal disable*/
0 0 0 100 /*panel power off*/
0xff 0 0 0>; /*ending*/
backlight_index = <0xff>;
};
mlvds_0{
model_name = "mlvds_1080p";
interface = "minilvds"; /*lcd_interface
*(lvds, vbyone, minilvds, p2p)
*/
basic_setting = <
1920 1080 /*h_active, v_active*/
2200 1125 /*h_period, v_period*/
8 /*lcd_bits */
16 9>; /*screen_widht, screen_height*/
range_setting = <
2080 2720 /*h_period_min, max*/
2200 1125 /*v_period_min, max*/
133940000 156000000>; /*pclk_min, max*/
lcd_timing = <
44 148 0 /*hs_width, hs_bp, hs_pol*/
5 30 0>; /*vs_width, vs_bp, vs_pol*/
clk_attr = <
2 /*fr_adj_type
*(0=clk, 1=htotal, 2=vtotal, 3=auto_range,
* 4=hdmi_mode)
*/
3 /*clk_ss_level*/
1 /*clk_auto_generate*/
0>; /*pixel_clk(unit in Hz)*/
minilvds_attr = <
6 /* channel_num */
0x76543210 /* channel_sel0 */
0xba98 /* channel_sel1 */
0x660 /* clk_phase */
0 /* pn_swap */
0>; /* bit_swap */
phy_attr=<0xf 0>; /* vswing_level, preem_level */
/* power step: type, index, value, delay(ms) */
power_on_step = <
0 0 1 20 /*panel power on*/
2 0 0 10 /*signal enable*/
0xff 0 0 0>; /*ending*/
power_off_step = <
2 0 0 10 /*signal disable*/
0 0 0 100 /*panel power off*/
0xff 0 0 0>; /*ending*/
backlight_index = <0xff>;
};
mlvds_1{
model_name = "mlvds_768p";
interface = "minilvds";/*lcd_interface
*(lvds, vbyone, minilvds, p2p)
*/
basic_setting = <
1366 768 /*h_active, v_active*/
1560 806 /*h_period, v_period*/
8 /*lcd_bits */
16 9>; /*screen_widht, screen_height*/
range_setting = <
1460 2000 /*h_period_min, max*/
784 1015 /*v_period_min, max*/
50000000 85000000>; /*pclk_min, max*/
lcd_timing = <
56 64 0 /*hs_width, hs_bp, hs_pol*/
3 28 0>; /*vs_width, vs_bp, vs_pol*/
clk_attr = <
2 /*fr_adj_type
*(0=clk, 1=htotal, 2=vtotal, 3=auto_range,
* 4=hdmi_mode)
*/
3 /*clk_ss_level*/
1 /*clk_auto_generate*/
0>; /*pixel_clk(unit in Hz)*/
minilvds_attr = <
6 /* channel_num */
0x76543210 /* channel_sel0 */
0xba98 /* channel_sel1 */
0x660 /* clk_phase */
0 /* pn_swap */
0>; /* bit_swap */
phy_attr=<0xf 0>; /* vswing_level, preem_level */
phy_attr=<3 0>; /*vswing_level, preem_level*/
/* power step: type, index, value, delay(ms) */
power_on_step = <

View File

@@ -425,7 +425,7 @@
basic_setting = <
3840 2160 /*h_active, v_active*/
5000 2250 /*h_period, v_period*/
10 /*lcd_bits */
8 /*lcd_bits */
16 9>; /*screen_widht, screen_height*/
range_setting = <
4240 5100 /*h_period_min, max*/
@@ -443,16 +443,15 @@
1 /*clk_auto_generate*/
0>; /*pixel_clk(unit in Hz)*/
p2p_attr = <
0x0 /* p2p_teyp:
* 0x0=ceds, 0x1=cmpi, 0x2=isp, 0x3=epi,
* 0x10=chpi, 0x11=cspi, 0x12=usit
*/
0 /* teyp: 0=ceds, 1=cspi, 2=cmpi, 3=isp,
* 4=chpi
*/
12 /* channel_num */
0x76543210 /* channel_sel0 */
0xba98 /* channel_sel1 */
0 /* pn_swap */
0>; /* bit_swap */
phy_attr=<0xf 1>; /* vswing_level, preem_level */
phy_attr=<3 0>; /*vswing_level, preem_level*/
/* power step: type, index, value, delay(ms) */
power_on_step = <
@@ -469,7 +468,7 @@
p2p_1{
model_name = "p2p_ceds";
interface = "p2p"; /*lcd_interface
*(lvds, vbyone, minilvds, p2p)
*(lvds, vbyone, mlvds, p2p)
*/
basic_setting = <
3840 2160 /*h_active, v_active*/
@@ -492,16 +491,15 @@
1 /*clk_auto_generate*/
0>; /*pixel_clk(unit in Hz)*/
p2p_attr = <
0x0 /* p2p_teyp:
* 0x0=ceds, 0x1=cmpi, 0x2=isp, 0x3=epi,
* 0x10=chpi, 0x11=cspi, 0x12=usit
*/
0 /* teyp: 0=ceds, 1=cspi, 2=cmpi, 3=isp,
* 4=chpi
*/
6 /* channel_num */
0x76543210 /* channel_sel0 */
0xba98 /* channel_sel1 */
0 /* pn_swap */
0>; /* bit_swap */
phy_attr=<0xf 1>; /* vswing_level, preem_level */
phy_attr=<3 0>; /*vswing_level, preem_level*/
/* power step: type, index, value, delay(ms) */
power_on_step = <
@@ -517,7 +515,7 @@
p2p_2{
model_name = "p2p_chpi";
interface = "p2p"; /*lcd_interface
*(lvds, vbyone, minilvds, p2p)
*(lvds, vbyone, mlvds, p2p)
*/
basic_setting = <
3840 2160 /*h_active, v_active*/
@@ -540,16 +538,15 @@
1 /*clk_auto_generate*/
0>; /*pixel_clk(unit in Hz)*/
p2p_attr = <
0x10 /* p2p_teyp:
* 0x0=ceds, 0x1=cmpi, 0x2=isp, 0x3=epi,
* 0x10=chpi, 0x11=cspi, 0x12=usit
*/
4 /* teyp: 0=ceds, 1=cspi, 2=cmpi, 3=isp,
* 4=chpi
*/
6 /* channel_num */
0x76543210 /* channel_sel0 */
0xba98 /* channel_sel1 */
0 /* pn_swap */
0>; /* bit_swap */
phy_attr=<0xf 1>; /* vswing_level, preem_level */
phy_attr=<3 0>; /*vswing_level, preem_level*/
/* power step: type, index, value, delay(ms) */
power_on_step = <
@@ -565,7 +562,7 @@
p2p_3{
model_name = "p2p_chpi";
interface = "p2p"; /*lcd_interface
*(lvds, vbyone, minilvds, p2p)
*(lvds, vbyone, mlvds, p2p)
*/
basic_setting = <
3840 2160 /*h_active, v_active*/
@@ -588,106 +585,16 @@
1 /*clk_auto_generate*/
0>; /*pixel_clk(unit in Hz)*/
p2p_attr = <
0x10 /* p2p_teyp:
* 0x0=ceds, 0x1=cmpi, 0x2=isp, 0x3=epi,
* 0x10=chpi, 0x11=cspi, 0x12=usit
*/
4 /* teyp: 0=ceds, 1=cspi, 2=cmpi, 3=isp,
* 4=chpi
*/
12 /* channel_num */
0x76543210 /* channel_sel0 */
0xba98 /* channel_sel1 */
0 /* pn_swap */
0>; /* bit_swap */
phy_attr=<0xf 1>; /* vswing_level, preem_level */
/* power step: type, index, value, delay(ms) */
power_on_step = <
0 0 1 20 /*panel power on*/
2 0 0 10 /*signal enable*/
0xff 0 0 0>; /*ending*/
power_off_step = <
2 0 0 10 /*signal disable*/
0 0 0 100 /*panel power off*/
0xff 0 0 0>; /*ending*/
backlight_index = <0xff>;
};
mlvds_0{
model_name = "mlvds_1080p";
interface = "minilvds"; /*lcd_interface
*(lvds, vbyone, minilvds, p2p)
*/
basic_setting = <
1920 1080 /*h_active, v_active*/
2200 1125 /*h_period, v_period*/
8 /*lcd_bits */
16 9>; /*screen_widht, screen_height*/
range_setting = <
2080 2720 /*h_period_min, max*/
2200 1125 /*v_period_min, max*/
133940000 156000000>; /*pclk_min, max*/
lcd_timing = <
44 148 0 /*hs_width, hs_bp, hs_pol*/
5 30 0>; /*vs_width, vs_bp, vs_pol*/
clk_attr = <
2 /*fr_adj_type
*(0=clk, 1=htotal, 2=vtotal, 3=auto_range,
* 4=hdmi_mode)
*/
0 /*clk_ss_level*/
1 /*clk_auto_generate*/
0>; /*pixel_clk(unit in Hz)*/
minilvds_attr = <
6 /* channel_num */
0x12304567 /* channel_sel0 */
0x0 /* channel_sel1 */
0xaa0 /* clk_phase */
0 /* pn_swap */
0>; /* bit_swap */
phy_attr=<0xf 0>; /* vswing_level, preem_level */
/* power step: type, index, value, delay(ms) */
power_on_step = <
0 0 1 20 /*panel power on*/
2 0 0 10 /*signal enable*/
0xff 0 0 0>; /*ending*/
power_off_step = <
2 0 0 10 /*signal disable*/
0 0 0 100 /*panel power off*/
0xff 0 0 0>; /*ending*/
backlight_index = <0xff>;
};
mlvds_1{
model_name = "mlvds_768p";
interface = "minilvds";/*lcd_interface
*(lvds, vbyone, minilvds, p2p)
*/
basic_setting = <
1366 768 /*h_active, v_active*/
1560 806 /*h_period, v_period*/
8 /*lcd_bits */
16 9>; /*screen_widht, screen_height*/
range_setting = <
1460 2000 /*h_period_min, max*/
784 1015 /*v_period_min, max*/
50000000 85000000>; /*pclk_min, max*/
lcd_timing = <
56 64 0 /*hs_width, hs_bp, hs_pol*/
3 28 0>; /*vs_width, vs_bp, vs_pol*/
clk_attr = <
2 /*fr_adj_type
*(0=clk, 1=htotal, 2=vtotal, 3=auto_range,
* 4=hdmi_mode)
*/
0 /*clk_ss_level*/
1 /*clk_auto_generate*/
0>; /*pixel_clk(unit in Hz)*/
minilvds_attr = <
6 /* channel_num */
0x45603012 /* channel_sel0 */
0x0 /* channel_sel1 */
0xaa0 /* clk_phase */
0 /* pn_swap */
0>; /* bit_swap */
phy_attr=<0xf 0>; /* vswing_level, preem_level */
phy_attr=<3 0>; /*vswing_level, preem_level*/
/* power step: type, index, value, delay(ms) */
power_on_step = <

View File

@@ -240,30 +240,32 @@
1 /*clk_auto_generate*/
0>; /*pixel_clk(unit in Hz)*/
p2p_attr = <
0x0 /* p2p_teyp:
* 0x0=ceds, 0x1=cmpi, 0x2=isp, 0x3=epi,
* 0x10=chpi, 0x11=cspi, 0x12=usit
*/
0 /* teyp: 0=ceds, 1=cspi, 2=cmpi, 3=isp,
* 4=chpi
*/
12 /* channel_num */
0x76543210 /* channel_sel0 */
0xba98 /* channel_sel1 */
0 /* pn_swap */
0>; /* bit_swap */
phy_attr=<0xf 1>; /* vswing_level, preem_level */
phy_attr=<3 0>; /*vswing_level, preem_level*/
/* power step: type, index, value, delay(ms) */
power_on_step = <
0 0 1 20 /*panel power on*/
3 2 0 200 /* extern init voltage */
2 0 0 10 /*signal enable*/
0xff 0 0 0>; /*ending*/
power_off_step = <
2 0 0 10 /*signal disable*/
0 0 0 100 /*panel power off*/
0xff 0 0 0>; /*ending*/
backlight_index = <0xff>;
};
p2p_1{
model_name = "p2p_ceds";
interface = "p2p"; /*lcd_interface
*(lvds, vbyone, minilvds, p2p)
*(lvds, vbyone, mlvds, p2p)
*/
basic_setting = <
3840 2160 /*h_active, v_active*/
@@ -286,30 +288,31 @@
1 /*clk_auto_generate*/
0>; /*pixel_clk(unit in Hz)*/
p2p_attr = <
0x0 /* p2p_teyp:
* 0x0=ceds, 0x1=cmpi, 0x2=isp, 0x3=epi,
* 0x10=chpi, 0x11=cspi, 0x12=usit
*/
0 /* teyp: 0=ceds, 1=cspi, 2=cmpi, 3=isp,
* 4=chpi
*/
6 /* channel_num */
0x76543210 /* channel_sel0 */
0xba98 /* channel_sel1 */
0 /* pn_swap */
0>; /* bit_swap */
phy_attr=<0xf 1>; /* vswing_level, preem_level */
phy_attr=<3 0>; /*vswing_level, preem_level*/
/* power step: type, index, value, delay(ms) */
power_on_step = <
0 0 1 20 /*panel power on*/
2 0 0 10 /*signal enable*/
0xff 0 0 0>; /*ending*/
power_off_step = <
2 0 0 10 /*signal disable*/
0 0 0 100 /*panel power off*/
0xff 0 0 0>; /*ending*/
backlight_index = <0xff>;
};
p2p_2{
model_name = "p2p_chpi";
interface = "p2p"; /*lcd_interface
*(lvds, vbyone, minilvds, p2p)
*(lvds, vbyone, mlvds, p2p)
*/
basic_setting = <
3840 2160 /*h_active, v_active*/
@@ -332,30 +335,31 @@
1 /*clk_auto_generate*/
0>; /*pixel_clk(unit in Hz)*/
p2p_attr = <
0x10 /* p2p_teyp:
* 0x0=ceds, 0x1=cmpi, 0x2=isp, 0x3=epi,
* 0x10=chpi, 0x11=cspi, 0x12=usit
*/
4 /* teyp: 0=ceds, 1=cspi, 2=cmpi, 3=isp,
* 4=chpi
*/
6 /* channel_num */
0x76543210 /* channel_sel0 */
0xba98 /* channel_sel1 */
0 /* pn_swap */
0>; /* bit_swap */
phy_attr=<0xf 1>; /* vswing_level, preem_level */
phy_attr=<3 0>; /*vswing_level, preem_level*/
/* power step: type, index, value, delay(ms) */
power_on_step = <
0 0 1 20 /*panel power on*/
2 0 0 10 /*signal enable*/
0xff 0 0 0>; /*ending*/
power_off_step = <
2 0 0 10 /*signal disable*/
0 0 0 100 /*panel power off*/
0xff 0 0 0>; /*ending*/
backlight_index = <0xff>;
};
p2p_3{
model_name = "p2p_chpi";
interface = "p2p"; /*lcd_interface
*(lvds, vbyone, minilvds, p2p)
*(lvds, vbyone, mlvds, p2p)
*/
basic_setting = <
3840 2160 /*h_active, v_active*/
@@ -378,109 +382,24 @@
1 /*clk_auto_generate*/
0>; /*pixel_clk(unit in Hz)*/
p2p_attr = <
0x10 /* p2p_teyp:
* 0x0=ceds, 0x1=cmpi, 0x2=isp, 0x3=epi,
* 0x10=chpi, 0x11=cspi, 0x12=usit
*/
4 /* teyp: 0=ceds, 1=cspi, 2=cmpi, 3=isp,
* 4=chpi
*/
12 /* channel_num */
0x76543210 /* channel_sel0 */
0xba98 /* channel_sel1 */
0 /* pn_swap */
0>; /* bit_swap */
phy_attr=<0xf 1>; /* vswing_level, preem_level */
/* power step: type, index, value, delay(ms) */
power_on_step = <
2 0 0 10 /*signal enable*/
0xff 0 0 0>; /*ending*/
power_off_step = <
2 0 0 10 /*signal disable*/
0xff 0 0 0>; /*ending*/
backlight_index = <0xff>;
};
mlvds_0{
model_name = "mlvds_1080p";
interface = "minilvds"; /*lcd_interface
*(lvds, vbyone, minilvds, p2p)
*/
basic_setting = <
1920 1080 /*h_active, v_active*/
2200 1125 /*h_period, v_period*/
8 /*lcd_bits */
16 9>; /*screen_widht, screen_height*/
range_setting = <
2080 2720 /*h_period_min, max*/
2200 1125 /*v_period_min, max*/
133940000 156000000>; /*pclk_min, max*/
lcd_timing = <
44 148 0 /*hs_width, hs_bp, hs_pol*/
5 30 0>; /*vs_width, vs_bp, vs_pol*/
clk_attr = <
2 /*fr_adj_type
*(0=clk, 1=htotal, 2=vtotal, 3=auto_range,
* 4=hdmi_mode)
*/
0 /*clk_ss_level*/
1 /*clk_auto_generate*/
0>; /*pixel_clk(unit in Hz)*/
minilvds_attr = <
6 /* channel_num */
0x76543210 /* channel_sel0 */
0xba98 /* channel_sel1 */
0x660 /* clk_phase */
0 /* pn_swap */
0>; /* bit_swap */
phy_attr=<0xf 0>; /* vswing_level, preem_level */
/* power step: type, index, value, delay(ms) */
power_on_step = <
2 0 0 10 /*signal enable*/
0xff 0 0 0>; /*ending*/
power_off_step = <
2 0 0 10 /*signal disable*/
0xff 0 0 0>; /*ending*/
backlight_index = <0xff>;
};
mlvds_1{
model_name = "mlvds_768p";
interface = "minilvds";/*lcd_interface
*(lvds, vbyone, minilvds, p2p)
*/
basic_setting = <
1366 768 /*h_active, v_active*/
1560 806 /*h_period, v_period*/
8 /*lcd_bits */
16 9>; /*screen_widht, screen_height*/
range_setting = <
1460 2000 /*h_period_min, max*/
784 1015 /*v_period_min, max*/
50000000 85000000>; /*pclk_min, max*/
lcd_timing = <
56 64 0 /*hs_width, hs_bp, hs_pol*/
3 28 0>; /*vs_width, vs_bp, vs_pol*/
clk_attr = <
2 /*fr_adj_type
*(0=clk, 1=htotal, 2=vtotal, 3=auto_range,
* 4=hdmi_mode)
*/
0 /*clk_ss_level*/
1 /*clk_auto_generate*/
0>; /*pixel_clk(unit in Hz)*/
minilvds_attr = <
6 /* channel_num */
0x76543210 /* channel_sel0 */
0xba98 /* channel_sel1 */
0x660 /* clk_phase */
0 /* pn_swap */
0>; /* bit_swap */
phy_attr=<0xf 0>; /* vswing_level, preem_level */
phy_attr=<3 0>; /*vswing_level, preem_level*/
/* power step: type, index, value, delay(ms) */
power_on_step = <
0 0 1 20 /*panel power on*/
2 0 0 10 /*signal enable*/
0xff 0 0 0>; /*ending*/
power_off_step = <
2 0 0 10 /*signal disable*/
0 0 0 100 /*panel power off*/
0xff 0 0 0>; /*ending*/
backlight_index = <0xff>;
};

View File

@@ -47,9 +47,11 @@ static struct lcd_clk_config_s clk_conf = { /* unit: kHz */
.pll_od1_sel = 0,
.pll_od2_sel = 0,
.pll_od3_sel = 0,
.pll_pi_div_sel = 0, /* for tcon */
.pll_tcon_div_sel = 0,
.pll_level = 0,
.ss_level = 0,
.ss_freq = 0,
.ss_mode = 0,
.div_sel = 0,
.xd = 0,
.pll_fout = 0,
@@ -163,7 +165,7 @@ pll_lock_end_g12a:
return ret;
}
static void lcd_set_pll_ss_txl(unsigned int ss_level)
static void lcd_set_pll_ss_level_txl(unsigned int level)
{
unsigned int pll_ctrl3, pll_ctrl4;
@@ -172,15 +174,13 @@ static void lcd_set_pll_ss_txl(unsigned int ss_level)
pll_ctrl3 &= ~((0xf << 10) | (1 << 14));
pll_ctrl4 &= ~(0x3 << 2);
ss_level = (ss_level >= SS_LEVEL_MAX_TXL) ? 0 : ss_level;
pll_ctrl3 |= pll_ss_reg_txl[ss_level][0];
pll_ctrl4 |= pll_ss_reg_txl[ss_level][1];
pll_ctrl3 |= pll_ss_reg_txl[level][0];
pll_ctrl4 |= pll_ss_reg_txl[level][1];
lcd_hiu_write(HHI_HDMI_PLL_CNTL3, pll_ctrl3);
lcd_hiu_write(HHI_HDMI_PLL_CNTL4, pll_ctrl4);
LCDPR("set pll spread spectrum: %s\n",
lcd_pll_ss_table_txl[ss_level]);
LCDPR("set pll spread spectrum: %s\n", lcd_ss_level_table_txl[level]);
}
static void lcd_set_pll_txl(struct lcd_clk_config_s *cConf)
@@ -217,10 +217,10 @@ static void lcd_set_pll_txl(struct lcd_clk_config_s *cConf)
LCDERR("hpll lock failed\n");
if (cConf->ss_level > 0)
lcd_set_pll_ss_txl(cConf->ss_level);
lcd_set_pll_ss_level_txl(cConf->ss_level);
}
static void lcd_set_pll_ss_txlx(unsigned int ss_level)
static void lcd_set_pll_ss_level_txlx(unsigned int level)
{
unsigned int pll_ctrl3, pll_ctrl4, pll_ctrl5;
@@ -231,17 +231,15 @@ static void lcd_set_pll_ss_txlx(unsigned int ss_level)
pll_ctrl4 &= ~(0x3 << 2);
pll_ctrl5 &= ~(0x3 << 30);
ss_level = (ss_level >= SS_LEVEL_MAX_TXLX) ? 0 : ss_level;
pll_ctrl3 |= pll_ss_reg_txlx[ss_level][0];
pll_ctrl4 |= pll_ss_reg_txlx[ss_level][1];
pll_ctrl5 |= pll_ss_reg_txlx[ss_level][2];
pll_ctrl3 |= pll_ss_reg_txlx[level][0];
pll_ctrl4 |= pll_ss_reg_txlx[level][1];
pll_ctrl5 |= pll_ss_reg_txlx[level][2];
lcd_hiu_write(HHI_HDMI_PLL_CNTL3, pll_ctrl3);
lcd_hiu_write(HHI_HDMI_PLL_CNTL4, pll_ctrl4);
lcd_hiu_write(HHI_HDMI_PLL_CNTL5, pll_ctrl5);
LCDPR("set pll spread spectrum: %s\n",
lcd_pll_ss_table_txlx[ss_level]);
LCDPR("set pll spread spectrum: %s\n", lcd_ss_level_table_txlx[level]);
}
static void lcd_set_pll_txlx(struct lcd_clk_config_s *cConf)
@@ -275,7 +273,7 @@ static void lcd_set_pll_txlx(struct lcd_clk_config_s *cConf)
LCDERR("hpll lock failed\n");
if (cConf->ss_level > 0)
lcd_set_pll_ss_txlx(cConf->ss_level);
lcd_set_pll_ss_level_txlx(cConf->ss_level);
}
static void lcd_set_pll_axg(struct lcd_clk_config_s *cConf)
@@ -477,40 +475,90 @@ static void lcd_set_hpll_g12b(struct lcd_clk_config_s *cConf)
LCDERR("hpll lock failed\n");
}
static void lcd_set_pll_ss_tl1(unsigned int ss_level)
static void lcd_set_pll_ss_level_tl1(unsigned int level)
{
LCDPR("%s: todo\n", __func__);
unsigned int pll_ctrl2;
unsigned int dep_sel, str_m;
pll_ctrl2 = lcd_hiu_read(HHI_TCON_PLL_CNTL2);
pll_ctrl2 &= ~((1 << 15) | (0xf << 16) | (0xf << 28));
if (level > 0) {
dep_sel = pll_ss_reg_tl1[level][0];
str_m = pll_ss_reg_tl1[level][1];
dep_sel = (dep_sel > 10) ? 10 : dep_sel;
str_m = (str_m > 10) ? 10 : str_m;
pll_ctrl2 |= ((1 << 15) | (dep_sel << 28) | (str_m << 16));
}
lcd_hiu_write(HHI_TCON_PLL_CNTL2, pll_ctrl2);
LCDPR("set pll spread spectrum: %s\n", lcd_ss_level_table_tl1[level]);
}
static void lcd_set_pll_ss_advance_tl1(unsigned int freq, unsigned int mode)
{
unsigned int pll_ctrl2;
pll_ctrl2 = lcd_hiu_read(HHI_TCON_PLL_CNTL2);
pll_ctrl2 &= ~(0x7 << 24); /* ss_freq */
pll_ctrl2 |= (freq << 24);
pll_ctrl2 &= ~(0x3 << 22); /* ss_mode */
pll_ctrl2 |= (mode << 22);
lcd_hiu_write(HHI_TCON_PLL_CNTL2, pll_ctrl2);
LCDPR("set pll spread spectrum: freq=%d, mode=%d\n", freq, mode);
}
static void lcd_set_pll_tl1(struct lcd_clk_config_s *cConf)
{
#if 0
#if 1
unsigned int pll_ctrl, pll_ctrl1;
unsigned int tcon_div_table[5][3] = {
{1, 0, 1},
{0, 0, 1},
{0, 1, 1},
{0, 0, 0},
{0, 1, 0},
};
unsigned int tcon_div_sel = cConf->pll_tcon_div_sel;
int ret;
if (lcd_debug_print_flag == 2)
LCDPR("%s\n", __func__);
pll_ctrl = ((0x3 << 17) | /* gate ctrl */
(1 << LCD_PLL_RST_TL1) |
(tcon_div_table[tcon_div_sel][2] << 16) |
(cConf->pll_n << LCD_PLL_N_TL1) |
(cConf->pll_m << LCD_PLL_M_TL1) |
(cConf->pll_od3_sel << LCD_PLL_OD3_TL1) |
(cConf->pll_od2_sel << LCD_PLL_OD2_TL1) |
(cConf->pll_od1_sel << LCD_PLL_OD1_TL1));
pll_ctrl1 = (1 << 28) | (1 << 23) |
((1 << 20) | (cConf->pll_frac << 0));
pll_ctrl1 = (1 << 28) |
(tcon_div_table[tcon_div_sel][0] << 22) |
(tcon_div_table[tcon_div_sel][1] << 21) |
((1 << 20) | /* sdm_en */
(cConf->pll_frac << 0));
lcd_hiu_write(HHI_TCON_PLL_CNTL0, pll_ctrl);
udelay(10);
lcd_hiu_setb(HHI_TCON_PLL_CNTL0, 1, LCD_PLL_RST_TL1, 1);
udelay(10);
lcd_hiu_setb(HHI_TCON_PLL_CNTL0, 1, LCD_PLL_EN_TL1, 1);
udelay(10);
lcd_hiu_write(HHI_TCON_PLL_CNTL1, pll_ctrl1);
udelay(10);
lcd_hiu_write(HHI_TCON_PLL_CNTL2, 0x00001108);
lcd_hiu_write(HHI_TCON_PLL_CNTL3, 0x10058f30);
lcd_hiu_write(HHI_TCON_PLL_CNTL4, 0x010100c0);
lcd_hiu_write(HHI_TCON_PLL_CNTL4, 0x038300c0);
udelay(10);
lcd_hiu_write(HHI_TCON_PLL_CNTL3, 0x10051400);
udelay(10);
lcd_hiu_write(HHI_TCON_PLL_CNTL4, 0x000100c0);
udelay(10);
lcd_hiu_write(HHI_TCON_PLL_CNTL4, 0x008300c0);
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);
lcd_hiu_write(HHI_TCON_PLL_CNTL4, 0x0b8300c0);
#else
struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
int ret;
@@ -605,8 +653,10 @@ static void lcd_set_pll_tl1(struct lcd_clk_config_s *cConf)
lcd_hiu_setb(HHI_TCON_PLL_CNTL2, 1, 5, 1);
}
if (cConf->ss_level > 0)
lcd_set_pll_ss_tl1(cConf->ss_level);
if (cConf->ss_level > 0) {
lcd_set_pll_ss_level_tl1(cConf->ss_level);
lcd_set_pll_ss_advance_tl1(cConf->ss_freq, cConf->ss_mode);
}
}
static void lcd_set_vid_pll_div(struct lcd_clk_config_s *cConf)
@@ -919,8 +969,7 @@ static int check_pll_txl(struct lcd_clk_config_s *cConf,
return done;
}
static int check_pll_tl1_mlvds(struct lcd_clk_config_s *cConf,
unsigned int pll_fvco)
static int check_pll_vco(struct lcd_clk_config_s *cConf, unsigned int pll_fvco)
{
struct lcd_clk_data_s *data = cConf->data;
unsigned int m, n;
@@ -953,8 +1002,7 @@ static int check_pll_tl1_mlvds(struct lcd_clk_config_s *cConf,
}
#define PLL_FVCO_ERR_MAX 2 /* kHz */
static int check_pll_od_tl1_mlvds(struct lcd_clk_config_s *cConf,
unsigned int pll_fout)
static int check_pll_od(struct lcd_clk_config_s *cConf, unsigned int pll_fout)
{
struct lcd_clk_data_s *data = cConf->data;
unsigned int od1_sel, od2_sel, od3_sel, od1, od2, od3;
@@ -1005,7 +1053,8 @@ static void lcd_clk_generate_txl(struct lcd_config_s *pconf)
{
unsigned int pll_fout, pll_fvco, bit_rate;
unsigned int clk_div_in, clk_div_out;
unsigned int clk_div_sel, xd, pi_div_sel;
unsigned int clk_div_sel, xd, tcon_div_sel = 0, phy_div = 1;
unsigned int od1, od2, od3;
struct lcd_clk_config_s *cConf = get_lcd_clk_config();
int done;
@@ -1078,8 +1127,24 @@ static void lcd_clk_generate_txl(struct lcd_config_s *pconf)
clk_div_sel, pll_fout);
}
done = check_pll_txl(cConf, pll_fout);
if (done)
if (done == 0)
goto generate_clk_done_txl;
done = 0;
if (pconf->lcd_control.lvds_config->dual_port)
phy_div = 2;
else
phy_div = 1;
od1 = od_table[cConf->pll_od1_sel];
od2 = od_table[cConf->pll_od2_sel];
od3 = od_table[cConf->pll_od3_sel];
for (tcon_div_sel = 0; tcon_div_sel < 5; tcon_div_sel++) {
if (tcon_div_table[tcon_div_sel] ==
phy_div * od1 * od2 * od3) {
cConf->pll_tcon_div_sel = tcon_div_sel;
done = 1;
break;
}
}
break;
case LCD_VBYONE:
cConf->div_sel_max = CLK_DIV_SEL_MAX;
@@ -1111,32 +1176,32 @@ static void lcd_clk_generate_txl(struct lcd_config_s *pconf)
cConf->div_sel);
}
done = check_pll_txl(cConf, pll_fout);
if (done == 0)
goto generate_clk_done_txl;
done = 0;
od1 = od_table[cConf->pll_od1_sel];
od2 = od_table[cConf->pll_od2_sel];
od3 = od_table[cConf->pll_od3_sel];
for (tcon_div_sel = 0; tcon_div_sel < 5; tcon_div_sel++) {
if (tcon_div_table[tcon_div_sel] == od1 * od2 * od3) {
cConf->pll_tcon_div_sel = tcon_div_sel;
done = 1;
break;
}
}
break;
case LCD_MLVDS:
/* must go through div4 for clk phase */
for (tcon_div_sel = 3; tcon_div_sel < 5; tcon_div_sel++) {
pll_fvco = bit_rate * tcon_div_table[tcon_div_sel];
bit_rate = pconf->lcd_control.mlvds_config->bit_rate / 1000;
for (tcon_div_sel = 1; tcon_div_sel < 3; tcon_div_sel++) {
pll_fvco = bit_rate * tcon_div_table[tcon_div_sel] * 4;
done = check_pll_vco(cConf, pll_fvco);
if (done == 0)
continue;
cConf->xd_max = CRT_VID_DIV_MAX;
for (xd = 1; xd <= cConf->xd_max; xd++) {
clk_div_out = cConf->fout * xd;
if (clk_div_out > cConf->data->div_out_fmax)
continue;
if (lcd_debug_print_flag == 2) {
LCDPR(
"fout=%d, xd=%d, clk_div_out=%d\n",
cConf->fout, xd, clk_div_out);
}
for (clk_div_sel = CLK_DIV_SEL_1;
clk_div_sel < CLK_DIV_SEL_MAX;
clk_div_sel++) {
clk_div_in = clk_vid_pll_div_calc(
clk_div_out, clk_div_sel,
CLK_DIV_O2I);
if (clk_div_in >
cConf->data->div_in_fmax)
if (done) {
clk_div_sel = CLK_DIV_SEL_1;
cConf->xd_max = CRT_VID_DIV_MAX;
for (xd = 1; xd <= cConf->xd_max; xd++) {
clk_div_out = cConf->fout * xd;
if (clk_div_out >
cConf->data->div_out_fmax)
continue;
if (lcd_debug_print_flag == 2) {
LCDPR("fout=%d, xd=%d\n",
@@ -1178,7 +1243,7 @@ static void lcd_clk_generate_txl(struct lcd_config_s *pconf)
continue;
cConf->xd = xd;
cConf->div_sel = clk_div_sel;
cConf->pll_pi_div_sel = pi_div_sel;
cConf->pll_tcon_div_sel = tcon_div_sel;
pll_fout = clk_div_in;
if (lcd_debug_print_flag == 2) {
LCDPR("clk_div_sel=%s(%d)\n",
@@ -1187,11 +1252,10 @@ static void lcd_clk_generate_txl(struct lcd_config_s *pconf)
clk_div_sel);
LCDPR("pll_fout=%d\n",
pll_fout);
LCDPR("pi_clk_sel=%d\n",
pi_div_sel);
LCDPR("tcon_div_sel=%d\n",
tcon_div_sel);
}
done = check_pll_od_tl1_mlvds(
cConf, pll_fout);
done = check_pll_od(cConf, pll_fout);
if (done)
goto generate_clk_done_txl;
}
@@ -1199,28 +1263,49 @@ static void lcd_clk_generate_txl(struct lcd_config_s *pconf)
}
break;
case LCD_P2P:
clk_div_sel = CLK_DIV_SEL_1;
xd = 1;
clk_div_out = cConf->fout * xd;
if (clk_div_out > cConf->data->div_out_fmax)
goto generate_clk_done_txl;
if (lcd_debug_print_flag == 2) {
LCDPR("fout=%d, xd=%d, clk_div_out=%d\n",
cConf->fout, xd, clk_div_out);
bit_rate = pconf->lcd_control.p2p_config->bit_rate / 1000;
for (tcon_div_sel = 0; tcon_div_sel < 5; tcon_div_sel++) {
pll_fvco = bit_rate * tcon_div_table[tcon_div_sel];
done = check_pll_vco(cConf, pll_fvco);
if (done == 0)
continue;
cConf->xd_max = CRT_VID_DIV_MAX;
for (xd = 1; xd <= cConf->xd_max; xd++) {
clk_div_out = cConf->fout * xd;
if (clk_div_out > cConf->data->div_out_fmax)
continue;
if (lcd_debug_print_flag == 2) {
LCDPR(
"fout=%d, xd=%d, clk_div_out=%d\n",
cConf->fout, xd, clk_div_out);
}
for (clk_div_sel = CLK_DIV_SEL_1;
clk_div_sel < CLK_DIV_SEL_MAX;
clk_div_sel++) {
clk_div_in = clk_vid_pll_div_calc(
clk_div_out, clk_div_sel,
CLK_DIV_O2I);
if (clk_div_in >
cConf->data->div_in_fmax)
continue;
cConf->xd = xd;
cConf->div_sel = clk_div_sel;
cConf->pll_tcon_div_sel = tcon_div_sel;
pll_fout = clk_div_in;
if (lcd_debug_print_flag == 2) {
LCDPR("clk_div_sel=%s(%d)\n",
lcd_clk_div_sel_table[clk_div_sel],
clk_div_sel);
LCDPR(
"pll_fout=%d, tcon_div_sel=%d\n",
pll_fout, tcon_div_sel);
}
done = check_pll_od(cConf, pll_fout);
if (done)
goto generate_clk_done_txl;
}
}
}
clk_div_in = clk_vid_pll_div_calc(clk_div_out,
clk_div_sel, CLK_DIV_O2I);
if (clk_div_in > cConf->data->div_in_fmax)
goto generate_clk_done_txl;
cConf->xd = xd;
cConf->div_sel = clk_div_sel;
pll_fout = clk_div_in;
if (lcd_debug_print_flag == 2) {
LCDPR("clk_div_sel=%s(index %d), pll_fout=%d\n",
lcd_clk_div_sel_table[clk_div_sel],
clk_div_sel, pll_fout);
}
done = check_pll_txl(cConf, pll_fout);
if (done)
goto generate_clk_done_txl;
break;
@@ -2032,7 +2117,9 @@ static void lcd_clk_config_init_print_dft(void)
"div_in_fmax: %d\n"
"div_out_fmax: %d\n"
"xd_out_fmax: %d\n"
"ss_level_max: %d\n\n",
"ss_level_max: %d\n"
"ss_freq_max: %d\n"
"ss_mode_max: %d\n\n",
data->pll_m_max, data->pll_m_min,
data->pll_n_max, data->pll_n_min,
data->pll_od_fb, data->pll_frac_range,
@@ -2041,7 +2128,8 @@ static void lcd_clk_config_init_print_dft(void)
data->pll_vco_fmax, data->pll_vco_fmin,
data->pll_out_fmax, data->pll_out_fmin,
data->div_in_fmax, data->div_out_fmax,
data->xd_out_fmax, data->ss_level_max);
data->xd_out_fmax, data->ss_level_max,
data->ss_freq_max, data->ss_mode_max);
}
static void lcd_clk_config_init_print_axg(void)
@@ -2063,8 +2151,7 @@ static void lcd_clk_config_init_print_axg(void)
"pll_vco_fmin: %d\n"
"pll_out_fmax: %d\n"
"pll_out_fmin: %d\n"
"xd_out_fmax: %d\n"
"ss_level_max: %d\n\n",
"xd_out_fmax: %d\n\n",
data->vclk_sel,
data->pll_m_max, data->pll_m_min,
data->pll_n_max, data->pll_n_min,
@@ -2073,7 +2160,7 @@ static void lcd_clk_config_init_print_axg(void)
data->pll_ref_fmax, data->pll_ref_fmin,
data->pll_vco_fmax, data->pll_vco_fmin,
data->pll_out_fmax, data->pll_out_fmin,
data->xd_out_fmax, data->ss_level_max);
data->xd_out_fmax);
}
static int lcd_clk_config_print_dft(char *buf, int offset)
@@ -2083,28 +2170,31 @@ static int lcd_clk_config_print_dft(char *buf, int offset)
n = lcd_debug_info_len(len + offset);
len += snprintf((buf+len), n,
"lcd clk config:\n"
"pll_mode: %d\n"
"pll_m: %d\n"
"pll_n: %d\n"
"pll_frac: 0x%03x\n"
"pll_fvco: %dkHz\n"
"pll_od1: %d\n"
"pll_od2: %d\n"
"pll_od3: %d\n"
"pll_pi_div_sel: %d\n"
"pll_out: %dkHz\n"
"div_sel: %s(index %d)\n"
"xd: %d\n"
"fout: %dkHz\n"
"ss_level: %d\n\n",
"pll_mode: %d\n"
"pll_m: %d\n"
"pll_n: %d\n"
"pll_frac: 0x%03x\n"
"pll_fvco: %dkHz\n"
"pll_od1: %d\n"
"pll_od2: %d\n"
"pll_od3: %d\n"
"pll_tcon_div_sel: %d\n"
"pll_out: %dkHz\n"
"div_sel: %s(index %d)\n"
"xd: %d\n"
"fout: %dkHz\n"
"ss_level: %d\n"
"ss_freq: %d\n"
"ss_mode: %d\n\n",
clk_conf.pll_mode, clk_conf.pll_m, clk_conf.pll_n,
clk_conf.pll_frac, clk_conf.pll_fvco,
clk_conf.pll_od1_sel, clk_conf.pll_od2_sel,
clk_conf.pll_od3_sel, clk_conf.pll_pi_div_sel,
clk_conf.pll_od3_sel, clk_conf.pll_tcon_div_sel,
clk_conf.pll_fout,
lcd_clk_div_sel_table[clk_conf.div_sel],
clk_conf.div_sel, clk_conf.xd,
clk_conf.fout, clk_conf.ss_level);
clk_conf.fout, clk_conf.ss_level,
clk_conf.ss_freq, clk_conf.ss_mode);
return len;
}
@@ -2123,12 +2213,11 @@ static int lcd_clk_config_print_axg(char *buf, int offset)
"pll_od: %d\n"
"pll_out: %dkHz\n"
"xd: %d\n"
"fout: %dkHz\n"
"ss_level: %d\n\n",
"fout: %dkHz\n\n",
clk_conf.pll_m, clk_conf.pll_n,
clk_conf.pll_frac, clk_conf.pll_fvco,
clk_conf.pll_od1_sel, clk_conf.pll_fout,
clk_conf.xd, clk_conf.fout, clk_conf.ss_level);
clk_conf.xd, clk_conf.fout);
return len;
}
@@ -2149,13 +2238,12 @@ static int lcd_clk_config_print_g12a(char *buf, int offset)
"pll_od: %d\n"
"pll_out: %dkHz\n"
"xd: %d\n"
"fout: %dkHz\n"
"ss_level: %d\n\n",
"fout: %dkHz\n\n",
clk_conf.data->vclk_sel,
clk_conf.pll_m, clk_conf.pll_n,
clk_conf.pll_frac, clk_conf.pll_fvco,
clk_conf.pll_od1_sel, clk_conf.pll_fout,
clk_conf.xd, clk_conf.fout, clk_conf.ss_level);
clk_conf.xd, clk_conf.fout);
} else {
len += snprintf((buf+len), n,
"lcd clk config:\n"
@@ -2170,8 +2258,7 @@ static int lcd_clk_config_print_g12a(char *buf, int offset)
"pll_out: %dkHz\n"
"div_sel: %s(index %d)\n"
"xd: %d\n"
"fout: %dkHz\n"
"ss_level: %d\n\n",
"fout: %dkHz\n\n",
clk_conf.data->vclk_sel,
clk_conf.pll_m, clk_conf.pll_n,
clk_conf.pll_frac, clk_conf.pll_fvco,
@@ -2179,7 +2266,7 @@ static int lcd_clk_config_print_g12a(char *buf, int offset)
clk_conf.pll_od3_sel, clk_conf.pll_fout,
lcd_clk_div_sel_table[clk_conf.div_sel],
clk_conf.div_sel, clk_conf.xd,
clk_conf.fout, clk_conf.ss_level);
clk_conf.fout);
}
return len;
@@ -2200,43 +2287,100 @@ void lcd_clk_generate_parameter(struct lcd_config_s *pconf)
clk_conf.data->clk_generate_parameter(pconf);
}
static char lcd_ss_invalid_str[10] = {'i', 'n', 'v', 'a', 'l', 'i', 'd', '\0',};
char *lcd_get_spread_spectrum(void)
int lcd_get_ss(char *buf)
{
char *ss_str = lcd_ss_invalid_str;
unsigned int level;
unsigned int temp;
int len = 0;
level = clk_conf.ss_level;
if (clk_conf.data) {
level = (level >= clk_conf.data->ss_level_max) ? 0 : level;
if (clk_conf.data->pll_ss_table)
ss_str = clk_conf.data->pll_ss_table[level];
if (clk_conf.data == NULL) {
len += sprintf(buf+len, "lcd clk config data is null\n");
return len;
}
if (clk_conf.data->ss_level_max == 0) {
len += sprintf(buf+len, "lcd spread spectrum is invalid\n");
return len;
}
return ss_str;
temp = (clk_conf.ss_level >= clk_conf.data->ss_level_max) ?
0 : clk_conf.ss_level;
if (clk_conf.data->ss_level_table) {
len += sprintf(buf+len, "ss_level: %s\n",
clk_conf.data->ss_level_table[temp]);
}
temp = (clk_conf.ss_freq >= clk_conf.data->ss_freq_max) ?
0 : clk_conf.ss_freq;
if (clk_conf.data->ss_freq_table) {
len += sprintf(buf+len, "ss_freq: %s\n",
clk_conf.data->ss_freq_table[temp]);
}
temp = (clk_conf.ss_mode >= clk_conf.data->ss_mode_max) ?
0 : clk_conf.ss_mode;
if (clk_conf.data->ss_mode_table) {
len += sprintf(buf+len, "ss_mode: %s\n",
clk_conf.data->ss_mode_table[temp]);
}
return len;
}
void lcd_set_spread_spectrum(unsigned int ss_level)
int lcd_set_ss(unsigned int level, unsigned int freq, unsigned int mode)
{
unsigned long flags = 0;
int ret = -1;
spin_lock_irqsave(&lcd_clk_lock, flags);
if (clk_conf.data == NULL) {
LCDERR("%s: clk config data is null\n", __func__);
goto lcd_set_spread_spectrum_end;
goto lcd_set_ss_end;
}
if (level < 0xff) {
if (level >= clk_conf.data->ss_level_max) {
LCDERR("%s: ss_level %d is out of support (max %d)\n",
__func__, level, clk_conf.data->ss_level_max);
goto lcd_set_ss_end;
}
}
if (freq < 0xff) {
if (freq >= clk_conf.data->ss_freq_max) {
LCDERR("%s: ss_freq %d is out of support (max %d)\n",
__func__, freq, clk_conf.data->ss_freq_max);
goto lcd_set_ss_end;
}
}
if (mode < 0xff) {
if (mode >= clk_conf.data->ss_freq_max) {
LCDERR("%s: ss_mode %d is out of support (max %d)\n",
__func__, mode, clk_conf.data->ss_mode_max);
goto lcd_set_ss_end;
}
}
clk_conf.ss_level = (ss_level >= clk_conf.data->ss_level_max) ?
0 : ss_level;
if (clk_conf.data->set_spread_spectrum)
clk_conf.data->set_spread_spectrum(clk_conf.ss_level);
if (clk_conf.data->set_ss_level) {
if (level < 0xff) {
clk_conf.ss_level = level;
clk_conf.data->set_ss_level(level);
}
}
lcd_set_spread_spectrum_end:
ret = 0;
if (clk_conf.data->set_ss_advance) {
if ((freq == 0xff) && (mode == 0xff))
goto lcd_set_ss_end;
if (freq < 0xff)
clk_conf.ss_freq = freq;
if (mode < 0xff)
clk_conf.ss_mode = mode;
clk_conf.data->set_ss_advance(clk_conf.ss_freq,
clk_conf.ss_mode);
}
lcd_set_ss_end:
spin_unlock_irqrestore(&lcd_clk_lock, flags);
if (lcd_debug_print_flag)
LCDPR("%s\n", __func__);
return ret;
}
/* design for vlock, don't save ss_level to clk_config */
@@ -2573,16 +2717,22 @@ static struct lcd_clk_data_s lcd_clk_data_gxl = {
.div_in_fmax = CLK_DIV_IN_MAX_GXL,
.div_out_fmax = CRT_VID_CLK_IN_MAX_GXL,
.xd_out_fmax = ENCL_CLK_IN_MAX_GXL,
.ss_level_max = SS_LEVEL_MAX_GXL,
.clk_path_valid = 0,
.vclk_sel = 0,
.pll_ctrl_table = pll_ctrl_table_txl,
.pll_ss_table = NULL,
.ss_level_max = 0,
.ss_freq_max = 0,
.ss_mode_max = 0,
.ss_level_table = NULL,
.ss_freq_table = NULL,
.ss_mode_table = NULL,
.clk_generate_parameter = lcd_clk_generate_txl,
.pll_frac_generate = lcd_pll_frac_generate_txl,
.set_spread_spectrum = NULL,
.set_ss_level = NULL,
.set_ss_advance = NULL,
.clk_set = lcd_clk_set_txl,
.clk_gate_switch = lcd_clk_gate_switch_dft,
.clk_gate_optional_switch = NULL,
@@ -2609,16 +2759,22 @@ static struct lcd_clk_data_s lcd_clk_data_txl = {
.div_in_fmax = CLK_DIV_IN_MAX_TXL,
.div_out_fmax = CRT_VID_CLK_IN_MAX_TXL,
.xd_out_fmax = ENCL_CLK_IN_MAX_TXL,
.ss_level_max = SS_LEVEL_MAX_TXL,
.clk_path_valid = 0,
.vclk_sel = 0,
.pll_ctrl_table = pll_ctrl_table_txl,
.pll_ss_table = lcd_pll_ss_table_txl,
.ss_level_max = sizeof(lcd_ss_level_table_txl) / sizeof(char *),
.ss_freq_max = 0,
.ss_mode_max = 0,
.ss_level_table = lcd_ss_level_table_txl,
.ss_freq_table = NULL,
.ss_mode_table = NULL,
.clk_generate_parameter = lcd_clk_generate_txl,
.pll_frac_generate = lcd_pll_frac_generate_txl,
.set_spread_spectrum = lcd_set_pll_ss_txl,
.set_ss_level = lcd_set_pll_ss_level_txl,
.set_ss_advance = NULL,
.clk_set = lcd_clk_set_txl,
.clk_gate_switch = lcd_clk_gate_switch_dft,
.clk_gate_optional_switch = NULL,
@@ -2645,16 +2801,22 @@ static struct lcd_clk_data_s lcd_clk_data_txlx = {
.div_in_fmax = CLK_DIV_IN_MAX_TXLX,
.div_out_fmax = CRT_VID_CLK_IN_MAX_TXLX,
.xd_out_fmax = ENCL_CLK_IN_MAX_TXLX,
.ss_level_max = SS_LEVEL_MAX_TXLX,
.clk_path_valid = 0,
.vclk_sel = 0,
.pll_ctrl_table = pll_ctrl_table_txl,
.pll_ss_table = lcd_pll_ss_table_txlx,
.ss_level_max = sizeof(lcd_ss_level_table_txlx) / sizeof(char *),
.ss_freq_max = 0,
.ss_mode_max = 0,
.ss_level_table = lcd_ss_level_table_txlx,
.ss_freq_table = NULL,
.ss_mode_table = NULL,
.clk_generate_parameter = lcd_clk_generate_txl,
.pll_frac_generate = lcd_pll_frac_generate_txl,
.set_spread_spectrum = lcd_set_pll_ss_txlx,
.set_ss_level = lcd_set_pll_ss_level_txlx,
.set_ss_advance = NULL,
.clk_set = lcd_clk_set_txlx,
.clk_gate_switch = lcd_clk_gate_switch_dft,
.clk_gate_optional_switch = NULL,
@@ -2681,16 +2843,22 @@ static struct lcd_clk_data_s lcd_clk_data_axg = {
.div_in_fmax = 0,
.div_out_fmax = CRT_VID_CLK_IN_MAX_AXG,
.xd_out_fmax = ENCL_CLK_IN_MAX_AXG,
.ss_level_max = SS_LEVEL_MAX_AXG,
.clk_path_valid = 0,
.vclk_sel = 0,
.pll_ctrl_table = pll_ctrl_table_axg,
.pll_ss_table = NULL,
.ss_level_max = 0,
.ss_freq_max = 0,
.ss_mode_max = 0,
.ss_level_table = NULL,
.ss_freq_table = NULL,
.ss_mode_table = NULL,
.clk_generate_parameter = lcd_clk_generate_axg,
.pll_frac_generate = lcd_pll_frac_generate_axg,
.set_spread_spectrum = NULL,
.set_ss_level = NULL,
.set_ss_advance = NULL,
.clk_set = lcd_clk_set_axg,
.clk_gate_switch = lcd_clk_gate_switch_axg,
.clk_gate_optional_switch = NULL,
@@ -2717,16 +2885,22 @@ static struct lcd_clk_data_s lcd_clk_data_g12a_path0 = {
.div_in_fmax = 0,
.div_out_fmax = CRT_VID_CLK_IN_MAX_G12A,
.xd_out_fmax = ENCL_CLK_IN_MAX_G12A,
.ss_level_max = SS_LEVEL_MAX_HPLL_G12A,
.clk_path_valid = 1,
.vclk_sel = 0,
.pll_ctrl_table = pll_ctrl_table_g12a_path0,
.pll_ss_table = NULL,
.ss_level_max = 0,
.ss_freq_max = 0,
.ss_mode_max = 0,
.ss_level_table = NULL,
.ss_freq_table = NULL,
.ss_mode_table = NULL,
.clk_generate_parameter = lcd_clk_generate_hpll_g12a,
.pll_frac_generate = lcd_pll_frac_generate_txl,
.set_spread_spectrum = NULL,
.set_ss_level = NULL,
.set_ss_advance = NULL,
.clk_set = lcd_clk_set_g12a_path0,
.clk_gate_switch = lcd_clk_gate_switch_g12a,
.clk_gate_optional_switch = NULL,
@@ -2753,16 +2927,22 @@ static struct lcd_clk_data_s lcd_clk_data_g12a_path1 = {
.div_in_fmax = 0,
.div_out_fmax = CRT_VID_CLK_IN_MAX_G12A,
.xd_out_fmax = ENCL_CLK_IN_MAX_G12A,
.ss_level_max = SS_LEVEL_MAX_GP0_G12A,
.clk_path_valid = 1,
.vclk_sel = 1,
.pll_ctrl_table = pll_ctrl_table_g12a_path1,
.pll_ss_table = NULL,
.ss_level_max = 0,
.ss_freq_max = 0,
.ss_mode_max = 0,
.ss_level_table = NULL,
.ss_freq_table = NULL,
.ss_mode_table = NULL,
.clk_generate_parameter = lcd_clk_generate_axg,
.pll_frac_generate = lcd_pll_frac_generate_axg,
.set_spread_spectrum = NULL,
.set_ss_level = NULL,
.set_ss_advance = NULL,
.clk_set = lcd_clk_set_g12a_path1,
.clk_gate_switch = lcd_clk_gate_switch_g12a,
.clk_gate_optional_switch = NULL,
@@ -2789,16 +2969,22 @@ static struct lcd_clk_data_s lcd_clk_data_g12b_path0 = {
.div_in_fmax = 0,
.div_out_fmax = CRT_VID_CLK_IN_MAX_G12A,
.xd_out_fmax = ENCL_CLK_IN_MAX_G12A,
.ss_level_max = SS_LEVEL_MAX_HPLL_G12A,
.clk_path_valid = 1,
.vclk_sel = 0,
.pll_ctrl_table = pll_ctrl_table_g12a_path0,
.pll_ss_table = NULL,
.ss_level_max = 0,
.ss_freq_max = 0,
.ss_mode_max = 0,
.ss_level_table = NULL,
.ss_freq_table = NULL,
.ss_mode_table = NULL,
.clk_generate_parameter = lcd_clk_generate_hpll_g12a,
.pll_frac_generate = lcd_pll_frac_generate_txl,
.set_spread_spectrum = NULL,
.set_ss_level = NULL,
.set_ss_advance = NULL,
.clk_set = lcd_clk_set_g12b_path0,
.clk_gate_switch = lcd_clk_gate_switch_g12a,
.clk_gate_optional_switch = NULL,
@@ -2825,16 +3011,22 @@ static struct lcd_clk_data_s lcd_clk_data_g12b_path1 = {
.div_in_fmax = 0,
.div_out_fmax = CRT_VID_CLK_IN_MAX_G12A,
.xd_out_fmax = ENCL_CLK_IN_MAX_G12A,
.ss_level_max = SS_LEVEL_MAX_GP0_G12A,
.clk_path_valid = 1,
.vclk_sel = 1,
.pll_ctrl_table = pll_ctrl_table_g12a_path1,
.pll_ss_table = NULL,
.ss_level_max = 0,
.ss_freq_max = 0,
.ss_mode_max = 0,
.ss_level_table = NULL,
.ss_freq_table = NULL,
.ss_mode_table = NULL,
.clk_generate_parameter = lcd_clk_generate_axg,
.pll_frac_generate = lcd_pll_frac_generate_axg,
.set_spread_spectrum = NULL,
.set_ss_level = NULL,
.set_ss_advance = NULL,
.clk_set = lcd_clk_set_g12b_path1,
.clk_gate_switch = lcd_clk_gate_switch_g12a,
.clk_gate_optional_switch = NULL,
@@ -2861,16 +3053,22 @@ static struct lcd_clk_data_s lcd_clk_data_tl1 = {
.div_in_fmax = CLK_DIV_IN_MAX_TL1,
.div_out_fmax = CRT_VID_CLK_IN_MAX_TL1,
.xd_out_fmax = ENCL_CLK_IN_MAX_TL1,
.ss_level_max = SS_LEVEL_MAX_TL1,
.clk_path_valid = 0,
.vclk_sel = 0,
.pll_ctrl_table = pll_ctrl_table_tl1,
.pll_ss_table = NULL,
.ss_level_max = sizeof(lcd_ss_level_table_tl1) / sizeof(char *),
.ss_freq_max = sizeof(lcd_ss_freq_table_tl1) / sizeof(char *),
.ss_mode_max = sizeof(lcd_ss_mode_table_tl1) / sizeof(char *),
.ss_level_table = lcd_ss_level_table_tl1,
.ss_freq_table = lcd_ss_freq_table_tl1,
.ss_mode_table = lcd_ss_mode_table_tl1,
.clk_generate_parameter = lcd_clk_generate_txl,
.pll_frac_generate = lcd_pll_frac_generate_txl,
.set_spread_spectrum = NULL,
.set_ss_level = lcd_set_pll_ss_level_tl1,
.set_ss_advance = lcd_set_pll_ss_advance_tl1,
.clk_set = lcd_clk_set_tl1,
.clk_gate_switch = lcd_clk_gate_switch_dft,
.clk_gate_optional_switch = lcd_clk_gate_optional_switch_tl1,

View File

@@ -58,16 +58,22 @@ struct lcd_clk_data_s {
unsigned int div_in_fmax;
unsigned int div_out_fmax;
unsigned int xd_out_fmax;
unsigned int ss_level_max;
unsigned char clk_path_valid;
unsigned char vclk_sel;
struct lcd_clk_ctrl_s *pll_ctrl_table;
char **pll_ss_table;
unsigned int ss_level_max;
unsigned int ss_freq_max;
unsigned int ss_mode_max;
char **ss_level_table;
char **ss_freq_table;
char **ss_mode_table;
void (*clk_generate_parameter)(struct lcd_config_s *pconf);
void (*pll_frac_generate)(struct lcd_config_s *pconf);
void (*set_spread_spectrum)(unsigned int ss_level);
void (*set_ss_level)(unsigned int level);
void (*set_ss_advance)(unsigned int freq, unsigned int mode);
void (*clk_set)(struct lcd_config_s *pconf);
void (*clk_gate_switch)(struct aml_lcd_drv_s *lcd_drv, int status);
void (*clk_gate_optional_switch)(struct aml_lcd_drv_s *lcd_drv,
@@ -92,11 +98,13 @@ struct lcd_clk_config_s { /* unit: kHz */
unsigned int pll_od1_sel;
unsigned int pll_od2_sel;
unsigned int pll_od3_sel;
unsigned int pll_pi_div_sel; /* for tcon */
unsigned int pll_tcon_div_sel;
unsigned int pll_level;
unsigned int pll_frac;
unsigned int pll_fout;
unsigned int ss_level;
unsigned int ss_freq;
unsigned int ss_mode;
unsigned int div_sel;
unsigned int xd;
unsigned int div_sel_max;
@@ -131,8 +139,8 @@ extern struct lcd_clk_config_s *get_lcd_clk_config(void);
extern int lcd_clk_config_print(char *buf, int offset);
extern int lcd_encl_clk_msr(void);
extern void lcd_pll_reset(void);
extern char *lcd_get_spread_spectrum(void);
extern void lcd_set_spread_spectrum(unsigned int ss_level);
extern int lcd_get_ss(char *buf);
extern int lcd_set_ss(unsigned int level, unsigned int freq, unsigned int mode);
extern void lcd_clk_update(struct lcd_config_s *pconf);
extern void lcd_clk_set(struct lcd_config_s *pconf);
extern void lcd_clk_disable(void);

View File

@@ -239,13 +239,8 @@
* Spread Spectrum
* **********************************
*/
#define SS_LEVEL_MAX_GXL 0
#define SS_LEVEL_MAX_AXG 0
#define SS_LEVEL_MAX_GP0_G12A 0
#define SS_LEVEL_MAX_HPLL_G12A 0
#define SS_LEVEL_MAX_TXL 5
static char *lcd_pll_ss_table_txl[] = {
static char *lcd_ss_level_table_txl[] = {
"0, disable",
"1, +/-0.3%",
"2, +/-0.4%",
@@ -253,8 +248,7 @@ static char *lcd_pll_ss_table_txl[] = {
"4, +/-1.2%",
};
#define SS_LEVEL_MAX_TXLX 6
static char *lcd_pll_ss_table_txlx[] = {
static char *lcd_ss_level_table_txlx[] = {
"0, disable",
"1, +/-0.3%",
"2, +/-0.5%",
@@ -263,7 +257,35 @@ static char *lcd_pll_ss_table_txlx[] = {
"5, +/-3.0%",
};
#define SS_LEVEL_MAX_TL1 0
static char *lcd_ss_level_table_tl1[] = {
"0, disable",
"1, 5000ppm",
"2, 10000ppm",
"3, 15000ppm",
"4, 20000ppm",
"5, 25000ppm",
"6, 30000ppm",
"7, 35000ppm",
"8, 40000ppm",
"9, 45000ppm",
"10, 50000ppm",
};
static char *lcd_ss_freq_table_tl1[] = {
"0, 29.5KHz",
"1, 31.5KHz",
"2, 50KHz",
"3, 75KHz",
"4, 100KHz",
"5, 150KHz",
"6, 200KHz",
};
static char *lcd_ss_mode_table_tl1[] = {
"0, center ss",
"1, up ss",
"2, down ss",
};
static unsigned int pll_ss_reg_txl[][2] = {
@@ -275,7 +297,6 @@ static unsigned int pll_ss_reg_txl[][2] = {
{((1 << 14) | (0xc << 10)), (0x3 << 2)}, /* 4: +/-1.2% */
};
static unsigned int pll_ss_reg_txlx[][3] = {
/* cntl3 cntl4 cntl5 */
{ 0, 0, 0}, /* disable */
@@ -286,6 +307,21 @@ static unsigned int pll_ss_reg_txlx[][3] = {
{((1 << 14) | (0xa << 10)), (0x3 << 2), (0x2 << 30)}, /* 5: +/-3.0% */
};
static unsigned int pll_ss_reg_tl1[][2] = {
/* dep_sel, str_m */
{ 0, 0}, /* 0: disable */
{10, 1}, /* 1: +/-0.25% */
{10, 2}, /* 2: +/-0.50% */
{10, 3}, /* 3: +/-0.75% */
{10, 4}, /* 4: +/-1.00% */
{10, 5}, /* 5: +/-1.25% */
{10, 6}, /* 1: +/-1.50% */
{10, 7}, /* 2: +/-1.75% */
{10, 8}, /* 3: +/-2.00% */
{10, 9}, /* 4: +/-2.25% */
{10, 10}, /* 5: +/-2.50% */
};
/* **********************************
* pll control
* **********************************
@@ -356,7 +392,7 @@ static const unsigned int od_table[6] = {
1, 2, 4, 8, 16, 32
};
static const unsigned int pi_div_table[2] = {2, 4};
static const unsigned int tcon_div_table[5] = {1, 2, 4, 8, 16};
static char *lcd_clk_div_sel_table[] = {
"1",

View File

@@ -34,11 +34,7 @@
/* 20180928: tl1 support, optimize clk config */
/* 20181012: tl1 support tcon */
/* 20181212: tl1 update p2p config and pll setting */
/* 20181225: update phy config */
/* 20190108: tl1 support tablet mode */
/* 20190115: tl1 tcon all interface support */
/* 20190225: optimize unifykey read flow to avoid crash */
#define LCD_DRV_VERSION "20190225"
#define LCD_DRV_VERSION "20181212"
#define VPP_OUT_SATURATE (1 << 0)

View File

@@ -102,9 +102,14 @@ static const char *lcd_common_usage_str = {
"\n"
" echo <num> > test ; show lcd bist pattern(1~7), 0=disable bist\n"
"\n"
" echo w<v|h|c|p|mh|mp> <reg> <data> > reg ; write data to vcbus|hiu|cbus|periphs|mipi host|mipi phy reg\n"
" echo r<v|h|c|p|mh|mp> <reg> > reg ; read vcbus|hiu|cbus|periphs|mipi host|mipi phy reg\n"
" echo d<v|h|c|p|mh|mp> <reg> <num> > reg ; dump vcbus|hiu|cbus|periphs|mipi host|mipi phy regs\n"
" echo level <val> > ss ; set lcd clk spread spectrum level\n"
" echo freq <val> > ss ; set lcd clk spread spectrum freq\n"
" echo mode <val> > ss ; set lcd clk spread spectrum mode\n"
" cat ss ; show lcd clk spread spectrum information\n"
"\n"
" echo w<v|h|c|p|mh|mp|t> <reg> <data> > reg ; write data to vcbus|hiu|cbus|periphs|mipi host|mipi phy reg\n"
" echo r<v|h|c|p|mh|mp|t> <reg> > reg ; read vcbus|hiu|cbus|periphs|mipi host|mipi phy reg\n"
" echo d<v|h|c|p|mh|mp|t> <reg> <num> > reg ; dump vcbus|hiu|cbus|periphs|mipi host|mipi phy regs\n"
"\n"
" echo <0|1> > print ; 0=disable debug print; 1=enable debug print\n"
" cat print ; read current debug print flag\n"
@@ -465,28 +470,24 @@ static int lcd_info_print_p2p(char *buf, int offset)
n = lcd_debug_info_len(len + offset);
len += snprintf((buf+len), n,
"p2p_type 0x%x\n"
"p2p_type %d\n"
"lane_num %d\n"
"channel_sel1 0x%08x\n"
"channel_sel1 0x%08x\n"
"clk_phase 0x%04x\n"
"pn_swap %u\n"
"bit_swap %u\n"
"phy_vswing 0x%x\n"
"phy_preem 0x%x\n"
"bit_rate %dHz\n"
"pi_clk_sel 0x%03x\n\n",
"phy_vswing 0x%x\n"
"phy_preem 0x%x\n\n",
pconf->lcd_control.p2p_config->p2p_type,
pconf->lcd_control.p2p_config->lane_num,
pconf->lcd_control.p2p_config->channel_sel0,
pconf->lcd_control.p2p_config->channel_sel1,
pconf->lcd_control.p2p_config->clk_phase,
pconf->lcd_control.p2p_config->pn_swap,
pconf->lcd_control.p2p_config->bit_swap,
pconf->lcd_timing.bit_rate,
pconf->lcd_control.p2p_config->phy_vswing,
pconf->lcd_control.p2p_config->phy_preem,
pconf->lcd_control.p2p_config->bit_rate,
pconf->lcd_control.p2p_config->pi_clk_sel);
pconf->lcd_control.p2p_config->phy_vswing,
pconf->lcd_control.p2p_config->phy_preem);
len += lcd_tcon_info_print((buf+len), (len+offset));
@@ -2067,24 +2068,21 @@ static ssize_t lcd_debug_change_store(struct class *class,
break;
case 'p':
p2p_conf = pconf->lcd_control.p2p_config;
ret = sscanf(buf, "p2p %x %d %x %x %d %d",
ret = sscanf(buf, "p2p %d %d %x %x %d %d",
&val[0], &val[1], &val[2], &val[3], &val[4], &val[5]);
if (ret == 6) {
p2p_conf->lane_num = val[0];
p2p_conf->channel_sel0 = val[1];
p2p_conf->channel_sel1 = val[2];
p2p_conf->clk_phase = val[3];
p2p_conf->p2p_type = val[0];
p2p_conf->lane_num = val[1];
p2p_conf->channel_sel0 = val[2];
p2p_conf->channel_sel1 = val[3];
p2p_conf->pn_swap = val[4];
p2p_conf->bit_swap = val[5];
pr_info("change p2p config:\n"
"p2p_type=0x%x, lane_num=%d,\n"
"p2p_type=%d, lane_num=%d,\n"
"channel_sel0=0x%08x, channel_sel1=0x%08x,\n"
"clk_phase=0x%04x,\n"
"pn_swap=%d, bit_swap=%d\n",
p2p_conf->lane_num,
p2p_conf->channel_sel0,
p2p_conf->channel_sel1,
p2p_conf->clk_phase,
p2p_conf->p2p_type, p2p_conf->lane_num,
p2p_conf->channel_sel0, p2p_conf->channel_sel1,
p2p_conf->pn_swap, p2p_conf->bit_swap);
lcd_debug_change_clk_change(pconf->lcd_timing.lcd_clk);
pconf->change_flag = 1;
@@ -2385,24 +2383,81 @@ static ssize_t lcd_debug_fr_policy_store(struct class *class,
static ssize_t lcd_debug_ss_show(struct class *class,
struct class_attribute *attr, char *buf)
{
return sprintf(buf, "get lcd pll spread spectrum: %s\n",
lcd_get_spread_spectrum());
int len;
len = lcd_get_ss(buf);
return len;
}
static ssize_t lcd_debug_ss_store(struct class *class,
struct class_attribute *attr, const char *buf, size_t count)
{
int ret = 0;
unsigned int temp = 0;
unsigned int value = 0, temp;
struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
ret = kstrtouint(buf, 10, &temp);
if (ret) {
pr_info("invalid data\n");
return -EINVAL;
temp = lcd_drv->lcd_config->lcd_timing.ss_level;
switch (buf[0]) {
case 'l':
ret = sscanf(buf, "level %x", &value);
if (ret == 1) {
value &= 0xff;
ret = lcd_set_ss(value, 0xff, 0xff);
if (ret == 0) {
temp &= ~(0xff);
temp |= value;
lcd_drv->lcd_config->lcd_timing.ss_level = temp;
}
} else {
pr_info("invalid data\n");
return -EINVAL;
}
break;
case 'f':
ret = sscanf(buf, "freq %x", &value);
if (ret == 1) {
value &= 0xf;
ret = lcd_set_ss(0xff, value, 0xff);
if (ret == 0) {
temp &= ~((0xf << LCD_CLK_SS_BIT_FREQ) << 8);
temp |= ((value << LCD_CLK_SS_BIT_FREQ) << 8);
lcd_drv->lcd_config->lcd_timing.ss_level = temp;
}
} else {
pr_info("invalid data\n");
return -EINVAL;
}
break;
case 'm':
ret = sscanf(buf, "mode %x", &value);
if (ret == 1) {
value &= 0xf;
ret = lcd_set_ss(0xff, 0xff, value);
if (ret == 0) {
temp &= ~((0xf << LCD_CLK_SS_BIT_MODE) << 8);
temp |= ((value << LCD_CLK_SS_BIT_MODE) << 8);
lcd_drv->lcd_config->lcd_timing.ss_level = temp;
}
} else {
pr_info("invalid data\n");
return -EINVAL;
}
break;
default:
ret = kstrtouint(buf, 16, &value);
if (ret) {
pr_info("invalid data\n");
return -EINVAL;
}
value &= 0xffff;
temp = value >> 8;
ret = lcd_set_ss((value & 0xff),
((temp >> LCD_CLK_SS_BIT_FREQ) & 0xf),
((temp >> LCD_CLK_SS_BIT_MODE) & 0xf));
if (ret == 0)
lcd_drv->lcd_config->lcd_timing.ss_level = value;
break;
}
lcd_drv->lcd_config->lcd_timing.ss_level = temp;
lcd_set_spread_spectrum(temp);
return count;
}
@@ -2525,9 +2580,9 @@ static ssize_t lcd_debug_mute_store(struct class *class,
}
static void lcd_debug_reg_write(unsigned int reg, unsigned int data,
unsigned int type)
unsigned int bus)
{
switch (type) {
switch (bus) {
case 0: /* vcbus */
lcd_vcbus_write(reg, data);
pr_info("write vcbus [0x%04x] = 0x%08x, readback 0x%08x\n",
@@ -3545,19 +3600,17 @@ static ssize_t lcd_p2p_debug_store(struct class *class,
struct p2p_config_s *p2p_conf;
p2p_conf = lcd_drv->lcd_config->lcd_control.p2p_config;
ret = sscanf(buf, "%x %d %x %x %d %d",
ret = sscanf(buf, "%d %d %x %x %d %d",
&p2p_conf->p2p_type, &p2p_conf->lane_num,
&p2p_conf->channel_sel0, &p2p_conf->channel_sel1,
&p2p_conf->pn_swap, &p2p_conf->bit_swap);
if (ret == 6) {
pr_info("set p2p config:\n"
"p2p_type=0x%x, lane_num=%d,\n"
"p2p_type=%d, lane_num=%d,\n"
"channel_sel0=0x%08x, channel_sel1=0x%08x,\n"
"clk_phase=0x%04x,\n"
"pn_swap=%d, bit_swap=%d\n",
p2p_conf->lane_num,
p2p_conf->p2p_type, p2p_conf->lane_num,
p2p_conf->channel_sel0, p2p_conf->channel_sel1,
p2p_conf->clk_phase,
p2p_conf->pn_swap, p2p_conf->bit_swap);
lcd_debug_config_update();
} else {

View File

@@ -195,7 +195,7 @@ static inline void __iomem *check_lcd_tcon_reg(unsigned int _reg)
reg_offset = LCD_REG_OFFSET(_reg);
if (reg_offset >= lcd_reg_map[reg_bus].size) {
LCDERR("invalid dsi_phy reg offset: 0x%04x\n", _reg);
LCDERR("invalid tcon reg offset: 0x%04x\n", _reg);
return NULL;
}
p = lcd_reg_map[reg_bus].p + reg_offset;
@@ -214,7 +214,7 @@ static inline void __iomem *check_lcd_tcon_reg_byte(unsigned int _reg)
reg_offset = LCD_REG_OFFSET_BYTE(_reg);
if (reg_offset >= lcd_reg_map[reg_bus].size) {
LCDERR("invalid dsi_phy reg offset: 0x%04x\n", _reg);
LCDERR("invalid tcon reg offset: 0x%04x\n", _reg);
return NULL;
}
p = lcd_reg_map[reg_bus].p + reg_offset;

View File

@@ -719,7 +719,7 @@ static int lcd_config_load_from_dts(struct lcd_config_s *pconf,
pconf->lcd_timing.lcd_clk = 60;
} else {
pconf->lcd_timing.fr_adjust_type = (unsigned char)(para[0]);
pconf->lcd_timing.ss_level = (unsigned char)(para[1]);
pconf->lcd_timing.ss_level = para[1];
pconf->lcd_timing.clk_auto = (unsigned char)(para[2]);
if (para[3] > 0) {
pconf->lcd_timing.lcd_clk = para[3];
@@ -1162,18 +1162,17 @@ static int lcd_config_load_from_unifykey(struct lcd_config_s *pconf)
static void lcd_config_init(struct lcd_config_s *pconf)
{
struct lcd_clk_config_s *cconf = get_lcd_clk_config();
unsigned int ss_level;
unsigned int clk;
unsigned int temp;
unsigned int sync_duration, h_period, v_period;
clk = pconf->lcd_timing.lcd_clk;
temp = pconf->lcd_timing.lcd_clk;
h_period = pconf->lcd_basic.h_period;
v_period = pconf->lcd_basic.v_period;
if (clk < 200) { /* regard as frame_rate */
sync_duration = clk * 100;
pconf->lcd_timing.lcd_clk = clk * h_period * v_period;
if (temp < 200) { /* regard as frame_rate */
sync_duration = temp * 100;
pconf->lcd_timing.lcd_clk = temp * h_period * v_period;
} else { /* regard as pixel clock */
sync_duration = ((clk / h_period) * 100) / v_period;
sync_duration = ((temp / h_period) * 100) / v_period;
}
pconf->lcd_timing.sync_duration_num = sync_duration;
pconf->lcd_timing.sync_duration_den = 100;
@@ -1186,13 +1185,23 @@ static void lcd_config_init(struct lcd_config_s *pconf)
lcd_tablet_config_update(pconf);
lcd_clk_generate_parameter(pconf);
ss_level = pconf->lcd_timing.ss_level;
if (cconf->data) {
cconf->ss_level = (ss_level >= cconf->data->ss_level_max) ?
0 : ss_level;
temp = pconf->lcd_timing.ss_level & 0xff;
cconf->ss_level = (temp >= cconf->data->ss_level_max) ?
0 : temp;
temp = (pconf->lcd_timing.ss_level >> 8) & 0xff;
temp = (temp >> LCD_CLK_SS_BIT_FREQ) & 0xf;
cconf->ss_freq = (temp >= cconf->data->ss_freq_max) ?
0 : temp;
temp = (pconf->lcd_timing.ss_level >> 8) & 0xff;
temp = (temp >> LCD_CLK_SS_BIT_MODE) & 0xf;
cconf->ss_mode = (temp >= cconf->data->ss_mode_max) ?
0 : temp;
} else {
LCDERR("%s: clk config data is null\n", __func__);
cconf->ss_level = 0;
cconf->ss_freq = 0;
cconf->ss_mode = 0;
}
lcd_tablet_config_post_update(pconf);

View File

@@ -314,7 +314,15 @@ static void lcd_p2p_phy_set(struct lcd_config_s *pconf, int status)
lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL11, 0);
lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL4, 0x06020602);
lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL12, 0);
lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL6, 0x06020602);
switch (pconf->lcd_control.p2p_config->p2p_type) {
case P2P_CHPI:
lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL6, 0x06020602);
lcd_hiu_setb(HHI_DIF_CSI_PHY_CNTL6, 1, 30, 1);
break;
default:
lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL6, 0x06020602);
break;
}
lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL13, 0);
lcd_hiu_write(HHI_DIF_CSI_PHY_CNTL7, 0x06020602);
} else {
@@ -338,11 +346,22 @@ static void lcd_p2p_phy_set(struct lcd_config_s *pconf, int status)
static void lcd_encl_tcon_set(struct lcd_config_s *pconf)
{
unsigned int lcd_bits;
lcd_vcbus_write(L_RGB_BASE_ADDR, 0);
lcd_vcbus_write(L_RGB_COEFF_ADDR, 0x400);
aml_lcd_notifier_call_chain(LCD_EVENT_GAMMA_UPDATE, NULL);
switch (pconf->lcd_basic.lcd_bits) {
switch (pconf->lcd_basic.lcd_type) {
case LCD_MLVDS:
case LCD_P2P:
lcd_bits = 10;
break;
default:
lcd_bits = pconf->lcd_basic.lcd_bits;
break;
}
switch (lcd_bits) {
case 8:
lcd_vcbus_write(L_DITH_CNTL_ADDR, 0x400);
break;
@@ -1512,10 +1531,22 @@ static void lcd_p2p_control_set(struct lcd_config_s *pconf)
{
struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
unsigned int reg_cntl0, reg_cntl1;
unsigned int phy_div;
unsigned int channel_sel0, channel_sel1;
if (lcd_debug_print_flag)
LCDPR("%s\n", __func__);
/* phy_div: 0=div6, 1=div 7, 2=div8, 3=div10 */
switch (pconf->lcd_control.p2p_config->p2p_type) {
case P2P_CHPI: /* 8/10 coding */
phy_div = 3;
break;
default:
phy_div = 2;
break;
}
switch (lcd_drv->data->chip_type) {
case LCD_CHIP_TL1:
case LCD_CHIP_TM2:
@@ -1529,7 +1560,7 @@ static void lcd_p2p_control_set(struct lcd_config_s *pconf)
}
/* fifo_clk_sel[7:6]: 0=div6, 1=div 7, 2=div8, 3=div10 */
lcd_hiu_write(reg_cntl0, (2 << 6));
lcd_hiu_write(reg_cntl0, (phy_div << 6));
/* serializer_en[27:16] */
lcd_hiu_setb(reg_cntl0, 0xfff, 16, 12);
/* pn swap[2] */
@@ -1541,9 +1572,11 @@ static void lcd_p2p_control_set(struct lcd_config_s *pconf)
lcd_hiu_setb(reg_cntl1, 1, 31, 1);
/* channel swap default no swap */
lcd_vcbus_write(LVDS_CH_SWAP0, 0x3210);
lcd_vcbus_write(LVDS_CH_SWAP1, 0x7654);
lcd_vcbus_write(LVDS_CH_SWAP2, 0xba98);
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_tcon_enable(pconf);
}
@@ -1697,7 +1730,7 @@ static void lcd_p2p_config_set(struct lcd_config_s *pconf)
break;
}
pconf->lcd_timing.bit_rate = bit_rate * 1000;
pconf->lcd_control.p2p_config->bit_rate = bit_rate * 1000;
if (lcd_debug_print_flag) {
LCDPR("lane_num=%u, bit_rate=%u.%03uMHz, pclk=%u.%03uMhz\n",
@@ -1718,6 +1751,9 @@ void lcd_tv_clk_config_change(struct lcd_config_s *pconf)
case LCD_MLVDS:
lcd_mlvds_config_set(pconf);
break;
case LCD_P2P:
lcd_p2p_config_set(pconf);
break;
default:
break;
}
@@ -1758,6 +1794,9 @@ void lcd_tv_config_update(struct lcd_config_s *pconf)
case LCD_MLVDS:
lcd_mlvds_config_set(pconf);
break;
case LCD_P2P:
lcd_p2p_config_set(pconf);
break;
default:
break;
}
@@ -1855,8 +1894,8 @@ int lcd_tv_driver_init(void)
break;
case LCD_P2P:
lcd_tcon_pinmux_set(1);
lcd_p2p_control_set(pconf);
lcd_p2p_phy_set(pconf, 1);
lcd_p2p_control_set(pconf);
break;
default:
break;

View File

@@ -801,6 +801,7 @@ static int lcd_config_load_from_dts(struct lcd_config_s *pconf,
struct device_node *child;
struct lvds_config_s *lvdsconf;
struct vbyone_config_s *vx1_conf;
struct p2p_config_s *p2p_conf;
child = of_get_child_by_name(dev->of_node, pconf->lcd_propname);
if (child == NULL) {
@@ -877,9 +878,9 @@ static int lcd_config_load_from_dts(struct lcd_config_s *pconf,
pconf->lcd_timing.lcd_clk = 60;
} else {
pconf->lcd_timing.fr_adjust_type = (unsigned char)(para[0]);
pconf->lcd_timing.ss_level = (unsigned char)(para[1]);
pconf->lcd_timing.ss_level = para[1];
pconf->lcd_timing.clk_auto = (unsigned char)(para[2]);
pconf->lcd_timing.lcd_clk = (unsigned char)(para[3]);
pconf->lcd_timing.lcd_clk = para[3];
}
switch (pconf->lcd_basic.lcd_type) {
@@ -1006,6 +1007,33 @@ static int lcd_config_load_from_dts(struct lcd_config_s *pconf,
}
break;
case LCD_P2P:
p2p_conf = pconf->lcd_control.p2p_config;
ret = of_property_read_u32_array(child, "p2p_attr",
&para[0], 6);
if (ret) {
LCDERR("failed to get p2p_attr\n");
} else {
p2p_conf->p2p_type = para[0];
p2p_conf->lane_num = para[1];
p2p_conf->channel_sel0 = para[2];
p2p_conf->channel_sel1 = para[3];
p2p_conf->pn_swap = para[4];
p2p_conf->bit_swap = para[5];
}
ret = of_property_read_u32_array(child, "phy_attr",
&para[0], 2);
if (ret) {
if (lcd_debug_print_flag)
LCDPR("failed to get phy_attr\n");
} else {
p2p_conf->phy_vswing = para[0];
p2p_conf->phy_preem = para[1];
if (lcd_debug_print_flag) {
LCDPR("phy vswing=0x%x, preem=0x%x\n",
p2p_conf->phy_vswing,
p2p_conf->phy_preem);
}
}
break;
default:
LCDERR("invalid lcd type\n");
@@ -1027,6 +1055,7 @@ static int lcd_config_load_from_unifykey(struct lcd_config_s *pconf)
struct aml_lcd_unifykey_header_s lcd_header;
struct lvds_config_s *lvdsconf = pconf->lcd_control.lvds_config;
struct vbyone_config_s *vx1_conf = pconf->lcd_control.vbyone_config;
struct p2p_config_s *p2p_conf = pconf->lcd_control.p2p_config;
int ret;
para = kmalloc((sizeof(unsigned char) * LCD_UKEY_LCD_SIZE), GFP_KERNEL);
@@ -1201,6 +1230,27 @@ static int lcd_config_load_from_unifykey(struct lcd_config_s *pconf)
((*(p + LCD_UKEY_IF_ATTR_7 + 1)) << 8)) & 0xff;
lvdsconf->lane_reverse = 0;
}
} else if (pconf->lcd_basic.lcd_type == LCD_P2P) {
p2p_conf->p2p_type = (*(p + LCD_UKEY_IF_ATTR_0) |
((*(p + LCD_UKEY_IF_ATTR_0 + 1)) << 8));
p2p_conf->lane_num = (*(p + LCD_UKEY_IF_ATTR_1) |
((*(p + LCD_UKEY_IF_ATTR_1 + 1)) << 8));
p2p_conf->channel_sel0 = (*(p + LCD_UKEY_IF_ATTR_2) |
((*(p + LCD_UKEY_IF_ATTR_2 + 1)) << 8) |
(*(p + LCD_UKEY_IF_ATTR_3) << 16) |
((*(p + LCD_UKEY_IF_ATTR_3 + 1)) << 24));
p2p_conf->channel_sel1 = (*(p + LCD_UKEY_IF_ATTR_4) |
((*(p + LCD_UKEY_IF_ATTR_4 + 1)) << 8) |
(*(p + LCD_UKEY_IF_ATTR_5) << 16) |
((*(p + LCD_UKEY_IF_ATTR_5 + 1)) << 24));
p2p_conf->pn_swap = (*(p + LCD_UKEY_IF_ATTR_6) |
((*(p + LCD_UKEY_IF_ATTR_6 + 1)) << 8));
p2p_conf->bit_swap = (*(p + LCD_UKEY_IF_ATTR_7) |
((*(p + LCD_UKEY_IF_ATTR_7 + 1)) << 8));
p2p_conf->phy_vswing = (*(p + LCD_UKEY_IF_ATTR_8) |
((*(p + LCD_UKEY_IF_ATTR_8 + 1)) << 8));
p2p_conf->phy_preem = (*(p + LCD_UKEY_IF_ATTR_9) |
((*(p + LCD_UKEY_IF_ATTR_9 + 1)) << 8));
} else
LCDERR("unsupport lcd_type: %d\n", pconf->lcd_basic.lcd_type);
@@ -1265,19 +1315,19 @@ static void lcd_vmode_init(struct lcd_config_s *pconf)
static void lcd_config_init(struct lcd_config_s *pconf)
{
struct lcd_clk_config_s *cconf = get_lcd_clk_config();
unsigned int ss_level;
unsigned int clk;
unsigned int temp;
if (pconf->lcd_timing.lcd_clk == 0) /* default 0 for 60hz */
pconf->lcd_timing.lcd_clk = 60;
else
LCDPR("custome clk: %d\n", pconf->lcd_timing.lcd_clk);
clk = pconf->lcd_timing.lcd_clk;
if (clk < 200) { /* regard as frame_rate */
pconf->lcd_timing.lcd_clk = clk * pconf->lcd_basic.h_period *
temp = pconf->lcd_timing.lcd_clk;
if (temp < 200) { /* regard as frame_rate */
pconf->lcd_timing.lcd_clk = temp * pconf->lcd_basic.h_period *
pconf->lcd_basic.v_period;
} else /* regard as pixel clock */
pconf->lcd_timing.lcd_clk = clk;
} else { /* regard as pixel clock */
pconf->lcd_timing.lcd_clk = temp;
}
pconf->lcd_timing.lcd_clk_dft = pconf->lcd_timing.lcd_clk;
pconf->lcd_timing.h_period_dft = pconf->lcd_basic.h_period;
@@ -1287,13 +1337,23 @@ static void lcd_config_init(struct lcd_config_s *pconf)
lcd_vmode_init(pconf);
lcd_tv_config_update(pconf);
lcd_clk_generate_parameter(pconf);
ss_level = pconf->lcd_timing.ss_level;
if (cconf->data) {
cconf->ss_level = (ss_level >= cconf->data->ss_level_max) ?
0 : ss_level;
temp = pconf->lcd_timing.ss_level & 0xff;
cconf->ss_level = (temp >= cconf->data->ss_level_max) ?
0 : temp;
temp = (pconf->lcd_timing.ss_level >> 8) & 0xff;
temp = (temp >> LCD_CLK_SS_BIT_FREQ) & 0xf;
cconf->ss_freq = (temp >= cconf->data->ss_freq_max) ?
0 : temp;
temp = (pconf->lcd_timing.ss_level >> 8) & 0xff;
temp = (temp >> LCD_CLK_SS_BIT_MODE) & 0xf;
cconf->ss_mode = (temp >= cconf->data->ss_mode_max) ?
0 : temp;
} else {
LCDERR("%s: clk config data is null\n", __func__);
cconf->ss_level = 0;
cconf->ss_freq = 0;
cconf->ss_mode = 0;
}
}

View File

@@ -48,6 +48,7 @@
#endif
#include "lcd_reg.h"
#include "lcd_common.h"
#include "lcd_clk_config.h"
#define LCD_CDEV_NAME "lcd"
@@ -129,15 +130,14 @@ static struct mlvds_config_s lcd_mlvds_config = {
static struct p2p_config_s lcd_p2p_config = {
.p2p_type = P2P_MAX,
.port_num = 6,
.lane_num = 12,
.channel_sel0 = 0x76543210,
.channel_sel1 = 0xba98,
.clk_phase = 0,
.pn_swap = 0,
.bit_swap = 0,
.phy_vswing = 0,
.phy_preem = 0,
.bit_rate = 0,
};
static unsigned char dsi_init_on_table[DSI_INIT_ON_MAX] = {0xff, 0xff};
@@ -260,8 +260,7 @@ static void lcd_power_ctrl(int status)
#ifdef CONFIG_AMLOGIC_LCD_EXTERN
struct aml_lcd_extern_driver_s *ext_drv;
#endif
unsigned int i, index, wait, temp;
int value = -1;
unsigned int i, index, value, temp;
int ret = 0;
LCDPR("%s: %d\n", __func__, status);
@@ -314,19 +313,6 @@ static void lcd_power_ctrl(int status)
break;
#endif
case LCD_POWER_TYPE_WAIT_GPIO:
index = power_step->index;
lcd_cpu_gpio_set(index, LCD_GPIO_INPUT);
LCDPR("lcd_power_type_wait_gpio wait\n");
for (wait = 0; wait < power_step->delay; wait++) {
value = lcd_cpu_gpio_get(index);
if (value == power_step->value) {
LCDPR("wait_gpio %d ok\n", value);
break;
}
mdelay(1);
}
if (wait == power_step->delay)
LCDERR("wait_gpio %d timeout!\n", value);
break;
case LCD_POWER_TYPE_CLK_SS:
temp = lcd_driver->lcd_config->lcd_timing.ss_level;

View File

@@ -138,18 +138,19 @@ struct lcd_basic_s {
#define LCD_CLK_PLL_CHANGE (1 << 1)
struct lcd_timing_s {
unsigned char clk_auto; /* clk parameters auto generation */
unsigned char fr_adjust_type; /* 0=clock, 1=htotal, 2=vtotal */
unsigned char clk_change; /* internal used */
unsigned int lcd_clk; /* pixel clock(unit: Hz) */
unsigned int lcd_clk_dft; /* internal used */
unsigned int bit_rate; /* Hz */
unsigned int h_period_dft; /* internal used */
unsigned int v_period_dft; /* internal used */
unsigned char clk_change; /* internal used */
unsigned int pll_ctrl; /* pll settings */
unsigned int div_ctrl; /* divider settings */
unsigned int clk_ctrl; /* clock settings */
unsigned char fr_adjust_type; /* 0=clock, 1=htotal, 2=vtotal */
unsigned char ss_level;
unsigned int ss_level; /* [15:12]: ss_freq, [11:8]: ss_mode,
* [7:0]: ss_level
*/
unsigned int sync_duration_num;
unsigned int sync_duration_den;
@@ -340,28 +341,24 @@ struct mlvds_config_s {
enum p2p_type_e {
P2P_CEDS = 0,
P2P_CSPI,
P2P_CMPI,
P2P_ISP,
P2P_EPI,
P2P_CHPI = 0x10, /* low common mode */
P2P_CSPI,
P2P_USIT,
P2P_CHPI,
P2P_MAX,
};
struct p2p_config_s {
unsigned int p2p_type;
unsigned int port_num;
unsigned int lane_num;
unsigned int channel_sel0;
unsigned int channel_sel1;
unsigned int clk_phase; /* [13:12]=clk01_pi_sel,
* [11:8]=pi2, [7:4]=pi1, [3:0]=pi0
*/
unsigned int pn_swap;
unsigned int bit_swap; /* MSB/LSB reverse */
unsigned int phy_vswing;
unsigned int phy_preem;
/* internal used */
unsigned int bit_rate; /* Hz */
};
struct lcd_control_config_s {
@@ -383,6 +380,8 @@ enum lcd_power_type_e {
LCD_POWER_TYPE_PMU,
LCD_POWER_TYPE_SIGNAL,
LCD_POWER_TYPE_EXTERN,
LCD_POWER_TYPE_WAIT_GPIO,
LCD_POWER_TYPE_CLK_SS,
LCD_POWER_TYPE_MAX,
};
@@ -395,6 +394,9 @@ enum lcd_pmu_gpio_e {
LCD_PMU_GPIO_MAX,
};
#define LCD_CLK_SS_BIT_FREQ 0
#define LCD_CLK_SS_BIT_MODE 4
#define LCD_GPIO_MAX 0xff
#define LCD_GPIO_OUTPUT_LOW 0
#define LCD_GPIO_OUTPUT_HIGH 1