diff options
| -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: |
