aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/fsl-diu-fb.c
diff options
context:
space:
mode:
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: