DISPC_COLOR_COMPONENT_UV                = 1 << 1,
 };
 
+enum mgr_reg_fields {
+       DISPC_MGR_FLD_ENABLE,
+       DISPC_MGR_FLD_STNTFT,
+       DISPC_MGR_FLD_GO,
+       DISPC_MGR_FLD_TFTDATALINES,
+       DISPC_MGR_FLD_STALLMODE,
+       DISPC_MGR_FLD_TCKENABLE,
+       DISPC_MGR_FLD_TCKSELECTION,
+       DISPC_MGR_FLD_CPR,
+       DISPC_MGR_FLD_FIFOHANDCHECK,
+       /* used to maintain a count of the above fields */
+       DISPC_MGR_FLD_NUM,
+};
+
+static const struct {
+       const char *name;
+       u32 vsync_irq;
+       u32 framedone_irq;
+       u32 sync_lost_irq;
+       struct reg_field reg_desc[DISPC_MGR_FLD_NUM];
+} mgr_desc[] = {
+       [OMAP_DSS_CHANNEL_LCD] = {
+               .name           = "LCD",
+               .vsync_irq      = DISPC_IRQ_VSYNC,
+               .framedone_irq  = DISPC_IRQ_FRAMEDONE,
+               .sync_lost_irq  = DISPC_IRQ_SYNC_LOST,
+               .reg_desc       = {
+                       [DISPC_MGR_FLD_ENABLE]          = { DISPC_CONTROL,  0,  0 },
+                       [DISPC_MGR_FLD_STNTFT]          = { DISPC_CONTROL,  3,  3 },
+                       [DISPC_MGR_FLD_GO]              = { DISPC_CONTROL,  5,  5 },
+                       [DISPC_MGR_FLD_TFTDATALINES]    = { DISPC_CONTROL,  9,  8 },
+                       [DISPC_MGR_FLD_STALLMODE]       = { DISPC_CONTROL, 11, 11 },
+                       [DISPC_MGR_FLD_TCKENABLE]       = { DISPC_CONFIG,  10, 10 },
+                       [DISPC_MGR_FLD_TCKSELECTION]    = { DISPC_CONFIG,  11, 11 },
+                       [DISPC_MGR_FLD_CPR]             = { DISPC_CONFIG,  15, 15 },
+                       [DISPC_MGR_FLD_FIFOHANDCHECK]   = { DISPC_CONFIG,  16, 16 },
+               },
+       },
+       [OMAP_DSS_CHANNEL_DIGIT] = {
+               .name           = "DIGIT",
+               .vsync_irq      = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN,
+               .framedone_irq  = 0,
+               .sync_lost_irq  = DISPC_IRQ_SYNC_LOST_DIGIT,
+               .reg_desc       = {
+                       [DISPC_MGR_FLD_ENABLE]          = { DISPC_CONTROL,  1,  1 },
+                       [DISPC_MGR_FLD_STNTFT]          = { },
+                       [DISPC_MGR_FLD_GO]              = { DISPC_CONTROL,  6,  6 },
+                       [DISPC_MGR_FLD_TFTDATALINES]    = { },
+                       [DISPC_MGR_FLD_STALLMODE]       = { },
+                       [DISPC_MGR_FLD_TCKENABLE]       = { DISPC_CONFIG,  12, 12 },
+                       [DISPC_MGR_FLD_TCKSELECTION]    = { DISPC_CONFIG,  13, 13 },
+                       [DISPC_MGR_FLD_CPR]             = { },
+                       [DISPC_MGR_FLD_FIFOHANDCHECK]   = { DISPC_CONFIG,  16, 16 },
+               },
+       },
+       [OMAP_DSS_CHANNEL_LCD2] = {
+               .name           = "LCD2",
+               .vsync_irq      = DISPC_IRQ_VSYNC2,
+               .framedone_irq  = DISPC_IRQ_FRAMEDONE2,
+               .sync_lost_irq  = DISPC_IRQ_SYNC_LOST2,
+               .reg_desc       = {
+                       [DISPC_MGR_FLD_ENABLE]          = { DISPC_CONTROL2,  0,  0 },
+                       [DISPC_MGR_FLD_STNTFT]          = { DISPC_CONTROL2,  3,  3 },
+                       [DISPC_MGR_FLD_GO]              = { DISPC_CONTROL2,  5,  5 },
+                       [DISPC_MGR_FLD_TFTDATALINES]    = { DISPC_CONTROL2,  9,  8 },
+                       [DISPC_MGR_FLD_STALLMODE]       = { DISPC_CONTROL2, 11, 11 },
+                       [DISPC_MGR_FLD_TCKENABLE]       = { DISPC_CONFIG2,  10, 10 },
+                       [DISPC_MGR_FLD_TCKSELECTION]    = { DISPC_CONFIG2,  11, 11 },
+                       [DISPC_MGR_FLD_CPR]             = { DISPC_CONFIG2,  15, 15 },
+                       [DISPC_MGR_FLD_FIFOHANDCHECK]   = { DISPC_CONFIG2,  16, 16 },
+               },
+       },
+};
+
 static void _omap_dispc_set_irqs(void);
 
 static inline void dispc_write_reg(const u16 idx, u32 val)
        return __raw_readl(dispc.base + idx);
 }
 
+static u32 mgr_fld_read(enum omap_channel channel, enum mgr_reg_fields regfld)
+{
+       const struct reg_field rfld = mgr_desc[channel].reg_desc[regfld];
+       return REG_GET(rfld.reg, rfld.high, rfld.low);
+}
+
+static void mgr_fld_write(enum omap_channel channel,
+                                       enum mgr_reg_fields regfld, int val) {
+       const struct reg_field rfld = mgr_desc[channel].reg_desc[regfld];
+       REG_FLD_MOD(rfld.reg, val, rfld.high, rfld.low);
+}
+
 #define SR(reg) \
        dispc.ctx[DISPC_##reg / sizeof(u32)] = dispc_read_reg(DISPC_##reg)
 #define RR(reg) \
 
 u32 dispc_mgr_get_vsync_irq(enum omap_channel channel)
 {
-       switch (channel) {
-       case OMAP_DSS_CHANNEL_LCD:
-               return DISPC_IRQ_VSYNC;
-       case OMAP_DSS_CHANNEL_LCD2:
-               return DISPC_IRQ_VSYNC2;
-       case OMAP_DSS_CHANNEL_DIGIT:
-               return DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
-       default:
-               BUG();
-               return 0;
-       }
+       return mgr_desc[channel].vsync_irq;
 }
 
 u32 dispc_mgr_get_framedone_irq(enum omap_channel channel)
 {
-       switch (channel) {
-       case OMAP_DSS_CHANNEL_LCD:
-               return DISPC_IRQ_FRAMEDONE;
-       case OMAP_DSS_CHANNEL_LCD2:
-               return DISPC_IRQ_FRAMEDONE2;
-       case OMAP_DSS_CHANNEL_DIGIT:
-               return 0;
-       default:
-               BUG();
-               return 0;
-       }
+       return mgr_desc[channel].framedone_irq;
 }
 
 bool dispc_mgr_go_busy(enum omap_channel channel)
 {
-       int bit;
-
-       if (dispc_mgr_is_lcd(channel))
-               bit = 5; /* GOLCD */
-       else
-               bit = 6; /* GODIGIT */
-
-       if (channel == OMAP_DSS_CHANNEL_LCD2)
-               return REG_GET(DISPC_CONTROL2, bit, bit) == 1;
-       else
-               return REG_GET(DISPC_CONTROL, bit, bit) == 1;
+       return mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1;
 }
 
 void dispc_mgr_go(enum omap_channel channel)
 {
-       int bit;
        bool enable_bit, go_bit;
 
-       if (dispc_mgr_is_lcd(channel))
-               bit = 0; /* LCDENABLE */
-       else
-               bit = 1; /* DIGITALENABLE */
-
        /* if the channel is not enabled, we don't need GO */
-       if (channel == OMAP_DSS_CHANNEL_LCD2)
-               enable_bit = REG_GET(DISPC_CONTROL2, bit, bit) == 1;
-       else
-               enable_bit = REG_GET(DISPC_CONTROL, bit, bit) == 1;
+       enable_bit = mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE) == 1;
 
        if (!enable_bit)
                return;
 
-       if (dispc_mgr_is_lcd(channel))
-               bit = 5; /* GOLCD */
-       else
-               bit = 6; /* GODIGIT */
-
-       if (channel == OMAP_DSS_CHANNEL_LCD2)
-               go_bit = REG_GET(DISPC_CONTROL2, bit, bit) == 1;
-       else
-               go_bit = REG_GET(DISPC_CONTROL, bit, bit) == 1;
+       go_bit = mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1;
 
        if (go_bit) {
                DSSERR("GO bit not down for channel %d\n", channel);
                return;
        }
 
-       DSSDBG("GO %s\n", channel == OMAP_DSS_CHANNEL_LCD ? "LCD" :
-               (channel == OMAP_DSS_CHANNEL_LCD2 ? "LCD2" : "DIGIT"));
+       DSSDBG("GO %s\n", mgr_desc[channel].name);
 
-       if (channel == OMAP_DSS_CHANNEL_LCD2)
-               REG_FLD_MOD(DISPC_CONTROL2, 1, bit, bit);
-       else
-               REG_FLD_MOD(DISPC_CONTROL, 1, bit, bit);
+       mgr_fld_write(channel, DISPC_MGR_FLD_GO, 1);
 }
 
 static void dispc_ovl_write_firh_reg(enum omap_plane plane, int reg, u32 value)
 
 static void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable)
 {
-       u16 reg;
-
-       if (channel == OMAP_DSS_CHANNEL_LCD)
-               reg = DISPC_CONFIG;
-       else if (channel == OMAP_DSS_CHANNEL_LCD2)
-               reg = DISPC_CONFIG2;
-       else
+       if (channel == OMAP_DSS_CHANNEL_DIGIT)
                return;
 
-       REG_FLD_MOD(reg, enable, 15, 15);
+       mgr_fld_write(channel, DISPC_MGR_FLD_CPR, enable);
 }
 
 static void dispc_mgr_set_cpr_coef(enum omap_channel channel,
 
 static void _enable_lcd_out(enum omap_channel channel, bool enable)
 {
-       if (channel == OMAP_DSS_CHANNEL_LCD2) {
-               REG_FLD_MOD(DISPC_CONTROL2, enable ? 1 : 0, 0, 0);
-               /* flush posted write */
-               dispc_read_reg(DISPC_CONTROL2);
-       } else {
-               REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0);
-               dispc_read_reg(DISPC_CONTROL);
-       }
+       mgr_fld_write(channel, DISPC_MGR_FLD_ENABLE, enable);
+       /* flush posted write */
+       mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
 }
 
 static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable)
        /* When we disable LCD output, we need to wait until frame is done.
         * Otherwise the DSS is still working, and turning off the clocks
         * prevents DSS from going to OFF mode */
-       is_on = channel == OMAP_DSS_CHANNEL_LCD2 ?
-                       REG_GET(DISPC_CONTROL2, 0, 0) :
-                       REG_GET(DISPC_CONTROL, 0, 0);
+       is_on = mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
 
-       irq = channel == OMAP_DSS_CHANNEL_LCD2 ? DISPC_IRQ_FRAMEDONE2 :
-                       DISPC_IRQ_FRAMEDONE;
+       irq = mgr_desc[channel].framedone_irq;
 
        if (!enable && is_on) {
                init_completion(&frame_done_completion);
 
 bool dispc_mgr_is_enabled(enum omap_channel channel)
 {
-       if (channel == OMAP_DSS_CHANNEL_LCD)
-               return !!REG_GET(DISPC_CONTROL, 0, 0);
-       else if (channel == OMAP_DSS_CHANNEL_DIGIT)
-               return !!REG_GET(DISPC_CONTROL, 1, 1);
-       else if (channel == OMAP_DSS_CHANNEL_LCD2)
-               return !!REG_GET(DISPC_CONTROL2, 0, 0);
-       else {
-               BUG();
-               return false;
-       }
+       return !!mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
 }
 
 void dispc_mgr_enable(enum omap_channel channel, bool enable)
 
 void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable)
 {
-       if (channel == OMAP_DSS_CHANNEL_LCD2)
-               REG_FLD_MOD(DISPC_CONFIG2, enable ? 1 : 0, 16, 16);
-       else
-               REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 16, 16);
+       mgr_fld_write(channel, DISPC_MGR_FLD_FIFOHANDCHECK, enable);
 }
 
 
                return;
        }
 
-       if (channel == OMAP_DSS_CHANNEL_LCD2)
-               REG_FLD_MOD(DISPC_CONTROL2, mode, 3, 3);
-       else
-               REG_FLD_MOD(DISPC_CONTROL, mode, 3, 3);
+       mgr_fld_write(channel, DISPC_MGR_FLD_STNTFT, mode);
 }
 
 void dispc_set_loadmode(enum omap_dss_load_mode mode)
                enum omap_dss_trans_key_type type,
                u32 trans_key)
 {
-       if (ch == OMAP_DSS_CHANNEL_LCD)
-               REG_FLD_MOD(DISPC_CONFIG, type, 11, 11);
-       else if (ch == OMAP_DSS_CHANNEL_DIGIT)
-               REG_FLD_MOD(DISPC_CONFIG, type, 13, 13);
-       else /* OMAP_DSS_CHANNEL_LCD2 */
-               REG_FLD_MOD(DISPC_CONFIG2, type, 11, 11);
+       mgr_fld_write(ch, DISPC_MGR_FLD_TCKSELECTION, type);
 
        dispc_write_reg(DISPC_TRANS_COLOR(ch), trans_key);
 }
 
 static void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable)
 {
-       if (ch == OMAP_DSS_CHANNEL_LCD)
-               REG_FLD_MOD(DISPC_CONFIG, enable, 10, 10);
-       else if (ch == OMAP_DSS_CHANNEL_DIGIT)
-               REG_FLD_MOD(DISPC_CONFIG, enable, 12, 12);
-       else /* OMAP_DSS_CHANNEL_LCD2 */
-               REG_FLD_MOD(DISPC_CONFIG2, enable, 10, 10);
+       mgr_fld_write(ch, DISPC_MGR_FLD_TCKENABLE, enable);
 }
 
 static void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch,
                return;
        }
 
-       if (channel == OMAP_DSS_CHANNEL_LCD2)
-               REG_FLD_MOD(DISPC_CONTROL2, code, 9, 8);
-       else
-               REG_FLD_MOD(DISPC_CONTROL, code, 9, 8);
+       mgr_fld_write(channel, DISPC_MGR_FLD_TFTDATALINES, code);
 }
 
 void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode)
 
 void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable)
 {
-       if (channel == OMAP_DSS_CHANNEL_LCD2)
-               REG_FLD_MOD(DISPC_CONTROL2, enable, 11, 11);
-       else
-               REG_FLD_MOD(DISPC_CONTROL, enable, 11, 11);
+       mgr_fld_write(channel, DISPC_MGR_FLD_STALLMODE, enable);
 }
 
 static bool _dispc_mgr_size_ok(u16 width, u16 height)
                DISPC_IRQ_VID3_FIFO_UNDERFLOW,
        };
 
-       static const unsigned sync_lost_bits[] = {
-               DISPC_IRQ_SYNC_LOST,
-               DISPC_IRQ_SYNC_LOST_DIGIT,
-               DISPC_IRQ_SYNC_LOST2,
-       };
-
        spin_lock_irqsave(&dispc.irq_lock, flags);
        errors = dispc.error_irqs;
        dispc.error_irqs = 0;
                unsigned bit;
 
                mgr = omap_dss_get_overlay_manager(i);
-               bit = sync_lost_bits[i];
+               bit = mgr_desc[i].sync_lost_irq;
 
                if (bit & errors) {
                        struct omap_dss_device *dssdev = mgr->device;