aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/fsl-diu-fb.c
diff options
context:
space:
mode:
authorAnatolij Gustschin <agust@denx.de>2010-07-23 00:00:35 -0400
committerGrant Likely <grant.likely@secretlab.ca>2010-08-01 19:06:44 -0400
commit0d9dab39fbbecfa8f78a4573a2e8eaf982f1207e (patch)
tree6aeb5a72f4ef9d4293a189e22970ee5b7a473e2a /drivers/video/fsl-diu-fb.c
parent9e2089cbed7441a21d72a510897f0336afb06492 (diff)
powerpc/5121: fsl-diu-fb: fix issue with re-enabling DIU area descriptor
On MPC5121e Rev 2.0 re-configuring the DIU area descriptor by writing new descriptor address doesn't always work. As a result, DIU continues to display using old area descriptor even if the new one has been written to the descriptor register of the plane. Add the code from Freescale MPC5121EADS BSP for writing descriptor addresses properly. This fixes the problem for Rev 2.0 silicon. Signed-off-by: Anatolij Gustschin <agust@denx.de> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/video/fsl-diu-fb.c')
-rw-r--r--drivers/video/fsl-diu-fb.c38
1 files changed, 23 insertions, 15 deletions
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index 27455ce298b7..9b8c99111221 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -317,6 +317,17 @@ static void fsl_diu_free(void *virt, size_t size)
317 free_pages_exact(virt, size); 317 free_pages_exact(virt, size);
318} 318}
319 319
320/*
321 * Workaround for failed writing desc register of planes.
322 * Needed with MPC5121 DIU rev 2.0 silicon.
323 */
324void wr_reg_wa(u32 *reg, u32 val)
325{
326 do {
327 out_be32(reg, val);
328 } while (in_be32(reg) != val);
329}
330
320static int fsl_diu_enable_panel(struct fb_info *info) 331static int fsl_diu_enable_panel(struct fb_info *info)
321{ 332{
322 struct mfb_info *pmfbi, *cmfbi, *mfbi = info->par; 333 struct mfb_info *pmfbi, *cmfbi, *mfbi = info->par;
@@ -330,7 +341,7 @@ static int fsl_diu_enable_panel(struct fb_info *info)
330 switch (mfbi->index) { 341 switch (mfbi->index) {
331 case 0: /* plane 0 */ 342 case 0: /* plane 0 */
332 if (hw->desc[0] != ad->paddr) 343 if (hw->desc[0] != ad->paddr)
333 out_be32(&hw->desc[0], ad->paddr); 344 wr_reg_wa(&hw->desc[0], ad->paddr);
334 break; 345 break;
335 case 1: /* plane 1 AOI 0 */ 346 case 1: /* plane 1 AOI 0 */
336 cmfbi = machine_data->fsl_diu_info[2]->par; 347 cmfbi = machine_data->fsl_diu_info[2]->par;
@@ -340,7 +351,7 @@ static int fsl_diu_enable_panel(struct fb_info *info)
340 cpu_to_le32(cmfbi->ad->paddr); 351 cpu_to_le32(cmfbi->ad->paddr);
341 else 352 else
342 ad->next_ad = 0; 353 ad->next_ad = 0;
343 out_be32(&hw->desc[1], ad->paddr); 354 wr_reg_wa(&hw->desc[1], ad->paddr);
344 } 355 }
345 break; 356 break;
346 case 3: /* plane 2 AOI 0 */ 357 case 3: /* plane 2 AOI 0 */
@@ -351,14 +362,14 @@ static int fsl_diu_enable_panel(struct fb_info *info)
351 cpu_to_le32(cmfbi->ad->paddr); 362 cpu_to_le32(cmfbi->ad->paddr);
352 else 363 else
353 ad->next_ad = 0; 364 ad->next_ad = 0;
354 out_be32(&hw->desc[2], ad->paddr); 365 wr_reg_wa(&hw->desc[2], ad->paddr);
355 } 366 }
356 break; 367 break;
357 case 2: /* plane 1 AOI 1 */ 368 case 2: /* plane 1 AOI 1 */
358 pmfbi = machine_data->fsl_diu_info[1]->par; 369 pmfbi = machine_data->fsl_diu_info[1]->par;
359 ad->next_ad = 0; 370 ad->next_ad = 0;
360 if (hw->desc[1] == machine_data->dummy_ad->paddr) 371 if (hw->desc[1] == machine_data->dummy_ad->paddr)
361 out_be32(&hw->desc[1], ad->paddr); 372 wr_reg_wa(&hw->desc[1], ad->paddr);
362 else /* AOI0 open */ 373 else /* AOI0 open */
363 pmfbi->ad->next_ad = cpu_to_le32(ad->paddr); 374 pmfbi->ad->next_ad = cpu_to_le32(ad->paddr);
364 break; 375 break;
@@ -366,7 +377,7 @@ static int fsl_diu_enable_panel(struct fb_info *info)
366 pmfbi = machine_data->fsl_diu_info[3]->par; 377 pmfbi = machine_data->fsl_diu_info[3]->par;
367 ad->next_ad = 0; 378 ad->next_ad = 0;
368 if (hw->desc[2] == machine_data->dummy_ad->paddr) 379 if (hw->desc[2] == machine_data->dummy_ad->paddr)
369 out_be32(&hw->desc[2], ad->paddr); 380 wr_reg_wa(&hw->desc[2], ad->paddr);
370 else /* AOI0 was open */ 381 else /* AOI0 was open */
371 pmfbi->ad->next_ad = cpu_to_le32(ad->paddr); 382 pmfbi->ad->next_ad = cpu_to_le32(ad->paddr);
372 break; 383 break;
@@ -390,27 +401,24 @@ static int fsl_diu_disable_panel(struct fb_info *info)
390 switch (mfbi->index) { 401 switch (mfbi->index) {
391 case 0: /* plane 0 */ 402 case 0: /* plane 0 */
392 if (hw->desc[0] != machine_data->dummy_ad->paddr) 403 if (hw->desc[0] != machine_data->dummy_ad->paddr)
393 out_be32(&hw->desc[0], 404 wr_reg_wa(&hw->desc[0], machine_data->dummy_ad->paddr);
394 machine_data->dummy_ad->paddr);
395 break; 405 break;
396 case 1: /* plane 1 AOI 0 */ 406 case 1: /* plane 1 AOI 0 */
397 cmfbi = machine_data->fsl_diu_info[2]->par; 407 cmfbi = machine_data->fsl_diu_info[2]->par;
398 if (cmfbi->count > 0) /* AOI1 is open */ 408 if (cmfbi->count > 0) /* AOI1 is open */
399 out_be32(&hw->desc[1], cmfbi->ad->paddr); 409 wr_reg_wa(&hw->desc[1], cmfbi->ad->paddr);
400 /* move AOI1 to the first */ 410 /* move AOI1 to the first */
401 else /* AOI1 was closed */ 411 else /* AOI1 was closed */
402 out_be32(&hw->desc[1], 412 wr_reg_wa(&hw->desc[1], machine_data->dummy_ad->paddr);
403 machine_data->dummy_ad->paddr);
404 /* close AOI 0 */ 413 /* close AOI 0 */
405 break; 414 break;
406 case 3: /* plane 2 AOI 0 */ 415 case 3: /* plane 2 AOI 0 */
407 cmfbi = machine_data->fsl_diu_info[4]->par; 416 cmfbi = machine_data->fsl_diu_info[4]->par;
408 if (cmfbi->count > 0) /* AOI1 is open */ 417 if (cmfbi->count > 0) /* AOI1 is open */
409 out_be32(&hw->desc[2], cmfbi->ad->paddr); 418 wr_reg_wa(&hw->desc[2], cmfbi->ad->paddr);
410 /* move AOI1 to the first */ 419 /* move AOI1 to the first */
411 else /* AOI1 was closed */ 420 else /* AOI1 was closed */
412 out_be32(&hw->desc[2], 421 wr_reg_wa(&hw->desc[2], machine_data->dummy_ad->paddr);
413 machine_data->dummy_ad->paddr);
414 /* close AOI 0 */ 422 /* close AOI 0 */
415 break; 423 break;
416 case 2: /* plane 1 AOI 1 */ 424 case 2: /* plane 1 AOI 1 */
@@ -421,7 +429,7 @@ static int fsl_diu_disable_panel(struct fb_info *info)
421 /* AOI0 is open, must be the first */ 429 /* AOI0 is open, must be the first */
422 pmfbi->ad->next_ad = 0; 430 pmfbi->ad->next_ad = 0;
423 } else /* AOI1 is the first in the chain */ 431 } else /* AOI1 is the first in the chain */
424 out_be32(&hw->desc[1], machine_data->dummy_ad->paddr); 432 wr_reg_wa(&hw->desc[1], machine_data->dummy_ad->paddr);
425 /* close AOI 1 */ 433 /* close AOI 1 */
426 break; 434 break;
427 case 4: /* plane 2 AOI 1 */ 435 case 4: /* plane 2 AOI 1 */
@@ -432,7 +440,7 @@ static int fsl_diu_disable_panel(struct fb_info *info)
432 /* AOI0 is open, must be the first */ 440 /* AOI0 is open, must be the first */
433 pmfbi->ad->next_ad = 0; 441 pmfbi->ad->next_ad = 0;
434 } else /* AOI1 is the first in the chain */ 442 } else /* AOI1 is the first in the chain */
435 out_be32(&hw->desc[2], machine_data->dummy_ad->paddr); 443 wr_reg_wa(&hw->desc[2], machine_data->dummy_ad->paddr);
436 /* close AOI 1 */ 444 /* close AOI 1 */
437 break; 445 break;
438 default: 446 default: