Skip to content

Commit 0d9dab3

Browse files
vdsaoglikely
authored andcommitted
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 <[email protected]> Signed-off-by: Grant Likely <[email protected]>
1 parent 9e2089c commit 0d9dab3

File tree

1 file changed

+23
-15
lines changed

1 file changed

+23
-15
lines changed

drivers/video/fsl-diu-fb.c

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,17 @@ static void fsl_diu_free(void *virt, size_t size)
317317
free_pages_exact(virt, size);
318318
}
319319

320+
/*
321+
* Workaround for failed writing desc register of planes.
322+
* Needed with MPC5121 DIU rev 2.0 silicon.
323+
*/
324+
void wr_reg_wa(u32 *reg, u32 val)
325+
{
326+
do {
327+
out_be32(reg, val);
328+
} while (in_be32(reg) != val);
329+
}
330+
320331
static int fsl_diu_enable_panel(struct fb_info *info)
321332
{
322333
struct mfb_info *pmfbi, *cmfbi, *mfbi = info->par;
@@ -330,7 +341,7 @@ static int fsl_diu_enable_panel(struct fb_info *info)
330341
switch (mfbi->index) {
331342
case 0: /* plane 0 */
332343
if (hw->desc[0] != ad->paddr)
333-
out_be32(&hw->desc[0], ad->paddr);
344+
wr_reg_wa(&hw->desc[0], ad->paddr);
334345
break;
335346
case 1: /* plane 1 AOI 0 */
336347
cmfbi = machine_data->fsl_diu_info[2]->par;
@@ -340,7 +351,7 @@ static int fsl_diu_enable_panel(struct fb_info *info)
340351
cpu_to_le32(cmfbi->ad->paddr);
341352
else
342353
ad->next_ad = 0;
343-
out_be32(&hw->desc[1], ad->paddr);
354+
wr_reg_wa(&hw->desc[1], ad->paddr);
344355
}
345356
break;
346357
case 3: /* plane 2 AOI 0 */
@@ -351,22 +362,22 @@ static int fsl_diu_enable_panel(struct fb_info *info)
351362
cpu_to_le32(cmfbi->ad->paddr);
352363
else
353364
ad->next_ad = 0;
354-
out_be32(&hw->desc[2], ad->paddr);
365+
wr_reg_wa(&hw->desc[2], ad->paddr);
355366
}
356367
break;
357368
case 2: /* plane 1 AOI 1 */
358369
pmfbi = machine_data->fsl_diu_info[1]->par;
359370
ad->next_ad = 0;
360371
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);
362373
else /* AOI0 open */
363374
pmfbi->ad->next_ad = cpu_to_le32(ad->paddr);
364375
break;
365376
case 4: /* plane 2 AOI 1 */
366377
pmfbi = machine_data->fsl_diu_info[3]->par;
367378
ad->next_ad = 0;
368379
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);
370381
else /* AOI0 was open */
371382
pmfbi->ad->next_ad = cpu_to_le32(ad->paddr);
372383
break;
@@ -390,27 +401,24 @@ static int fsl_diu_disable_panel(struct fb_info *info)
390401
switch (mfbi->index) {
391402
case 0: /* plane 0 */
392403
if (hw->desc[0] != machine_data->dummy_ad->paddr)
393-
out_be32(&hw->desc[0],
394-
machine_data->dummy_ad->paddr);
404+
wr_reg_wa(&hw->desc[0], machine_data->dummy_ad->paddr);
395405
break;
396406
case 1: /* plane 1 AOI 0 */
397407
cmfbi = machine_data->fsl_diu_info[2]->par;
398408
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);
400410
/* move AOI1 to the first */
401411
else /* AOI1 was closed */
402-
out_be32(&hw->desc[1],
403-
machine_data->dummy_ad->paddr);
412+
wr_reg_wa(&hw->desc[1], machine_data->dummy_ad->paddr);
404413
/* close AOI 0 */
405414
break;
406415
case 3: /* plane 2 AOI 0 */
407416
cmfbi = machine_data->fsl_diu_info[4]->par;
408417
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);
410419
/* move AOI1 to the first */
411420
else /* AOI1 was closed */
412-
out_be32(&hw->desc[2],
413-
machine_data->dummy_ad->paddr);
421+
wr_reg_wa(&hw->desc[2], machine_data->dummy_ad->paddr);
414422
/* close AOI 0 */
415423
break;
416424
case 2: /* plane 1 AOI 1 */
@@ -421,7 +429,7 @@ static int fsl_diu_disable_panel(struct fb_info *info)
421429
/* AOI0 is open, must be the first */
422430
pmfbi->ad->next_ad = 0;
423431
} 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);
425433
/* close AOI 1 */
426434
break;
427435
case 4: /* plane 2 AOI 1 */
@@ -432,7 +440,7 @@ static int fsl_diu_disable_panel(struct fb_info *info)
432440
/* AOI0 is open, must be the first */
433441
pmfbi->ad->next_ad = 0;
434442
} 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);
436444
/* close AOI 1 */
437445
break;
438446
default:

0 commit comments

Comments
 (0)