aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2
diff options
context:
space:
mode:
authorMythri P K <mythripk@ti.com>2012-01-06 07:22:09 -0500
committerTomi Valkeinen <tomi.valkeinen@ti.com>2012-01-25 06:48:33 -0500
commit46095b2d96bac92c2cc5ca557ec7de73e13311ab (patch)
tree676e095506bc293d78472854cb79e84db664b983 /drivers/video/omap2
parenta05ce78f308fa22b6254995c25ff79e82a27de75 (diff)
OMAPDSS: HDMI: change the timing match logic
Change the timing match logic, Instead of the statically mapped method to get the corresponding timings for a given code and mode, move to a simpler array indexed method. It will help to scale up to add more timings when needed. Signed-off-by: Mythri P K <mythripk@ti.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video/omap2')
-rw-r--r--drivers/video/omap2/dss/hdmi.c176
1 files changed, 76 insertions, 100 deletions
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 266af264eb9b..6f027d30d5dd 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -58,8 +58,6 @@
58#define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR 4 58#define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR 4
59#define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR 4 59#define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR 4
60 60
61#define OMAP_HDMI_TIMINGS_NB 34
62
63#define HDMI_DEFAULT_REGN 16 61#define HDMI_DEFAULT_REGN 16
64#define HDMI_DEFAULT_REGM2 1 62#define HDMI_DEFAULT_REGM2 1
65 63
@@ -88,7 +86,7 @@ static struct {
88 * map it to corresponding CEA or VESA index. 86 * map it to corresponding CEA or VESA index.
89 */ 87 */
90 88
91static const struct hdmi_config cea_vesa_timings[OMAP_HDMI_TIMINGS_NB] = { 89static const struct hdmi_config cea_timings[] = {
92{ {640, 480, 25200, 96, 16, 48, 2, 10, 33, 0, 0, 0}, {1, HDMI_HDMI} }, 90{ {640, 480, 25200, 96, 16, 48, 2, 10, 33, 0, 0, 0}, {1, HDMI_HDMI} },
93{ {720, 480, 27027, 62, 16, 60, 6, 9, 30, 0, 0, 0}, {2, HDMI_HDMI} }, 91{ {720, 480, 27027, 62, 16, 60, 6, 9, 30, 0, 0, 0}, {2, HDMI_HDMI} },
94{ {1280, 720, 74250, 40, 110, 220, 5, 5, 20, 1, 1, 0}, {4, HDMI_HDMI} }, 92{ {1280, 720, 74250, 40, 110, 220, 5, 5, 20, 1, 1, 0}, {4, HDMI_HDMI} },
@@ -104,6 +102,8 @@ static const struct hdmi_config cea_vesa_timings[OMAP_HDMI_TIMINGS_NB] = {
104{ {1920, 1080, 74250, 44, 638, 148, 5, 4, 36, 1, 1, 0}, {32, HDMI_HDMI} }, 102{ {1920, 1080, 74250, 44, 638, 148, 5, 4, 36, 1, 1, 0}, {32, HDMI_HDMI} },
105{ {2880, 480, 108108, 248, 64, 240, 6, 9, 30, 0, 0, 0}, {35, HDMI_HDMI} }, 103{ {2880, 480, 108108, 248, 64, 240, 6, 9, 30, 0, 0, 0}, {35, HDMI_HDMI} },
106{ {2880, 576, 108000, 256, 48, 272, 5, 5, 39, 0, 0, 0}, {37, HDMI_HDMI} }, 104{ {2880, 576, 108000, 256, 48, 272, 5, 5, 39, 0, 0, 0}, {37, HDMI_HDMI} },
105};
106static const struct hdmi_config vesa_timings[] = {
107/* VESA From Here */ 107/* VESA From Here */
108{ {640, 480, 25175, 96, 16, 48, 2 , 11, 31, 0, 0, 0}, {4, HDMI_DVI} }, 108{ {640, 480, 25175, 96, 16, 48, 2 , 11, 31, 0, 0, 0}, {4, HDMI_DVI} },
109{ {800, 600, 40000, 128, 40, 88, 4 , 1, 23, 1, 1, 0}, {9, HDMI_DVI} }, 109{ {800, 600, 40000, 128, 40, 88, 4 , 1, 23, 1, 1, 0}, {9, HDMI_DVI} },
@@ -126,39 +126,6 @@ static const struct hdmi_config cea_vesa_timings[OMAP_HDMI_TIMINGS_NB] = {
126{ {1280, 720, 74250, 40, 110, 220, 5, 5, 20, 1, 1, 0}, {0x55, HDMI_DVI} } 126{ {1280, 720, 74250, 40, 110, 220, 5, 5, 20, 1, 1, 0}, {0x55, HDMI_DVI} }
127}; 127};
128 128
129/*
130 * This is a static mapping array which maps the timing values
131 * with corresponding CEA / VESA code
132 */
133static const int code_index[OMAP_HDMI_TIMINGS_NB] = {
134 1, 19, 4, 2, 37, 6, 21, 20, 5, 16, 17, 29, 31, 35, 32,
135 /* <--15 CEA 17--> vesa*/
136 4, 9, 0xE, 0x17, 0x1C, 0x27, 0x20, 0x23, 0x10, 0x2A,
137 0X2F, 0x3A, 0X51, 0X52, 0x16, 0x29, 0x39, 0x1B
138};
139
140/*
141 * This is reverse static mapping which maps the CEA / VESA code
142 * to the corresponding timing values
143 */
144static const int code_cea[39] = {
145 -1, 0, 3, 3, 2, 8, 5, 5, -1, -1,
146 -1, -1, -1, -1, -1, -1, 9, 10, 10, 1,
147 7, 6, 6, -1, -1, -1, -1, -1, -1, 11,
148 11, 12, 14, -1, -1, 13, 13, 4, 4
149};
150
151static const int code_vesa[85] = {
152 -1, -1, -1, -1, 15, -1, -1, -1, -1, 16,
153 -1, -1, -1, -1, 17, -1, 23, -1, -1, -1,
154 -1, -1, 29, 18, -1, -1, -1, 32, 19, -1,
155 -1, -1, 21, -1, -1, 22, -1, -1, -1, 20,
156 -1, 30, 24, -1, -1, -1, -1, 25, -1, -1,
157 -1, -1, -1, -1, -1, -1, -1, 31, 26, -1,
158 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
159 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
160 -1, 27, 28, -1, 33};
161
162static int hdmi_runtime_get(void) 129static int hdmi_runtime_get(void)
163{ 130{
164 int r; 131 int r;
@@ -188,82 +155,83 @@ int hdmi_init_display(struct omap_dss_device *dssdev)
188 return 0; 155 return 0;
189} 156}
190 157
191static int get_timings_index(void) 158static const struct hdmi_config *hdmi_find_timing(
159 const struct hdmi_config *timings_arr,
160 int len)
192{ 161{
193 int code; 162 int i;
194 163
195 if (hdmi.mode == 0) 164 for (i = 0; i < len; i++) {
196 code = code_vesa[hdmi.code]; 165 if (timings_arr[i].cm.code == hdmi.code)
197 else 166 return &timings_arr[i];
198 code = code_cea[hdmi.code]; 167 }
168 return NULL;
169}
199 170
200 if (code == -1) { 171static const struct hdmi_config *hdmi_get_timings(void)
201 /* HDMI code 4 corresponds to 640 * 480 VGA */ 172{
202 hdmi.code = 4; 173 const struct hdmi_config *arr;
203 /* DVI mode 1 corresponds to HDMI 0 to DVI */ 174 int len;
204 hdmi.mode = HDMI_DVI; 175
176 if (hdmi.mode == HDMI_DVI) {
177 arr = vesa_timings;
178 len = ARRAY_SIZE(vesa_timings);
179 } else {
180 arr = cea_timings;
181 len = ARRAY_SIZE(cea_timings);
182 }
183
184 return hdmi_find_timing(arr, len);
185}
186
187static bool hdmi_timings_compare(struct omap_video_timings *timing1,
188 const struct hdmi_video_timings *timing2)
189{
190 int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync;
191
192 if ((timing2->pixel_clock == timing1->pixel_clock) &&
193 (timing2->x_res == timing1->x_res) &&
194 (timing2->y_res == timing1->y_res)) {
195
196 timing2_hsync = timing2->hfp + timing2->hsw + timing2->hbp;
197 timing1_hsync = timing1->hfp + timing1->hsw + timing1->hbp;
198 timing2_vsync = timing2->vfp + timing2->vsw + timing2->vbp;
199 timing1_vsync = timing2->vfp + timing2->vsw + timing2->vbp;
205 200
206 code = code_vesa[hdmi.code]; 201 DSSDBG("timing1_hsync = %d timing1_vsync = %d"\
202 "timing2_hsync = %d timing2_vsync = %d\n",
203 timing1_hsync, timing1_vsync,
204 timing2_hsync, timing2_vsync);
205
206 if ((timing1_hsync == timing2_hsync) &&
207 (timing1_vsync == timing2_vsync)) {
208 return true;
209 }
207 } 210 }
208 return code; 211 return false;
209} 212}
210 213
211static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing) 214static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing)
212{ 215{
213 int i = 0, code = -1, temp_vsync = 0, temp_hsync = 0; 216 int i;
214 int timing_vsync = 0, timing_hsync = 0;
215 struct hdmi_video_timings temp;
216 struct hdmi_cm cm = {-1}; 217 struct hdmi_cm cm = {-1};
217 DSSDBG("hdmi_get_code\n"); 218 DSSDBG("hdmi_get_code\n");
218 219
219 for (i = 0; i < OMAP_HDMI_TIMINGS_NB; i++) { 220 for (i = 0; i < ARRAY_SIZE(cea_timings); i++) {
220 temp = cea_vesa_timings[i].timings; 221 if (hdmi_timings_compare(timing, &cea_timings[i].timings)) {
221 if ((temp.pixel_clock == timing->pixel_clock) && 222 cm = cea_timings[i].cm;
222 (temp.x_res == timing->x_res) && 223 goto end;
223 (temp.y_res == timing->y_res)) { 224 }
224 225 }
225 temp_hsync = temp.hfp + temp.hsw + temp.hbp; 226 for (i = 0; i < ARRAY_SIZE(vesa_timings); i++) {
226 timing_hsync = timing->hfp + timing->hsw + timing->hbp; 227 if (hdmi_timings_compare(timing, &vesa_timings[i].timings)) {
227 temp_vsync = temp.vfp + temp.vsw + temp.vbp; 228 cm = vesa_timings[i].cm;
228 timing_vsync = timing->vfp + timing->vsw + timing->vbp; 229 goto end;
229
230 DSSDBG("temp_hsync = %d , temp_vsync = %d"
231 "timing_hsync = %d, timing_vsync = %d\n",
232 temp_hsync, temp_hsync,
233 timing_hsync, timing_vsync);
234
235 if ((temp_hsync == timing_hsync) &&
236 (temp_vsync == timing_vsync)) {
237 code = i;
238 cm.code = code_index[i];
239 if (code < 14)
240 cm.mode = HDMI_HDMI;
241 else
242 cm.mode = HDMI_DVI;
243 DSSDBG("Hdmi_code = %d mode = %d\n",
244 cm.code, cm.mode);
245 break;
246 }
247 } 230 }
248 } 231 }
249 232
250 return cm; 233end: return cm;
251}
252 234
253static void update_hdmi_timings(struct hdmi_config *cfg,
254 struct omap_video_timings *timings, int code)
255{
256 cfg->timings.x_res = timings->x_res;
257 cfg->timings.y_res = timings->y_res;
258 cfg->timings.hbp = timings->hbp;
259 cfg->timings.hfp = timings->hfp;
260 cfg->timings.hsw = timings->hsw;
261 cfg->timings.vbp = timings->vbp;
262 cfg->timings.vfp = timings->vfp;
263 cfg->timings.vsw = timings->vsw;
264 cfg->timings.pixel_clock = timings->pixel_clock;
265 cfg->timings.vsync_pol = cea_vesa_timings[code].timings.vsync_pol;
266 cfg->timings.hsync_pol = cea_vesa_timings[code].timings.hsync_pol;
267} 235}
268 236
269unsigned long hdmi_get_pixel_clock(void) 237unsigned long hdmi_get_pixel_clock(void)
@@ -325,7 +293,8 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
325 293
326static int hdmi_power_on(struct omap_dss_device *dssdev) 294static int hdmi_power_on(struct omap_dss_device *dssdev)
327{ 295{
328 int r, code = 0; 296 int r;
297 const struct hdmi_config *timing;
329 struct omap_video_timings *p; 298 struct omap_video_timings *p;
330 unsigned long phy; 299 unsigned long phy;
331 300
@@ -341,9 +310,16 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
341 dssdev->panel.timings.x_res, 310 dssdev->panel.timings.x_res,
342 dssdev->panel.timings.y_res); 311 dssdev->panel.timings.y_res);
343 312
344 code = get_timings_index(); 313 timing = hdmi_get_timings();
345 update_hdmi_timings(&hdmi.ip_data.cfg, p, code); 314 if (timing == NULL) {
346 315 /* HDMI code 4 corresponds to 640 * 480 VGA */
316 hdmi.code = 4;
317 /* DVI mode 1 corresponds to HDMI 0 to DVI */
318 hdmi.mode = HDMI_DVI;
319 hdmi.ip_data.cfg = vesa_timings[0];
320 } else {
321 hdmi.ip_data.cfg = *timing;
322 }
347 phy = p->pixel_clock; 323 phy = p->pixel_clock;
348 324
349 hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data); 325 hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data);