aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2011-08-22 10:47:56 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2011-09-30 09:16:46 -0400
commit032b8ea508dd0c641785f338b87c342337419ed6 (patch)
tree36e3c0c17ecf612daaa831e76e7404dab00a705a /drivers/video
parent2ea51fef8626debc6c3b73573cf99fae0593aa6a (diff)
OMAP: DSS2: HDMI: split hdmi_core_ddc_edid
Split the DDC initialization off from hdmi_core_ddc_edid() into a separate function hdmi_core_ddc_init(). This cleans up the implementation. Cc: Mythri P K <mythripk@ti.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c117
1 files changed, 67 insertions, 50 deletions
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
index d4cdfc2e6c5e..ecf854e2596c 100644
--- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
@@ -264,92 +264,105 @@ void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data)
264 hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF); 264 hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
265} 265}
266 266
267static int hdmi_core_ddc_edid(struct hdmi_ip_data *ip_data, 267static int hdmi_core_ddc_init(struct hdmi_ip_data *ip_data)
268 u8 *pedid, int ext)
269{ 268{
270 u32 i, j; 269 void __iomem *base = hdmi_core_sys_base(ip_data);
271 char checksum = 0;
272 u32 offset = 0;
273 void __iomem *core_sys_base = hdmi_core_sys_base(ip_data);
274 270
275 /* Turn on CLK for DDC */ 271 /* Turn on CLK for DDC */
276 REG_FLD_MOD(hdmi_av_base(ip_data), HDMI_CORE_AV_DPD, 0x7, 2, 0); 272 REG_FLD_MOD(base, HDMI_CORE_AV_DPD, 0x7, 2, 0);
273
274 /* IN_PROG */
275 if (REG_GET(base, HDMI_CORE_DDC_STATUS, 4, 4) == 1) {
276 /* Abort transaction */
277 REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0xf, 3, 0);
278 /* IN_PROG */
279 if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS,
280 4, 4, 0) != 0) {
281 DSSERR("Timeout aborting DDC transaction\n");
282 return -ETIMEDOUT;
283 }
284 }
277 285
278 /* 286 /* Clk SCL Devices */
279 * SW HACK : Without the Delay DDC(i2c bus) reads 0 values / 287 REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0xA, 3, 0);
280 * right shifted values( The behavior is not consistent and seen only 288
281 * with some TV's) 289 /* HDMI_CORE_DDC_STATUS_IN_PROG */
282 */ 290 if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS,
283 usleep_range(800, 1000); 291 4, 4, 0) != 0) {
292 DSSERR("Timeout starting SCL clock\n");
293 return -ETIMEDOUT;
294 }
284 295
285 if (!ext) { 296 /* Clear FIFO */
286 /* Clk SCL Devices */ 297 REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x9, 3, 0);
287 REG_FLD_MOD(core_sys_base, HDMI_CORE_DDC_CMD, 0xA, 3, 0);
288 298
289 /* HDMI_CORE_DDC_STATUS_IN_PROG */ 299 /* HDMI_CORE_DDC_STATUS_IN_PROG */
290 if (hdmi_wait_for_bit_change(core_sys_base, 300 if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS,
291 HDMI_CORE_DDC_STATUS, 4, 4, 0) != 0) { 301 4, 4, 0) != 0) {
292 pr_err("Failed to program DDC\n"); 302 DSSERR("Timeout clearing DDC fifo\n");
293 return -ETIMEDOUT; 303 return -ETIMEDOUT;
294 } 304 }
295 305
296 /* Clear FIFO */ 306 return 0;
297 REG_FLD_MOD(core_sys_base, HDMI_CORE_DDC_CMD, 0x9, 3, 0); 307}
298 308
299 /* HDMI_CORE_DDC_STATUS_IN_PROG */ 309static int hdmi_core_ddc_edid(struct hdmi_ip_data *ip_data,
300 if (hdmi_wait_for_bit_change(core_sys_base, 310 u8 *pedid, int ext)
301 HDMI_CORE_DDC_STATUS, 4, 4, 0) != 0) { 311{
302 pr_err("Failed to program DDC\n"); 312 void __iomem *base = hdmi_core_sys_base(ip_data);
303 return -ETIMEDOUT; 313 u32 i, j;
304 } 314 char checksum = 0;
315 u32 offset = 0;
305 316
306 } else { 317 /* HDMI_CORE_DDC_STATUS_IN_PROG */
307 if (ext % 2 != 0) 318 if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS,
308 offset = 0x80; 319 4, 4, 0) != 0) {
320 DSSERR("Timeout waiting DDC to be ready\n");
321 return -ETIMEDOUT;
309 } 322 }
310 323
324 if (ext % 2 != 0)
325 offset = 0x80;
326
311 /* Load Segment Address Register */ 327 /* Load Segment Address Register */
312 REG_FLD_MOD(core_sys_base, HDMI_CORE_DDC_SEGM, ext/2, 7, 0); 328 REG_FLD_MOD(base, HDMI_CORE_DDC_SEGM, ext / 2, 7, 0);
313 329
314 /* Load Slave Address Register */ 330 /* Load Slave Address Register */
315 REG_FLD_MOD(core_sys_base, HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1); 331 REG_FLD_MOD(base, HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1);
316 332
317 /* Load Offset Address Register */ 333 /* Load Offset Address Register */
318 REG_FLD_MOD(core_sys_base, HDMI_CORE_DDC_OFFSET, offset, 7, 0); 334 REG_FLD_MOD(base, HDMI_CORE_DDC_OFFSET, offset, 7, 0);
319 335
320 /* Load Byte Count */ 336 /* Load Byte Count */
321 REG_FLD_MOD(core_sys_base, HDMI_CORE_DDC_COUNT1, 0x80, 7, 0); 337 REG_FLD_MOD(base, HDMI_CORE_DDC_COUNT1, 0x80, 7, 0);
322 REG_FLD_MOD(core_sys_base, HDMI_CORE_DDC_COUNT2, 0x0, 1, 0); 338 REG_FLD_MOD(base, HDMI_CORE_DDC_COUNT2, 0x0, 1, 0);
323 339
324 /* Set DDC_CMD */ 340 /* Set DDC_CMD */
325 if (ext) 341 if (ext)
326 REG_FLD_MOD(core_sys_base, HDMI_CORE_DDC_CMD, 0x4, 3, 0); 342 REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x4, 3, 0);
327 else 343 else
328 REG_FLD_MOD(core_sys_base, HDMI_CORE_DDC_CMD, 0x2, 3, 0); 344 REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x2, 3, 0);
329 345
330 /* HDMI_CORE_DDC_STATUS_BUS_LOW */ 346 /* HDMI_CORE_DDC_STATUS_BUS_LOW */
331 if (REG_GET(core_sys_base, 347 if (REG_GET(base, HDMI_CORE_DDC_STATUS, 6, 6) == 1) {
332 HDMI_CORE_DDC_STATUS, 6, 6) == 1) {
333 pr_err("I2C Bus Low?\n"); 348 pr_err("I2C Bus Low?\n");
334 return -EIO; 349 return -EIO;
335 } 350 }
336 /* HDMI_CORE_DDC_STATUS_NO_ACK */ 351 /* HDMI_CORE_DDC_STATUS_NO_ACK */
337 if (REG_GET(core_sys_base, 352 if (REG_GET(base, HDMI_CORE_DDC_STATUS, 5, 5) == 1) {
338 HDMI_CORE_DDC_STATUS, 5, 5) == 1) {
339 pr_err("I2C No Ack\n"); 353 pr_err("I2C No Ack\n");
340 return -EIO; 354 return -EIO;
341 } 355 }
342 356
343 i = ext * 128; 357 i = ext * 128;
344 j = 0; 358 j = 0;
345 while (((REG_GET(core_sys_base, HDMI_CORE_DDC_STATUS, 4, 4) == 1) || 359 while (((REG_GET(base, HDMI_CORE_DDC_STATUS, 4, 4) == 1) ||
346 (REG_GET(core_sys_base, 360 (REG_GET(base, HDMI_CORE_DDC_STATUS, 2, 2) == 0)) &&
347 HDMI_CORE_DDC_STATUS, 2, 2) == 0)) && j < 128) { 361 j < 128) {
348 362
349 if (REG_GET(core_sys_base, HDMI_CORE_DDC_STATUS, 2, 2) == 0) { 363 if (REG_GET(base, HDMI_CORE_DDC_STATUS, 2, 2) == 0) {
350 /* FIFO not empty */ 364 /* FIFO not empty */
351 pedid[i++] = REG_GET(core_sys_base, 365 pedid[i++] = REG_GET(base, HDMI_CORE_DDC_DATA, 7, 0);
352 HDMI_CORE_DDC_DATA, 7, 0);
353 j++; 366 j++;
354 } 367 }
355 } 368 }
@@ -372,6 +385,10 @@ int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data,
372 int max_ext_blocks = (max_length / 128) - 1; 385 int max_ext_blocks = (max_length / 128) - 1;
373 int len; 386 int len;
374 387
388 r = hdmi_core_ddc_init(ip_data);
389 if (r)
390 return r;
391
375 r = hdmi_core_ddc_edid(ip_data, pedid, 0); 392 r = hdmi_core_ddc_edid(ip_data, pedid, 0);
376 if (r) 393 if (r)
377 return r; 394 return r;