summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Minnick <michael.minnick@freescale.com>2012-11-13 12:51:13 -0600
committerJason Liu <r64343@freescale.com>2012-11-28 16:57:02 +0800
commitd372bcc67c15e3056ead11588714a910d5c668ec (patch)
tree0988a93c47b2972a8a0a96a4d75429123d6d2b69
parentbb43ffa36d84a7d2e54c6a4296442dccdeb0c21a (diff)
ENGR00233494 EPDC: Driver only supports 16 LUTs
This bug was introduced by ENGR00229290 which fixed the problem of greater than 16 LUTs used when 5-bit waveform loaded. The bug is that now the driver is also restricted to using 16 LUTs in 4-bit mode. The fix is to correct the test of the EPDC_FORMAT register used to determine if a 5-bit waveform is loaded. Also removed the while loop in favor of a bitwise OR used to determine if a chosen LUT has yet to be acknowledged by the interrupt handler. Signed-off-by: Michael Minnick <michael.minnick@freescale.com>
-rw-r--r--drivers/video/mxc/epdc_regs.h1
-rw-r--r--drivers/video/mxc/mxc_epdc_fb.c77
2 files changed, 37 insertions, 41 deletions
diff --git a/drivers/video/mxc/epdc_regs.h b/drivers/video/mxc/epdc_regs.h
index cc7b5000db18..4f5137ecde9e 100644
--- a/drivers/video/mxc/epdc_regs.h
+++ b/drivers/video/mxc/epdc_regs.h
@@ -197,6 +197,7 @@ enum {
EPDC_FORMAT_BUF_PIXEL_SCALE_ROUND = 0x1000000,
EPDC_FORMAT_DEFAULT_TFT_PIXEL_MASK = 0xFF0000,
EPDC_FORMAT_DEFAULT_TFT_PIXEL_OFFSET = 16,
+ EPDC_FORMAT_BUF_PIXEL_FORMAT_MASK = 0x700,
EPDC_FORMAT_BUF_PIXEL_FORMAT_P2N = 0x200,
EPDC_FORMAT_BUF_PIXEL_FORMAT_P3N = 0x300,
EPDC_FORMAT_BUF_PIXEL_FORMAT_P4N = 0x400,
diff --git a/drivers/video/mxc/mxc_epdc_fb.c b/drivers/video/mxc/mxc_epdc_fb.c
index f3c8ea8d18ad..6787b1ee78fe 100644
--- a/drivers/video/mxc/mxc_epdc_fb.c
+++ b/drivers/video/mxc/mxc_epdc_fb.c
@@ -733,11 +733,11 @@ static inline int epdc_get_next_lut(void)
static int epdc_choose_next_lut(int rev, int *next_lut)
{
- u64 luts_status, unprocessed_luts;
- bool next_lut_found = false;
+ u64 luts_status, unprocessed_luts, used_luts;
/* Available LUTs are reduced to 16 in 5-bit waveform mode */
- u32 format_p5n = __raw_readl(EPDC_FORMAT) &
- EPDC_FORMAT_BUF_PIXEL_FORMAT_P5N;
+ bool format_p5n = ((__raw_readl(EPDC_FORMAT) &
+ EPDC_FORMAT_BUF_PIXEL_FORMAT_MASK) ==
+ EPDC_FORMAT_BUF_PIXEL_FORMAT_P5N);
luts_status = __raw_readl(EPDC_STATUS_LUTS);
if ((rev < 20) || format_p5n)
@@ -754,48 +754,43 @@ static int epdc_choose_next_lut(int rev, int *next_lut)
unprocessed_luts &= 0xFFFF;
}
- while (!next_lut_found) {
- /*
- * Selecting a LUT to minimize incidence of TCE Underrun Error
- * --------------------------------------------------------
- * We want to find the lowest order LUT that is of greater
- * order than all other active LUTs. If highest order LUT
- * is active, then we want to choose the lowest order
- * available LUT.
- *
- * NOTE: For EPDC version 2.0 and later, TCE Underrun error
- * bug is fixed, so it doesn't matter which LUT is used.
- */
- *next_lut = fls64(luts_status);
+ /*
+ * Note on unprocessed_luts: There is a race condition
+ * where a LUT completes, but has not been processed by
+ * IRQ handler workqueue, and then a new update request
+ * attempts to use that LUT. We prevent that here by
+ * ensuring that the LUT we choose doesn't have its IRQ
+ * bit set (indicating it has completed but not yet been
+ * processed).
+ */
+ used_luts = luts_status | unprocessed_luts;
- if ((rev < 20) || format_p5n) {
- if (*next_lut > 15)
- *next_lut = ffz(luts_status);
- } else {
- if (*next_lut > 63) {
- *next_lut = ffz((u32)luts_status);
- if (*next_lut == -1)
- *next_lut =
- ffz((u32)(luts_status >> 32)) + 32;
- }
- }
+ /*
+ * Selecting a LUT to minimize incidence of TCE Underrun Error
+ * --------------------------------------------------------
+ * We want to find the lowest order LUT that is of greater
+ * order than all other active LUTs. If highest order LUT
+ * is active, then we want to choose the lowest order
+ * available LUT.
+ *
+ * NOTE: For EPDC version 2.0 and later, TCE Underrun error
+ * bug is fixed, so it doesn't matter which LUT is used.
+ */
- /*
- * Note on unprocessed_luts: There is a race condition
- * where a LUT completes, but has not been processed by
- * IRQ handler workqueue, and then a new update request
- * attempts to use that LUT. We prevent that here by
- * ensuring that the LUT we choose doesn't have its IRQ
- * bit set (indicating it has completed but not yet been
- * processed).
- */
- if ((1 << *next_lut) & unprocessed_luts)
- luts_status |= (1 << *next_lut);
+ if ((rev < 20) || format_p5n) {
+ *next_lut = fls64(used_luts);
+ if (*next_lut > 15)
+ *next_lut = ffz(used_luts);
+ } else {
+ if ((u32)used_luts != ~0UL)
+ *next_lut = ffz((u32)used_luts);
+ else if ((u32)(used_luts >> 32) != ~0UL)
+ *next_lut = ffz((u32)(used_luts >> 32)) + 32;
else
- next_lut_found = true;
+ *next_lut = INVALID_LUT;
}
- if (luts_status & 0x8000)
+ if (used_luts & 0x8000)
return 1;
else
return 0;