Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/panel: st7701: Add Winstar wf40eswaa6mnn0 panel support

The Winstar wf40eswaa6mnn0 panel is a square 4.0" TFT LCD with a
resolution of 480x480 pixels.

This panel is driven by the Sitronix ST7701 controller and uses a MIPI
DSI interface. The settings are based on the panel's datasheet and the
init sequence provided by Winstar.

It was tested on a Verdin iMX8MP from Toradex with a Carrier Board
providing a MIPI DSI interface.

Signed-off-by: Stefan Eichenberger <eichest@gmail.com>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
Link: https://lore.kernel.org/r/20250606114644.105371-2-eichest@gmail.com

authored by

Stefan Eichenberger and committed by
Neil Armstrong
d04f6367 783334f3

+124
+124
drivers/gpu/drm/panel/panel-sitronix-st7701.c
··· 520 520 st7701_switch_cmd_bkx(st7701, false, 0); 521 521 } 522 522 523 + static void wf40eswaa6mnn0_gip_sequence(struct st7701 *st7701) 524 + { 525 + ST7701_WRITE(st7701, 0xE0, 0x00, 0x28, 0x02); 526 + ST7701_WRITE(st7701, 0xE1, 0x08, 0xA0, 0x00, 0x00, 0x07, 0xA0, 0x00, 527 + 0x00, 0x00, 0x44, 0x44); 528 + ST7701_WRITE(st7701, 0xE2, 0x11, 0x11, 0x44, 0x44, 0xED, 0xA0, 0x00, 529 + 0x00, 0xEC, 0xA0, 0x00, 0x00); 530 + ST7701_WRITE(st7701, 0xE3, 0x00, 0x00, 0x11, 0x11); 531 + ST7701_WRITE(st7701, 0xE4, 0x44, 0x44); 532 + ST7701_WRITE(st7701, 0xE5, 0x0A, 0xE9, 0xD8, 0xA0, 0x0C, 0xEB, 0xD8, 533 + 0xA0, 0x0E, 0xED, 0xD8, 0xA0, 0x10, 0xEF, 0xD8, 0xA0); 534 + ST7701_WRITE(st7701, 0xE6, 0x00, 0x00, 0x11, 0x11); 535 + ST7701_WRITE(st7701, 0xE7, 0x44, 0x44); 536 + ST7701_WRITE(st7701, 0xE8, 0x09, 0xE8, 0xD8, 0xA0, 0x0B, 0xEA, 0xD8, 537 + 0xA0, 0x0D, 0xEC, 0xD8, 0xA0, 0x0F, 0xEE, 0xD8, 0xA0); 538 + ST7701_WRITE(st7701, 0xEB, 0x00, 0x00, 0xE4, 0xE4, 0x88, 0x00, 0x40); 539 + ST7701_WRITE(st7701, 0xEC, 0x3C, 0x00); 540 + ST7701_WRITE(st7701, 0xED, 0xAB, 0x89, 0x76, 0x54, 0x02, 0xFF, 0xFF, 541 + 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x45, 0x67, 0x98, 0xBA); 542 + ST7701_WRITE(st7701, MIPI_DCS_SET_ADDRESS_MODE, 0); 543 + } 544 + 523 545 static int st7701_prepare(struct drm_panel *panel) 524 546 { 525 547 struct st7701 *st7701 = panel_to_st7701(panel); ··· 1157 1135 .gip_sequence = rg28xx_gip_sequence, 1158 1136 }; 1159 1137 1138 + static const struct drm_display_mode wf40eswaa6mnn0_mode = { 1139 + .clock = 18306, 1140 + 1141 + .hdisplay = 480, 1142 + .hsync_start = 480 + 2, 1143 + .hsync_end = 480 + 2 + 45, 1144 + .htotal = 480 + 2 + 45 + 13, 1145 + 1146 + .vdisplay = 480, 1147 + .vsync_start = 480 + 2, 1148 + .vsync_end = 480 + 2 + 70, 1149 + .vtotal = 480 + 2 + 70 + 13, 1150 + 1151 + .width_mm = 72, 1152 + .height_mm = 70, 1153 + 1154 + .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, 1155 + 1156 + .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, 1157 + }; 1158 + 1159 + static const struct st7701_panel_desc wf40eswaa6mnn0_desc = { 1160 + .mode = &wf40eswaa6mnn0_mode, 1161 + .lanes = 2, 1162 + .format = MIPI_DSI_FMT_RGB888, 1163 + .panel_sleep_delay = 0, 1164 + 1165 + .pv_gamma = { 1166 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1167 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC0_MASK, 0x1), 1168 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1169 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC4_MASK, 0x08), 1170 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1171 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC8_MASK, 0x10), 1172 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC16_MASK, 0x0c), 1173 + 1174 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1175 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC24_MASK, 0x10), 1176 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC52_MASK, 0x08), 1177 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC80_MASK, 0x10), 1178 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC108_MASK, 0x0c), 1179 + 1180 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC147_MASK, 0x08), 1181 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC175_MASK, 0x22), 1182 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC203_MASK, 0x04), 1183 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1184 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC231_MASK, 0x14), 1185 + 1186 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC239_MASK, 0x12), 1187 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1188 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC247_MASK, 0xb3), 1189 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1190 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC251_MASK, 0x3a), 1191 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1192 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC255_MASK, 0x1f) 1193 + }, 1194 + .nv_gamma = { 1195 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1196 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC4_MASK, 0x13), 1197 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1198 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC4_MASK, 0x19), 1199 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1200 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC8_MASK, 0x1f), 1201 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC16_MASK, 0x0f), 1202 + 1203 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1204 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC24_MASK, 0x14), 1205 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC52_MASK, 0x07), 1206 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC80_MASK, 0x07), 1207 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC108_MASK, 0x08), 1208 + 1209 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC147_MASK, 0x07), 1210 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC175_MASK, 0x22), 1211 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC203_MASK, 0x02), 1212 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1213 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC231_MASK, 0xf), 1214 + 1215 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC239_MASK, 0x0f), 1216 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1217 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC247_MASK, 0xa3), 1218 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1219 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC251_MASK, 0x29), 1220 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 1221 + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC255_MASK, 0x0d) 1222 + }, 1223 + .nlinv = 3, 1224 + .vop_uv = 4737500, 1225 + .vcom_uv = 662500, 1226 + .vgh_mv = 15000, 1227 + .vgl_mv = -10170, 1228 + .avdd_mv = 6600, 1229 + .avcl_mv = -4600, 1230 + .gamma_op_bias = OP_BIAS_MIDDLE, 1231 + .input_op_bias = OP_BIAS_MIDDLE, 1232 + .output_op_bias = OP_BIAS_MIN, 1233 + .t2d_ns = 1600, 1234 + .t3d_ns = 10400, 1235 + .eot_en = true, 1236 + .gip_sequence = wf40eswaa6mnn0_gip_sequence, 1237 + }; 1238 + 1160 1239 static void st7701_cleanup(void *data) 1161 1240 { 1162 1241 struct st7701 *st7701 = (struct st7701 *)data; ··· 1388 1265 { .compatible = "densitron,dmt028vghmcmi-1a", .data = &dmt028vghmcmi_1a_desc }, 1389 1266 { .compatible = "elida,kd50t048a", .data = &kd50t048a_desc }, 1390 1267 { .compatible = "techstar,ts8550b", .data = &ts8550b_desc }, 1268 + { .compatible = "winstar,wf40eswaa6mnn0", .data = &wf40eswaa6mnn0_desc }, 1391 1269 { } 1392 1270 }; 1393 1271 MODULE_DEVICE_TABLE(of, st7701_dsi_of_match);