1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Himax HX8279 DriverIC panels driver 4 * 5 * Copyright (c) 2025 Collabora Ltd. 6 * AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> 7 */ 8 9 #include <linux/bitfield.h> 10 #include <linux/delay.h> 11 #include <linux/gpio/consumer.h> 12 #include <linux/module.h> 13 #include <linux/of.h> 14 #include <linux/of_graph.h> 15 #include <linux/regulator/consumer.h> 16 17 #include <drm/drm_connector.h> 18 #include <drm/drm_crtc.h> 19 #include <drm/drm_mipi_dsi.h> 20 #include <drm/drm_modes.h> 21 #include <drm/drm_panel.h> 22 23 /* Page selection */ 24 #define HX8279_REG_PAGE 0xb0 25 #define HX8279_PAGE_SEL GENMASK(3, 0) 26 27 /* Page 0 - Driver/Module Configuration */ 28 #define HX8279_P0_VGHS 0xbf 29 #define HX8279_P0_VGLS 0xc0 30 #define HX8279_P0_VGPHS 0xc2 31 #define HX8279_P0_VGNHS 0xc4 32 #define HX8279_P0_VG_SEL GENMASK(4, 0) 33 #define HX8279_VGH_MIN_MV 8700 34 #define HX8279_VGH_STEP_MV 300 35 #define HX8279_VGL_MIN_MV 6700 36 #define HX8279_VGL_STEP_MV 300 37 #define HX8279_VGPNH_MIN_MV 4000 38 #define HX8279_VGPNX_STEP_MV 50 39 #define HX8279_VGH_VOLT_SEL(x) ((x - HX8279_VGH_MIN_MV) / HX8279_VGH_STEP_MV) 40 #define HX8279_VGL_VOLT_SEL(x) ((x - HX8279_VGL_MIN_MV) / HX8279_VGL_STEP_MV) 41 #define HX8279_VGPN_VOLT_SEL(x) ((x - HX8279_VGPNH_MIN_MV) / HX8279_VGPNX_STEP_MV) 42 43 /* Page 1 - Gate driver On Array (GOA) Mux */ 44 #define HX8279_P1_REG_GOA_L 0xc0 45 #define HX8279_P1_REG_GOUTL(x) (HX8279_P1_REG_GOA_L + (x)) 46 #define HX8279_P1_REG_GOA_R 0xd4 47 #define HX8279_P1_REG_GOUTR(x) (HX8279_P1_REG_GOA_R + (x)) 48 #define HX8279_GOUT_STB GENMASK(7, 6) 49 #define HX8279_GOUT_SEL GENMASK(5, 0) 50 51 /* Page 2 - Analog Gamma Configuration */ 52 #define HX8279_P2_REG_ANALOG_GAMMA 0xc0 53 #define HX8279_P2_REG_GAMMA_T_PVP(x) (HX8279_P2_REG_ANALOG_GAMMA + (x)) /* 0..16 */ 54 #define HX8279_P2_REG_GAMMA_T_PVN(x) (HX8279_P2_REG_GAMMA_T_PVP(17) + (x)) /* 0..16 */ 55 56 /* Page 3 - Gate driver On Array (GOA) Configuration */ 57 #define HX8279_P3_REG_UNKNOWN_BA 0xba 58 #define HX8279_P3_REG_GOA_CKV_FALL_PREC 0xbc 59 #define HX8279_P3_REG_GOA_TIMING_ODD 0xc2 60 #define HX8279_P3_REG_GOA_TO(x) (HX8279_P3_REG_GOA_TIMING_ODD + x) /* GOA_T0..5 */ 61 #define HX8279_P3_REG_GOA_STVL 0xc8 62 #define HX8279_P3_GOA_STV_LEAD GENMASK(4, 0) 63 #define HX8279_P3_REG_GOA_CKVL 0xc9 64 #define HX8279_P3_GOA_CKV_LEAD GENMASK(4, 0) 65 #define HX8279_P3_REG_GOA_CKVD 0xca 66 #define HX8279_P3_GOA_CKV_NONOVERLAP BIT(7) 67 #define HX8279_P3_GOA_CKV_RESERVED BIT(6) 68 #define HX8279_P3_GOA_CKV_DUMMY GENMASK(5, 0) 69 #define HX8279_P3_REG_GOA_CKV_RISE_PREC 0xcb 70 #define HX8279_P3_REG_GOA_CLR1_W_ADJ 0xd2 71 #define HX8279_P3_REG_GOA_CLR234_W_ADJ 0xd3 72 #define HX8279_P3_REG_GOA_CLR1_CFG 0xd4 73 #define HX8279_P3_REG_GOA_CLR_CFG(x) (HX8279_P3_REG_GOA_CLR1_CFG + (x)) /* CLR1..4 */ 74 #define HX8279_P3_GOA_CLR_CFG_POLARITY BIT(7) 75 #define HX8279_P3_GOA_CLR_CFG_STARTPOS GENMASK(6, 0) 76 #define HX8279_P3_REG_GOA_TIMING_EVEN 0xdd 77 #define HX8279_P3_REG_GOA_TE(x) (HX8279_P3_REG_GOA_TIMING_EVEN + x) 78 #define HX8279_P3_REG_UNKNOWN_E4 0xe4 79 #define HX8279_P3_REG_UNKNOWN_E5 0xe5 80 81 /* Page 5 - MIPI */ 82 #define HX8279_P5_REG_TIMING 0xb3 83 #define HX8279_P5_TIMING_THS_SETTLE GENMASK(7, 5) 84 #define HX8279_P5_TIMING_LHS_SETTLE BIT(4) 85 #define HX8279_P5_TIMING_TLPX GENMASK(3, 0) 86 #define HX8279_P5_REG_UNKNOWN_B8 0xb8 87 #define HX8279_P5_REG_UNKNOWN_BC 0xbc 88 #define HX8279_P5_REG_UNKNOWN_D6 0xd6 89 90 /* Page 6 - Engineer */ 91 #define HX8279_P6_REG_ENGINEER_PWD 0xb8 92 #define HX8279_P6_REG_INHOUSE_FUNC 0xc0 93 #define HX8279_P6_ENG_UNLOCK_WORD 0xa5 94 #define HX8279_P6_REG_GAMMA_CHOPPER 0xbc 95 #define HX8279_P6_GAMMA_POCGM_CTL GENMASK(6, 4) 96 #define HX8279_P6_GAMMA_POGCMD_CTL GENMASK(2, 0) 97 #define HX8279_P6_REG_VOLT_ADJ 0xc7 98 /* For VCCIFS and VCCS - 0: 1450, 1: 1500, 2: 1550, 3: 1600 uV */ 99 #define HX8279_P6_VOLT_ADJ_VCCIFS GENMASK(3, 2) 100 #define HX8279_P6_VOLT_ADJ_VCCS GENMASK(1, 0) 101 #define HX8279_P6_REG_DLY_TIME_ADJ 0xd5 102 103 /* Page 7...12 - Digital Gamma Adjustment */ 104 #define HX8279_PG_DIGITAL_GAMMA 0xb1 105 #define HX8279_DGAMMA_DGMA1_HI GENMASK(7, 6) 106 #define HX8279_DGAMMA_DGMA2_HI GENMASK(5, 4) 107 #define HX8279_DGAMMA_DGMA3_HI GENMASK(3, 2) 108 #define HX8279_DGAMMA_DGMA4_HI GENMASK(1, 0) 109 #define HX8279_PG_DGAMMA_NUM_LO_BYTES 24 110 #define HX8279_PG_DGAMMA_NUM_HI_BYTES 6 111 112 struct hx8279 { 113 struct drm_panel panel; 114 struct mipi_dsi_device *dsi[2]; 115 struct regulator_bulk_data vregs[2]; 116 struct gpio_desc *enable_gpio; 117 struct gpio_desc *reset_gpio; 118 const struct hx8279_panel_desc *desc; 119 u8 last_page; 120 bool skip_voltage_config; 121 bool skip_goa_config; 122 bool skip_goa_timing; 123 bool skip_goa_even_timing; 124 bool skip_mipi_timing; 125 }; 126 127 struct hx8279_panel_mode { 128 const struct drm_display_mode mode; 129 u8 bpc; 130 bool is_video_mode; 131 }; 132 133 /** 134 * struct hx8279_goa_mux - Gate driver On Array Muxer 135 * @gout_l: Mux GOA signal to GOUT Left pin 136 * @gout_r: Mux GOA signal to GOUT Right pin 137 */ 138 struct hx8279_goa_mux { 139 u8 gout_l[20]; 140 u8 gout_r[20]; 141 }; 142 143 /** 144 * struct hx8279_analog_gamma - Analog Gamma Adjustment 145 * @pos: Positive gamma op's input voltage, adjusted by VGP(H/L) 146 * @neg: Negative gamma op's input voltage, adjusted by VGN(H/L) 147 * 148 * Analog Gamma correction is performed with 17+17 reference voltages, 149 * changed with resistor streams, and defined with 17 register values 150 * for positive and 17 for negative. 151 * 152 * Each register holds resistance values, in 8.5ohms per unit, for the 153 * following gamma levels: 154 * 0, 8, 16, 28, 40, 56, 80, 128, 176, 200, 216, 228, 240, 248, 252, 255. 155 */ 156 struct hx8279_analog_gamma { 157 u8 pos[17]; 158 u8 neg[17]; 159 }; 160 161 /** 162 * struct hx8279_digital_gamma - Digital Gamma Adjustment 163 * @r: Adjustment for red component 164 * @g: Adjustment for green component 165 * @b: Adjustment for blue component 166 * 167 * The layout of this structure follows the register layout to simplify 168 * both the handling and the declaration of those values in the driver. 169 * Gamma correction is internally done with a 24 segment piecewise 170 * linear interpolation; those segments are defined with 24 ten bits 171 * values of which: 172 * - The LOW eight bits for the first 24 registers start at the first 173 * register (at 0xb1) of the Digital Gamma Adjustment page; 174 * - The HIGH two bits for each of the 24 registers are contained 175 * in the last six registers; 176 * - The last six registers contain four groups of two-bits HI values 177 * for each of the first 24 registers, but in an inverted fashion, 178 * this means that the first two bits relate to the last register 179 * of a set of four. 180 * 181 * The 24 segments refer to the following gamma levels: 182 * 0, 1, 3, 7, 11, 15, 23, 31, 47, 63, 95, 127, 128, 160, 183 * 192, 208, 224, 232, 240, 244, 248, 252, 254, 255 184 */ 185 struct hx8279_digital_gamma { 186 u8 r[HX8279_PG_DGAMMA_NUM_LO_BYTES + HX8279_PG_DGAMMA_NUM_HI_BYTES]; 187 u8 g[HX8279_PG_DGAMMA_NUM_LO_BYTES + HX8279_PG_DGAMMA_NUM_HI_BYTES]; 188 u8 b[HX8279_PG_DGAMMA_NUM_LO_BYTES + HX8279_PG_DGAMMA_NUM_HI_BYTES]; 189 }; 190 191 struct hx8279_panel_desc { 192 const struct mipi_dsi_device_info dsi_info; 193 const struct hx8279_panel_mode *mode_data; 194 u8 num_lanes; 195 u8 num_modes; 196 197 /* Page 0 */ 198 unsigned int vgh_mv; 199 unsigned int vgl_mv; 200 unsigned int vgph_mv; 201 unsigned int vgnh_mv; 202 203 /* Page 1 */ 204 const struct hx8279_goa_mux *gmux; 205 206 /* Page 2 */ 207 const struct hx8279_analog_gamma *agamma; 208 209 /* Page 3 */ 210 u8 goa_unk_ba; 211 u8 goa_odd_timing[6]; 212 u8 goa_even_timing[6]; 213 u8 goa_stv_lead_time_ck; 214 u8 goa_ckv_lead_time_ck; 215 u8 goa_ckv_dummy_vblank_num; 216 u8 goa_ckv_rise_precharge; 217 u8 goa_ckv_fall_precharge; 218 bool goa_ckv_non_overlap_ctl; 219 u8 goa_clr1_width_adj; 220 u8 goa_clr234_width_adj; 221 s8 goa_clr_polarity[4]; 222 int goa_clr_start_pos[4]; 223 u8 goa_unk_e4; 224 u8 goa_unk_e5; 225 226 /* Page 5 */ 227 u8 bta_tlpx; 228 bool lhs_settle_time_by_osc25; 229 u8 ths_settle_time; 230 u8 timing_unk_b8; 231 u8 timing_unk_bc; 232 u8 timing_unk_d6; 233 234 /* Page 6 */ 235 u8 gamma_ctl; 236 u8 volt_adj; 237 u8 src_delay_time_adj_ck; 238 239 /* Page 7..12 */ 240 const struct hx8279_digital_gamma *dgamma; 241 }; 242 243 static inline struct hx8279 *to_hx8279(struct drm_panel *panel) 244 { 245 return container_of(panel, struct hx8279, panel); 246 } 247 248 static void hx8279_set_page(struct hx8279 *hx, 249 struct mipi_dsi_multi_context *dsi_ctx, u8 page) 250 { 251 const u8 cmd_set_page[] = { HX8279_REG_PAGE, page }; 252 253 if (hx->last_page == page) 254 return; 255 256 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_page, ARRAY_SIZE(cmd_set_page)); 257 if (!dsi_ctx->accum_err) 258 hx->last_page = page; 259 } 260 261 static void hx8279_set_module_config(struct hx8279 *hx, 262 struct mipi_dsi_multi_context *dsi_ctx) 263 { 264 const struct hx8279_panel_desc *desc = hx->desc; 265 u8 cmd_set_voltage[2]; 266 267 if (hx->skip_voltage_config) 268 return; 269 270 /* Page 0 - Driver/Module Configuration */ 271 hx8279_set_page(hx, dsi_ctx, 0); 272 273 if (desc->vgh_mv) { 274 cmd_set_voltage[0] = HX8279_P0_VGHS; 275 cmd_set_voltage[1] = HX8279_VGH_VOLT_SEL(desc->vgh_mv); 276 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_voltage, 277 ARRAY_SIZE(cmd_set_voltage)); 278 } 279 280 if (desc->vgl_mv) { 281 cmd_set_voltage[0] = HX8279_P0_VGLS; 282 cmd_set_voltage[1] = HX8279_VGL_VOLT_SEL(desc->vgl_mv); 283 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_voltage, 284 ARRAY_SIZE(cmd_set_voltage)); 285 } 286 287 if (desc->vgph_mv) { 288 cmd_set_voltage[0] = HX8279_P0_VGPHS; 289 cmd_set_voltage[1] = HX8279_VGPN_VOLT_SEL(desc->vgph_mv); 290 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_voltage, 291 ARRAY_SIZE(cmd_set_voltage)); 292 } 293 294 if (desc->vgnh_mv) { 295 cmd_set_voltage[0] = HX8279_P0_VGNHS; 296 cmd_set_voltage[1] = HX8279_VGPN_VOLT_SEL(desc->vgnh_mv); 297 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_voltage, 298 ARRAY_SIZE(cmd_set_voltage)); 299 } 300 } 301 302 static void hx8279_set_gmux(struct hx8279 *hx, 303 struct mipi_dsi_multi_context *dsi_ctx) 304 { 305 const struct hx8279_goa_mux *gmux = hx->desc->gmux; 306 u8 cmd_set_gmux[2]; 307 int i; 308 309 if (!gmux) 310 return; 311 312 hx8279_set_page(hx, dsi_ctx, 1); 313 314 for (i = 0; i < ARRAY_SIZE(gmux->gout_l); i++) { 315 cmd_set_gmux[0] = HX8279_P1_REG_GOUTL(i); 316 cmd_set_gmux[1] = gmux->gout_l[i]; 317 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_gmux, 318 ARRAY_SIZE(cmd_set_gmux)); 319 } 320 321 for (i = 0; i < ARRAY_SIZE(gmux->gout_r); i++) { 322 cmd_set_gmux[0] = HX8279_P1_REG_GOUTR(i); 323 cmd_set_gmux[1] = gmux->gout_r[i]; 324 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_gmux, 325 ARRAY_SIZE(cmd_set_gmux)); 326 } 327 } 328 329 static void hx8279_set_analog_gamma(struct hx8279 *hx, 330 struct mipi_dsi_multi_context *dsi_ctx) 331 { 332 const struct hx8279_analog_gamma *agamma = hx->desc->agamma; 333 u8 cmd_set_ana_gamma[2]; 334 int i; 335 336 if (!agamma) 337 return; 338 339 hx8279_set_page(hx, dsi_ctx, 2); 340 341 for (i = 0; i < ARRAY_SIZE(agamma->pos); i++) { 342 cmd_set_ana_gamma[0] = HX8279_P2_REG_GAMMA_T_PVP(i); 343 cmd_set_ana_gamma[1] = agamma->pos[i]; 344 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_ana_gamma, 345 ARRAY_SIZE(cmd_set_ana_gamma)); 346 } 347 348 for (i = 0; i < ARRAY_SIZE(agamma->neg); i++) { 349 cmd_set_ana_gamma[0] = HX8279_P2_REG_GAMMA_T_PVN(i); 350 cmd_set_ana_gamma[1] = agamma->neg[i]; 351 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_ana_gamma, 352 ARRAY_SIZE(cmd_set_ana_gamma)); 353 } 354 } 355 356 static void hx8279_set_goa_timing(struct hx8279 *hx, 357 struct mipi_dsi_multi_context *dsi_ctx) 358 { 359 const struct hx8279_panel_desc *desc = hx->desc; 360 u8 cmd_set_goa_t[2]; 361 int i; 362 363 if (hx->skip_goa_timing) 364 return; 365 366 hx8279_set_page(hx, dsi_ctx, 3); 367 368 for (i = 0; i < ARRAY_SIZE(desc->goa_odd_timing); i++) { 369 cmd_set_goa_t[0] = HX8279_P3_REG_GOA_TO(i); 370 cmd_set_goa_t[1] = desc->goa_odd_timing[i]; 371 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_goa_t, 372 ARRAY_SIZE(cmd_set_goa_t)); 373 } 374 375 for (i = 0; i < ARRAY_SIZE(desc->goa_even_timing); i++) { 376 cmd_set_goa_t[0] = HX8279_P3_REG_GOA_TE(i); 377 cmd_set_goa_t[1] = desc->goa_odd_timing[i]; 378 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_goa_t, 379 ARRAY_SIZE(cmd_set_goa_t)); 380 } 381 } 382 383 static void hx8279_set_goa_cfg(struct hx8279 *hx, 384 struct mipi_dsi_multi_context *dsi_ctx) 385 { 386 const struct hx8279_panel_desc *desc = hx->desc; 387 u8 cmd_set_goa[2]; 388 int i; 389 390 if (hx->skip_goa_config) 391 return; 392 393 hx8279_set_page(hx, dsi_ctx, 3); 394 395 if (desc->goa_unk_ba) { 396 cmd_set_goa[0] = HX8279_P3_REG_UNKNOWN_BA; 397 cmd_set_goa[1] = desc->goa_unk_ba; 398 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_goa, 399 ARRAY_SIZE(cmd_set_goa)); 400 } 401 402 if (desc->goa_stv_lead_time_ck) { 403 cmd_set_goa[0] = HX8279_P3_REG_GOA_STVL; 404 cmd_set_goa[1] = FIELD_PREP(HX8279_P3_GOA_STV_LEAD, 405 desc->goa_stv_lead_time_ck); 406 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_goa, 407 ARRAY_SIZE(cmd_set_goa)); 408 } 409 410 if (desc->goa_ckv_lead_time_ck) { 411 cmd_set_goa[0] = HX8279_P3_REG_GOA_CKVL; 412 cmd_set_goa[1] = FIELD_PREP(HX8279_P3_GOA_CKV_DUMMY, 413 desc->goa_ckv_lead_time_ck); 414 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_goa, 415 ARRAY_SIZE(cmd_set_goa)); 416 } 417 418 if (desc->goa_ckv_dummy_vblank_num) { 419 cmd_set_goa[0] = HX8279_P3_REG_GOA_CKVD; 420 cmd_set_goa[1] = FIELD_PREP(HX8279_P3_GOA_CKV_LEAD, 421 desc->goa_ckv_dummy_vblank_num); 422 cmd_set_goa[1] |= FIELD_PREP(HX8279_P3_GOA_CKV_NONOVERLAP, 423 desc->goa_ckv_non_overlap_ctl); 424 /* RESERVED must be always set */ 425 cmd_set_goa[1] |= HX8279_P3_GOA_CKV_RESERVED; 426 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_goa, 427 ARRAY_SIZE(cmd_set_goa)); 428 } 429 430 /* 431 * One of the two being more than zero means that we want to write 432 * both of them. Anyway, the register default is zero in this case. 433 */ 434 if (desc->goa_ckv_rise_precharge || desc->goa_ckv_fall_precharge) { 435 cmd_set_goa[0] = HX8279_P3_REG_GOA_CKV_RISE_PREC; 436 cmd_set_goa[1] = desc->goa_ckv_rise_precharge; 437 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_goa, 438 ARRAY_SIZE(cmd_set_goa)); 439 440 cmd_set_goa[0] = HX8279_P3_REG_GOA_CKV_FALL_PREC; 441 cmd_set_goa[1] = desc->goa_ckv_fall_precharge; 442 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_goa, 443 ARRAY_SIZE(cmd_set_goa)); 444 } 445 446 if (desc->goa_clr1_width_adj) { 447 cmd_set_goa[0] = HX8279_P3_REG_GOA_CLR1_W_ADJ; 448 cmd_set_goa[1] = desc->goa_clr1_width_adj; 449 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_goa, 450 ARRAY_SIZE(cmd_set_goa)); 451 } 452 453 if (desc->goa_clr234_width_adj) { 454 cmd_set_goa[0] = HX8279_P3_REG_GOA_CLR234_W_ADJ; 455 cmd_set_goa[1] = desc->goa_clr234_width_adj; 456 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_goa, 457 ARRAY_SIZE(cmd_set_goa)); 458 } 459 460 /* Polarity and Start Position arrays are of the same size */ 461 for (i = 0; i < ARRAY_SIZE(desc->goa_clr_polarity); i++) { 462 if (desc->goa_clr_polarity[i] < 0 || desc->goa_clr_start_pos[i] < 0) 463 continue; 464 465 cmd_set_goa[0] = HX8279_P3_REG_GOA_CLR_CFG(i); 466 cmd_set_goa[1] = FIELD_PREP(HX8279_P3_GOA_CLR_CFG_STARTPOS, 467 desc->goa_clr_start_pos[i]); 468 cmd_set_goa[1] |= FIELD_PREP(HX8279_P3_GOA_CLR_CFG_POLARITY, 469 desc->goa_clr_polarity[i]); 470 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_goa, 471 ARRAY_SIZE(cmd_set_goa)); 472 } 473 474 if (desc->goa_unk_e4) { 475 cmd_set_goa[0] = HX8279_P3_REG_UNKNOWN_E4; 476 cmd_set_goa[1] = desc->goa_unk_e4; 477 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_goa, 478 ARRAY_SIZE(cmd_set_goa)); 479 } 480 481 cmd_set_goa[0] = HX8279_P3_REG_UNKNOWN_E5; 482 cmd_set_goa[1] = desc->goa_unk_e5; 483 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_goa, 484 ARRAY_SIZE(cmd_set_goa)); 485 } 486 487 static void hx8279_set_mipi_cfg(struct hx8279 *hx, 488 struct mipi_dsi_multi_context *dsi_ctx) 489 { 490 const struct hx8279_panel_desc *desc = hx->desc; 491 u8 cmd_set_mipi[2]; 492 493 if (hx->skip_mipi_timing) 494 return; 495 496 hx8279_set_page(hx, dsi_ctx, 5); 497 498 if (desc->bta_tlpx || desc->ths_settle_time || desc->lhs_settle_time_by_osc25) { 499 cmd_set_mipi[0] = HX8279_P5_REG_TIMING; 500 cmd_set_mipi[1] = FIELD_PREP(HX8279_P5_TIMING_TLPX, desc->bta_tlpx); 501 cmd_set_mipi[1] |= FIELD_PREP(HX8279_P5_TIMING_THS_SETTLE, 502 desc->ths_settle_time); 503 cmd_set_mipi[1] |= FIELD_PREP(HX8279_P5_TIMING_LHS_SETTLE, 504 desc->lhs_settle_time_by_osc25); 505 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_mipi, 506 ARRAY_SIZE(cmd_set_mipi)); 507 } 508 509 if (desc->timing_unk_b8) { 510 cmd_set_mipi[0] = HX8279_P5_REG_UNKNOWN_B8; 511 cmd_set_mipi[1] = desc->timing_unk_b8; 512 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_mipi, 513 ARRAY_SIZE(cmd_set_mipi)); 514 } 515 516 if (desc->timing_unk_bc) { 517 cmd_set_mipi[0] = HX8279_P5_REG_UNKNOWN_BC; 518 cmd_set_mipi[1] = desc->timing_unk_bc; 519 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_mipi, 520 ARRAY_SIZE(cmd_set_mipi)); 521 } 522 523 if (desc->timing_unk_d6) { 524 cmd_set_mipi[0] = HX8279_P5_REG_UNKNOWN_D6; 525 cmd_set_mipi[1] = desc->timing_unk_d6; 526 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_mipi, 527 ARRAY_SIZE(cmd_set_mipi)); 528 } 529 } 530 531 static void hx8279_set_adv_cfg(struct hx8279 *hx, 532 struct mipi_dsi_multi_context *dsi_ctx) 533 { 534 const struct hx8279_panel_desc *desc = hx->desc; 535 const u8 cmd_set_dly[] = { HX8279_P6_REG_DLY_TIME_ADJ, desc->src_delay_time_adj_ck }; 536 const u8 cmd_set_gamma[] = { HX8279_P6_REG_GAMMA_CHOPPER, desc->gamma_ctl }; 537 const u8 cmd_set_volt_adj[] = { HX8279_P6_REG_VOLT_ADJ, desc->volt_adj }; 538 u8 cmd_set_eng[] = { HX8279_P6_REG_ENGINEER_PWD, HX8279_P6_ENG_UNLOCK_WORD }; 539 540 if (!desc->gamma_ctl && !desc->src_delay_time_adj_ck && !desc->volt_adj) 541 return; 542 543 hx8279_set_page(hx, dsi_ctx, 6); 544 545 /* Unlock ENG settings: write same word to both ENGINEER_PWD and INHOUSE_FUNC */ 546 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_eng, ARRAY_SIZE(cmd_set_eng)); 547 548 cmd_set_eng[0] = HX8279_P6_REG_INHOUSE_FUNC; 549 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_eng, ARRAY_SIZE(cmd_set_eng)); 550 551 /* Set Gamma Chopper and Gamma buffer Chopper control */ 552 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_gamma, ARRAY_SIZE(cmd_set_gamma)); 553 554 /* Set Source delay time adjustment (CKV falling to Source off) */ 555 if (desc->src_delay_time_adj_ck) 556 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_dly, 557 ARRAY_SIZE(cmd_set_dly)); 558 559 /* Set voltage adjustment */ 560 if (desc->volt_adj) 561 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_volt_adj, 562 ARRAY_SIZE(cmd_set_volt_adj)); 563 564 /* Lock ENG settings again */ 565 cmd_set_eng[0] = HX8279_P6_REG_ENGINEER_PWD; 566 cmd_set_eng[1] = 0; 567 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_eng, ARRAY_SIZE(cmd_set_eng)); 568 569 cmd_set_eng[0] = HX8279_P6_REG_INHOUSE_FUNC; 570 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_eng, ARRAY_SIZE(cmd_set_eng)); 571 } 572 573 static void hx8279_set_digital_gamma(struct hx8279 *hx, 574 struct mipi_dsi_multi_context *dsi_ctx) 575 { 576 const struct hx8279_digital_gamma *dgamma = hx->desc->dgamma; 577 u8 cmd_set_dig_gamma[2]; 578 int i; 579 580 if (!dgamma) 581 return; 582 583 /* 584 * Pages 7..9 are for RGB Positive, 10..12 are for RGB Negative: 585 * The first iteration sets all positive component registers, 586 * the second one sets all negatives. 587 */ 588 for (i = 0; i < 2; i++) { 589 u8 pg_neg = i * 3; 590 591 hx8279_set_page(hx, dsi_ctx, 7 + pg_neg); 592 593 for (i = 0; i < ARRAY_SIZE(dgamma->r); i++) { 594 cmd_set_dig_gamma[0] = HX8279_PG_DIGITAL_GAMMA + i; 595 cmd_set_dig_gamma[1] = dgamma->r[i]; 596 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_dig_gamma, 597 ARRAY_SIZE(cmd_set_dig_gamma)); 598 } 599 600 hx8279_set_page(hx, dsi_ctx, 8 + pg_neg); 601 602 for (i = 0; i < ARRAY_SIZE(dgamma->g); i++) { 603 cmd_set_dig_gamma[0] = HX8279_PG_DIGITAL_GAMMA + i; 604 cmd_set_dig_gamma[1] = dgamma->g[i]; 605 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_dig_gamma, 606 ARRAY_SIZE(cmd_set_dig_gamma)); 607 } 608 609 hx8279_set_page(hx, dsi_ctx, 9 + pg_neg); 610 611 for (i = 0; i < ARRAY_SIZE(dgamma->b); i++) { 612 cmd_set_dig_gamma[0] = HX8279_PG_DIGITAL_GAMMA + i; 613 cmd_set_dig_gamma[1] = dgamma->b[i]; 614 mipi_dsi_generic_write_multi(dsi_ctx, cmd_set_dig_gamma, 615 ARRAY_SIZE(cmd_set_dig_gamma)); 616 } 617 } 618 } 619 620 static int hx8279_on(struct hx8279 *hx) 621 { 622 struct mipi_dsi_device *dsi = hx->dsi[0]; 623 struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; 624 625 /* Page 5 */ 626 hx8279_set_mipi_cfg(hx, &dsi_ctx); 627 628 /* Page 1 */ 629 hx8279_set_gmux(hx, &dsi_ctx); 630 631 /* Page 2 */ 632 hx8279_set_analog_gamma(hx, &dsi_ctx); 633 634 /* Page 3 */ 635 hx8279_set_goa_cfg(hx, &dsi_ctx); 636 hx8279_set_goa_timing(hx, &dsi_ctx); 637 638 /* Page 0 - Driver/Module Configuration */ 639 hx8279_set_module_config(hx, &dsi_ctx); 640 641 /* Page 6 */ 642 hx8279_set_adv_cfg(hx, &dsi_ctx); 643 644 /* Pages 7..12 */ 645 hx8279_set_digital_gamma(hx, &dsi_ctx); 646 647 return dsi_ctx.accum_err; 648 } 649 650 static void hx8279_power_off(struct hx8279 *hx) 651 { 652 gpiod_set_value_cansleep(hx->reset_gpio, 0); 653 usleep_range(100, 500); 654 gpiod_set_value_cansleep(hx->enable_gpio, 0); 655 regulator_bulk_disable(ARRAY_SIZE(hx->vregs), hx->vregs); 656 } 657 658 static int hx8279_disable(struct drm_panel *panel) 659 { 660 struct hx8279 *hx = to_hx8279(panel); 661 struct mipi_dsi_device *dsi = hx->dsi[0]; 662 struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; 663 664 mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); 665 666 return 0; 667 } 668 669 static int hx8279_enable(struct drm_panel *panel) 670 { 671 struct hx8279 *hx = to_hx8279(panel); 672 struct mipi_dsi_device *dsi = hx->dsi[0]; 673 struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; 674 675 mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); 676 677 return 0; 678 } 679 680 static int hx8279_prepare(struct drm_panel *panel) 681 { 682 struct hx8279 *hx = to_hx8279(panel); 683 struct mipi_dsi_device *dsi = hx->dsi[0]; 684 struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; 685 int ret; 686 687 ret = regulator_bulk_enable(ARRAY_SIZE(hx->vregs), hx->vregs); 688 if (ret) 689 return ret; 690 691 gpiod_set_value_cansleep(hx->enable_gpio, 1); 692 usleep_range(5000, 6000); 693 gpiod_set_value_cansleep(hx->reset_gpio, 1); 694 usleep_range(6000, 7000); 695 696 dsi->mode_flags |= MIPI_DSI_MODE_LPM; 697 if (hx->dsi[1]) 698 hx->dsi[1]->mode_flags |= MIPI_DSI_MODE_LPM; 699 700 ret = hx8279_on(hx); 701 if (ret) { 702 hx8279_power_off(hx); 703 return ret; 704 } 705 706 mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); 707 mipi_dsi_msleep(&dsi_ctx, 130); 708 709 return dsi_ctx.accum_err; 710 } 711 712 static int hx8279_unprepare(struct drm_panel *panel) 713 { 714 struct hx8279 *hx = to_hx8279(panel); 715 struct mipi_dsi_device *dsi = hx->dsi[0]; 716 struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; 717 718 mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx); 719 mipi_dsi_msleep(&dsi_ctx, 130); 720 721 dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; 722 if (hx->dsi[1]) 723 hx->dsi[1]->mode_flags &= ~MIPI_DSI_MODE_LPM; 724 725 hx8279_power_off(hx); 726 727 return dsi_ctx.accum_err; 728 } 729 730 static int hx8279_get_modes(struct drm_panel *panel, struct drm_connector *connector) 731 { 732 struct hx8279 *hx = to_hx8279(panel); 733 int i; 734 735 for (i = 0; i < hx->desc->num_modes; i++) { 736 struct drm_display_mode *mode; 737 738 mode = drm_mode_duplicate(connector->dev, &hx->desc->mode_data[i].mode); 739 if (!mode) 740 return -ENOMEM; 741 742 drm_mode_set_name(mode); 743 744 mode->type |= DRM_MODE_TYPE_DRIVER; 745 if (hx->desc->num_modes == 1) 746 mode->type |= DRM_MODE_TYPE_PREFERRED; 747 748 drm_mode_probed_add(connector, mode); 749 } 750 751 connector->display_info.bpc = hx->desc->mode_data[0].bpc; 752 connector->display_info.height_mm = hx->desc->mode_data[0].mode.height_mm; 753 connector->display_info.width_mm = hx->desc->mode_data[0].mode.width_mm; 754 755 return hx->desc->num_modes; 756 } 757 758 static const struct drm_panel_funcs hx8279_panel_funcs = { 759 .disable = hx8279_disable, 760 .unprepare = hx8279_unprepare, 761 .prepare = hx8279_prepare, 762 .enable = hx8279_enable, 763 .get_modes = hx8279_get_modes, 764 }; 765 766 static int hx8279_init_vregs(struct hx8279 *hx, struct device *dev) 767 { 768 int ret; 769 770 hx->vregs[0].supply = "vdd"; 771 hx->vregs[1].supply = "iovcc"; 772 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(hx->vregs), 773 hx->vregs); 774 if (ret < 0) 775 return ret; 776 777 ret = regulator_is_supported_voltage(hx->vregs[0].consumer, 778 3000000, 5000000); 779 if (!ret) 780 return -EINVAL; 781 782 ret = regulator_is_supported_voltage(hx->vregs[1].consumer, 783 1700000, 1900000); 784 if (!ret) 785 return -EINVAL; 786 787 return 0; 788 } 789 790 static int hx8279_check_gmux_config(struct hx8279 *hx, struct device *dev) 791 { 792 const struct hx8279_panel_desc *desc = hx->desc; 793 const struct hx8279_goa_mux *gmux = desc->gmux; 794 int i; 795 796 /* No gmux defined means we simply skip the GOA mux configuration */ 797 if (!gmux) 798 return 0; 799 800 for (i = 0; i < ARRAY_SIZE(gmux->gout_l); i++) { 801 if (gmux->gout_l[i] > (HX8279_GOUT_STB | HX8279_GOUT_SEL)) 802 return dev_err_probe(dev, -EINVAL, 803 "Invalid value found in gout_l[%d]\n", i); 804 } 805 806 for (i = 0; i < ARRAY_SIZE(gmux->gout_r); i++) { 807 if (gmux->gout_r[i] > (HX8279_GOUT_STB | HX8279_GOUT_SEL)) 808 return dev_err_probe(dev, -EINVAL, 809 "Invalid value found in gout_r[%d]\n", i); 810 } 811 812 return 0; 813 } 814 815 static int hx8279_check_goa_config(struct hx8279 *hx, struct device *dev) 816 { 817 const struct hx8279_panel_desc *desc = hx->desc; 818 bool goa_odd_valid, goa_even_valid; 819 int i, num_zero, num_clr = 0; 820 821 /* Up to 4 zero values is a valid configuration. Check them all. */ 822 num_zero = 1; 823 for (i = 0; i < ARRAY_SIZE(desc->goa_odd_timing); i++) { 824 if (desc->goa_odd_timing[i]) 825 num_zero++; 826 } 827 828 goa_odd_valid = (num_zero != ARRAY_SIZE(desc->goa_odd_timing)); 829 830 /* Up to 3 zeroes is a valid config. Check them all. */ 831 num_zero = 1; 832 for (i = 0; i < ARRAY_SIZE(desc->goa_even_timing); i++) { 833 if (desc->goa_even_timing[i]) 834 num_zero++; 835 } 836 837 goa_even_valid = (num_zero != ARRAY_SIZE(desc->goa_even_timing)); 838 839 /* Programming one without the other would make no sense! */ 840 if (goa_odd_valid != goa_even_valid) 841 return -EINVAL; 842 843 /* We know that both are either true or false now, check just one */ 844 if (!goa_odd_valid) 845 hx->skip_goa_timing = true; 846 847 if (!desc->goa_unk_ba && !desc->goa_stv_lead_time_ck && 848 !desc->goa_ckv_lead_time_ck && !desc->goa_ckv_dummy_vblank_num && 849 !desc->goa_ckv_rise_precharge && !desc->goa_ckv_fall_precharge && 850 !desc->goa_clr1_width_adj && !desc->goa_clr234_width_adj && 851 !desc->goa_unk_e4 && !desc->goa_unk_e5) { 852 hx->skip_goa_config = true; 853 return 0; 854 } 855 856 if ((desc->goa_stv_lead_time_ck > HX8279_P3_GOA_STV_LEAD) || 857 (desc->goa_ckv_lead_time_ck > HX8279_P3_GOA_CKV_LEAD) || 858 (desc->goa_ckv_dummy_vblank_num > HX8279_P3_GOA_CKV_DUMMY)) 859 return dev_err_probe(dev, -EINVAL, 860 "Invalid lead timings in GOA config\n"); 861 862 /* 863 * Don't perform zero check for polarity and start position, as 864 * both pol=0 and start=0 are valid configuration values. 865 */ 866 for (i = 0; i < ARRAY_SIZE(desc->goa_clr_start_pos); i++) { 867 if (desc->goa_clr_start_pos[i] < 0) 868 continue; 869 else if (desc->goa_clr_start_pos[i] > HX8279_P3_GOA_CLR_CFG_STARTPOS) 870 return dev_err_probe(dev, -EINVAL, 871 "Invalid start position for CLR%d\n", i + 1); 872 else 873 num_clr++; 874 } 875 if (!num_clr) 876 return -EINVAL; 877 878 for (i = 0; i < ARRAY_SIZE(desc->goa_clr_polarity); i++) { 879 if (num_clr < 0) 880 return -EINVAL; 881 882 if (desc->goa_clr_polarity[i] < 0) 883 continue; 884 else if (desc->goa_clr_polarity[i] > 1) 885 return dev_err_probe(dev, -EINVAL, 886 "Invalid polarity for CLR%d\n", i + 1); 887 else 888 num_clr--; 889 } 890 891 return 0; 892 } 893 894 static int hx8279_check_dig_gamma(struct hx8279 *hx, struct device *dev, const u8 *component) 895 { 896 u8 gamma_high_bits[4]; 897 u16 prev_val = 0; 898 int i, j, k, x; 899 900 /* 901 * The gamma values are 10 bits long and shall be incremental 902 * to form a digital gamma correction reference curve. 903 * 904 * As for the registers format: the first 24 bytes contain each the 905 * lowest 8 bits for each of the gamma level references, and the last 906 * 6 bytes contain the high two bits of 4 registers at a time, where 907 * the first two bits are relative to the last register, and the last 908 * two are relative to the first register. 909 * 910 * Another way of saying, those are the first four LOW values: 911 * DGMA1_LO = 0xb1, DGMA2_LO = 0xb2, DGMA3_LO = 0xb3, DGMA4_LO = 0xb4 912 * 913 * The high values for those four are at DGMA1_4_HI = 0xc9; 914 * ...and DGMA1_4_HI's data contains the following bits: 915 * [1:0] = DGMA4_HI, [3:2] = DGMA3_HI, [5:4] = DGMA2_HI, [7:6] = DGMA1_HI 916 */ 917 for (i = 0; i < HX8279_PG_DGAMMA_NUM_HI_BYTES; i++) { 918 k = HX8279_PG_DGAMMA_NUM_LO_BYTES + i; 919 j = i * 4; 920 x = 0; 921 922 gamma_high_bits[0] = FIELD_GET(HX8279_DGAMMA_DGMA1_HI, component[k]); 923 gamma_high_bits[1] = FIELD_GET(HX8279_DGAMMA_DGMA2_HI, component[k]); 924 gamma_high_bits[2] = FIELD_GET(HX8279_DGAMMA_DGMA3_HI, component[k]); 925 gamma_high_bits[3] = FIELD_GET(HX8279_DGAMMA_DGMA4_HI, component[k]); 926 927 do { 928 u16 cur_val = component[j] | (gamma_high_bits[x] << 8); 929 930 if (cur_val < prev_val) 931 return dev_err_probe(dev, -EINVAL, 932 "Invalid dgamma values: %u < %u!\n", 933 cur_val, prev_val); 934 prev_val = cur_val; 935 j++; 936 x++; 937 } while (x < 4); 938 }; 939 940 return 0; 941 } 942 943 static int hx8279_check_params(struct hx8279 *hx, struct device *dev) 944 { 945 const struct hx8279_panel_desc *desc = hx->desc; 946 int ret; 947 948 /* Voltages config validation */ 949 if (!desc->vgh_mv && !desc->vgl_mv && !desc->vgph_mv && !desc->vgnh_mv) 950 hx->skip_voltage_config = true; 951 else if ((desc->vgh_mv && desc->vgh_mv < HX8279_VGH_MIN_MV) || 952 (desc->vgl_mv && desc->vgl_mv < HX8279_VGL_MIN_MV) || 953 (desc->vgph_mv && desc->vgph_mv < HX8279_VGPNH_MIN_MV) || 954 (desc->vgnh_mv && desc->vgnh_mv < HX8279_VGPNH_MIN_MV)) 955 return -EINVAL; 956 957 /* GOA Muxing validation */ 958 ret = hx8279_check_gmux_config(hx, dev); 959 if (ret) 960 return ret; 961 962 /* GOA Configuration validation */ 963 ret = hx8279_check_goa_config(hx, dev); 964 if (ret) 965 return ret; 966 967 /* MIPI Configuration validation */ 968 if (!desc->bta_tlpx && !desc->lhs_settle_time_by_osc25 && 969 !desc->ths_settle_time && !desc->timing_unk_b8 && 970 !desc->timing_unk_bc && !desc->timing_unk_d6) 971 hx->skip_mipi_timing = true; 972 973 /* ENG/Gamma Configuration validation */ 974 if (desc->gamma_ctl > (HX8279_P6_GAMMA_POCGM_CTL | HX8279_P6_GAMMA_POGCMD_CTL)) 975 return -EINVAL; 976 977 /* Digital Gamma values validation */ 978 if (desc->dgamma) { 979 ret = hx8279_check_dig_gamma(hx, dev, desc->dgamma->r); 980 if (ret) 981 return ret; 982 983 ret = hx8279_check_dig_gamma(hx, dev, desc->dgamma->g); 984 if (ret) 985 return ret; 986 987 ret = hx8279_check_dig_gamma(hx, dev, desc->dgamma->b); 988 if (ret) 989 return ret; 990 } 991 992 return 0; 993 } 994 995 static int hx8279_probe(struct mipi_dsi_device *dsi) 996 { 997 struct device *dev = &dsi->dev; 998 struct device_node *dsi_r; 999 struct hx8279 *hx; 1000 int i, ret; 1001 1002 hx = devm_drm_panel_alloc(dev, struct hx8279, panel, 1003 &hx8279_panel_funcs, DRM_MODE_CONNECTOR_DSI); 1004 if (IS_ERR(hx)) 1005 return PTR_ERR(hx); 1006 1007 ret = hx8279_init_vregs(hx, dev); 1008 if (ret) 1009 return ret; 1010 1011 hx->desc = device_get_match_data(dev); 1012 if (!hx->desc) 1013 return -ENODEV; 1014 1015 /* 1016 * In some DriverICs some or all fields may be OTP: perform a 1017 * basic configuration check before writing to help avoiding 1018 * irreparable mistakes. 1019 * 1020 * Please note that this is not perfect and will only check if 1021 * the values may be plausible; values that are wrong for a 1022 * specific display, but still plausible for DrIC config will 1023 * be accepted. 1024 */ 1025 ret = hx8279_check_params(hx, dev); 1026 if (ret) 1027 return dev_err_probe(dev, ret, "Invalid DriverIC configuration\n"); 1028 1029 /* The enable line may be always tied to VCCIO, so this is optional */ 1030 hx->enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_ASIS); 1031 if (IS_ERR(hx->enable_gpio)) 1032 return dev_err_probe(dev, PTR_ERR(hx->enable_gpio), 1033 "Failed to get enable GPIO\n"); 1034 1035 hx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS); 1036 if (IS_ERR(hx->reset_gpio)) 1037 return dev_err_probe(dev, PTR_ERR(hx->reset_gpio), 1038 "Failed to get reset GPIO\n"); 1039 1040 /* If the panel is connected on two DSIs then DSI0 left, DSI1 right */ 1041 dsi_r = of_graph_get_remote_node(dsi->dev.of_node, 1, -1); 1042 if (dsi_r) { 1043 const struct mipi_dsi_device_info *info = &hx->desc->dsi_info; 1044 struct mipi_dsi_host *dsi_r_host; 1045 1046 dsi_r_host = of_find_mipi_dsi_host_by_node(dsi_r); 1047 of_node_put(dsi_r); 1048 if (!dsi_r_host) 1049 return dev_err_probe(dev, -EPROBE_DEFER, 1050 "Cannot get secondary DSI host\n"); 1051 1052 hx->dsi[1] = devm_mipi_dsi_device_register_full(dev, dsi_r_host, info); 1053 if (IS_ERR(hx->dsi[1])) 1054 return dev_err_probe(dev, PTR_ERR(hx->dsi[1]), 1055 "Cannot get secondary DSI node\n"); 1056 mipi_dsi_set_drvdata(hx->dsi[1], hx); 1057 } 1058 1059 hx->dsi[0] = dsi; 1060 mipi_dsi_set_drvdata(dsi, hx); 1061 1062 ret = drm_panel_of_backlight(&hx->panel); 1063 if (ret) 1064 return dev_err_probe(dev, ret, "Failed to get backlight\n"); 1065 1066 drm_panel_add(&hx->panel); 1067 1068 for (i = 0; i < 2; i++) { 1069 if (!hx->dsi[i]) 1070 continue; 1071 1072 hx->dsi[i]->lanes = hx->desc->num_lanes; 1073 hx->dsi[i]->format = MIPI_DSI_FMT_RGB888; 1074 1075 hx->dsi[i]->mode_flags = MIPI_DSI_CLOCK_NON_CONTINUOUS | 1076 MIPI_DSI_MODE_LPM; 1077 1078 if (hx->desc->mode_data[0].is_video_mode) 1079 hx->dsi[i]->mode_flags |= MIPI_DSI_MODE_VIDEO | 1080 MIPI_DSI_MODE_VIDEO_SYNC_PULSE; 1081 1082 ret = devm_mipi_dsi_attach(dev, hx->dsi[i]); 1083 if (ret < 0) { 1084 drm_panel_remove(&hx->panel); 1085 return dev_err_probe(dev, ret, 1086 "Cannot attach to DSI%d host.\n", i); 1087 } 1088 } 1089 1090 return 0; 1091 } 1092 1093 static void hx8279_remove(struct mipi_dsi_device *dsi) 1094 { 1095 struct hx8279 *hx = mipi_dsi_get_drvdata(dsi); 1096 1097 drm_panel_remove(&hx->panel); 1098 } 1099 1100 static const struct hx8279_panel_mode aoly_sl101pm1794fog_v15_modes[] = { 1101 { 1102 .mode = { 1103 .clock = 159420, 1104 .hdisplay = 1200, 1105 .hsync_start = 1200 + 80, 1106 .hsync_end = 1200 + 80 + 60, 1107 .htotal = 1200 + 80 + 60 + 24, 1108 .vdisplay = 1920, 1109 .vsync_start = 1920 + 10, 1110 .vsync_end = 1920 + 10 + 14, 1111 .vtotal = 1920 + 10 + 14 + 4, 1112 .width_mm = 136, 1113 .height_mm = 217, 1114 .type = DRM_MODE_TYPE_DRIVER 1115 }, 1116 .bpc = 8, 1117 .is_video_mode = true, 1118 }, 1119 }; 1120 1121 static const struct hx8279_panel_mode startek_kd070fhfid078_modes[] = { 1122 { 1123 .mode = { 1124 .clock = 156458, 1125 .hdisplay = 1200, 1126 .hsync_start = 1200 + 50, 1127 .hsync_end = 1200 + 50 + 24, 1128 .htotal = 1200 + 50 + 24 + 66, 1129 .vdisplay = 1920, 1130 .vsync_start = 1920 + 14, 1131 .vsync_end = 1920 + 14 + 2, 1132 .vtotal = 1920 + 14 + 2 + 10, 1133 .width_mm = 95, 1134 .height_mm = 151, 1135 .type = DRM_MODE_TYPE_DRIVER 1136 }, 1137 .bpc = 8, 1138 .is_video_mode = true, 1139 }, 1140 }; 1141 1142 static const struct hx8279_goa_mux aoly_sl101pm1794fog_v15_gmux = { 1143 .gout_l = { 0x5, 0x5, 0xb, 0xb, 0x9, 0x9, 0x16, 0x16, 0xe, 0xe, 1144 0x7, 0x7, 0x26, 0x26, 0x15, 0x15, 0x1, 0x1, 0x3, 0x3 }, 1145 .gout_r = { 0x6, 0x6, 0xc, 0xc, 0xa, 0xa, 0x16, 0x16, 0xe, 0xe, 1146 0x8, 0x8, 0x26, 0x26, 0x15, 0x15, 0x2, 0x2, 0x4, 0x4 }, 1147 }; 1148 1149 static const struct hx8279_analog_gamma aoly_sl101pm1794fog_v15_ana_gamma = { 1150 .pos = { 0x0, 0xd, 0x17, 0x26, 0x31, 0x1c, 0x2c, 0x33, 0x31, 1151 0x37, 0x37, 0x37, 0x39, 0x2e, 0x2f, 0x2f, 0x7 }, 1152 .neg = { 0x0, 0xd, 0x17, 0x26, 0x31, 0x3f, 0x3f, 0x3f, 0x3f, 1153 0x37, 0x37, 0x37, 0x39, 0x2e, 0x2f, 0x2f, 0x7 }, 1154 }; 1155 1156 static const struct hx8279_digital_gamma aoly_sl101pm1794fog_v15_dig_gamma = { 1157 .r = { 0x0, 0x5, 0x10, 0x22, 0x36, 0x4a, 0x6c, 0x9a, 0xd7, 0x17, 1158 0x92, 0x15, 0x18, 0x8c, 0x0, 0x3a, 0x72, 0x8c, 0xa5, 0xb1, 1159 0xbe, 0xca, 0xd1, 0xd4, 0x0, 0x0, 0x16, 0xaf, 0xff, 0xff }, 1160 .g = { 0x4, 0x5, 0x11, 0x24, 0x39, 0x4e, 0x72, 0xa3, 0xe1, 0x25, 1161 0xa8, 0x2e, 0x32, 0xad, 0x28, 0x63, 0x9b, 0xb5, 0xcf, 0xdb, 1162 0xe8, 0xf5, 0xfa, 0xfc, 0x0, 0x0, 0x16, 0xaf, 0xff, 0xff }, 1163 .b = { 0x4, 0x4, 0xf, 0x22, 0x37, 0x4d, 0x71, 0xa2, 0xe1, 0x26, 1164 0xa9, 0x2f, 0x33, 0xac, 0x24, 0x5d, 0x94, 0xac, 0xc5, 0xd1, 1165 0xdc, 0xe8, 0xed, 0xf0, 0x0, 0x0, 0x16, 0xaf, 0xff, 0xff }, 1166 }; 1167 1168 static const struct hx8279_panel_desc aoly_sl101pm1794fog_v15 = { 1169 .dsi_info = { 1170 .type = "L101PM1794FOG-V15", 1171 .channel = 0, 1172 .node = NULL, 1173 }, 1174 .mode_data = aoly_sl101pm1794fog_v15_modes, 1175 .num_modes = ARRAY_SIZE(aoly_sl101pm1794fog_v15_modes), 1176 .num_lanes = 4, 1177 1178 /* Driver/Module Configuration: LC Matrix voltages */ 1179 .vgh_mv = 16500, 1180 .vgl_mv = 11200, 1181 .vgph_mv = 4600, 1182 .vgnh_mv = 4600, 1183 1184 /* Analog Gamma correction */ 1185 .agamma = &aoly_sl101pm1794fog_v15_ana_gamma, 1186 1187 /* Gate driver On Array (GOA) Muxing */ 1188 .gmux = &aoly_sl101pm1794fog_v15_gmux, 1189 1190 /* Gate driver On Array (GOA) Mux Config */ 1191 .goa_unk_ba = 0xf0, 1192 .goa_odd_timing = { 0, 0, 0, 42, 0, 0 }, 1193 .goa_even_timing = { 1, 42, 0, 0 }, 1194 .goa_stv_lead_time_ck = 11, 1195 .goa_ckv_lead_time_ck = 7, 1196 .goa_ckv_dummy_vblank_num = 3, 1197 .goa_ckv_rise_precharge = 1, 1198 .goa_clr1_width_adj = 0, 1199 .goa_clr234_width_adj = 0, 1200 .goa_clr_polarity = { 1, 0, 0, 0 }, 1201 .goa_clr_start_pos = { 8, 9, 3, 4 }, 1202 .goa_unk_e4 = 0xc0, 1203 .goa_unk_e5 = 0x0d, 1204 1205 /* MIPI Configuration */ 1206 .bta_tlpx = 2, 1207 .lhs_settle_time_by_osc25 = true, 1208 .ths_settle_time = 2, 1209 .timing_unk_b8 = 0xa5, 1210 .timing_unk_bc = 0x20, 1211 .timing_unk_d6 = 0x7f, 1212 1213 /* ENG/Gamma Configuration */ 1214 .gamma_ctl = 0, 1215 .volt_adj = FIELD_PREP_CONST(HX8279_P6_VOLT_ADJ_VCCIFS, 3) | 1216 FIELD_PREP_CONST(HX8279_P6_VOLT_ADJ_VCCS, 3), 1217 .src_delay_time_adj_ck = 50, 1218 1219 /* Digital Gamma Adjustment */ 1220 .dgamma = &aoly_sl101pm1794fog_v15_dig_gamma, 1221 }; 1222 1223 static const struct hx8279_goa_mux startek_kd070fhfid078_gmux = { 1224 .gout_l = { 0xd, 0xd, 0x6, 0x6, 0x8, 0x8, 0xa, 0xa, 0xc, 0xc, 1225 0x0, 0x0, 0xe, 0xe, 0x1, 0x1, 0x4, 0x4, 0x0, 0x0 }, 1226 .gout_r = { 0xd, 0xd, 0x5, 0x5, 0x7, 0x7, 0x9, 0x9, 0xb, 0xb, 1227 0x0, 0x0, 0xe, 0xe, 0x1, 0x1, 0x3, 0x3, 0x0, 0x0 }, 1228 }; 1229 1230 static const struct hx8279_panel_desc startek_kd070fhfid078 = { 1231 .dsi_info = { 1232 .type = "KD070FHFID078", 1233 .channel = 0, 1234 .node = NULL, 1235 }, 1236 .mode_data = startek_kd070fhfid078_modes, 1237 .num_modes = ARRAY_SIZE(startek_kd070fhfid078_modes), 1238 .num_lanes = 4, 1239 1240 /* Driver/Module Configuration: LC Matrix voltages */ 1241 .vgh_mv = 18000, 1242 .vgl_mv = 12100, 1243 .vgph_mv = 5500, 1244 .vgnh_mv = 5500, 1245 1246 /* Gate driver On Array (GOA) Mux Config */ 1247 .gmux = &startek_kd070fhfid078_gmux, 1248 1249 /* Gate driver On Array (GOA) Configuration */ 1250 .goa_unk_ba = 0xf0, 1251 .goa_stv_lead_time_ck = 7, 1252 .goa_ckv_lead_time_ck = 3, 1253 .goa_ckv_dummy_vblank_num = 1, 1254 .goa_ckv_rise_precharge = 0, 1255 .goa_ckv_fall_precharge = 0, 1256 .goa_clr1_width_adj = 1, 1257 .goa_clr234_width_adj = 5, 1258 .goa_clr_polarity = { 0, 1, -1, -1 }, 1259 .goa_clr_start_pos = { 5, 10, -1, -1 }, 1260 .goa_unk_e4 = 0xc0, 1261 .goa_unk_e5 = 0x00, 1262 1263 /* MIPI Configuration */ 1264 .bta_tlpx = 2, 1265 .lhs_settle_time_by_osc25 = true, 1266 .ths_settle_time = 2, 1267 .timing_unk_b8 = 0x7f, 1268 .timing_unk_bc = 0x20, 1269 .timing_unk_d6 = 0x7f, 1270 1271 /* ENG/Gamma Configuration */ 1272 .gamma_ctl = FIELD_PREP_CONST(HX8279_P6_GAMMA_POCGM_CTL, 1) | 1273 FIELD_PREP_CONST(HX8279_P6_GAMMA_POGCMD_CTL, 1), 1274 .src_delay_time_adj_ck = 72, 1275 }; 1276 1277 static const struct of_device_id hx8279_of_match[] = { 1278 { .compatible = "aoly,sl101pm1794fog-v15", .data = &aoly_sl101pm1794fog_v15 }, 1279 { .compatible = "startek,kd070fhfid078", .data = &startek_kd070fhfid078 }, 1280 { /* sentinel */ } 1281 }; 1282 MODULE_DEVICE_TABLE(of, hx8279_of_match); 1283 1284 static struct mipi_dsi_driver hx8279_driver = { 1285 .probe = hx8279_probe, 1286 .remove = hx8279_remove, 1287 .driver = { 1288 .name = "panel-himax-hx8279", 1289 .of_match_table = hx8279_of_match, 1290 }, 1291 }; 1292 module_mipi_dsi_driver(hx8279_driver); 1293 1294 MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>"); 1295 MODULE_DESCRIPTION("Himax HX8279 DriverIC panels driver"); 1296 MODULE_LICENSE("GPL"); 1297