1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2019, Amarula Solutions. 4 * Author: Jagan Teki <jagan@amarulasolutions.com> 5 */ 6 7 #include <drm/drm_mipi_dbi.h> 8 #include <drm/drm_mipi_dsi.h> 9 #include <drm/drm_modes.h> 10 #include <drm/drm_of.h> 11 #include <drm/drm_panel.h> 12 13 #include <linux/bitfield.h> 14 #include <linux/gpio/consumer.h> 15 #include <linux/delay.h> 16 #include <linux/module.h> 17 #include <linux/of.h> 18 #include <linux/regulator/consumer.h> 19 #include <linux/spi/spi.h> 20 21 #include <video/mipi_display.h> 22 23 /* Command2 BKx selection command */ 24 #define ST7701_CMD2BKX_SEL 0xFF 25 #define ST7701_CMD1 0 26 #define ST7701_CMD2 BIT(4) 27 #define ST7701_CMD2BK_MASK GENMASK(3, 0) 28 29 /* Command2, BK0 commands */ 30 #define ST7701_CMD2_BK0_PVGAMCTRL 0xB0 /* Positive Voltage Gamma Control */ 31 #define ST7701_CMD2_BK0_NVGAMCTRL 0xB1 /* Negative Voltage Gamma Control */ 32 #define ST7701_CMD2_BK0_LNESET 0xC0 /* Display Line setting */ 33 #define ST7701_CMD2_BK0_PORCTRL 0xC1 /* Porch control */ 34 #define ST7701_CMD2_BK0_INVSEL 0xC2 /* Inversion selection, Frame Rate Control */ 35 36 /* Command2, BK1 commands */ 37 #define ST7701_CMD2_BK1_VRHS 0xB0 /* Vop amplitude setting */ 38 #define ST7701_CMD2_BK1_VCOM 0xB1 /* VCOM amplitude setting */ 39 #define ST7701_CMD2_BK1_VGHSS 0xB2 /* VGH Voltage setting */ 40 #define ST7701_CMD2_BK1_TESTCMD 0xB3 /* TEST Command Setting */ 41 #define ST7701_CMD2_BK1_VGLS 0xB5 /* VGL Voltage setting */ 42 #define ST7701_CMD2_BK1_PWCTLR1 0xB7 /* Power Control 1 */ 43 #define ST7701_CMD2_BK1_PWCTLR2 0xB8 /* Power Control 2 */ 44 #define ST7701_CMD2_BK1_SPD1 0xC1 /* Source pre_drive timing set1 */ 45 #define ST7701_CMD2_BK1_SPD2 0xC2 /* Source EQ2 Setting */ 46 #define ST7701_CMD2_BK1_MIPISET1 0xD0 /* MIPI Setting 1 */ 47 48 /* Command2, BK0 bytes */ 49 #define ST7701_CMD2_BK0_GAMCTRL_AJ_MASK GENMASK(7, 6) 50 #define ST7701_CMD2_BK0_GAMCTRL_VC0_MASK GENMASK(3, 0) 51 #define ST7701_CMD2_BK0_GAMCTRL_VC4_MASK GENMASK(5, 0) 52 #define ST7701_CMD2_BK0_GAMCTRL_VC8_MASK GENMASK(5, 0) 53 #define ST7701_CMD2_BK0_GAMCTRL_VC16_MASK GENMASK(4, 0) 54 #define ST7701_CMD2_BK0_GAMCTRL_VC24_MASK GENMASK(4, 0) 55 #define ST7701_CMD2_BK0_GAMCTRL_VC52_MASK GENMASK(3, 0) 56 #define ST7701_CMD2_BK0_GAMCTRL_VC80_MASK GENMASK(5, 0) 57 #define ST7701_CMD2_BK0_GAMCTRL_VC108_MASK GENMASK(3, 0) 58 #define ST7701_CMD2_BK0_GAMCTRL_VC147_MASK GENMASK(3, 0) 59 #define ST7701_CMD2_BK0_GAMCTRL_VC175_MASK GENMASK(5, 0) 60 #define ST7701_CMD2_BK0_GAMCTRL_VC203_MASK GENMASK(3, 0) 61 #define ST7701_CMD2_BK0_GAMCTRL_VC231_MASK GENMASK(4, 0) 62 #define ST7701_CMD2_BK0_GAMCTRL_VC239_MASK GENMASK(4, 0) 63 #define ST7701_CMD2_BK0_GAMCTRL_VC247_MASK GENMASK(5, 0) 64 #define ST7701_CMD2_BK0_GAMCTRL_VC251_MASK GENMASK(5, 0) 65 #define ST7701_CMD2_BK0_GAMCTRL_VC255_MASK GENMASK(4, 0) 66 #define ST7701_CMD2_BK0_LNESET_LINE_MASK GENMASK(6, 0) 67 #define ST7701_CMD2_BK0_LNESET_LDE_EN BIT(7) 68 #define ST7701_CMD2_BK0_LNESET_LINEDELTA GENMASK(1, 0) 69 #define ST7701_CMD2_BK0_PORCTRL_VBP_MASK GENMASK(7, 0) 70 #define ST7701_CMD2_BK0_PORCTRL_VFP_MASK GENMASK(7, 0) 71 #define ST7701_CMD2_BK0_INVSEL_ONES_MASK GENMASK(5, 4) 72 #define ST7701_CMD2_BK0_INVSEL_NLINV_MASK GENMASK(2, 0) 73 #define ST7701_CMD2_BK0_INVSEL_RTNI_MASK GENMASK(4, 0) 74 75 /* Command2, BK1 bytes */ 76 #define ST7701_CMD2_BK1_VRHA_MASK GENMASK(7, 0) 77 #define ST7701_CMD2_BK1_VCOM_MASK GENMASK(7, 0) 78 #define ST7701_CMD2_BK1_VGHSS_MASK GENMASK(3, 0) 79 #define ST7701_CMD2_BK1_TESTCMD_VAL BIT(7) 80 #define ST7701_CMD2_BK1_VGLS_ONES BIT(6) 81 #define ST7701_CMD2_BK1_VGLS_MASK GENMASK(3, 0) 82 #define ST7701_CMD2_BK1_PWRCTRL1_AP_MASK GENMASK(7, 6) 83 #define ST7701_CMD2_BK1_PWRCTRL1_APIS_MASK GENMASK(3, 2) 84 #define ST7701_CMD2_BK1_PWRCTRL1_APOS_MASK GENMASK(1, 0) 85 #define ST7701_CMD2_BK1_PWRCTRL2_AVDD_MASK GENMASK(5, 4) 86 #define ST7701_CMD2_BK1_PWRCTRL2_AVCL_MASK GENMASK(1, 0) 87 #define ST7701_CMD2_BK1_SPD1_ONES_MASK GENMASK(6, 4) 88 #define ST7701_CMD2_BK1_SPD1_T2D_MASK GENMASK(3, 0) 89 #define ST7701_CMD2_BK1_SPD2_ONES_MASK GENMASK(6, 4) 90 #define ST7701_CMD2_BK1_SPD2_T3D_MASK GENMASK(3, 0) 91 #define ST7701_CMD2_BK1_MIPISET1_ONES BIT(7) 92 #define ST7701_CMD2_BK1_MIPISET1_EOT_EN BIT(3) 93 94 #define CFIELD_PREP(_mask, _val) \ 95 (((typeof(_mask))(_val) << (__builtin_ffsll(_mask) - 1)) & (_mask)) 96 97 enum op_bias { 98 OP_BIAS_OFF = 0, 99 OP_BIAS_MIN, 100 OP_BIAS_MIDDLE, 101 OP_BIAS_MAX 102 }; 103 104 struct st7701; 105 106 struct st7701_panel_desc { 107 const struct drm_display_mode *mode; 108 unsigned int lanes; 109 enum mipi_dsi_pixel_format format; 110 unsigned int panel_sleep_delay; 111 112 /* TFT matrix driver configuration, panel specific. */ 113 const u8 pv_gamma[16]; /* Positive voltage gamma control */ 114 const u8 nv_gamma[16]; /* Negative voltage gamma control */ 115 const u8 nlinv; /* Inversion selection */ 116 const u32 vop_uv; /* Vop in uV */ 117 const u32 vcom_uv; /* Vcom in uV */ 118 const u16 vgh_mv; /* Vgh in mV */ 119 const s16 vgl_mv; /* Vgl in mV */ 120 const u16 avdd_mv; /* Avdd in mV */ 121 const s16 avcl_mv; /* Avcl in mV */ 122 const enum op_bias gamma_op_bias; 123 const enum op_bias input_op_bias; 124 const enum op_bias output_op_bias; 125 const u16 t2d_ns; /* T2D in ns */ 126 const u16 t3d_ns; /* T3D in ns */ 127 const bool eot_en; 128 129 /* GIP sequence, fully custom and undocumented. */ 130 void (*gip_sequence)(struct st7701 *st7701); 131 }; 132 133 struct st7701 { 134 struct drm_panel panel; 135 struct mipi_dsi_device *dsi; 136 struct mipi_dbi dbi; 137 const struct st7701_panel_desc *desc; 138 139 struct regulator_bulk_data supplies[2]; 140 struct gpio_desc *reset; 141 unsigned int sleep_delay; 142 enum drm_panel_orientation orientation; 143 144 int (*write_command)(struct st7701 *st7701, u8 cmd, const u8 *seq, 145 size_t len); 146 }; 147 148 static inline struct st7701 *panel_to_st7701(struct drm_panel *panel) 149 { 150 return container_of(panel, struct st7701, panel); 151 } 152 153 static int st7701_dsi_write(struct st7701 *st7701, u8 cmd, const u8 *seq, 154 size_t len) 155 { 156 return mipi_dsi_dcs_write(st7701->dsi, cmd, seq, len); 157 } 158 159 static int st7701_dbi_write(struct st7701 *st7701, u8 cmd, const u8 *seq, 160 size_t len) 161 { 162 return mipi_dbi_command_stackbuf(&st7701->dbi, cmd, seq, len); 163 } 164 165 #define ST7701_WRITE(st7701, cmd, seq...) \ 166 { \ 167 const u8 d[] = { seq }; \ 168 st7701->write_command(st7701, cmd, d, ARRAY_SIZE(d)); \ 169 } 170 171 static u8 st7701_vgls_map(struct st7701 *st7701) 172 { 173 const struct st7701_panel_desc *desc = st7701->desc; 174 struct { 175 s32 vgl; 176 u8 val; 177 } map[16] = { 178 { -7060, 0x0 }, { -7470, 0x1 }, 179 { -7910, 0x2 }, { -8140, 0x3 }, 180 { -8650, 0x4 }, { -8920, 0x5 }, 181 { -9210, 0x6 }, { -9510, 0x7 }, 182 { -9830, 0x8 }, { -10170, 0x9 }, 183 { -10530, 0xa }, { -10910, 0xb }, 184 { -11310, 0xc }, { -11730, 0xd }, 185 { -12200, 0xe }, { -12690, 0xf } 186 }; 187 int i; 188 189 for (i = 0; i < ARRAY_SIZE(map); i++) 190 if (desc->vgl_mv == map[i].vgl) 191 return map[i].val; 192 193 return 0; 194 } 195 196 static void st7701_switch_cmd_bkx(struct st7701 *st7701, bool cmd2, u8 bkx) 197 { 198 u8 val; 199 200 if (cmd2) 201 val = ST7701_CMD2 | FIELD_PREP(ST7701_CMD2BK_MASK, bkx); 202 else 203 val = ST7701_CMD1; 204 205 ST7701_WRITE(st7701, ST7701_CMD2BKX_SEL, 0x77, 0x01, 0x00, 0x00, val); 206 } 207 208 static void st7701_init_sequence(struct st7701 *st7701) 209 { 210 const struct st7701_panel_desc *desc = st7701->desc; 211 const struct drm_display_mode *mode = desc->mode; 212 const u8 linecount8 = mode->vdisplay / 8; 213 const u8 linecountrem2 = (mode->vdisplay % 8) / 2; 214 215 ST7701_WRITE(st7701, MIPI_DCS_SOFT_RESET, 0x00); 216 217 /* We need to wait 5ms before sending new commands */ 218 msleep(5); 219 220 ST7701_WRITE(st7701, MIPI_DCS_EXIT_SLEEP_MODE, 0x00); 221 222 msleep(st7701->sleep_delay); 223 224 /* Command2, BK0 */ 225 st7701_switch_cmd_bkx(st7701, true, 0); 226 227 st7701->write_command(st7701, ST7701_CMD2_BK0_PVGAMCTRL, desc->pv_gamma, 228 ARRAY_SIZE(desc->pv_gamma)); 229 st7701->write_command(st7701, ST7701_CMD2_BK0_NVGAMCTRL, desc->nv_gamma, 230 ARRAY_SIZE(desc->nv_gamma)); 231 /* 232 * Vertical line count configuration: 233 * Line[6:0]: select number of vertical lines of the TFT matrix in 234 * multiples of 8 lines 235 * LDE_EN: enable sub-8-line granularity line count 236 * Line_delta[1:0]: add 0/2/4/6 extra lines to line count selected 237 * using Line[6:0] 238 * 239 * Total number of vertical lines: 240 * LN = ((Line[6:0] + 1) * 8) + (LDE_EN ? Line_delta[1:0] * 2 : 0) 241 */ 242 ST7701_WRITE(st7701, ST7701_CMD2_BK0_LNESET, 243 FIELD_PREP(ST7701_CMD2_BK0_LNESET_LINE_MASK, linecount8 - 1) | 244 (linecountrem2 ? ST7701_CMD2_BK0_LNESET_LDE_EN : 0), 245 FIELD_PREP(ST7701_CMD2_BK0_LNESET_LINEDELTA, linecountrem2)); 246 ST7701_WRITE(st7701, ST7701_CMD2_BK0_PORCTRL, 247 FIELD_PREP(ST7701_CMD2_BK0_PORCTRL_VBP_MASK, 248 mode->vtotal - mode->vsync_end), 249 FIELD_PREP(ST7701_CMD2_BK0_PORCTRL_VFP_MASK, 250 mode->vsync_start - mode->vdisplay)); 251 /* 252 * Horizontal pixel count configuration: 253 * PCLK = 512 + (RTNI[4:0] * 16) 254 * The PCLK is number of pixel clock per line, which matches 255 * mode htotal. The minimum is 512 PCLK. 256 */ 257 ST7701_WRITE(st7701, ST7701_CMD2_BK0_INVSEL, 258 ST7701_CMD2_BK0_INVSEL_ONES_MASK | 259 FIELD_PREP(ST7701_CMD2_BK0_INVSEL_NLINV_MASK, desc->nlinv), 260 FIELD_PREP(ST7701_CMD2_BK0_INVSEL_RTNI_MASK, 261 (clamp((u32)mode->htotal, 512U, 1008U) - 512) / 16)); 262 263 /* Command2, BK1 */ 264 st7701_switch_cmd_bkx(st7701, true, 1); 265 266 /* Vop = 3.5375V + (VRHA[7:0] * 0.0125V) */ 267 ST7701_WRITE(st7701, ST7701_CMD2_BK1_VRHS, 268 FIELD_PREP(ST7701_CMD2_BK1_VRHA_MASK, 269 DIV_ROUND_CLOSEST(desc->vop_uv - 3537500, 12500))); 270 271 /* Vcom = 0.1V + (VCOM[7:0] * 0.0125V) */ 272 ST7701_WRITE(st7701, ST7701_CMD2_BK1_VCOM, 273 FIELD_PREP(ST7701_CMD2_BK1_VCOM_MASK, 274 DIV_ROUND_CLOSEST(desc->vcom_uv - 100000, 12500))); 275 276 /* Vgh = 11.5V + (VGHSS[7:0] * 0.5V) */ 277 ST7701_WRITE(st7701, ST7701_CMD2_BK1_VGHSS, 278 FIELD_PREP(ST7701_CMD2_BK1_VGHSS_MASK, 279 DIV_ROUND_CLOSEST(clamp(desc->vgh_mv, 280 (u16)11500, 281 (u16)17000) - 11500, 282 500))); 283 284 ST7701_WRITE(st7701, ST7701_CMD2_BK1_TESTCMD, ST7701_CMD2_BK1_TESTCMD_VAL); 285 286 /* Vgl is non-linear */ 287 ST7701_WRITE(st7701, ST7701_CMD2_BK1_VGLS, 288 ST7701_CMD2_BK1_VGLS_ONES | 289 FIELD_PREP(ST7701_CMD2_BK1_VGLS_MASK, st7701_vgls_map(st7701))); 290 291 ST7701_WRITE(st7701, ST7701_CMD2_BK1_PWCTLR1, 292 FIELD_PREP(ST7701_CMD2_BK1_PWRCTRL1_AP_MASK, 293 desc->gamma_op_bias) | 294 FIELD_PREP(ST7701_CMD2_BK1_PWRCTRL1_APIS_MASK, 295 desc->input_op_bias) | 296 FIELD_PREP(ST7701_CMD2_BK1_PWRCTRL1_APOS_MASK, 297 desc->output_op_bias)); 298 299 /* Avdd = 6.2V + (AVDD[1:0] * 0.2V) , Avcl = -4.4V - (AVCL[1:0] * 0.2V) */ 300 ST7701_WRITE(st7701, ST7701_CMD2_BK1_PWCTLR2, 301 FIELD_PREP(ST7701_CMD2_BK1_PWRCTRL2_AVDD_MASK, 302 DIV_ROUND_CLOSEST(desc->avdd_mv - 6200, 200)) | 303 FIELD_PREP(ST7701_CMD2_BK1_PWRCTRL2_AVCL_MASK, 304 DIV_ROUND_CLOSEST(-4400 - desc->avcl_mv, 200))); 305 306 /* T2D = 0.2us * T2D[3:0] */ 307 ST7701_WRITE(st7701, ST7701_CMD2_BK1_SPD1, 308 ST7701_CMD2_BK1_SPD1_ONES_MASK | 309 FIELD_PREP(ST7701_CMD2_BK1_SPD1_T2D_MASK, 310 DIV_ROUND_CLOSEST(desc->t2d_ns, 200))); 311 312 /* T3D = 4us + (0.8us * T3D[3:0]) */ 313 ST7701_WRITE(st7701, ST7701_CMD2_BK1_SPD2, 314 ST7701_CMD2_BK1_SPD2_ONES_MASK | 315 FIELD_PREP(ST7701_CMD2_BK1_SPD2_T3D_MASK, 316 DIV_ROUND_CLOSEST(desc->t3d_ns - 4000, 800))); 317 318 ST7701_WRITE(st7701, ST7701_CMD2_BK1_MIPISET1, 319 ST7701_CMD2_BK1_MIPISET1_ONES | 320 (desc->eot_en ? ST7701_CMD2_BK1_MIPISET1_EOT_EN : 0)); 321 } 322 323 static void ts8550b_gip_sequence(struct st7701 *st7701) 324 { 325 /** 326 * ST7701_SPEC_V1.2 is unable to provide enough information above this 327 * specific command sequence, so grab the same from vendor BSP driver. 328 */ 329 ST7701_WRITE(st7701, 0xE0, 0x00, 0x00, 0x02); 330 ST7701_WRITE(st7701, 0xE1, 0x0B, 0x00, 0x0D, 0x00, 0x0C, 0x00, 0x0E, 331 0x00, 0x00, 0x44, 0x44); 332 ST7701_WRITE(st7701, 0xE2, 0x33, 0x33, 0x44, 0x44, 0x64, 0x00, 0x66, 333 0x00, 0x65, 0x00, 0x67, 0x00, 0x00); 334 ST7701_WRITE(st7701, 0xE3, 0x00, 0x00, 0x33, 0x33); 335 ST7701_WRITE(st7701, 0xE4, 0x44, 0x44); 336 ST7701_WRITE(st7701, 0xE5, 0x0C, 0x78, 0x3C, 0xA0, 0x0E, 0x78, 0x3C, 337 0xA0, 0x10, 0x78, 0x3C, 0xA0, 0x12, 0x78, 0x3C, 0xA0); 338 ST7701_WRITE(st7701, 0xE6, 0x00, 0x00, 0x33, 0x33); 339 ST7701_WRITE(st7701, 0xE7, 0x44, 0x44); 340 ST7701_WRITE(st7701, 0xE8, 0x0D, 0x78, 0x3C, 0xA0, 0x0F, 0x78, 0x3C, 341 0xA0, 0x11, 0x78, 0x3C, 0xA0, 0x13, 0x78, 0x3C, 0xA0); 342 ST7701_WRITE(st7701, 0xEB, 0x02, 0x02, 0x39, 0x39, 0xEE, 0x44, 0x00); 343 ST7701_WRITE(st7701, 0xEC, 0x00, 0x00); 344 ST7701_WRITE(st7701, 0xED, 0xFF, 0xF1, 0x04, 0x56, 0x72, 0x3F, 0xFF, 345 0xFF, 0xFF, 0xFF, 0xF3, 0x27, 0x65, 0x40, 0x1F, 0xFF); 346 } 347 348 static void dmt028vghmcmi_1a_gip_sequence(struct st7701 *st7701) 349 { 350 ST7701_WRITE(st7701, 0xEE, 0x42); 351 ST7701_WRITE(st7701, 0xE0, 0x00, 0x00, 0x02); 352 353 ST7701_WRITE(st7701, 0xE1, 354 0x04, 0xA0, 0x06, 0xA0, 355 0x05, 0xA0, 0x07, 0xA0, 356 0x00, 0x44, 0x44); 357 ST7701_WRITE(st7701, 0xE2, 358 0x00, 0x00, 0x00, 0x00, 359 0x00, 0x00, 0x00, 0x00, 360 0x00, 0x00, 0x00, 0x00); 361 ST7701_WRITE(st7701, 0xE3, 362 0x00, 0x00, 0x22, 0x22); 363 ST7701_WRITE(st7701, 0xE4, 0x44, 0x44); 364 ST7701_WRITE(st7701, 0xE5, 365 0x0C, 0x90, 0xA0, 0xA0, 366 0x0E, 0x92, 0xA0, 0xA0, 367 0x08, 0x8C, 0xA0, 0xA0, 368 0x0A, 0x8E, 0xA0, 0xA0); 369 ST7701_WRITE(st7701, 0xE6, 370 0x00, 0x00, 0x22, 0x22); 371 ST7701_WRITE(st7701, 0xE7, 0x44, 0x44); 372 ST7701_WRITE(st7701, 0xE8, 373 0x0D, 0x91, 0xA0, 0xA0, 374 0x0F, 0x93, 0xA0, 0xA0, 375 0x09, 0x8D, 0xA0, 0xA0, 376 0x0B, 0x8F, 0xA0, 0xA0); 377 ST7701_WRITE(st7701, 0xEB, 378 0x00, 0x00, 0xE4, 0xE4, 379 0x44, 0x00, 0x00); 380 ST7701_WRITE(st7701, 0xED, 381 0xFF, 0xF5, 0x47, 0x6F, 382 0x0B, 0xA1, 0xAB, 0xFF, 383 0xFF, 0xBA, 0x1A, 0xB0, 384 0xF6, 0x74, 0x5F, 0xFF); 385 ST7701_WRITE(st7701, 0xEF, 386 0x08, 0x08, 0x08, 0x40, 387 0x3F, 0x64); 388 389 st7701_switch_cmd_bkx(st7701, false, 0); 390 391 st7701_switch_cmd_bkx(st7701, true, 3); 392 ST7701_WRITE(st7701, 0xE6, 0x7C); 393 ST7701_WRITE(st7701, 0xE8, 0x00, 0x0E); 394 395 st7701_switch_cmd_bkx(st7701, false, 0); 396 ST7701_WRITE(st7701, 0x11); 397 msleep(120); 398 399 st7701_switch_cmd_bkx(st7701, true, 3); 400 ST7701_WRITE(st7701, 0xE8, 0x00, 0x0C); 401 msleep(10); 402 ST7701_WRITE(st7701, 0xE8, 0x00, 0x00); 403 404 st7701_switch_cmd_bkx(st7701, false, 0); 405 ST7701_WRITE(st7701, 0x11); 406 msleep(120); 407 ST7701_WRITE(st7701, 0xE8, 0x00, 0x00); 408 409 st7701_switch_cmd_bkx(st7701, false, 0); 410 411 ST7701_WRITE(st7701, 0x3A, 0x70); 412 } 413 414 static void kd50t048a_gip_sequence(struct st7701 *st7701) 415 { 416 /** 417 * ST7701_SPEC_V1.2 is unable to provide enough information above this 418 * specific command sequence, so grab the same from vendor BSP driver. 419 */ 420 ST7701_WRITE(st7701, 0xE0, 0x00, 0x00, 0x02); 421 ST7701_WRITE(st7701, 0xE1, 0x08, 0x00, 0x0A, 0x00, 0x07, 0x00, 0x09, 422 0x00, 0x00, 0x33, 0x33); 423 ST7701_WRITE(st7701, 0xE2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 424 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); 425 ST7701_WRITE(st7701, 0xE3, 0x00, 0x00, 0x33, 0x33); 426 ST7701_WRITE(st7701, 0xE4, 0x44, 0x44); 427 ST7701_WRITE(st7701, 0xE5, 0x0E, 0x60, 0xA0, 0xA0, 0x10, 0x60, 0xA0, 428 0xA0, 0x0A, 0x60, 0xA0, 0xA0, 0x0C, 0x60, 0xA0, 0xA0); 429 ST7701_WRITE(st7701, 0xE6, 0x00, 0x00, 0x33, 0x33); 430 ST7701_WRITE(st7701, 0xE7, 0x44, 0x44); 431 ST7701_WRITE(st7701, 0xE8, 0x0D, 0x60, 0xA0, 0xA0, 0x0F, 0x60, 0xA0, 432 0xA0, 0x09, 0x60, 0xA0, 0xA0, 0x0B, 0x60, 0xA0, 0xA0); 433 ST7701_WRITE(st7701, 0xEB, 0x02, 0x01, 0xE4, 0xE4, 0x44, 0x00, 0x40); 434 ST7701_WRITE(st7701, 0xEC, 0x02, 0x01); 435 ST7701_WRITE(st7701, 0xED, 0xAB, 0x89, 0x76, 0x54, 0x01, 0xFF, 0xFF, 436 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x45, 0x67, 0x98, 0xBA); 437 } 438 439 static void rg_arc_gip_sequence(struct st7701 *st7701) 440 { 441 st7701_switch_cmd_bkx(st7701, true, 3); 442 ST7701_WRITE(st7701, 0xEF, 0x08); 443 st7701_switch_cmd_bkx(st7701, true, 0); 444 ST7701_WRITE(st7701, 0xC7, 0x04); 445 ST7701_WRITE(st7701, 0xCC, 0x38); 446 st7701_switch_cmd_bkx(st7701, true, 1); 447 ST7701_WRITE(st7701, 0xB9, 0x10); 448 ST7701_WRITE(st7701, 0xBC, 0x03); 449 ST7701_WRITE(st7701, 0xC0, 0x89); 450 ST7701_WRITE(st7701, 0xE0, 0x00, 0x00, 0x02); 451 ST7701_WRITE(st7701, 0xE1, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 452 0x00, 0x00, 0x20, 0x20); 453 ST7701_WRITE(st7701, 0xE2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 454 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); 455 ST7701_WRITE(st7701, 0xE3, 0x00, 0x00, 0x33, 0x00); 456 ST7701_WRITE(st7701, 0xE4, 0x22, 0x00); 457 ST7701_WRITE(st7701, 0xE5, 0x04, 0x5C, 0xA0, 0xA0, 0x06, 0x5C, 0xA0, 458 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); 459 ST7701_WRITE(st7701, 0xE6, 0x00, 0x00, 0x33, 0x00); 460 ST7701_WRITE(st7701, 0xE7, 0x22, 0x00); 461 ST7701_WRITE(st7701, 0xE8, 0x05, 0x5C, 0xA0, 0xA0, 0x07, 0x5C, 0xA0, 462 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); 463 ST7701_WRITE(st7701, 0xEB, 0x02, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00); 464 ST7701_WRITE(st7701, 0xEC, 0x00, 0x00); 465 ST7701_WRITE(st7701, 0xED, 0xFA, 0x45, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 466 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB0, 0x54, 0xAF); 467 ST7701_WRITE(st7701, 0xEF, 0x08, 0x08, 0x08, 0x45, 0x3F, 0x54); 468 st7701_switch_cmd_bkx(st7701, false, 0); 469 ST7701_WRITE(st7701, MIPI_DCS_SET_ADDRESS_MODE, 0x17); 470 ST7701_WRITE(st7701, MIPI_DCS_SET_PIXEL_FORMAT, 0x77); 471 ST7701_WRITE(st7701, MIPI_DCS_EXIT_SLEEP_MODE, 0x00); 472 msleep(120); 473 } 474 475 static void rg28xx_gip_sequence(struct st7701 *st7701) 476 { 477 st7701_switch_cmd_bkx(st7701, true, 3); 478 ST7701_WRITE(st7701, 0xEF, 0x08); 479 480 st7701_switch_cmd_bkx(st7701, true, 0); 481 ST7701_WRITE(st7701, 0xC3, 0x02, 0x10, 0x02); 482 ST7701_WRITE(st7701, 0xC7, 0x04); 483 ST7701_WRITE(st7701, 0xCC, 0x10); 484 485 st7701_switch_cmd_bkx(st7701, true, 1); 486 ST7701_WRITE(st7701, 0xEE, 0x42); 487 ST7701_WRITE(st7701, 0xE0, 0x00, 0x00, 0x02); 488 489 ST7701_WRITE(st7701, 0xE1, 0x04, 0xA0, 0x06, 0xA0, 0x05, 0xA0, 0x07, 0xA0, 490 0x00, 0x44, 0x44); 491 ST7701_WRITE(st7701, 0xE2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 492 0x00, 0x00, 0x00, 0x00); 493 ST7701_WRITE(st7701, 0xE3, 0x00, 0x00, 0x22, 0x22); 494 ST7701_WRITE(st7701, 0xE4, 0x44, 0x44); 495 ST7701_WRITE(st7701, 0xE5, 0x0C, 0x90, 0xA0, 0xA0, 0x0E, 0x92, 0xA0, 0xA0, 496 0x08, 0x8C, 0xA0, 0xA0, 0x0A, 0x8E, 0xA0, 0xA0); 497 ST7701_WRITE(st7701, 0xE6, 0x00, 0x00, 0x22, 0x22); 498 ST7701_WRITE(st7701, 0xE7, 0x44, 0x44); 499 ST7701_WRITE(st7701, 0xE8, 0x0D, 0x91, 0xA0, 0xA0, 0x0F, 0x93, 0xA0, 0xA0, 500 0x09, 0x8D, 0xA0, 0xA0, 0x0B, 0x8F, 0xA0, 0xA0); 501 ST7701_WRITE(st7701, 0xEB, 0x00, 0x00, 0xE4, 0xE4, 0x44, 0x00, 0x40); 502 ST7701_WRITE(st7701, 0xED, 0xFF, 0xF5, 0x47, 0x6F, 0x0B, 0xA1, 0xBA, 0xFF, 503 0xFF, 0xAB, 0x1A, 0xB0, 0xF6, 0x74, 0x5F, 0xFF); 504 ST7701_WRITE(st7701, 0xEF, 0x08, 0x08, 0x08, 0x45, 0x3F, 0x54); 505 506 st7701_switch_cmd_bkx(st7701, false, 0); 507 508 st7701_switch_cmd_bkx(st7701, true, 3); 509 ST7701_WRITE(st7701, 0xE6, 0x16); 510 ST7701_WRITE(st7701, 0xE8, 0x00, 0x0E); 511 512 st7701_switch_cmd_bkx(st7701, false, 0); 513 ST7701_WRITE(st7701, MIPI_DCS_SET_ADDRESS_MODE, 0x10); 514 ST7701_WRITE(st7701, MIPI_DCS_EXIT_SLEEP_MODE); 515 msleep(120); 516 517 st7701_switch_cmd_bkx(st7701, true, 3); 518 ST7701_WRITE(st7701, 0xE8, 0x00, 0x0C); 519 msleep(10); 520 ST7701_WRITE(st7701, 0xE8, 0x00, 0x00); 521 st7701_switch_cmd_bkx(st7701, false, 0); 522 } 523 524 static void wf40eswaa6mnn0_gip_sequence(struct st7701 *st7701) 525 { 526 ST7701_WRITE(st7701, 0xE0, 0x00, 0x28, 0x02); 527 ST7701_WRITE(st7701, 0xE1, 0x08, 0xA0, 0x00, 0x00, 0x07, 0xA0, 0x00, 528 0x00, 0x00, 0x44, 0x44); 529 ST7701_WRITE(st7701, 0xE2, 0x11, 0x11, 0x44, 0x44, 0xED, 0xA0, 0x00, 530 0x00, 0xEC, 0xA0, 0x00, 0x00); 531 ST7701_WRITE(st7701, 0xE3, 0x00, 0x00, 0x11, 0x11); 532 ST7701_WRITE(st7701, 0xE4, 0x44, 0x44); 533 ST7701_WRITE(st7701, 0xE5, 0x0A, 0xE9, 0xD8, 0xA0, 0x0C, 0xEB, 0xD8, 534 0xA0, 0x0E, 0xED, 0xD8, 0xA0, 0x10, 0xEF, 0xD8, 0xA0); 535 ST7701_WRITE(st7701, 0xE6, 0x00, 0x00, 0x11, 0x11); 536 ST7701_WRITE(st7701, 0xE7, 0x44, 0x44); 537 ST7701_WRITE(st7701, 0xE8, 0x09, 0xE8, 0xD8, 0xA0, 0x0B, 0xEA, 0xD8, 538 0xA0, 0x0D, 0xEC, 0xD8, 0xA0, 0x0F, 0xEE, 0xD8, 0xA0); 539 ST7701_WRITE(st7701, 0xEB, 0x00, 0x00, 0xE4, 0xE4, 0x88, 0x00, 0x40); 540 ST7701_WRITE(st7701, 0xEC, 0x3C, 0x00); 541 ST7701_WRITE(st7701, 0xED, 0xAB, 0x89, 0x76, 0x54, 0x02, 0xFF, 0xFF, 542 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x45, 0x67, 0x98, 0xBA); 543 ST7701_WRITE(st7701, MIPI_DCS_SET_ADDRESS_MODE, 0); 544 } 545 546 static int st7701_prepare(struct drm_panel *panel) 547 { 548 struct st7701 *st7701 = panel_to_st7701(panel); 549 int ret; 550 551 gpiod_set_value(st7701->reset, 0); 552 553 ret = regulator_bulk_enable(ARRAY_SIZE(st7701->supplies), 554 st7701->supplies); 555 if (ret < 0) 556 return ret; 557 msleep(20); 558 559 gpiod_set_value(st7701->reset, 1); 560 msleep(150); 561 562 st7701_init_sequence(st7701); 563 564 if (st7701->desc->gip_sequence) 565 st7701->desc->gip_sequence(st7701); 566 567 /* Disable Command2 */ 568 st7701_switch_cmd_bkx(st7701, false, 0); 569 570 return 0; 571 } 572 573 static int st7701_enable(struct drm_panel *panel) 574 { 575 struct st7701 *st7701 = panel_to_st7701(panel); 576 577 ST7701_WRITE(st7701, MIPI_DCS_SET_DISPLAY_ON, 0x00); 578 579 return 0; 580 } 581 582 static int st7701_disable(struct drm_panel *panel) 583 { 584 struct st7701 *st7701 = panel_to_st7701(panel); 585 586 ST7701_WRITE(st7701, MIPI_DCS_SET_DISPLAY_OFF, 0x00); 587 588 return 0; 589 } 590 591 static int st7701_unprepare(struct drm_panel *panel) 592 { 593 struct st7701 *st7701 = panel_to_st7701(panel); 594 595 ST7701_WRITE(st7701, MIPI_DCS_ENTER_SLEEP_MODE, 0x00); 596 597 msleep(st7701->sleep_delay); 598 599 gpiod_set_value(st7701->reset, 0); 600 601 /** 602 * During the Resetting period, the display will be blanked 603 * (The display is entering blanking sequence, which maximum 604 * time is 120 ms, when Reset Starts in Sleep Out –mode. The 605 * display remains the blank state in Sleep In –mode.) and 606 * then return to Default condition for Hardware Reset. 607 * 608 * So we need wait sleep_delay time to make sure reset completed. 609 */ 610 msleep(st7701->sleep_delay); 611 612 regulator_bulk_disable(ARRAY_SIZE(st7701->supplies), st7701->supplies); 613 614 return 0; 615 } 616 617 static int st7701_get_modes(struct drm_panel *panel, 618 struct drm_connector *connector) 619 { 620 struct st7701 *st7701 = panel_to_st7701(panel); 621 const struct drm_display_mode *desc_mode = st7701->desc->mode; 622 struct drm_display_mode *mode; 623 624 mode = drm_mode_duplicate(connector->dev, desc_mode); 625 if (!mode) { 626 dev_err(panel->dev, "failed to add mode %ux%u@%u\n", 627 desc_mode->hdisplay, desc_mode->vdisplay, 628 drm_mode_vrefresh(desc_mode)); 629 return -ENOMEM; 630 } 631 632 drm_mode_set_name(mode); 633 drm_mode_probed_add(connector, mode); 634 635 connector->display_info.width_mm = desc_mode->width_mm; 636 connector->display_info.height_mm = desc_mode->height_mm; 637 638 /* 639 * TODO: Remove once all drm drivers call 640 * drm_connector_set_orientation_from_panel() 641 */ 642 drm_connector_set_panel_orientation(connector, st7701->orientation); 643 644 return 1; 645 } 646 647 static enum drm_panel_orientation st7701_get_orientation(struct drm_panel *panel) 648 { 649 struct st7701 *st7701 = panel_to_st7701(panel); 650 651 return st7701->orientation; 652 } 653 654 static const struct drm_panel_funcs st7701_funcs = { 655 .disable = st7701_disable, 656 .unprepare = st7701_unprepare, 657 .prepare = st7701_prepare, 658 .enable = st7701_enable, 659 .get_modes = st7701_get_modes, 660 .get_orientation = st7701_get_orientation, 661 }; 662 663 static const struct drm_display_mode ts8550b_mode = { 664 .clock = 27500, 665 666 .hdisplay = 480, 667 .hsync_start = 480 + 38, 668 .hsync_end = 480 + 38 + 12, 669 .htotal = 480 + 38 + 12 + 12, 670 671 .vdisplay = 854, 672 .vsync_start = 854 + 18, 673 .vsync_end = 854 + 18 + 8, 674 .vtotal = 854 + 18 + 8 + 4, 675 676 .width_mm = 69, 677 .height_mm = 139, 678 679 .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, 680 }; 681 682 static const struct st7701_panel_desc ts8550b_desc = { 683 .mode = &ts8550b_mode, 684 .lanes = 2, 685 .format = MIPI_DSI_FMT_RGB888, 686 .panel_sleep_delay = 80, /* panel need extra 80ms for sleep out cmd */ 687 688 .pv_gamma = { 689 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 690 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC0_MASK, 0), 691 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 692 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC4_MASK, 0xe), 693 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 694 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC8_MASK, 0x15), 695 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC16_MASK, 0xf), 696 697 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 698 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC24_MASK, 0x11), 699 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC52_MASK, 0x8), 700 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC80_MASK, 0x8), 701 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC108_MASK, 0x8), 702 703 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC147_MASK, 0x8), 704 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC175_MASK, 0x23), 705 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC203_MASK, 0x4), 706 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 707 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC231_MASK, 0x13), 708 709 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC239_MASK, 0x12), 710 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 711 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC247_MASK, 0x2b), 712 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 713 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC251_MASK, 0x34), 714 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 715 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC255_MASK, 0x1f) 716 }, 717 .nv_gamma = { 718 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 719 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC0_MASK, 0), 720 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 721 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC4_MASK, 0xe), 722 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0x2) | 723 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC8_MASK, 0x15), 724 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC16_MASK, 0xf), 725 726 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 727 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC24_MASK, 0x13), 728 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC52_MASK, 0x7), 729 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC80_MASK, 0x9), 730 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC108_MASK, 0x8), 731 732 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC147_MASK, 0x8), 733 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC175_MASK, 0x22), 734 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC203_MASK, 0x4), 735 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 736 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC231_MASK, 0x10), 737 738 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC239_MASK, 0xe), 739 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 740 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC247_MASK, 0x2c), 741 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 742 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC251_MASK, 0x34), 743 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 744 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC255_MASK, 0x1f) 745 }, 746 .nlinv = 7, 747 .vop_uv = 4400000, 748 .vcom_uv = 337500, 749 .vgh_mv = 15000, 750 .vgl_mv = -9510, 751 .avdd_mv = 6600, 752 .avcl_mv = -4400, 753 .gamma_op_bias = OP_BIAS_MAX, 754 .input_op_bias = OP_BIAS_MIN, 755 .output_op_bias = OP_BIAS_MIN, 756 .t2d_ns = 1600, 757 .t3d_ns = 10400, 758 .eot_en = true, 759 .gip_sequence = ts8550b_gip_sequence, 760 }; 761 762 static const struct drm_display_mode dmt028vghmcmi_1a_mode = { 763 .clock = 22325, 764 765 .hdisplay = 480, 766 .hsync_start = 480 + 40, 767 .hsync_end = 480 + 40 + 4, 768 .htotal = 480 + 40 + 4 + 20, 769 770 .vdisplay = 640, 771 .vsync_start = 640 + 2, 772 .vsync_end = 640 + 2 + 40, 773 .vtotal = 640 + 2 + 40 + 16, 774 775 .width_mm = 56, 776 .height_mm = 78, 777 778 .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, 779 780 .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, 781 }; 782 783 static const struct st7701_panel_desc dmt028vghmcmi_1a_desc = { 784 .mode = &dmt028vghmcmi_1a_mode, 785 .lanes = 2, 786 .format = MIPI_DSI_FMT_RGB888, 787 .panel_sleep_delay = 5, /* panel need extra 5ms for sleep out cmd */ 788 789 .pv_gamma = { 790 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 791 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC0_MASK, 0), 792 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 793 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC4_MASK, 0x10), 794 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 795 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC8_MASK, 0x17), 796 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC16_MASK, 0xd), 797 798 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 799 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC24_MASK, 0x11), 800 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC52_MASK, 0x6), 801 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC80_MASK, 0x5), 802 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC108_MASK, 0x8), 803 804 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC147_MASK, 0x7), 805 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC175_MASK, 0x1f), 806 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC203_MASK, 0x4), 807 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 808 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC231_MASK, 0x11), 809 810 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC239_MASK, 0xe), 811 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 812 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC247_MASK, 0x29), 813 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 814 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC251_MASK, 0x30), 815 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 816 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC255_MASK, 0x1f) 817 }, 818 .nv_gamma = { 819 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 820 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC0_MASK, 0), 821 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 822 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC4_MASK, 0xd), 823 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 824 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC8_MASK, 0x14), 825 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC16_MASK, 0xe), 826 827 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 828 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC24_MASK, 0x11), 829 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC52_MASK, 0x6), 830 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC80_MASK, 0x4), 831 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC108_MASK, 0x8), 832 833 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC147_MASK, 0x8), 834 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC175_MASK, 0x20), 835 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC203_MASK, 0x5), 836 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 837 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC231_MASK, 0x13), 838 839 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC239_MASK, 0x13), 840 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 841 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC247_MASK, 0x26), 842 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 843 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC251_MASK, 0x30), 844 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 845 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC255_MASK, 0x1f) 846 }, 847 .nlinv = 1, 848 .vop_uv = 4800000, 849 .vcom_uv = 1650000, 850 .vgh_mv = 15000, 851 .vgl_mv = -10170, 852 .avdd_mv = 6600, 853 .avcl_mv = -4400, 854 .gamma_op_bias = OP_BIAS_MIDDLE, 855 .input_op_bias = OP_BIAS_MIN, 856 .output_op_bias = OP_BIAS_MIN, 857 .t2d_ns = 1600, 858 .t3d_ns = 10400, 859 .eot_en = true, 860 .gip_sequence = dmt028vghmcmi_1a_gip_sequence, 861 }; 862 863 static const struct drm_display_mode kd50t048a_mode = { 864 .clock = 27500, 865 866 .hdisplay = 480, 867 .hsync_start = 480 + 2, 868 .hsync_end = 480 + 2 + 10, 869 .htotal = 480 + 2 + 10 + 2, 870 871 .vdisplay = 854, 872 .vsync_start = 854 + 2, 873 .vsync_end = 854 + 2 + 2, 874 .vtotal = 854 + 2 + 2 + 17, 875 876 .width_mm = 69, 877 .height_mm = 139, 878 879 .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, 880 }; 881 882 static const struct st7701_panel_desc kd50t048a_desc = { 883 .mode = &kd50t048a_mode, 884 .lanes = 2, 885 .format = MIPI_DSI_FMT_RGB888, 886 .panel_sleep_delay = 0, 887 888 .pv_gamma = { 889 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 890 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC0_MASK, 0), 891 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 892 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC4_MASK, 0xd), 893 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 894 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC8_MASK, 0x14), 895 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC16_MASK, 0xd), 896 897 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 898 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC24_MASK, 0x10), 899 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC52_MASK, 0x5), 900 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC80_MASK, 0x2), 901 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC108_MASK, 0x8), 902 903 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC147_MASK, 0x8), 904 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC175_MASK, 0x1e), 905 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC203_MASK, 0x5), 906 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 907 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC231_MASK, 0x13), 908 909 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC239_MASK, 0x11), 910 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 2) | 911 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC247_MASK, 0x23), 912 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 913 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC251_MASK, 0x29), 914 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 915 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC255_MASK, 0x18) 916 }, 917 .nv_gamma = { 918 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 919 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC0_MASK, 0), 920 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 921 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC4_MASK, 0xc), 922 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 923 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC8_MASK, 0x14), 924 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC16_MASK, 0xc), 925 926 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 927 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC24_MASK, 0x10), 928 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC52_MASK, 0x5), 929 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC80_MASK, 0x3), 930 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC108_MASK, 0x8), 931 932 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC147_MASK, 0x7), 933 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC175_MASK, 0x20), 934 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC203_MASK, 0x5), 935 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 936 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC231_MASK, 0x13), 937 938 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC239_MASK, 0x11), 939 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 2) | 940 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC247_MASK, 0x24), 941 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 942 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC251_MASK, 0x29), 943 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 944 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC255_MASK, 0x18) 945 }, 946 .nlinv = 1, 947 .vop_uv = 4887500, 948 .vcom_uv = 937500, 949 .vgh_mv = 15000, 950 .vgl_mv = -9510, 951 .avdd_mv = 6600, 952 .avcl_mv = -4400, 953 .gamma_op_bias = OP_BIAS_MIDDLE, 954 .input_op_bias = OP_BIAS_MIN, 955 .output_op_bias = OP_BIAS_MIN, 956 .t2d_ns = 1600, 957 .t3d_ns = 10400, 958 .eot_en = true, 959 .gip_sequence = kd50t048a_gip_sequence, 960 }; 961 962 static const struct drm_display_mode rg_arc_mode = { 963 .clock = 25600, 964 965 .hdisplay = 480, 966 .hsync_start = 480 + 60, 967 .hsync_end = 480 + 60 + 42, 968 .htotal = 480 + 60 + 42 + 60, 969 970 .vdisplay = 640, 971 .vsync_start = 640 + 10, 972 .vsync_end = 640 + 10 + 4, 973 .vtotal = 640 + 10 + 4 + 16, 974 975 .width_mm = 63, 976 .height_mm = 84, 977 978 .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, 979 }; 980 981 static const struct st7701_panel_desc rg_arc_desc = { 982 .mode = &rg_arc_mode, 983 .lanes = 2, 984 .format = MIPI_DSI_FMT_RGB888, 985 .panel_sleep_delay = 80, 986 987 .pv_gamma = { 988 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0x01) | 989 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC0_MASK, 0), 990 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 991 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC4_MASK, 0x16), 992 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 993 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC8_MASK, 0x1d), 994 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC16_MASK, 0x0e), 995 996 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 997 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC24_MASK, 0x12), 998 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC52_MASK, 0x06), 999 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC80_MASK, 0x0c), 1000 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC108_MASK, 0x0a), 1001 1002 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC147_MASK, 0x09), 1003 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC175_MASK, 0x25), 1004 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC203_MASK, 0x00), 1005 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1006 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC231_MASK, 0x03), 1007 1008 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC239_MASK, 0x00), 1009 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1010 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC247_MASK, 0x3f), 1011 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1012 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC251_MASK, 0x3f), 1013 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1014 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC255_MASK, 0x1c) 1015 }, 1016 .nv_gamma = { 1017 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0x01) | 1018 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC0_MASK, 0), 1019 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1020 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC4_MASK, 0x16), 1021 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1022 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC8_MASK, 0x1e), 1023 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC16_MASK, 0x0e), 1024 1025 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1026 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC24_MASK, 0x11), 1027 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC52_MASK, 0x06), 1028 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC80_MASK, 0x0c), 1029 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC108_MASK, 0x08), 1030 1031 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC147_MASK, 0x09), 1032 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC175_MASK, 0x26), 1033 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC203_MASK, 0x00), 1034 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1035 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC231_MASK, 0x15), 1036 1037 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC239_MASK, 0x00), 1038 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1039 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC247_MASK, 0x3f), 1040 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1041 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC251_MASK, 0x3f), 1042 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1043 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC255_MASK, 0x1c) 1044 }, 1045 .nlinv = 0, 1046 .vop_uv = 4500000, 1047 .vcom_uv = 762500, 1048 .vgh_mv = 15000, 1049 .vgl_mv = -9510, 1050 .avdd_mv = 6600, 1051 .avcl_mv = -4400, 1052 .gamma_op_bias = OP_BIAS_MIDDLE, 1053 .input_op_bias = OP_BIAS_MIN, 1054 .output_op_bias = OP_BIAS_MIN, 1055 .t2d_ns = 1600, 1056 .t3d_ns = 10400, 1057 .eot_en = true, 1058 .gip_sequence = rg_arc_gip_sequence, 1059 }; 1060 1061 static const struct drm_display_mode rg28xx_mode = { 1062 .clock = 22325, 1063 1064 .hdisplay = 480, 1065 .hsync_start = 480 + 40, 1066 .hsync_end = 480 + 40 + 4, 1067 .htotal = 480 + 40 + 4 + 20, 1068 1069 .vdisplay = 640, 1070 .vsync_start = 640 + 2, 1071 .vsync_end = 640 + 2 + 40, 1072 .vtotal = 640 + 2 + 40 + 16, 1073 1074 .width_mm = 44, 1075 .height_mm = 58, 1076 1077 .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, 1078 1079 .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, 1080 }; 1081 1082 static const struct st7701_panel_desc rg28xx_desc = { 1083 .mode = &rg28xx_mode, 1084 1085 .panel_sleep_delay = 80, 1086 1087 .pv_gamma = { 1088 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1089 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC0_MASK, 0), 1090 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1091 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC4_MASK, 0x10), 1092 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1093 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC8_MASK, 0x17), 1094 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC16_MASK, 0xd), 1095 1096 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1097 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC24_MASK, 0x11), 1098 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC52_MASK, 0x6), 1099 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC80_MASK, 0x5), 1100 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC108_MASK, 0x8), 1101 1102 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC147_MASK, 0x7), 1103 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC175_MASK, 0x1f), 1104 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC203_MASK, 0x4), 1105 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1106 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC231_MASK, 0x11), 1107 1108 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC239_MASK, 0xe), 1109 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1110 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC247_MASK, 0x29), 1111 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1112 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC251_MASK, 0x30), 1113 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1114 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC255_MASK, 0x1f) 1115 }, 1116 .nv_gamma = { 1117 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1118 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC0_MASK, 0), 1119 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1120 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC4_MASK, 0xd), 1121 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1122 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC8_MASK, 0x14), 1123 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC16_MASK, 0xe), 1124 1125 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1126 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC24_MASK, 0x11), 1127 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC52_MASK, 0x6), 1128 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC80_MASK, 0x4), 1129 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC108_MASK, 0x8), 1130 1131 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC147_MASK, 0x8), 1132 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC175_MASK, 0x20), 1133 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC203_MASK, 0x5), 1134 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1135 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC231_MASK, 0x13), 1136 1137 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC239_MASK, 0x13), 1138 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1139 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC247_MASK, 0x26), 1140 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1141 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC251_MASK, 0x30), 1142 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1143 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC255_MASK, 0x1f) 1144 }, 1145 .nlinv = 7, 1146 .vop_uv = 4800000, 1147 .vcom_uv = 1512500, 1148 .vgh_mv = 15000, 1149 .vgl_mv = -11730, 1150 .avdd_mv = 6600, 1151 .avcl_mv = -4400, 1152 .gamma_op_bias = OP_BIAS_MIDDLE, 1153 .input_op_bias = OP_BIAS_MIN, 1154 .output_op_bias = OP_BIAS_MIN, 1155 .t2d_ns = 1600, 1156 .t3d_ns = 10400, 1157 .eot_en = true, 1158 .gip_sequence = rg28xx_gip_sequence, 1159 }; 1160 1161 static const struct drm_display_mode wf40eswaa6mnn0_mode = { 1162 .clock = 18306, 1163 1164 .hdisplay = 480, 1165 .hsync_start = 480 + 2, 1166 .hsync_end = 480 + 2 + 45, 1167 .htotal = 480 + 2 + 45 + 13, 1168 1169 .vdisplay = 480, 1170 .vsync_start = 480 + 2, 1171 .vsync_end = 480 + 2 + 70, 1172 .vtotal = 480 + 2 + 70 + 13, 1173 1174 .width_mm = 72, 1175 .height_mm = 70, 1176 1177 .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, 1178 1179 .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, 1180 }; 1181 1182 static const struct st7701_panel_desc wf40eswaa6mnn0_desc = { 1183 .mode = &wf40eswaa6mnn0_mode, 1184 .lanes = 2, 1185 .format = MIPI_DSI_FMT_RGB888, 1186 .panel_sleep_delay = 0, 1187 1188 .pv_gamma = { 1189 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1190 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC0_MASK, 0x1), 1191 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1192 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC4_MASK, 0x08), 1193 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1194 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC8_MASK, 0x10), 1195 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC16_MASK, 0x0c), 1196 1197 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1198 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC24_MASK, 0x10), 1199 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC52_MASK, 0x08), 1200 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC80_MASK, 0x10), 1201 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC108_MASK, 0x0c), 1202 1203 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC147_MASK, 0x08), 1204 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC175_MASK, 0x22), 1205 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC203_MASK, 0x04), 1206 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1207 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC231_MASK, 0x14), 1208 1209 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC239_MASK, 0x12), 1210 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1211 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC247_MASK, 0xb3), 1212 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1213 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC251_MASK, 0x3a), 1214 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1215 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC255_MASK, 0x1f) 1216 }, 1217 .nv_gamma = { 1218 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1219 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC4_MASK, 0x13), 1220 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1221 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC4_MASK, 0x19), 1222 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1223 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC8_MASK, 0x1f), 1224 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC16_MASK, 0x0f), 1225 1226 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1227 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC24_MASK, 0x14), 1228 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC52_MASK, 0x07), 1229 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC80_MASK, 0x07), 1230 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC108_MASK, 0x08), 1231 1232 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC147_MASK, 0x07), 1233 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC175_MASK, 0x22), 1234 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC203_MASK, 0x02), 1235 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1236 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC231_MASK, 0xf), 1237 1238 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC239_MASK, 0x0f), 1239 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1240 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC247_MASK, 0xa3), 1241 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1242 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC251_MASK, 0x29), 1243 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1244 CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC255_MASK, 0x0d) 1245 }, 1246 .nlinv = 3, 1247 .vop_uv = 4737500, 1248 .vcom_uv = 662500, 1249 .vgh_mv = 15000, 1250 .vgl_mv = -10170, 1251 .avdd_mv = 6600, 1252 .avcl_mv = -4600, 1253 .gamma_op_bias = OP_BIAS_MIDDLE, 1254 .input_op_bias = OP_BIAS_MIDDLE, 1255 .output_op_bias = OP_BIAS_MIN, 1256 .t2d_ns = 1600, 1257 .t3d_ns = 10400, 1258 .eot_en = true, 1259 .gip_sequence = wf40eswaa6mnn0_gip_sequence, 1260 }; 1261 1262 static void st7701_cleanup(void *data) 1263 { 1264 struct st7701 *st7701 = (struct st7701 *)data; 1265 1266 drm_panel_remove(&st7701->panel); 1267 drm_panel_disable(&st7701->panel); 1268 drm_panel_unprepare(&st7701->panel); 1269 } 1270 1271 static int st7701_probe(struct device *dev, int connector_type) 1272 { 1273 const struct st7701_panel_desc *desc; 1274 struct st7701 *st7701; 1275 int ret; 1276 1277 st7701 = devm_drm_panel_alloc(dev, struct st7701, panel, &st7701_funcs, 1278 connector_type); 1279 if (IS_ERR(st7701)) 1280 return PTR_ERR(st7701); 1281 1282 desc = of_device_get_match_data(dev); 1283 if (!desc) 1284 return -ENODEV; 1285 1286 st7701->supplies[0].supply = "VCC"; 1287 st7701->supplies[1].supply = "IOVCC"; 1288 1289 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(st7701->supplies), 1290 st7701->supplies); 1291 if (ret < 0) 1292 return ret; 1293 1294 st7701->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); 1295 if (IS_ERR(st7701->reset)) { 1296 dev_err(dev, "Couldn't get our reset GPIO\n"); 1297 return PTR_ERR(st7701->reset); 1298 } 1299 1300 ret = drm_of_get_panel_orientation(dev->of_node, &st7701->orientation); 1301 if (ret < 0) 1302 return dev_err_probe(dev, ret, "Failed to get orientation\n"); 1303 1304 st7701->panel.prepare_prev_first = true; 1305 1306 /** 1307 * Once sleep out has been issued, ST7701 IC required to wait 120ms 1308 * before initiating new commands. 1309 * 1310 * On top of that some panels might need an extra delay to wait, so 1311 * add panel specific delay for those cases. As now this panel specific 1312 * delay information is referenced from those panel BSP driver, example 1313 * ts8550b and there is no valid documentation for that. 1314 */ 1315 st7701->sleep_delay = 120 + desc->panel_sleep_delay; 1316 1317 ret = drm_panel_of_backlight(&st7701->panel); 1318 if (ret) 1319 return ret; 1320 1321 drm_panel_add(&st7701->panel); 1322 1323 dev_set_drvdata(dev, st7701); 1324 st7701->desc = desc; 1325 1326 return devm_add_action_or_reset(dev, st7701_cleanup, st7701); 1327 } 1328 1329 static int st7701_dsi_probe(struct mipi_dsi_device *dsi) 1330 { 1331 struct st7701 *st7701; 1332 int err; 1333 1334 err = st7701_probe(&dsi->dev, DRM_MODE_CONNECTOR_DSI); 1335 if (err) 1336 return err; 1337 1338 st7701 = dev_get_drvdata(&dsi->dev); 1339 st7701->dsi = dsi; 1340 st7701->write_command = st7701_dsi_write; 1341 1342 if (!st7701->desc->lanes) 1343 return dev_err_probe(&dsi->dev, -EINVAL, "This panel is not for MIPI DSI\n"); 1344 1345 dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | 1346 MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS; 1347 dsi->format = st7701->desc->format; 1348 dsi->lanes = st7701->desc->lanes; 1349 1350 err = mipi_dsi_attach(dsi); 1351 if (err) 1352 return dev_err_probe(&dsi->dev, err, "Failed to init MIPI DSI\n"); 1353 1354 return 0; 1355 } 1356 1357 static int st7701_spi_probe(struct spi_device *spi) 1358 { 1359 struct st7701 *st7701; 1360 struct gpio_desc *dc; 1361 int err; 1362 1363 err = st7701_probe(&spi->dev, DRM_MODE_CONNECTOR_DPI); 1364 if (err) 1365 return err; 1366 1367 st7701 = dev_get_drvdata(&spi->dev); 1368 st7701->write_command = st7701_dbi_write; 1369 1370 dc = devm_gpiod_get_optional(&spi->dev, "dc", GPIOD_OUT_LOW); 1371 if (IS_ERR(dc)) 1372 return dev_err_probe(&spi->dev, PTR_ERR(dc), "Failed to get GPIO for D/CX\n"); 1373 1374 err = mipi_dbi_spi_init(spi, &st7701->dbi, dc); 1375 if (err) 1376 return dev_err_probe(&spi->dev, err, "Failed to init MIPI DBI\n"); 1377 st7701->dbi.read_commands = NULL; 1378 1379 return 0; 1380 } 1381 1382 static void st7701_dsi_remove(struct mipi_dsi_device *dsi) 1383 { 1384 mipi_dsi_detach(dsi); 1385 } 1386 1387 static const struct of_device_id st7701_dsi_of_match[] = { 1388 { .compatible = "anbernic,rg-arc-panel", .data = &rg_arc_desc }, 1389 { .compatible = "densitron,dmt028vghmcmi-1a", .data = &dmt028vghmcmi_1a_desc }, 1390 { .compatible = "elida,kd50t048a", .data = &kd50t048a_desc }, 1391 { .compatible = "techstar,ts8550b", .data = &ts8550b_desc }, 1392 { .compatible = "winstar,wf40eswaa6mnn0", .data = &wf40eswaa6mnn0_desc }, 1393 { } 1394 }; 1395 MODULE_DEVICE_TABLE(of, st7701_dsi_of_match); 1396 1397 static const struct of_device_id st7701_spi_of_match[] = { 1398 { .compatible = "anbernic,rg28xx-panel", .data = &rg28xx_desc }, 1399 { /* sentinel */ } 1400 }; 1401 MODULE_DEVICE_TABLE(of, st7701_spi_of_match); 1402 1403 static const struct spi_device_id st7701_spi_ids[] = { 1404 { "rg28xx-panel" }, 1405 { /* sentinel */ } 1406 }; 1407 MODULE_DEVICE_TABLE(spi, st7701_spi_ids); 1408 1409 static struct mipi_dsi_driver st7701_dsi_driver = { 1410 .probe = st7701_dsi_probe, 1411 .remove = st7701_dsi_remove, 1412 .driver = { 1413 .name = "st7701", 1414 .of_match_table = st7701_dsi_of_match, 1415 }, 1416 }; 1417 1418 static struct spi_driver st7701_spi_driver = { 1419 .probe = st7701_spi_probe, 1420 .id_table = st7701_spi_ids, 1421 .driver = { 1422 .name = "st7701", 1423 .of_match_table = st7701_spi_of_match, 1424 }, 1425 }; 1426 1427 static int __init st7701_driver_init(void) 1428 { 1429 int err; 1430 1431 if (IS_ENABLED(CONFIG_SPI)) { 1432 err = spi_register_driver(&st7701_spi_driver); 1433 if (err) 1434 return err; 1435 } 1436 1437 if (IS_ENABLED(CONFIG_DRM_MIPI_DSI)) { 1438 err = mipi_dsi_driver_register(&st7701_dsi_driver); 1439 if (err) { 1440 if (IS_ENABLED(CONFIG_SPI)) 1441 spi_unregister_driver(&st7701_spi_driver); 1442 return err; 1443 } 1444 } 1445 1446 return 0; 1447 } 1448 module_init(st7701_driver_init); 1449 1450 static void __exit st7701_driver_exit(void) 1451 { 1452 if (IS_ENABLED(CONFIG_DRM_MIPI_DSI)) 1453 mipi_dsi_driver_unregister(&st7701_dsi_driver); 1454 1455 if (IS_ENABLED(CONFIG_SPI)) 1456 spi_unregister_driver(&st7701_spi_driver); 1457 } 1458 module_exit(st7701_driver_exit); 1459 1460 MODULE_AUTHOR("Jagan Teki <jagan@amarulasolutions.com>"); 1461 MODULE_AUTHOR("Hironori KIKUCHI <kikuchan98@gmail.com>"); 1462 MODULE_DESCRIPTION("Sitronix ST7701 LCD Panel Driver"); 1463 MODULE_LICENSE("GPL"); 1464