aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/dss/hdmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/omap2/dss/hdmi.c')
-rw-r--r--drivers/video/omap2/dss/hdmi.c42
1 files changed, 19 insertions, 23 deletions
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index bfd113ce3b47..47e9f4abe322 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -59,7 +59,6 @@ static struct {
59 u8 edid[HDMI_EDID_MAX_LENGTH]; 59 u8 edid[HDMI_EDID_MAX_LENGTH];
60 u8 edid_set; 60 u8 edid_set;
61 bool custom_set; 61 bool custom_set;
62 struct hdmi_config cfg;
63 62
64 struct clk *sys_clk; 63 struct clk *sys_clk;
65} hdmi; 64} hdmi;
@@ -229,12 +228,11 @@ int hdmi_init_display(struct omap_dss_device *dssdev)
229 return 0; 228 return 0;
230} 229}
231 230
232static int hdmi_pll_init(struct hdmi_ip_data *ip_data, 231static int hdmi_pll_init(struct hdmi_ip_data *ip_data)
233 enum hdmi_clk_refsel refsel, int dcofreq,
234 struct hdmi_pll_info *fmt, u16 sd)
235{ 232{
236 u32 r; 233 u32 r;
237 void __iomem *pll_base = hdmi_pll_base(ip_data); 234 void __iomem *pll_base = hdmi_pll_base(ip_data);
235 struct hdmi_pll_info *fmt = &ip_data->pll_data;
238 236
239 /* PLL start always use manual mode */ 237 /* PLL start always use manual mode */
240 REG_FLD_MOD(pll_base, PLLCTRL_PLL_CONTROL, 0x0, 0, 0); 238 REG_FLD_MOD(pll_base, PLLCTRL_PLL_CONTROL, 0x0, 0, 0);
@@ -250,10 +248,11 @@ static int hdmi_pll_init(struct hdmi_ip_data *ip_data,
250 r = FLD_MOD(r, 0x0, 12, 12); /* PLL_HIGHFREQ divide by 2 */ 248 r = FLD_MOD(r, 0x0, 12, 12); /* PLL_HIGHFREQ divide by 2 */
251 r = FLD_MOD(r, 0x1, 13, 13); /* PLL_REFEN */ 249 r = FLD_MOD(r, 0x1, 13, 13); /* PLL_REFEN */
252 r = FLD_MOD(r, 0x0, 14, 14); /* PHY_CLKINEN de-assert during locking */ 250 r = FLD_MOD(r, 0x0, 14, 14); /* PHY_CLKINEN de-assert during locking */
251 r = FLD_MOD(r, fmt->refsel, 22, 21); /* REFSEL */
253 252
254 if (dcofreq) { 253 if (fmt->dcofreq) {
255 /* divider programming for frequency beyond 1000Mhz */ 254 /* divider programming for frequency beyond 1000Mhz */
256 REG_FLD_MOD(pll_base, PLLCTRL_CFG3, sd, 17, 10); 255 REG_FLD_MOD(pll_base, PLLCTRL_CFG3, fmt->regsd, 17, 10);
257 r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */ 256 r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */
258 } else { 257 } else {
259 r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */ 258 r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */
@@ -379,11 +378,9 @@ static int hdmi_phy_init(struct hdmi_ip_data *ip_data)
379 return 0; 378 return 0;
380} 379}
381 380
382static int hdmi_pll_program(struct hdmi_ip_data *ip_data, 381static int hdmi_pll_program(struct hdmi_ip_data *ip_data)
383 struct hdmi_pll_info *fmt)
384{ 382{
385 u16 r = 0; 383 u16 r = 0;
386 enum hdmi_clk_refsel refsel;
387 384
388 r = hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_ALLOFF); 385 r = hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_ALLOFF);
389 if (r) 386 if (r)
@@ -397,9 +394,7 @@ static int hdmi_pll_program(struct hdmi_ip_data *ip_data,
397 if (r) 394 if (r)
398 return r; 395 return r;
399 396
400 refsel = HDMI_REFSEL_SYSCLK; 397 r = hdmi_pll_init(ip_data);
401
402 r = hdmi_pll_init(ip_data, refsel, fmt->dcofreq, fmt, fmt->regsd);
403 if (r) 398 if (r)
404 return r; 399 return r;
405 400
@@ -1015,8 +1010,7 @@ static void hdmi_wp_video_config_timing(struct hdmi_ip_data *ip_data,
1015 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_TIMING_V, timing_v); 1010 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_TIMING_V, timing_v);
1016} 1011}
1017 1012
1018static void hdmi_basic_configure(struct hdmi_ip_data *ip_data, 1013static void hdmi_basic_configure(struct hdmi_ip_data *ip_data)
1019 struct hdmi_config *cfg)
1020{ 1014{
1021 /* HDMI */ 1015 /* HDMI */
1022 struct omap_video_timings video_timing; 1016 struct omap_video_timings video_timing;
@@ -1026,6 +1020,7 @@ static void hdmi_basic_configure(struct hdmi_ip_data *ip_data,
1026 struct hdmi_core_infoframe_avi avi_cfg; 1020 struct hdmi_core_infoframe_avi avi_cfg;
1027 struct hdmi_core_video_config v_core_cfg; 1021 struct hdmi_core_video_config v_core_cfg;
1028 struct hdmi_core_packet_enable_repeat repeat_cfg; 1022 struct hdmi_core_packet_enable_repeat repeat_cfg;
1023 struct hdmi_config *cfg = &ip_data->cfg;
1029 1024
1030 hdmi_wp_init(&video_timing, &video_format, 1025 hdmi_wp_init(&video_timing, &video_format,
1031 &video_interface); 1026 &video_interface);
@@ -1034,8 +1029,7 @@ static void hdmi_basic_configure(struct hdmi_ip_data *ip_data,
1034 &avi_cfg, 1029 &avi_cfg,
1035 &repeat_cfg); 1030 &repeat_cfg);
1036 1031
1037 hdmi_wp_video_init_format(&video_format, 1032 hdmi_wp_video_init_format(&video_format, &video_timing, cfg);
1038 &video_timing, cfg);
1039 1033
1040 hdmi_wp_video_config_timing(ip_data, &video_timing); 1034 hdmi_wp_video_config_timing(ip_data, &video_timing);
1041 1035
@@ -1154,6 +1148,9 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
1154 pi->dcofreq = phy > 1000 * 100; 1148 pi->dcofreq = phy > 1000 * 100;
1155 pi->regsd = ((pi->regm * clkin / 10) / ((pi->regn + 1) * 250) + 5) / 10; 1149 pi->regsd = ((pi->regm * clkin / 10) / ((pi->regn + 1) * 250) + 5) / 10;
1156 1150
1151 /* Set the reference clock to sysclk reference */
1152 pi->refsel = HDMI_REFSEL_SYSCLK;
1153
1157 DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf); 1154 DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf);
1158 DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd); 1155 DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
1159} 1156}
@@ -1161,7 +1158,6 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
1161static int hdmi_power_on(struct omap_dss_device *dssdev) 1158static int hdmi_power_on(struct omap_dss_device *dssdev)
1162{ 1159{
1163 int r, code = 0; 1160 int r, code = 0;
1164 struct hdmi_pll_info pll_data;
1165 struct omap_video_timings *p; 1161 struct omap_video_timings *p;
1166 unsigned long phy; 1162 unsigned long phy;
1167 1163
@@ -1183,16 +1179,16 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
1183 } 1179 }
1184 code = get_timings_index(); 1180 code = get_timings_index();
1185 dssdev->panel.timings = cea_vesa_timings[code].timings; 1181 dssdev->panel.timings = cea_vesa_timings[code].timings;
1186 update_hdmi_timings(&hdmi.cfg, p, code); 1182 update_hdmi_timings(&hdmi.ip_data.cfg, p, code);
1187 1183
1188 phy = p->pixel_clock; 1184 phy = p->pixel_clock;
1189 1185
1190 hdmi_compute_pll(dssdev, phy, &pll_data); 1186 hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data);
1191 1187
1192 hdmi_wp_video_start(&hdmi.ip_data, 0); 1188 hdmi_wp_video_start(&hdmi.ip_data, 0);
1193 1189
1194 /* config the PLL and PHY hdmi_set_pll_pwrfirst */ 1190 /* config the PLL and PHY hdmi_set_pll_pwrfirst */
1195 r = hdmi_pll_program(&hdmi.ip_data, &pll_data); 1191 r = hdmi_pll_program(&hdmi.ip_data);
1196 if (r) { 1192 if (r) {
1197 DSSDBG("Failed to lock PLL\n"); 1193 DSSDBG("Failed to lock PLL\n");
1198 goto err; 1194 goto err;
@@ -1204,9 +1200,9 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
1204 goto err; 1200 goto err;
1205 } 1201 }
1206 1202
1207 hdmi.cfg.cm.mode = hdmi.mode; 1203 hdmi.ip_data.cfg.cm.mode = hdmi.mode;
1208 hdmi.cfg.cm.code = hdmi.code; 1204 hdmi.ip_data.cfg.cm.code = hdmi.code;
1209 hdmi_basic_configure(&hdmi.ip_data, &hdmi.cfg); 1205 hdmi_basic_configure(&hdmi.ip_data);
1210 1206
1211 /* Make selection of HDMI in DSS */ 1207 /* Make selection of HDMI in DSS */
1212 dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK); 1208 dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);