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