#define DSI_CMD2BKX_SEL_NONE           0x00
 
 /* Command2, BK0 bytes */
+#define DSI_CMD2_BK0_GAMCTRL_AJ_MASK   GENMASK(7, 6)
+#define DSI_CMD2_BK0_GAMCTRL_VC0_MASK  GENMASK(3, 0)
+#define DSI_CMD2_BK0_GAMCTRL_VC4_MASK  GENMASK(5, 0)
+#define DSI_CMD2_BK0_GAMCTRL_VC8_MASK  GENMASK(5, 0)
+#define DSI_CMD2_BK0_GAMCTRL_VC16_MASK GENMASK(4, 0)
+#define DSI_CMD2_BK0_GAMCTRL_VC24_MASK GENMASK(4, 0)
+#define DSI_CMD2_BK0_GAMCTRL_VC52_MASK GENMASK(3, 0)
+#define DSI_CMD2_BK0_GAMCTRL_VC80_MASK GENMASK(5, 0)
+#define DSI_CMD2_BK0_GAMCTRL_VC108_MASK        GENMASK(3, 0)
+#define DSI_CMD2_BK0_GAMCTRL_VC147_MASK        GENMASK(3, 0)
+#define DSI_CMD2_BK0_GAMCTRL_VC175_MASK        GENMASK(5, 0)
+#define DSI_CMD2_BK0_GAMCTRL_VC203_MASK        GENMASK(3, 0)
+#define DSI_CMD2_BK0_GAMCTRL_VC231_MASK        GENMASK(4, 0)
+#define DSI_CMD2_BK0_GAMCTRL_VC239_MASK        GENMASK(4, 0)
+#define DSI_CMD2_BK0_GAMCTRL_VC247_MASK        GENMASK(5, 0)
+#define DSI_CMD2_BK0_GAMCTRL_VC251_MASK        GENMASK(5, 0)
+#define DSI_CMD2_BK0_GAMCTRL_VC255_MASK        GENMASK(4, 0)
 #define DSI_LINESET_LINE               0x69
 #define DSI_LINESET_LDE_EN             BIT(7)
 #define DSI_LINESET_LINEDELTA          GENMASK(1, 0)
 #define DSI_MIPISET1_EOT_EN            BIT(3)
 #define DSI_CMD2_BK1_MIPISET1_SET      (BIT(7) | DSI_MIPISET1_EOT_EN)
 
+#define CFIELD_PREP(_mask, _val)                                       \
+       (((typeof(_mask))(_val) << (__builtin_ffsll(_mask) - 1)) & (_mask))
+
 struct st7701_panel_desc {
        const struct drm_display_mode *mode;
        unsigned int lanes;
        enum mipi_dsi_pixel_format format;
        unsigned int panel_sleep_delay;
+
+       /* TFT matrix driver configuration, panel specific. */
+       const u8        pv_gamma[16];   /* Positive voltage gamma control */
+       const u8        nv_gamma[16];   /* Negative voltage gamma control */
 };
 
 struct st7701 {
 
 static void st7701_init_sequence(struct st7701 *st7701)
 {
-       const struct drm_display_mode *mode = st7701->desc->mode;
+       const struct st7701_panel_desc *desc = st7701->desc;
+       const struct drm_display_mode *mode = desc->mode;
 
        ST7701_DSI(st7701, MIPI_DCS_SOFT_RESET, 0x00);
 
        /* Command2, BK0 */
        ST7701_DSI(st7701, DSI_CMD2BKX_SEL,
                   0x77, 0x01, 0x00, 0x00, DSI_CMD2BK0_SEL);
-       ST7701_DSI(st7701, DSI_CMD2_BK0_PVGAMCTRL, 0x00, 0x0E, 0x15, 0x0F,
-                  0x11, 0x08, 0x08, 0x08, 0x08, 0x23, 0x04, 0x13, 0x12,
-                  0x2B, 0x34, 0x1F);
-       ST7701_DSI(st7701, DSI_CMD2_BK0_NVGAMCTRL, 0x00, 0x0E, 0x95, 0x0F,
-                  0x13, 0x07, 0x09, 0x08, 0x08, 0x22, 0x04, 0x10, 0x0E,
-                  0x2C, 0x34, 0x1F);
+       mipi_dsi_dcs_write(st7701->dsi, DSI_CMD2_BK0_PVGAMCTRL,
+                          desc->pv_gamma, ARRAY_SIZE(desc->pv_gamma));
+       mipi_dsi_dcs_write(st7701->dsi, DSI_CMD2_BK0_NVGAMCTRL,
+                          desc->nv_gamma, ARRAY_SIZE(desc->nv_gamma));
        ST7701_DSI(st7701, DSI_CMD2_BK0_LNESET,
                   DSI_CMD2_BK0_LNESET_B0, DSI_CMD2_BK0_LNESET_B1);
        ST7701_DSI(st7701, DSI_CMD2_BK0_PORCTRL,
        .lanes = 2,
        .format = MIPI_DSI_FMT_RGB888,
        .panel_sleep_delay = 80, /* panel need extra 80ms for sleep out cmd */
+
+       .pv_gamma = {
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) |
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC0_MASK, 0),
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) |
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC4_MASK, 0xe),
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) |
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC8_MASK, 0x15),
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC16_MASK, 0xf),
+
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) |
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC24_MASK, 0x11),
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC52_MASK, 0x8),
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC80_MASK, 0x8),
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC108_MASK, 0x8),
+
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC147_MASK, 0x8),
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC175_MASK, 0x23),
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC203_MASK, 0x4),
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) |
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC231_MASK, 0x13),
+
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC239_MASK, 0x12),
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) |
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC247_MASK, 0x2b),
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) |
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC251_MASK, 0x34),
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) |
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC255_MASK, 0x1f)
+       },
+       .nv_gamma = {
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) |
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC0_MASK, 0),
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) |
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC4_MASK, 0xe),
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0x2) |
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC8_MASK, 0x15),
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC16_MASK, 0xf),
+
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) |
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC24_MASK, 0x13),
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC52_MASK, 0x7),
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC80_MASK, 0x9),
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC108_MASK, 0x8),
+
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC147_MASK, 0x8),
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC175_MASK, 0x22),
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC203_MASK, 0x4),
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) |
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC231_MASK, 0x10),
+
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC239_MASK, 0xe),
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) |
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC247_MASK, 0x2c),
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) |
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC251_MASK, 0x34),
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) |
+               CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC255_MASK, 0x1f)
+       },
 };
 
 static int st7701_dsi_probe(struct mipi_dsi_device *dsi)