diff options
Diffstat (limited to 'drivers/video/fsl-diu-fb.c')
-rw-r--r-- | drivers/video/fsl-diu-fb.c | 38 |
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 | */ | ||
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 | |||
320 | static int fsl_diu_enable_panel(struct fb_info *info) | 331 | static 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: |