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

Merge tag 'drm-misc-next-2024-07-04' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-next

drm-misc-next for $kernel-version:

UAPI Changes:

Cross-subsystem Changes:

Core Changes:
- dp/mst: Fix daisy-chaining at resume
- dsc: Add helper to dump the DSC configuration
- tests: Add tests for the new monochrome TV mode variant

Driver Changes:
- ast: Refactor the mode setting code
- panfrost: Fix devfreq job reporting
- stm: Add LDVS support, DSI PHY updates
- panels:
- New panel: AUO G104STN01, K&d kd101ne3-40ti,

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
From: Maxime Ripard <mripard@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240704-curvy-outstanding-lizard-bcea78@houat

+2605 -560
+1
Documentation/devicetree/bindings/display/panel/jadard,jd9365da-h3.yaml
··· 17 17 items: 18 18 - enum: 19 19 - chongzhou,cz101b4001 20 + - kingdisplay,kd101ne3-40ti 20 21 - radxa,display-10hd-ad001 21 22 - radxa,display-8hd-ad002 22 23 - const: jadard,jd9365da-h3
+2
Documentation/devicetree/bindings/display/panel/panel-simple.yaml
··· 51 51 - auo,g101evn010 52 52 # AU Optronics Corporation 10.4" (800x600) color TFT LCD panel 53 53 - auo,g104sn02 54 + # AU Optronics Corporation 10.4" (800x600) color TFT LCD panel 55 + - auo,g104stn01 54 56 # AU Optronics Corporation 12.1" (1280x800) TFT LCD panel 55 57 - auo,g121ean01 56 58 # AU Optronics Corporation 15.6" (1366x768) TFT LCD panel
+119
Documentation/devicetree/bindings/display/st,stm32mp25-lvds.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/display/st,stm32mp25-lvds.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: STMicroelectronics STM32 LVDS Display Interface Transmitter 8 + 9 + maintainers: 10 + - Raphael Gallais-Pou <raphael.gallais-pou@foss.st.com> 11 + - Yannick Fertre <yannick.fertre@foss.st.com> 12 + 13 + description: | 14 + The STMicroelectronics STM32 LVDS Display Interface Transmitter handles the 15 + LVDS protocol: it maps the pixels received from the upstream Pixel-DMA (LTDC) 16 + onto the LVDS PHY. 17 + 18 + It is composed of three sub blocks: 19 + - LVDS host: handles the LVDS protocol (FPD / OpenLDI) and maps its input 20 + pixels onto the data lanes of the PHY 21 + - LVDS PHY: parallelize the data and drives the LVDS data lanes 22 + - LVDS wrapper: handles top-level settings 23 + 24 + The LVDS controller driver supports the following high-level features: 25 + - FDP-Link-I and OpenLDI (v0.95) protocols 26 + - Single-Link or Dual-Link operation 27 + - Single-Display or Double-Display (with the same content duplicated on both) 28 + - Flexible Bit-Mapping, including JEIDA and VESA 29 + - RGB888 or RGB666 output 30 + - Synchronous design, with one input pixel per clock cycle 31 + 32 + properties: 33 + compatible: 34 + const: st,stm32mp25-lvds 35 + 36 + "#clock-cells": 37 + const: 0 38 + description: 39 + Provides the internal LVDS PHY clock to the framework. 40 + 41 + reg: 42 + maxItems: 1 43 + 44 + clocks: 45 + items: 46 + - description: APB peripheral clock 47 + - description: Reference clock for the internal PLL 48 + 49 + clock-names: 50 + items: 51 + - const: pclk 52 + - const: ref 53 + 54 + resets: 55 + maxItems: 1 56 + 57 + ports: 58 + $ref: /schemas/graph.yaml#/properties/ports 59 + 60 + properties: 61 + port@0: 62 + $ref: /schemas/graph.yaml#/properties/port 63 + description: 64 + LVDS input port node, connected to the LTDC RGB output port. 65 + 66 + port@1: 67 + $ref: /schemas/graph.yaml#/properties/port 68 + description: 69 + LVDS output port node, connected to a panel or bridge input port. 70 + 71 + required: 72 + - port@0 73 + - port@1 74 + 75 + required: 76 + - compatible 77 + - "#clock-cells" 78 + - reg 79 + - clocks 80 + - clock-names 81 + - resets 82 + - ports 83 + 84 + additionalProperties: false 85 + 86 + examples: 87 + - | 88 + #include <dt-bindings/clock/st,stm32mp25-rcc.h> 89 + #include <dt-bindings/reset/st,stm32mp25-rcc.h> 90 + 91 + lvds: lvds@48060000 { 92 + compatible = "st,stm32mp25-lvds"; 93 + reg = <0x48060000 0x2000>; 94 + #clock-cells = <0>; 95 + clocks = <&rcc CK_BUS_LVDS>, <&rcc CK_KER_LVDSPHY>; 96 + clock-names = "pclk", "ref"; 97 + resets = <&rcc LVDS_R>; 98 + 99 + ports { 100 + #address-cells = <1>; 101 + #size-cells = <0>; 102 + 103 + port@0 { 104 + reg = <0>; 105 + lvds_in: endpoint { 106 + remote-endpoint = <&ltdc_ep1_out>; 107 + }; 108 + }; 109 + 110 + port@1 { 111 + reg = <1>; 112 + lvds_out0: endpoint { 113 + remote-endpoint = <&lvds_panel_in>; 114 + }; 115 + }; 116 + }; 117 + }; 118 + 119 + ...
+1
MAINTAINERS
··· 7484 7484 S: Maintained 7485 7485 T: git https://gitlab.freedesktop.org/drm/misc/kernel.git 7486 7486 F: Documentation/devicetree/bindings/display/st,stm32-ltdc.yaml 7487 + F: Documentation/devicetree/bindings/display/st,stm32mp25-lvds.yaml 7487 7488 F: drivers/gpu/drm/stm 7488 7489 7489 7490 DRM DRIVERS FOR TI KEYSTONE
+109 -95
drivers/gpu/drm/ast/ast_mode.c
··· 303 303 304 304 /* Set SEQ; except Screen Disable field */ 305 305 ast_set_index_reg(ast, AST_IO_VGASRI, 0x00, 0x03); 306 - ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, stdtable->seq[0]); 306 + ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0x20, stdtable->seq[0]); 307 307 for (i = 1; i < 4; i++) { 308 308 jreg = stdtable->seq[i]; 309 309 ast_set_index_reg(ast, AST_IO_VGASRI, (i + 1), jreg); ··· 649 649 struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane); 650 650 struct drm_framebuffer *old_fb = old_plane_state->fb; 651 651 struct ast_plane *ast_plane = to_ast_plane(plane); 652 + struct drm_crtc *crtc = plane_state->crtc; 653 + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); 652 654 struct drm_rect damage; 653 655 struct drm_atomic_helper_damage_iter iter; 654 656 655 - if (!old_fb || (fb->format != old_fb->format)) { 656 - struct drm_crtc *crtc = plane_state->crtc; 657 - struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); 657 + if (!old_fb || (fb->format != old_fb->format) || crtc_state->mode_changed) { 658 658 struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state); 659 659 struct ast_vbios_mode_info *vbios_mode_info = &ast_crtc_state->vbios_mode_info; 660 660 ··· 690 690 * Therefore only reprogram the address after enabling the plane. 691 691 */ 692 692 ast_set_start_address_crt1(ast, (u32)ast_plane->offset); 693 - ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x1, 0xdf, 0x00); 694 693 } 695 694 696 695 static void ast_primary_plane_helper_atomic_disable(struct drm_plane *plane, 697 696 struct drm_atomic_state *state) 698 697 { 699 - struct ast_device *ast = to_ast_device(plane->dev); 700 - 701 - ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x1, 0xdf, 0x20); 698 + /* 699 + * Keep this empty function to avoid calling 700 + * atomic_update when disabling the plane. 701 + */ 702 702 } 703 703 704 704 static int ast_primary_plane_helper_get_scanout_buffer(struct drm_plane *plane, ··· 1019 1019 * CRTC 1020 1020 */ 1021 1021 1022 - static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) 1023 - { 1024 - struct ast_device *ast = to_ast_device(crtc->dev); 1025 - u8 ch = AST_DPMS_VSYNC_OFF | AST_DPMS_HSYNC_OFF; 1026 - struct ast_crtc_state *ast_state; 1027 - const struct drm_format_info *format; 1028 - struct ast_vbios_mode_info *vbios_mode_info; 1029 - 1030 - /* TODO: Maybe control display signal generation with 1031 - * Sync Enable (bit CR17.7). 1032 - */ 1033 - switch (mode) { 1034 - case DRM_MODE_DPMS_ON: 1035 - ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, 0); 1036 - ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xfc, 0); 1037 - if (ast->tx_chip_types & AST_TX_DP501_BIT) 1038 - ast_set_dp501_video_output(crtc->dev, 1); 1039 - 1040 - if (ast->tx_chip_types & AST_TX_ASTDP_BIT) { 1041 - ast_dp_power_on_off(crtc->dev, AST_DP_POWER_ON); 1042 - ast_wait_for_vretrace(ast); 1043 - ast_dp_set_on_off(crtc->dev, 1); 1044 - } 1045 - 1046 - ast_state = to_ast_crtc_state(crtc->state); 1047 - format = ast_state->format; 1048 - 1049 - if (format) { 1050 - vbios_mode_info = &ast_state->vbios_mode_info; 1051 - 1052 - ast_set_color_reg(ast, format); 1053 - ast_set_vbios_color_reg(ast, format, vbios_mode_info); 1054 - if (crtc->state->gamma_lut) 1055 - ast_crtc_set_gamma(ast, format, crtc->state->gamma_lut->data); 1056 - else 1057 - ast_crtc_set_gamma_linear(ast, format); 1058 - } 1059 - break; 1060 - case DRM_MODE_DPMS_STANDBY: 1061 - case DRM_MODE_DPMS_SUSPEND: 1062 - case DRM_MODE_DPMS_OFF: 1063 - ch = mode; 1064 - if (ast->tx_chip_types & AST_TX_DP501_BIT) 1065 - ast_set_dp501_video_output(crtc->dev, 0); 1066 - 1067 - if (ast->tx_chip_types & AST_TX_ASTDP_BIT) { 1068 - ast_dp_set_on_off(crtc->dev, 0); 1069 - ast_dp_power_on_off(crtc->dev, AST_DP_POWER_OFF); 1070 - } 1071 - 1072 - ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, 0x20); 1073 - ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xfc, ch); 1074 - break; 1075 - } 1076 - } 1077 - 1078 1022 static enum drm_mode_status 1079 1023 ast_crtc_helper_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode) 1080 1024 { ··· 1091 1147 return status; 1092 1148 } 1093 1149 1150 + static void ast_crtc_helper_mode_set_nofb(struct drm_crtc *crtc) 1151 + { 1152 + struct drm_device *dev = crtc->dev; 1153 + struct ast_device *ast = to_ast_device(dev); 1154 + struct drm_crtc_state *crtc_state = crtc->state; 1155 + struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state); 1156 + struct ast_vbios_mode_info *vbios_mode_info = 1157 + &ast_crtc_state->vbios_mode_info; 1158 + struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode; 1159 + 1160 + /* 1161 + * Ensure that no scanout takes place before reprogramming mode 1162 + * and format registers. 1163 + * 1164 + * TODO: Get vblank interrupts working and remove this line. 1165 + */ 1166 + ast_wait_for_vretrace(ast); 1167 + 1168 + ast_set_vbios_mode_reg(ast, adjusted_mode, vbios_mode_info); 1169 + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa1, 0x06); 1170 + ast_set_std_reg(ast, adjusted_mode, vbios_mode_info); 1171 + ast_set_crtc_reg(ast, adjusted_mode, vbios_mode_info); 1172 + ast_set_dclk_reg(ast, adjusted_mode, vbios_mode_info); 1173 + ast_set_crtthd_reg(ast); 1174 + ast_set_sync_reg(ast, adjusted_mode, vbios_mode_info); 1175 + } 1176 + 1094 1177 static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc, 1095 1178 struct drm_atomic_state *state) 1096 1179 { ··· 1177 1206 struct drm_device *dev = crtc->dev; 1178 1207 struct ast_device *ast = to_ast_device(dev); 1179 1208 struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state); 1180 - struct ast_vbios_mode_info *vbios_mode_info = &ast_crtc_state->vbios_mode_info; 1181 1209 1182 1210 /* 1183 1211 * The gamma LUT has to be reloaded after changing the primary ··· 1190 1220 else 1191 1221 ast_crtc_set_gamma_linear(ast, ast_crtc_state->format); 1192 1222 } 1193 - 1194 - //Set Aspeed Display-Port 1195 - if (ast->tx_chip_types & AST_TX_ASTDP_BIT) 1196 - ast_dp_set_mode(crtc, vbios_mode_info); 1197 1223 } 1198 1224 1199 1225 static void ast_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state) 1200 1226 { 1201 - struct drm_device *dev = crtc->dev; 1202 - struct ast_device *ast = to_ast_device(dev); 1203 - struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); 1204 - struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state); 1205 - struct ast_vbios_mode_info *vbios_mode_info = 1206 - &ast_crtc_state->vbios_mode_info; 1207 - struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode; 1227 + struct ast_device *ast = to_ast_device(crtc->dev); 1208 1228 1209 - ast_set_vbios_mode_reg(ast, adjusted_mode, vbios_mode_info); 1210 - ast_set_index_reg(ast, AST_IO_VGACRI, 0xa1, 0x06); 1211 - ast_set_std_reg(ast, adjusted_mode, vbios_mode_info); 1212 - ast_set_crtc_reg(ast, adjusted_mode, vbios_mode_info); 1213 - ast_set_dclk_reg(ast, adjusted_mode, vbios_mode_info); 1214 - ast_set_crtthd_reg(ast); 1215 - ast_set_sync_reg(ast, adjusted_mode, vbios_mode_info); 1216 - 1217 - ast_crtc_dpms(crtc, DRM_MODE_DPMS_ON); 1229 + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xfc, 0x00); 1230 + ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, 0x00); 1218 1231 } 1219 1232 1220 1233 static void ast_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *state) 1221 1234 { 1222 1235 struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc); 1223 - struct drm_device *dev = crtc->dev; 1224 - struct ast_device *ast = to_ast_device(dev); 1236 + struct ast_device *ast = to_ast_device(crtc->dev); 1237 + u8 vgacrb6; 1225 1238 1226 - ast_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); 1239 + ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, AST_IO_VGASR1_SD); 1240 + 1241 + vgacrb6 = AST_IO_VGACRB6_VSYNC_OFF | 1242 + AST_IO_VGACRB6_HSYNC_OFF; 1243 + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xfc, vgacrb6); 1227 1244 1228 1245 /* 1229 1246 * HW cursors require the underlying primary plane and CRTC to ··· 1223 1266 * simple pageflips on the planes. 1224 1267 */ 1225 1268 drm_atomic_helper_disable_planes_on_crtc(old_crtc_state, false); 1226 - 1227 - /* 1228 - * Ensure that no scanout takes place before reprogramming mode 1229 - * and format registers. 1230 - */ 1231 - ast_wait_for_vretrace(ast); 1232 1269 } 1233 1270 1234 1271 static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = { 1235 1272 .mode_valid = ast_crtc_helper_mode_valid, 1273 + .mode_set_nofb = ast_crtc_helper_mode_set_nofb, 1236 1274 .atomic_check = ast_crtc_helper_atomic_check, 1237 1275 .atomic_flush = ast_crtc_helper_atomic_flush, 1238 1276 .atomic_enable = ast_crtc_helper_atomic_enable, ··· 1473 1521 .destroy = drm_encoder_cleanup, 1474 1522 }; 1475 1523 1524 + static void ast_dp501_encoder_helper_atomic_enable(struct drm_encoder *encoder, 1525 + struct drm_atomic_state *state) 1526 + { 1527 + struct drm_device *dev = encoder->dev; 1528 + 1529 + ast_set_dp501_video_output(dev, 1); 1530 + } 1531 + 1532 + static void ast_dp501_encoder_helper_atomic_disable(struct drm_encoder *encoder, 1533 + struct drm_atomic_state *state) 1534 + { 1535 + struct drm_device *dev = encoder->dev; 1536 + 1537 + ast_set_dp501_video_output(dev, 0); 1538 + } 1539 + 1540 + static const struct drm_encoder_helper_funcs ast_dp501_encoder_helper_funcs = { 1541 + .atomic_enable = ast_dp501_encoder_helper_atomic_enable, 1542 + .atomic_disable = ast_dp501_encoder_helper_atomic_disable, 1543 + }; 1544 + 1476 1545 /* 1477 1546 * DP501 Connector 1478 1547 */ ··· 1580 1607 DRM_MODE_ENCODER_TMDS, NULL); 1581 1608 if (ret) 1582 1609 return ret; 1610 + drm_encoder_helper_add(encoder, &ast_dp501_encoder_helper_funcs); 1611 + 1583 1612 encoder->possible_crtcs = drm_crtc_mask(crtc); 1584 1613 1585 1614 ret = ast_dp501_connector_init(dev, connector); ··· 1601 1626 1602 1627 static const struct drm_encoder_funcs ast_astdp_encoder_funcs = { 1603 1628 .destroy = drm_encoder_cleanup, 1629 + }; 1630 + 1631 + static void ast_astdp_encoder_helper_atomic_mode_set(struct drm_encoder *encoder, 1632 + struct drm_crtc_state *crtc_state, 1633 + struct drm_connector_state *conn_state) 1634 + { 1635 + struct drm_crtc *crtc = crtc_state->crtc; 1636 + struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state); 1637 + struct ast_vbios_mode_info *vbios_mode_info = &ast_crtc_state->vbios_mode_info; 1638 + 1639 + ast_dp_set_mode(crtc, vbios_mode_info); 1640 + } 1641 + 1642 + static void ast_astdp_encoder_helper_atomic_enable(struct drm_encoder *encoder, 1643 + struct drm_atomic_state *state) 1644 + { 1645 + struct drm_device *dev = encoder->dev; 1646 + struct ast_device *ast = to_ast_device(dev); 1647 + 1648 + ast_dp_power_on_off(dev, AST_DP_POWER_ON); 1649 + ast_wait_for_vretrace(ast); 1650 + ast_dp_set_on_off(dev, 1); 1651 + } 1652 + 1653 + static void ast_astdp_encoder_helper_atomic_disable(struct drm_encoder *encoder, 1654 + struct drm_atomic_state *state) 1655 + { 1656 + struct drm_device *dev = encoder->dev; 1657 + 1658 + ast_dp_set_on_off(dev, 0); 1659 + ast_dp_power_on_off(dev, AST_DP_POWER_OFF); 1660 + } 1661 + 1662 + static const struct drm_encoder_helper_funcs ast_astdp_encoder_helper_funcs = { 1663 + .atomic_mode_set = ast_astdp_encoder_helper_atomic_mode_set, 1664 + .atomic_enable = ast_astdp_encoder_helper_atomic_enable, 1665 + .atomic_disable = ast_astdp_encoder_helper_atomic_disable, 1604 1666 }; 1605 1667 1606 1668 /* ··· 1738 1726 DRM_MODE_ENCODER_TMDS, NULL); 1739 1727 if (ret) 1740 1728 return ret; 1729 + drm_encoder_helper_add(encoder, &ast_astdp_encoder_helper_funcs); 1730 + 1741 1731 encoder->possible_crtcs = drm_crtc_mask(crtc); 1742 1732 1743 1733 ret = ast_astdp_connector_init(dev, connector); ··· 1865 1851 * the I/O-register lock. Released in atomic_flush(). 1866 1852 */ 1867 1853 mutex_lock(&ast->modeset_lock); 1868 - drm_atomic_helper_commit_tail_rpm(state); 1854 + drm_atomic_helper_commit_tail(state); 1869 1855 mutex_unlock(&ast->modeset_lock); 1870 1856 } 1871 1857
+3 -7
drivers/gpu/drm/ast/ast_reg.h
··· 22 22 #define AST_IO_VGAER_VGA_ENABLE BIT(0) 23 23 24 24 #define AST_IO_VGASRI (0x44) 25 + #define AST_IO_VGASR1_SD BIT(5) 25 26 #define AST_IO_VGADRR (0x47) 26 27 #define AST_IO_VGADWR (0x48) 27 28 #define AST_IO_VGAPDR (0x49) ··· 32 31 #define AST_IO_VGACR80_PASSWORD (0xa8) 33 32 #define AST_IO_VGACRA1_VGAIO_DISABLED BIT(1) 34 33 #define AST_IO_VGACRA1_MMIO_ENABLED BIT(2) 34 + #define AST_IO_VGACRB6_HSYNC_OFF BIT(0) 35 + #define AST_IO_VGACRB6_VSYNC_OFF BIT(1) 35 36 #define AST_IO_VGACRCB_HWC_16BPP BIT(0) /* set: ARGB4444, cleared: 2bpp palette */ 36 37 #define AST_IO_VGACRCB_HWC_ENABLED BIT(1) 37 38 ··· 77 74 #define ASTDP_HPD BIT(0) 78 75 #define ASTDP_HOST_EDID_READ_DONE BIT(0) 79 76 #define ASTDP_HOST_EDID_READ_DONE_MASK GENMASK(0, 0) 80 - 81 - /* 82 - * CRB8[b1]: Enable VSYNC off 83 - * CRB8[b0]: Enable HSYNC off 84 - */ 85 - #define AST_DPMS_VSYNC_OFF BIT(1) 86 - #define AST_DPMS_HSYNC_OFF BIT(0) 87 77 88 78 /* 89 79 * CRDF[b4]: Mirror of AST_DP_VIDEO_ENABLE
+3 -2
drivers/gpu/drm/display/drm_dp_helper.c
··· 35 35 #include <drm/display/drm_dp_helper.h> 36 36 #include <drm/display/drm_dp_mst_helper.h> 37 37 #include <drm/drm_edid.h> 38 + #include <drm/drm_fixed.h> 38 39 #include <drm/drm_print.h> 39 40 #include <drm/drm_vblank.h> 40 41 #include <drm/drm_panel.h> ··· 4152 4151 int symbol_cycles; 4153 4152 4154 4153 if (lane_count == 0 || hactive == 0 || bpp_x16 == 0) { 4155 - DRM_DEBUG_KMS("Invalid BW overhead params: lane_count %d, hactive %d, bpp_x16 %d.%04d\n", 4154 + DRM_DEBUG_KMS("Invalid BW overhead params: lane_count %d, hactive %d, bpp_x16 " FXP_Q4_FMT "\n", 4156 4155 lane_count, hactive, 4157 - bpp_x16 >> 4, (bpp_x16 & 0xf) * 625); 4156 + FXP_Q4_ARGS(bpp_x16)); 4158 4157 return 0; 4159 4158 } 4160 4159
+13 -2
drivers/gpu/drm/display/drm_dp_mst_topology.c
··· 2929 2929 2930 2930 /* FIXME: Actually do some real error handling here */ 2931 2931 ret = drm_dp_mst_wait_tx_reply(mstb, txmsg); 2932 - if (ret <= 0) { 2932 + if (ret < 0) { 2933 2933 drm_err(mgr->dev, "Sending link address failed with %d\n", ret); 2934 2934 goto out; 2935 2935 } ··· 2981 2981 mutex_unlock(&mgr->lock); 2982 2982 2983 2983 out: 2984 - if (ret <= 0) 2984 + if (ret < 0) 2985 2985 mstb->link_address_sent = false; 2986 2986 kfree(txmsg); 2987 2987 return ret < 0 ? ret : changed; ··· 4069 4069 if (up_req->msg.req_type == DP_CONNECTION_STATUS_NOTIFY) { 4070 4070 const struct drm_dp_connection_status_notify *conn_stat = 4071 4071 &up_req->msg.u.conn_stat; 4072 + bool handle_csn; 4072 4073 4073 4074 drm_dbg_kms(mgr->dev, "Got CSN: pn: %d ldps:%d ddps: %d mcs: %d ip: %d pdt: %d\n", 4074 4075 conn_stat->port_number, ··· 4078 4077 conn_stat->message_capability_status, 4079 4078 conn_stat->input_port, 4080 4079 conn_stat->peer_device_type); 4080 + 4081 + mutex_lock(&mgr->probe_lock); 4082 + handle_csn = mgr->mst_primary->link_address_sent; 4083 + mutex_unlock(&mgr->probe_lock); 4084 + 4085 + if (!handle_csn) { 4086 + drm_dbg_kms(mgr->dev, "Got CSN before finish topology probing. Skip it."); 4087 + kfree(up_req); 4088 + goto out; 4089 + } 4081 4090 } else if (up_req->msg.req_type == DP_RESOURCE_STATUS_NOTIFY) { 4082 4091 const struct drm_dp_resource_status_notify *res_stat = 4083 4092 &up_req->msg.u.resource_stat;
+91
drivers/gpu/drm/display/drm_dsc_helper.c
··· 14 14 15 15 #include <drm/display/drm_dp_helper.h> 16 16 #include <drm/display/drm_dsc_helper.h> 17 + #include <drm/drm_fixed.h> 17 18 #include <drm/drm_print.h> 18 19 19 20 /** ··· 1473 1472 return 2 << (dsc->bits_per_component - 8); 1474 1473 } 1475 1474 EXPORT_SYMBOL(drm_dsc_flatness_det_thresh); 1475 + 1476 + static void drm_dsc_dump_config_main_params(struct drm_printer *p, int indent, 1477 + const struct drm_dsc_config *cfg) 1478 + { 1479 + drm_printf_indent(p, indent, 1480 + "dsc-cfg: version: %d.%d, picture: w=%d, h=%d, slice: count=%d, w=%d, h=%d, size=%d\n", 1481 + cfg->dsc_version_major, cfg->dsc_version_minor, 1482 + cfg->pic_width, cfg->pic_height, 1483 + cfg->slice_count, cfg->slice_width, cfg->slice_height, cfg->slice_chunk_size); 1484 + drm_printf_indent(p, indent, 1485 + "dsc-cfg: mode: block-pred=%s, vbr=%s, rgb=%s, simple-422=%s, native-422=%s, native-420=%s\n", 1486 + str_yes_no(cfg->block_pred_enable), str_yes_no(cfg->vbr_enable), 1487 + str_yes_no(cfg->convert_rgb), 1488 + str_yes_no(cfg->simple_422), str_yes_no(cfg->native_422), str_yes_no(cfg->native_420)); 1489 + drm_printf_indent(p, indent, 1490 + "dsc-cfg: color-depth: uncompressed-bpc=%d, compressed-bpp=" FXP_Q4_FMT " line-buf-bpp=%d\n", 1491 + cfg->bits_per_component, FXP_Q4_ARGS(cfg->bits_per_pixel), cfg->line_buf_depth); 1492 + drm_printf_indent(p, indent, 1493 + "dsc-cfg: rc-model: size=%d, bits=%d, mux-word-size: %d, initial-delays: xmit=%d, dec=%d\n", 1494 + cfg->rc_model_size, cfg->rc_bits, cfg->mux_word_size, 1495 + cfg->initial_xmit_delay, cfg->initial_dec_delay); 1496 + drm_printf_indent(p, indent, 1497 + "dsc-cfg: offsets: initial=%d, final=%d, slice-bpg=%d\n", 1498 + cfg->initial_offset, cfg->final_offset, cfg->slice_bpg_offset); 1499 + drm_printf_indent(p, indent, 1500 + "dsc-cfg: line-bpg-offsets: first=%d, non-first=%d, second=%d, non-second=%d, second-adj=%d\n", 1501 + cfg->first_line_bpg_offset, cfg->nfl_bpg_offset, 1502 + cfg->second_line_bpg_offset, cfg->nsl_bpg_offset, cfg->second_line_offset_adj); 1503 + drm_printf_indent(p, indent, 1504 + "dsc-cfg: rc-tgt-offsets: low=%d, high=%d, rc-edge-factor: %d, rc-quant-incr-limits: [0]=%d, [1]=%d\n", 1505 + cfg->rc_tgt_offset_low, cfg->rc_tgt_offset_high, 1506 + cfg->rc_edge_factor, cfg->rc_quant_incr_limit0, cfg->rc_quant_incr_limit1); 1507 + drm_printf_indent(p, indent, 1508 + "dsc-cfg: initial-scale: %d, scale-intervals: increment=%d, decrement=%d\n", 1509 + cfg->initial_scale_value, cfg->scale_increment_interval, cfg->scale_decrement_interval); 1510 + drm_printf_indent(p, indent, 1511 + "dsc-cfg: flatness: min-qp=%d, max-qp=%d\n", 1512 + cfg->flatness_min_qp, cfg->flatness_max_qp); 1513 + } 1514 + 1515 + static void drm_dsc_dump_config_rc_params(struct drm_printer *p, int indent, 1516 + const struct drm_dsc_config *cfg) 1517 + { 1518 + const u16 *bt = cfg->rc_buf_thresh; 1519 + const struct drm_dsc_rc_range_parameters *rp = cfg->rc_range_params; 1520 + 1521 + BUILD_BUG_ON(ARRAY_SIZE(cfg->rc_buf_thresh) != 14); 1522 + BUILD_BUG_ON(ARRAY_SIZE(cfg->rc_range_params) != 15); 1523 + 1524 + drm_printf_indent(p, indent, 1525 + "dsc-cfg: rc-level: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14\n"); 1526 + drm_printf_indent(p, indent, 1527 + "dsc-cfg: rc-buf-thresh: %3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d\n", 1528 + bt[0], bt[1], bt[2], bt[3], bt[4], bt[5], bt[6], bt[7], 1529 + bt[8], bt[9], bt[10], bt[11], bt[12], bt[13]); 1530 + drm_printf_indent(p, indent, 1531 + "dsc-cfg: rc-min-qp: %3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d\n", 1532 + rp[0].range_min_qp, rp[1].range_min_qp, rp[2].range_min_qp, rp[3].range_min_qp, 1533 + rp[4].range_min_qp, rp[5].range_min_qp, rp[6].range_min_qp, rp[7].range_min_qp, 1534 + rp[8].range_min_qp, rp[9].range_min_qp, rp[10].range_min_qp, rp[11].range_min_qp, 1535 + rp[12].range_min_qp, rp[13].range_min_qp, rp[14].range_min_qp); 1536 + drm_printf_indent(p, indent, 1537 + "dsc-cfg: rc-max-qp: %3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d\n", 1538 + rp[0].range_max_qp, rp[1].range_max_qp, rp[2].range_max_qp, rp[3].range_max_qp, 1539 + rp[4].range_max_qp, rp[5].range_max_qp, rp[6].range_max_qp, rp[7].range_max_qp, 1540 + rp[8].range_max_qp, rp[9].range_max_qp, rp[10].range_max_qp, rp[11].range_max_qp, 1541 + rp[12].range_max_qp, rp[13].range_max_qp, rp[14].range_max_qp); 1542 + drm_printf_indent(p, indent, 1543 + "dsc-cfg: rc-bpg-offset: %3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d\n", 1544 + rp[0].range_bpg_offset, rp[1].range_bpg_offset, rp[2].range_bpg_offset, rp[3].range_bpg_offset, 1545 + rp[4].range_bpg_offset, rp[5].range_bpg_offset, rp[6].range_bpg_offset, rp[7].range_bpg_offset, 1546 + rp[8].range_bpg_offset, rp[9].range_bpg_offset, rp[10].range_bpg_offset, rp[11].range_bpg_offset, 1547 + rp[12].range_bpg_offset, rp[13].range_bpg_offset, rp[14].range_bpg_offset); 1548 + } 1549 + 1550 + /** 1551 + * drm_dsc_dump_config - Dump the provided DSC configuration 1552 + * @p: The printer used for output 1553 + * @indent: Tab indentation level (max 5) 1554 + * @cfg: DSC configuration to print 1555 + * 1556 + * Print the provided DSC configuration in @cfg. 1557 + */ 1558 + void drm_dsc_dump_config(struct drm_printer *p, int indent, 1559 + const struct drm_dsc_config *cfg) 1560 + { 1561 + drm_dsc_dump_config_main_params(p, indent, cfg); 1562 + drm_dsc_dump_config_rc_params(p, indent, cfg); 1563 + } 1564 + EXPORT_SYMBOL(drm_dsc_dump_config);
+1 -1
drivers/gpu/drm/drm_managed.c
··· 197 197 spin_lock_irqsave(&dev->managed.lock, flags); 198 198 list_for_each_entry_reverse(dr, &dev->managed.resources, node.entry) { 199 199 if (dr->node.release == action) { 200 - if (!data || (data && *(void **)dr->data == data)) { 200 + if (!data || *(void **)dr->data == data) { 201 201 dr_match = dr; 202 202 del_dr(dev, dr_match); 203 203 break;
+1
drivers/gpu/drm/lima/lima_drv.c
··· 501 501 MODULE_AUTHOR("Lima Project Developers"); 502 502 MODULE_DESCRIPTION("Lima DRM Driver"); 503 503 MODULE_LICENSE("GPL v2"); 504 + MODULE_SOFTDEP("pre: governor_simpleondemand");
+3 -3
drivers/gpu/drm/mgag200/mgag200_mode.c
··· 111 111 unsigned int status = 0; 112 112 113 113 do { 114 - status = RREG32(MGAREG_Status); 114 + status = RREG32(MGAREG_STATUS); 115 115 } while ((status & 0x08) && time_before(jiffies, timeout)); 116 116 timeout = jiffies + HZ/10; 117 117 status = 0; 118 118 do { 119 - status = RREG32(MGAREG_Status); 119 + status = RREG32(MGAREG_STATUS); 120 120 } while (!(status & 0x08) && time_before(jiffies, timeout)); 121 121 } 122 122 ··· 125 125 unsigned long timeout = jiffies + HZ; 126 126 unsigned int status = 0; 127 127 do { 128 - status = RREG8(MGAREG_Status + 2); 128 + status = RREG8(MGAREG_STATUS + 2); 129 129 } while ((status & 0x01) && time_before(jiffies, timeout)); 130 130 } 131 131
+1 -1
drivers/gpu/drm/mgag200/mgag200_reg.h
··· 102 102 #define MGAREG_EXEC 0x0100 103 103 104 104 #define MGAREG_FIFOSTATUS 0x1e10 105 - #define MGAREG_Status 0x1e14 105 + #define MGAREG_STATUS 0x1e14 106 106 #define MGAREG_CACHEFLUSH 0x1fff 107 107 #define MGAREG_ICLEAR 0x1e18 108 108 #define MGAREG_IEN 0x1e1c
+682 -408
drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c
··· 19 19 #include <linux/of.h> 20 20 #include <linux/regulator/consumer.h> 21 21 22 - #define JD9365DA_INIT_CMD_LEN 2 23 - 24 - struct jadard_init_cmd { 25 - u8 data[JD9365DA_INIT_CMD_LEN]; 26 - }; 22 + struct jadard; 27 23 28 24 struct jadard_panel_desc { 29 25 const struct drm_display_mode mode; 30 26 unsigned int lanes; 31 27 enum mipi_dsi_pixel_format format; 32 - const struct jadard_init_cmd *init_cmds; 28 + int (*init)(struct jadard *jadard); 33 29 u32 num_init_cmds; 30 + bool lp11_before_reset; 31 + bool reset_before_power_off_vcioo; 32 + unsigned int vcioo_to_lp11_delay_ms; 33 + unsigned int lp11_to_reset_delay_ms; 34 + unsigned int exit_sleep_to_display_on_delay_ms; 35 + unsigned int display_on_delay_ms; 36 + unsigned int backlight_off_to_display_off_delay_ms; 37 + unsigned int display_off_to_enter_sleep_delay_ms; 38 + unsigned int enter_sleep_to_reset_down_delay_ms; 34 39 }; 35 40 36 41 struct jadard { 37 42 struct drm_panel panel; 38 43 struct mipi_dsi_device *dsi; 39 44 const struct jadard_panel_desc *desc; 40 - 45 + enum drm_panel_orientation orientation; 41 46 struct regulator *vdd; 42 47 struct regulator *vccio; 43 48 struct gpio_desc *reset; ··· 55 50 56 51 static int jadard_enable(struct drm_panel *panel) 57 52 { 58 - struct device *dev = panel->dev; 59 53 struct jadard *jadard = panel_to_jadard(panel); 60 - const struct jadard_panel_desc *desc = jadard->desc; 61 - struct mipi_dsi_device *dsi = jadard->dsi; 62 - unsigned int i; 63 - int err; 64 - 65 - msleep(10); 66 - 67 - for (i = 0; i < desc->num_init_cmds; i++) { 68 - const struct jadard_init_cmd *cmd = &desc->init_cmds[i]; 69 - 70 - err = mipi_dsi_dcs_write_buffer(dsi, cmd->data, JD9365DA_INIT_CMD_LEN); 71 - if (err < 0) 72 - return err; 73 - } 54 + struct mipi_dsi_multi_context dsi_ctx = { .dsi = jadard->dsi }; 74 55 75 56 msleep(120); 76 57 77 - err = mipi_dsi_dcs_exit_sleep_mode(dsi); 78 - if (err < 0) 79 - DRM_DEV_ERROR(dev, "failed to exit sleep mode ret = %d\n", err); 58 + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); 80 59 81 - err = mipi_dsi_dcs_set_display_on(dsi); 82 - if (err < 0) 83 - DRM_DEV_ERROR(dev, "failed to set display on ret = %d\n", err); 60 + if (jadard->desc->exit_sleep_to_display_on_delay_ms) 61 + mipi_dsi_msleep(&dsi_ctx, jadard->desc->exit_sleep_to_display_on_delay_ms); 84 62 85 - return 0; 63 + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); 64 + 65 + if (jadard->desc->display_on_delay_ms) 66 + mipi_dsi_msleep(&dsi_ctx, jadard->desc->display_on_delay_ms); 67 + 68 + return dsi_ctx.accum_err; 86 69 } 87 70 88 71 static int jadard_disable(struct drm_panel *panel) 89 72 { 90 - struct device *dev = panel->dev; 91 73 struct jadard *jadard = panel_to_jadard(panel); 92 - int ret; 74 + struct mipi_dsi_multi_context dsi_ctx = { .dsi = jadard->dsi }; 93 75 94 - ret = mipi_dsi_dcs_set_display_off(jadard->dsi); 95 - if (ret < 0) 96 - DRM_DEV_ERROR(dev, "failed to set display off: %d\n", ret); 76 + if (jadard->desc->backlight_off_to_display_off_delay_ms) 77 + mipi_dsi_msleep(&dsi_ctx, jadard->desc->backlight_off_to_display_off_delay_ms); 97 78 98 - ret = mipi_dsi_dcs_enter_sleep_mode(jadard->dsi); 99 - if (ret < 0) 100 - DRM_DEV_ERROR(dev, "failed to enter sleep mode: %d\n", ret); 79 + mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); 101 80 102 - return 0; 81 + if (jadard->desc->display_off_to_enter_sleep_delay_ms) 82 + mipi_dsi_msleep(&dsi_ctx, jadard->desc->display_off_to_enter_sleep_delay_ms); 83 + 84 + mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx); 85 + 86 + if (jadard->desc->enter_sleep_to_reset_down_delay_ms) 87 + mipi_dsi_msleep(&dsi_ctx, jadard->desc->enter_sleep_to_reset_down_delay_ms); 88 + 89 + return dsi_ctx.accum_err; 103 90 } 104 91 105 92 static int jadard_prepare(struct drm_panel *panel) ··· 107 110 if (ret) 108 111 return ret; 109 112 113 + if (jadard->desc->vcioo_to_lp11_delay_ms) 114 + msleep(jadard->desc->vcioo_to_lp11_delay_ms); 115 + 116 + if (jadard->desc->lp11_before_reset) { 117 + ret = mipi_dsi_dcs_nop(jadard->dsi); 118 + if (ret) 119 + return ret; 120 + } 121 + 122 + if (jadard->desc->lp11_to_reset_delay_ms) 123 + msleep(jadard->desc->lp11_to_reset_delay_ms); 124 + 110 125 gpiod_set_value(jadard->reset, 1); 111 126 msleep(5); 112 127 ··· 126 117 msleep(10); 127 118 128 119 gpiod_set_value(jadard->reset, 1); 129 - msleep(120); 120 + msleep(130); 121 + 122 + ret = jadard->desc->init(jadard); 123 + if (ret) 124 + return ret; 130 125 131 126 return 0; 132 127 } ··· 141 128 142 129 gpiod_set_value(jadard->reset, 1); 143 130 msleep(120); 131 + 132 + if (jadard->desc->reset_before_power_off_vcioo) { 133 + gpiod_set_value(jadard->reset, 0); 134 + 135 + usleep_range(1000, 2000); 136 + } 144 137 145 138 regulator_disable(jadard->vdd); 146 139 regulator_disable(jadard->vccio); ··· 178 159 return 1; 179 160 } 180 161 162 + static enum drm_panel_orientation jadard_panel_get_orientation(struct drm_panel *panel) 163 + { 164 + struct jadard *jadard = panel_to_jadard(panel); 165 + 166 + return jadard->orientation; 167 + } 168 + 181 169 static const struct drm_panel_funcs jadard_funcs = { 182 170 .disable = jadard_disable, 183 171 .unprepare = jadard_unprepare, 184 172 .prepare = jadard_prepare, 185 173 .enable = jadard_enable, 186 174 .get_modes = jadard_get_modes, 175 + .get_orientation = jadard_panel_get_orientation, 187 176 }; 188 177 189 - static const struct jadard_init_cmd radxa_display_8hd_ad002_init_cmds[] = { 190 - { .data = { 0xE0, 0x00 } }, 191 - { .data = { 0xE1, 0x93 } }, 192 - { .data = { 0xE2, 0x65 } }, 193 - { .data = { 0xE3, 0xF8 } }, 194 - { .data = { 0x80, 0x03 } }, 195 - { .data = { 0xE0, 0x01 } }, 196 - { .data = { 0x00, 0x00 } }, 197 - { .data = { 0x01, 0x7E } }, 198 - { .data = { 0x03, 0x00 } }, 199 - { .data = { 0x04, 0x65 } }, 200 - { .data = { 0x0C, 0x74 } }, 201 - { .data = { 0x17, 0x00 } }, 202 - { .data = { 0x18, 0xB7 } }, 203 - { .data = { 0x19, 0x00 } }, 204 - { .data = { 0x1A, 0x00 } }, 205 - { .data = { 0x1B, 0xB7 } }, 206 - { .data = { 0x1C, 0x00 } }, 207 - { .data = { 0x24, 0xFE } }, 208 - { .data = { 0x37, 0x19 } }, 209 - { .data = { 0x38, 0x05 } }, 210 - { .data = { 0x39, 0x00 } }, 211 - { .data = { 0x3A, 0x01 } }, 212 - { .data = { 0x3B, 0x01 } }, 213 - { .data = { 0x3C, 0x70 } }, 214 - { .data = { 0x3D, 0xFF } }, 215 - { .data = { 0x3E, 0xFF } }, 216 - { .data = { 0x3F, 0xFF } }, 217 - { .data = { 0x40, 0x06 } }, 218 - { .data = { 0x41, 0xA0 } }, 219 - { .data = { 0x43, 0x1E } }, 220 - { .data = { 0x44, 0x0F } }, 221 - { .data = { 0x45, 0x28 } }, 222 - { .data = { 0x4B, 0x04 } }, 223 - { .data = { 0x55, 0x02 } }, 224 - { .data = { 0x56, 0x01 } }, 225 - { .data = { 0x57, 0xA9 } }, 226 - { .data = { 0x58, 0x0A } }, 227 - { .data = { 0x59, 0x0A } }, 228 - { .data = { 0x5A, 0x37 } }, 229 - { .data = { 0x5B, 0x19 } }, 230 - { .data = { 0x5D, 0x78 } }, 231 - { .data = { 0x5E, 0x63 } }, 232 - { .data = { 0x5F, 0x54 } }, 233 - { .data = { 0x60, 0x49 } }, 234 - { .data = { 0x61, 0x45 } }, 235 - { .data = { 0x62, 0x38 } }, 236 - { .data = { 0x63, 0x3D } }, 237 - { .data = { 0x64, 0x28 } }, 238 - { .data = { 0x65, 0x43 } }, 239 - { .data = { 0x66, 0x41 } }, 240 - { .data = { 0x67, 0x43 } }, 241 - { .data = { 0x68, 0x62 } }, 242 - { .data = { 0x69, 0x50 } }, 243 - { .data = { 0x6A, 0x57 } }, 244 - { .data = { 0x6B, 0x49 } }, 245 - { .data = { 0x6C, 0x44 } }, 246 - { .data = { 0x6D, 0x37 } }, 247 - { .data = { 0x6E, 0x23 } }, 248 - { .data = { 0x6F, 0x10 } }, 249 - { .data = { 0x70, 0x78 } }, 250 - { .data = { 0x71, 0x63 } }, 251 - { .data = { 0x72, 0x54 } }, 252 - { .data = { 0x73, 0x49 } }, 253 - { .data = { 0x74, 0x45 } }, 254 - { .data = { 0x75, 0x38 } }, 255 - { .data = { 0x76, 0x3D } }, 256 - { .data = { 0x77, 0x28 } }, 257 - { .data = { 0x78, 0x43 } }, 258 - { .data = { 0x79, 0x41 } }, 259 - { .data = { 0x7A, 0x43 } }, 260 - { .data = { 0x7B, 0x62 } }, 261 - { .data = { 0x7C, 0x50 } }, 262 - { .data = { 0x7D, 0x57 } }, 263 - { .data = { 0x7E, 0x49 } }, 264 - { .data = { 0x7F, 0x44 } }, 265 - { .data = { 0x80, 0x37 } }, 266 - { .data = { 0x81, 0x23 } }, 267 - { .data = { 0x82, 0x10 } }, 268 - { .data = { 0xE0, 0x02 } }, 269 - { .data = { 0x00, 0x47 } }, 270 - { .data = { 0x01, 0x47 } }, 271 - { .data = { 0x02, 0x45 } }, 272 - { .data = { 0x03, 0x45 } }, 273 - { .data = { 0x04, 0x4B } }, 274 - { .data = { 0x05, 0x4B } }, 275 - { .data = { 0x06, 0x49 } }, 276 - { .data = { 0x07, 0x49 } }, 277 - { .data = { 0x08, 0x41 } }, 278 - { .data = { 0x09, 0x1F } }, 279 - { .data = { 0x0A, 0x1F } }, 280 - { .data = { 0x0B, 0x1F } }, 281 - { .data = { 0x0C, 0x1F } }, 282 - { .data = { 0x0D, 0x1F } }, 283 - { .data = { 0x0E, 0x1F } }, 284 - { .data = { 0x0F, 0x5F } }, 285 - { .data = { 0x10, 0x5F } }, 286 - { .data = { 0x11, 0x57 } }, 287 - { .data = { 0x12, 0x77 } }, 288 - { .data = { 0x13, 0x35 } }, 289 - { .data = { 0x14, 0x1F } }, 290 - { .data = { 0x15, 0x1F } }, 291 - { .data = { 0x16, 0x46 } }, 292 - { .data = { 0x17, 0x46 } }, 293 - { .data = { 0x18, 0x44 } }, 294 - { .data = { 0x19, 0x44 } }, 295 - { .data = { 0x1A, 0x4A } }, 296 - { .data = { 0x1B, 0x4A } }, 297 - { .data = { 0x1C, 0x48 } }, 298 - { .data = { 0x1D, 0x48 } }, 299 - { .data = { 0x1E, 0x40 } }, 300 - { .data = { 0x1F, 0x1F } }, 301 - { .data = { 0x20, 0x1F } }, 302 - { .data = { 0x21, 0x1F } }, 303 - { .data = { 0x22, 0x1F } }, 304 - { .data = { 0x23, 0x1F } }, 305 - { .data = { 0x24, 0x1F } }, 306 - { .data = { 0x25, 0x5F } }, 307 - { .data = { 0x26, 0x5F } }, 308 - { .data = { 0x27, 0x57 } }, 309 - { .data = { 0x28, 0x77 } }, 310 - { .data = { 0x29, 0x35 } }, 311 - { .data = { 0x2A, 0x1F } }, 312 - { .data = { 0x2B, 0x1F } }, 313 - { .data = { 0x58, 0x40 } }, 314 - { .data = { 0x59, 0x00 } }, 315 - { .data = { 0x5A, 0x00 } }, 316 - { .data = { 0x5B, 0x10 } }, 317 - { .data = { 0x5C, 0x06 } }, 318 - { .data = { 0x5D, 0x40 } }, 319 - { .data = { 0x5E, 0x01 } }, 320 - { .data = { 0x5F, 0x02 } }, 321 - { .data = { 0x60, 0x30 } }, 322 - { .data = { 0x61, 0x01 } }, 323 - { .data = { 0x62, 0x02 } }, 324 - { .data = { 0x63, 0x03 } }, 325 - { .data = { 0x64, 0x6B } }, 326 - { .data = { 0x65, 0x05 } }, 327 - { .data = { 0x66, 0x0C } }, 328 - { .data = { 0x67, 0x73 } }, 329 - { .data = { 0x68, 0x09 } }, 330 - { .data = { 0x69, 0x03 } }, 331 - { .data = { 0x6A, 0x56 } }, 332 - { .data = { 0x6B, 0x08 } }, 333 - { .data = { 0x6C, 0x00 } }, 334 - { .data = { 0x6D, 0x04 } }, 335 - { .data = { 0x6E, 0x04 } }, 336 - { .data = { 0x6F, 0x88 } }, 337 - { .data = { 0x70, 0x00 } }, 338 - { .data = { 0x71, 0x00 } }, 339 - { .data = { 0x72, 0x06 } }, 340 - { .data = { 0x73, 0x7B } }, 341 - { .data = { 0x74, 0x00 } }, 342 - { .data = { 0x75, 0xF8 } }, 343 - { .data = { 0x76, 0x00 } }, 344 - { .data = { 0x77, 0xD5 } }, 345 - { .data = { 0x78, 0x2E } }, 346 - { .data = { 0x79, 0x12 } }, 347 - { .data = { 0x7A, 0x03 } }, 348 - { .data = { 0x7B, 0x00 } }, 349 - { .data = { 0x7C, 0x00 } }, 350 - { .data = { 0x7D, 0x03 } }, 351 - { .data = { 0x7E, 0x7B } }, 352 - { .data = { 0xE0, 0x04 } }, 353 - { .data = { 0x00, 0x0E } }, 354 - { .data = { 0x02, 0xB3 } }, 355 - { .data = { 0x09, 0x60 } }, 356 - { .data = { 0x0E, 0x2A } }, 357 - { .data = { 0x36, 0x59 } }, 358 - { .data = { 0xE0, 0x00 } }, 178 + static int radxa_display_8hd_ad002_init_cmds(struct jadard *jadard) 179 + { 180 + struct mipi_dsi_multi_context dsi_ctx = { .dsi = jadard->dsi }; 181 + 182 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xE0, 0x00); 183 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xE1, 0x93); 184 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xE2, 0x65); 185 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xE3, 0xF8); 186 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x80, 0x03); 187 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xE0, 0x01); 188 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x00); 189 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x01, 0x7E); 190 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x03, 0x00); 191 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x04, 0x65); 192 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0C, 0x74); 193 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x17, 0x00); 194 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x18, 0xB7); 195 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x19, 0x00); 196 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1A, 0x00); 197 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1B, 0xB7); 198 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1C, 0x00); 199 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x24, 0xFE); 200 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x37, 0x19); 201 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x38, 0x05); 202 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x39, 0x00); 203 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3A, 0x01); 204 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3B, 0x01); 205 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3C, 0x70); 206 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3D, 0xFF); 207 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3E, 0xFF); 208 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3F, 0xFF); 209 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x40, 0x06); 210 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x41, 0xA0); 211 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x43, 0x1E); 212 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x44, 0x0F); 213 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x45, 0x28); 214 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4B, 0x04); 215 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x55, 0x02); 216 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x56, 0x01); 217 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x57, 0xA9); 218 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x58, 0x0A); 219 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x59, 0x0A); 220 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5A, 0x37); 221 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5B, 0x19); 222 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5D, 0x78); 223 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5E, 0x63); 224 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5F, 0x54); 225 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x60, 0x49); 226 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x61, 0x45); 227 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x62, 0x38); 228 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x63, 0x3D); 229 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x64, 0x28); 230 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x65, 0x43); 231 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x66, 0x41); 232 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x67, 0x43); 233 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x68, 0x62); 234 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x69, 0x50); 235 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6A, 0x57); 236 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6B, 0x49); 237 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6C, 0x44); 238 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6D, 0x37); 239 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6E, 0x23); 240 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6F, 0x10); 241 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x70, 0x78); 242 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x71, 0x63); 243 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x72, 0x54); 244 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x73, 0x49); 245 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x74, 0x45); 246 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x75, 0x38); 247 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x76, 0x3D); 248 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x77, 0x28); 249 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x78, 0x43); 250 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x79, 0x41); 251 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7A, 0x43); 252 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7B, 0x62); 253 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7C, 0x50); 254 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7D, 0x57); 255 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7E, 0x49); 256 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7F, 0x44); 257 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x80, 0x37); 258 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x81, 0x23); 259 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x82, 0x10); 260 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xE0, 0x02); 261 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x47); 262 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x01, 0x47); 263 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x02, 0x45); 264 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x03, 0x45); 265 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x04, 0x4B); 266 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x05, 0x4B); 267 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x06, 0x49); 268 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x07, 0x49); 269 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x08, 0x41); 270 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x09, 0x1F); 271 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0A, 0x1F); 272 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0B, 0x1F); 273 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0C, 0x1F); 274 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0D, 0x1F); 275 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0E, 0x1F); 276 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0F, 0x5F); 277 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x10, 0x5F); 278 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x11, 0x57); 279 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x12, 0x77); 280 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x13, 0x35); 281 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x14, 0x1F); 282 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x15, 0x1F); 283 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x16, 0x46); 284 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x17, 0x46); 285 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x18, 0x44); 286 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x19, 0x44); 287 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1A, 0x4A); 288 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1B, 0x4A); 289 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1C, 0x48); 290 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1D, 0x48); 291 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1E, 0x40); 292 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1F, 0x1F); 293 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x20, 0x1F); 294 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x21, 0x1F); 295 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x22, 0x1F); 296 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x23, 0x1F); 297 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x24, 0x1F); 298 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x25, 0x5F); 299 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x26, 0x5F); 300 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x27, 0x57); 301 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x28, 0x77); 302 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x29, 0x35); 303 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2A, 0x1F); 304 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2B, 0x1F); 305 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x58, 0x40); 306 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x59, 0x00); 307 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5A, 0x00); 308 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5B, 0x10); 309 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5C, 0x06); 310 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5D, 0x40); 311 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5E, 0x01); 312 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5F, 0x02); 313 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x60, 0x30); 314 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x61, 0x01); 315 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x62, 0x02); 316 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x63, 0x03); 317 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x64, 0x6B); 318 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x65, 0x05); 319 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x66, 0x0C); 320 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x67, 0x73); 321 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x68, 0x09); 322 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x69, 0x03); 323 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6A, 0x56); 324 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6B, 0x08); 325 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6C, 0x00); 326 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6D, 0x04); 327 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6E, 0x04); 328 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6F, 0x88); 329 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x70, 0x00); 330 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x71, 0x00); 331 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x72, 0x06); 332 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x73, 0x7B); 333 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x74, 0x00); 334 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x75, 0xF8); 335 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x76, 0x00); 336 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x77, 0xD5); 337 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x78, 0x2E); 338 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x79, 0x12); 339 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7A, 0x03); 340 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7B, 0x00); 341 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7C, 0x00); 342 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7D, 0x03); 343 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7E, 0x7B); 344 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xE0, 0x04); 345 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x0E); 346 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x02, 0xB3); 347 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x09, 0x60); 348 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0E, 0x2A); 349 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x36, 0x59); 350 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xE0, 0x00); 351 + 352 + return dsi_ctx.accum_err; 359 353 }; 360 354 361 355 static const struct jadard_panel_desc radxa_display_8hd_ad002_desc = { ··· 391 359 }, 392 360 .lanes = 4, 393 361 .format = MIPI_DSI_FMT_RGB888, 394 - .init_cmds = radxa_display_8hd_ad002_init_cmds, 395 - .num_init_cmds = ARRAY_SIZE(radxa_display_8hd_ad002_init_cmds), 362 + .init = radxa_display_8hd_ad002_init_cmds, 396 363 }; 397 364 398 - static const struct jadard_init_cmd cz101b4001_init_cmds[] = { 399 - { .data = { 0xE0, 0x00 } }, 400 - { .data = { 0xE1, 0x93 } }, 401 - { .data = { 0xE2, 0x65 } }, 402 - { .data = { 0xE3, 0xF8 } }, 403 - { .data = { 0x80, 0x03 } }, 404 - { .data = { 0xE0, 0x01 } }, 405 - { .data = { 0x00, 0x00 } }, 406 - { .data = { 0x01, 0x3B } }, 407 - { .data = { 0x0C, 0x74 } }, 408 - { .data = { 0x17, 0x00 } }, 409 - { .data = { 0x18, 0xAF } }, 410 - { .data = { 0x19, 0x00 } }, 411 - { .data = { 0x1A, 0x00 } }, 412 - { .data = { 0x1B, 0xAF } }, 413 - { .data = { 0x1C, 0x00 } }, 414 - { .data = { 0x35, 0x26 } }, 415 - { .data = { 0x37, 0x09 } }, 416 - { .data = { 0x38, 0x04 } }, 417 - { .data = { 0x39, 0x00 } }, 418 - { .data = { 0x3A, 0x01 } }, 419 - { .data = { 0x3C, 0x78 } }, 420 - { .data = { 0x3D, 0xFF } }, 421 - { .data = { 0x3E, 0xFF } }, 422 - { .data = { 0x3F, 0x7F } }, 423 - { .data = { 0x40, 0x06 } }, 424 - { .data = { 0x41, 0xA0 } }, 425 - { .data = { 0x42, 0x81 } }, 426 - { .data = { 0x43, 0x14 } }, 427 - { .data = { 0x44, 0x23 } }, 428 - { .data = { 0x45, 0x28 } }, 429 - { .data = { 0x55, 0x02 } }, 430 - { .data = { 0x57, 0x69 } }, 431 - { .data = { 0x59, 0x0A } }, 432 - { .data = { 0x5A, 0x2A } }, 433 - { .data = { 0x5B, 0x17 } }, 434 - { .data = { 0x5D, 0x7F } }, 435 - { .data = { 0x5E, 0x6B } }, 436 - { .data = { 0x5F, 0x5C } }, 437 - { .data = { 0x60, 0x4F } }, 438 - { .data = { 0x61, 0x4D } }, 439 - { .data = { 0x62, 0x3F } }, 440 - { .data = { 0x63, 0x42 } }, 441 - { .data = { 0x64, 0x2B } }, 442 - { .data = { 0x65, 0x44 } }, 443 - { .data = { 0x66, 0x43 } }, 444 - { .data = { 0x67, 0x43 } }, 445 - { .data = { 0x68, 0x63 } }, 446 - { .data = { 0x69, 0x52 } }, 447 - { .data = { 0x6A, 0x5A } }, 448 - { .data = { 0x6B, 0x4F } }, 449 - { .data = { 0x6C, 0x4E } }, 450 - { .data = { 0x6D, 0x20 } }, 451 - { .data = { 0x6E, 0x0F } }, 452 - { .data = { 0x6F, 0x00 } }, 453 - { .data = { 0x70, 0x7F } }, 454 - { .data = { 0x71, 0x6B } }, 455 - { .data = { 0x72, 0x5C } }, 456 - { .data = { 0x73, 0x4F } }, 457 - { .data = { 0x74, 0x4D } }, 458 - { .data = { 0x75, 0x3F } }, 459 - { .data = { 0x76, 0x42 } }, 460 - { .data = { 0x77, 0x2B } }, 461 - { .data = { 0x78, 0x44 } }, 462 - { .data = { 0x79, 0x43 } }, 463 - { .data = { 0x7A, 0x43 } }, 464 - { .data = { 0x7B, 0x63 } }, 465 - { .data = { 0x7C, 0x52 } }, 466 - { .data = { 0x7D, 0x5A } }, 467 - { .data = { 0x7E, 0x4F } }, 468 - { .data = { 0x7F, 0x4E } }, 469 - { .data = { 0x80, 0x20 } }, 470 - { .data = { 0x81, 0x0F } }, 471 - { .data = { 0x82, 0x00 } }, 472 - { .data = { 0xE0, 0x02 } }, 473 - { .data = { 0x00, 0x02 } }, 474 - { .data = { 0x01, 0x02 } }, 475 - { .data = { 0x02, 0x00 } }, 476 - { .data = { 0x03, 0x00 } }, 477 - { .data = { 0x04, 0x1E } }, 478 - { .data = { 0x05, 0x1E } }, 479 - { .data = { 0x06, 0x1F } }, 480 - { .data = { 0x07, 0x1F } }, 481 - { .data = { 0x08, 0x1F } }, 482 - { .data = { 0x09, 0x17 } }, 483 - { .data = { 0x0A, 0x17 } }, 484 - { .data = { 0x0B, 0x37 } }, 485 - { .data = { 0x0C, 0x37 } }, 486 - { .data = { 0x0D, 0x47 } }, 487 - { .data = { 0x0E, 0x47 } }, 488 - { .data = { 0x0F, 0x45 } }, 489 - { .data = { 0x10, 0x45 } }, 490 - { .data = { 0x11, 0x4B } }, 491 - { .data = { 0x12, 0x4B } }, 492 - { .data = { 0x13, 0x49 } }, 493 - { .data = { 0x14, 0x49 } }, 494 - { .data = { 0x15, 0x1F } }, 495 - { .data = { 0x16, 0x01 } }, 496 - { .data = { 0x17, 0x01 } }, 497 - { .data = { 0x18, 0x00 } }, 498 - { .data = { 0x19, 0x00 } }, 499 - { .data = { 0x1A, 0x1E } }, 500 - { .data = { 0x1B, 0x1E } }, 501 - { .data = { 0x1C, 0x1F } }, 502 - { .data = { 0x1D, 0x1F } }, 503 - { .data = { 0x1E, 0x1F } }, 504 - { .data = { 0x1F, 0x17 } }, 505 - { .data = { 0x20, 0x17 } }, 506 - { .data = { 0x21, 0x37 } }, 507 - { .data = { 0x22, 0x37 } }, 508 - { .data = { 0x23, 0x46 } }, 509 - { .data = { 0x24, 0x46 } }, 510 - { .data = { 0x25, 0x44 } }, 511 - { .data = { 0x26, 0x44 } }, 512 - { .data = { 0x27, 0x4A } }, 513 - { .data = { 0x28, 0x4A } }, 514 - { .data = { 0x29, 0x48 } }, 515 - { .data = { 0x2A, 0x48 } }, 516 - { .data = { 0x2B, 0x1F } }, 517 - { .data = { 0x2C, 0x01 } }, 518 - { .data = { 0x2D, 0x01 } }, 519 - { .data = { 0x2E, 0x00 } }, 520 - { .data = { 0x2F, 0x00 } }, 521 - { .data = { 0x30, 0x1F } }, 522 - { .data = { 0x31, 0x1F } }, 523 - { .data = { 0x32, 0x1E } }, 524 - { .data = { 0x33, 0x1E } }, 525 - { .data = { 0x34, 0x1F } }, 526 - { .data = { 0x35, 0x17 } }, 527 - { .data = { 0x36, 0x17 } }, 528 - { .data = { 0x37, 0x37 } }, 529 - { .data = { 0x38, 0x37 } }, 530 - { .data = { 0x39, 0x08 } }, 531 - { .data = { 0x3A, 0x08 } }, 532 - { .data = { 0x3B, 0x0A } }, 533 - { .data = { 0x3C, 0x0A } }, 534 - { .data = { 0x3D, 0x04 } }, 535 - { .data = { 0x3E, 0x04 } }, 536 - { .data = { 0x3F, 0x06 } }, 537 - { .data = { 0x40, 0x06 } }, 538 - { .data = { 0x41, 0x1F } }, 539 - { .data = { 0x42, 0x02 } }, 540 - { .data = { 0x43, 0x02 } }, 541 - { .data = { 0x44, 0x00 } }, 542 - { .data = { 0x45, 0x00 } }, 543 - { .data = { 0x46, 0x1F } }, 544 - { .data = { 0x47, 0x1F } }, 545 - { .data = { 0x48, 0x1E } }, 546 - { .data = { 0x49, 0x1E } }, 547 - { .data = { 0x4A, 0x1F } }, 548 - { .data = { 0x4B, 0x17 } }, 549 - { .data = { 0x4C, 0x17 } }, 550 - { .data = { 0x4D, 0x37 } }, 551 - { .data = { 0x4E, 0x37 } }, 552 - { .data = { 0x4F, 0x09 } }, 553 - { .data = { 0x50, 0x09 } }, 554 - { .data = { 0x51, 0x0B } }, 555 - { .data = { 0x52, 0x0B } }, 556 - { .data = { 0x53, 0x05 } }, 557 - { .data = { 0x54, 0x05 } }, 558 - { .data = { 0x55, 0x07 } }, 559 - { .data = { 0x56, 0x07 } }, 560 - { .data = { 0x57, 0x1F } }, 561 - { .data = { 0x58, 0x40 } }, 562 - { .data = { 0x5B, 0x30 } }, 563 - { .data = { 0x5C, 0x16 } }, 564 - { .data = { 0x5D, 0x34 } }, 565 - { .data = { 0x5E, 0x05 } }, 566 - { .data = { 0x5F, 0x02 } }, 567 - { .data = { 0x63, 0x00 } }, 568 - { .data = { 0x64, 0x6A } }, 569 - { .data = { 0x67, 0x73 } }, 570 - { .data = { 0x68, 0x1D } }, 571 - { .data = { 0x69, 0x08 } }, 572 - { .data = { 0x6A, 0x6A } }, 573 - { .data = { 0x6B, 0x08 } }, 574 - { .data = { 0x6C, 0x00 } }, 575 - { .data = { 0x6D, 0x00 } }, 576 - { .data = { 0x6E, 0x00 } }, 577 - { .data = { 0x6F, 0x88 } }, 578 - { .data = { 0x75, 0xFF } }, 579 - { .data = { 0x77, 0xDD } }, 580 - { .data = { 0x78, 0x3F } }, 581 - { .data = { 0x79, 0x15 } }, 582 - { .data = { 0x7A, 0x17 } }, 583 - { .data = { 0x7D, 0x14 } }, 584 - { .data = { 0x7E, 0x82 } }, 585 - { .data = { 0xE0, 0x04 } }, 586 - { .data = { 0x00, 0x0E } }, 587 - { .data = { 0x02, 0xB3 } }, 588 - { .data = { 0x09, 0x61 } }, 589 - { .data = { 0x0E, 0x48 } }, 590 - { .data = { 0xE0, 0x00 } }, 591 - { .data = { 0xE6, 0x02 } }, 592 - { .data = { 0xE7, 0x0C } }, 365 + static int cz101b4001_init_cmds(struct jadard *jadard) 366 + { 367 + struct mipi_dsi_multi_context dsi_ctx = { .dsi = jadard->dsi }; 368 + 369 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xE0, 0x00); 370 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xE1, 0x93); 371 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xE2, 0x65); 372 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xE3, 0xF8); 373 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x80, 0x03); 374 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xE0, 0x01); 375 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x00); 376 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x01, 0x3B); 377 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0C, 0x74); 378 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x17, 0x00); 379 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x18, 0xAF); 380 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x19, 0x00); 381 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1A, 0x00); 382 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1B, 0xAF); 383 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1C, 0x00); 384 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x35, 0x26); 385 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x37, 0x09); 386 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x38, 0x04); 387 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x39, 0x00); 388 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3A, 0x01); 389 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3C, 0x78); 390 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3D, 0xFF); 391 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3E, 0xFF); 392 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3F, 0x7F); 393 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x40, 0x06); 394 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x41, 0xA0); 395 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x42, 0x81); 396 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x43, 0x14); 397 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x44, 0x23); 398 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x45, 0x28); 399 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x55, 0x02); 400 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x57, 0x69); 401 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x59, 0x0A); 402 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5A, 0x2A); 403 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5B, 0x17); 404 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5D, 0x7F); 405 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5E, 0x6B); 406 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5F, 0x5C); 407 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x60, 0x4F); 408 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x61, 0x4D); 409 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x62, 0x3F); 410 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x63, 0x42); 411 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x64, 0x2B); 412 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x65, 0x44); 413 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x66, 0x43); 414 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x67, 0x43); 415 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x68, 0x63); 416 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x69, 0x52); 417 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6A, 0x5A); 418 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6B, 0x4F); 419 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6C, 0x4E); 420 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6D, 0x20); 421 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6E, 0x0F); 422 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6F, 0x00); 423 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x70, 0x7F); 424 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x71, 0x6B); 425 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x72, 0x5C); 426 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x73, 0x4F); 427 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x74, 0x4D); 428 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x75, 0x3F); 429 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x76, 0x42); 430 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x77, 0x2B); 431 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x78, 0x44); 432 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x79, 0x43); 433 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7A, 0x43); 434 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7B, 0x63); 435 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7C, 0x52); 436 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7D, 0x5A); 437 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7E, 0x4F); 438 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7F, 0x4E); 439 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x80, 0x20); 440 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x81, 0x0F); 441 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x82, 0x00); 442 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xE0, 0x02); 443 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x02); 444 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x01, 0x02); 445 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x02, 0x00); 446 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x03, 0x00); 447 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x04, 0x1E); 448 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x05, 0x1E); 449 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x06, 0x1F); 450 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x07, 0x1F); 451 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x08, 0x1F); 452 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x09, 0x17); 453 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0A, 0x17); 454 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0B, 0x37); 455 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0C, 0x37); 456 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0D, 0x47); 457 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0E, 0x47); 458 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0F, 0x45); 459 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x10, 0x45); 460 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x11, 0x4B); 461 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x12, 0x4B); 462 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x13, 0x49); 463 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x14, 0x49); 464 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x15, 0x1F); 465 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x16, 0x01); 466 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x17, 0x01); 467 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x18, 0x00); 468 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x19, 0x00); 469 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1A, 0x1E); 470 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1B, 0x1E); 471 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1C, 0x1F); 472 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1D, 0x1F); 473 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1E, 0x1F); 474 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1F, 0x17); 475 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x20, 0x17); 476 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x21, 0x37); 477 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x22, 0x37); 478 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x23, 0x46); 479 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x24, 0x46); 480 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x25, 0x44); 481 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x26, 0x44); 482 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x27, 0x4A); 483 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x28, 0x4A); 484 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x29, 0x48); 485 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2A, 0x48); 486 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2B, 0x1F); 487 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2C, 0x01); 488 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2D, 0x01); 489 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2E, 0x00); 490 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2F, 0x00); 491 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x30, 0x1F); 492 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x31, 0x1F); 493 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x32, 0x1E); 494 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x33, 0x1E); 495 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x34, 0x1F); 496 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x35, 0x17); 497 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x36, 0x17); 498 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x37, 0x37); 499 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x38, 0x37); 500 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x39, 0x08); 501 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3A, 0x08); 502 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3B, 0x0A); 503 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3C, 0x0A); 504 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3D, 0x04); 505 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3E, 0x04); 506 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3F, 0x06); 507 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x40, 0x06); 508 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x41, 0x1F); 509 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x42, 0x02); 510 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x43, 0x02); 511 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x44, 0x00); 512 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x45, 0x00); 513 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x46, 0x1F); 514 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x47, 0x1F); 515 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x48, 0x1E); 516 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x49, 0x1E); 517 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4A, 0x1F); 518 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4B, 0x17); 519 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4C, 0x17); 520 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4D, 0x37); 521 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4E, 0x37); 522 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4F, 0x09); 523 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x50, 0x09); 524 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x51, 0x0B); 525 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x52, 0x0B); 526 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x53, 0x05); 527 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x54, 0x05); 528 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x55, 0x07); 529 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x56, 0x07); 530 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x57, 0x1F); 531 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x58, 0x40); 532 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5B, 0x30); 533 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5C, 0x16); 534 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5D, 0x34); 535 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5E, 0x05); 536 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5F, 0x02); 537 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x63, 0x00); 538 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x64, 0x6A); 539 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x67, 0x73); 540 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x68, 0x1D); 541 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x69, 0x08); 542 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6A, 0x6A); 543 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6B, 0x08); 544 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6C, 0x00); 545 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6D, 0x00); 546 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6E, 0x00); 547 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6F, 0x88); 548 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x75, 0xFF); 549 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x77, 0xDD); 550 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x78, 0x3F); 551 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x79, 0x15); 552 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7A, 0x17); 553 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7D, 0x14); 554 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7E, 0x82); 555 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xE0, 0x04); 556 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x0E); 557 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x02, 0xB3); 558 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x09, 0x61); 559 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0E, 0x48); 560 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xE0, 0x00); 561 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xE6, 0x02); 562 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xE7, 0x0C); 563 + 564 + return dsi_ctx.accum_err; 593 565 }; 594 566 595 567 static const struct jadard_panel_desc cz101b4001_desc = { ··· 616 580 }, 617 581 .lanes = 4, 618 582 .format = MIPI_DSI_FMT_RGB888, 619 - .init_cmds = cz101b4001_init_cmds, 620 - .num_init_cmds = ARRAY_SIZE(cz101b4001_init_cmds), 583 + .init = cz101b4001_init_cmds, 584 + }; 585 + 586 + static int kingdisplay_kd101ne3_init_cmds(struct jadard *jadard) 587 + { 588 + struct mipi_dsi_multi_context dsi_ctx = { .dsi = jadard->dsi }; 589 + 590 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xe0, 0x00); 591 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xe1, 0x93); 592 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xe2, 0x65); 593 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xe3, 0xf8); 594 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x80, 0x03); 595 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xe0, 0x01); 596 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0c, 0x74); 597 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x17, 0x00); 598 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x18, 0xc7); 599 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x19, 0x01); 600 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1a, 0x00); 601 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1b, 0xc7); 602 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1c, 0x01); 603 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x24, 0xfe); 604 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x37, 0x19); 605 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x35, 0x28); 606 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x38, 0x05); 607 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x39, 0x08); 608 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3a, 0x12); 609 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3c, 0x7e); 610 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3d, 0xff); 611 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3e, 0xff); 612 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3f, 0x7f); 613 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x40, 0x06); 614 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x41, 0xa0); 615 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x43, 0x1e); 616 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x44, 0x0b); 617 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x55, 0x02); 618 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x57, 0x6a); 619 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x59, 0x0a); 620 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5a, 0x2e); 621 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5b, 0x1a); 622 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5c, 0x15); 623 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5d, 0x7f); 624 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5e, 0x61); 625 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5f, 0x50); 626 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x60, 0x43); 627 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x61, 0x3f); 628 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x62, 0x32); 629 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x63, 0x35); 630 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x64, 0x1f); 631 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x65, 0x38); 632 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x66, 0x36); 633 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x67, 0x36); 634 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x68, 0x54); 635 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x69, 0x42); 636 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6a, 0x48); 637 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6b, 0x39); 638 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6c, 0x34); 639 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6d, 0x26); 640 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6e, 0x14); 641 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x02); 642 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x70, 0x7f); 643 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x71, 0x61); 644 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x72, 0x50); 645 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x73, 0x43); 646 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x74, 0x3f); 647 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x75, 0x32); 648 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x76, 0x35); 649 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x77, 0x1f); 650 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x78, 0x38); 651 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x79, 0x36); 652 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7a, 0x36); 653 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7b, 0x54); 654 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7c, 0x42); 655 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7d, 0x48); 656 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7e, 0x39); 657 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7f, 0x34); 658 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x80, 0x26); 659 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x81, 0x14); 660 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x82, 0x02); 661 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xe0, 0x02); 662 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x52); 663 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x01, 0x5f); 664 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x02, 0x5f); 665 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x03, 0x50); 666 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x04, 0x77); 667 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x05, 0x57); 668 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x06, 0x5f); 669 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x07, 0x4e); 670 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x08, 0x4c); 671 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x09, 0x5f); 672 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0a, 0x4a); 673 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0b, 0x48); 674 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0c, 0x5f); 675 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0d, 0x46); 676 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0e, 0x44); 677 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0f, 0x40); 678 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x10, 0x5f); 679 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x11, 0x5f); 680 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x12, 0x5f); 681 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x13, 0x5f); 682 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x14, 0x5f); 683 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x15, 0x5f); 684 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x16, 0x53); 685 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x17, 0x5f); 686 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x18, 0x5f); 687 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x19, 0x51); 688 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1a, 0x77); 689 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1b, 0x57); 690 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1c, 0x5f); 691 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1d, 0x4f); 692 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1e, 0x4d); 693 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1f, 0x5f); 694 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x20, 0x4b); 695 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x21, 0x49); 696 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x22, 0x5f); 697 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x23, 0x47); 698 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x24, 0x45); 699 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x25, 0x41); 700 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x26, 0x5f); 701 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x27, 0x5f); 702 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x28, 0x5f); 703 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x29, 0x5f); 704 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2a, 0x5f); 705 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2b, 0x5f); 706 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2c, 0x13); 707 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2d, 0x1f); 708 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2e, 0x1f); 709 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2f, 0x01); 710 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x30, 0x17); 711 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x31, 0x17); 712 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x32, 0x1f); 713 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x33, 0x0d); 714 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x34, 0x0f); 715 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x35, 0x1f); 716 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x36, 0x05); 717 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x37, 0x07); 718 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x38, 0x1f); 719 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x39, 0x09); 720 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3a, 0x0b); 721 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3b, 0x11); 722 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3c, 0x1f); 723 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3d, 0x1f); 724 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3e, 0x1f); 725 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3f, 0x1f); 726 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x40, 0x1f); 727 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x41, 0x1f); 728 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x42, 0x12); 729 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x43, 0x1f); 730 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x44, 0x1f); 731 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x45, 0x00); 732 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x46, 0x17); 733 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x47, 0x17); 734 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x48, 0x1f); 735 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x49, 0x0c); 736 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4a, 0x0e); 737 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4b, 0x1f); 738 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4c, 0x04); 739 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4d, 0x06); 740 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4e, 0x1f); 741 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4f, 0x08); 742 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x50, 0x0a); 743 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x51, 0x10); 744 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x52, 0x1f); 745 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x53, 0x1f); 746 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x54, 0x1f); 747 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x55, 0x1f); 748 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x56, 0x1f); 749 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x57, 0x1f); 750 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x58, 0x40); 751 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5b, 0x10); 752 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5c, 0x06); 753 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5d, 0x40); 754 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5e, 0x00); 755 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5f, 0x00); 756 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x60, 0x40); 757 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x61, 0x03); 758 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x62, 0x04); 759 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x63, 0x6c); 760 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x64, 0x6c); 761 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x65, 0x75); 762 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x66, 0x08); 763 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x67, 0xb4); 764 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x68, 0x08); 765 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x69, 0x6c); 766 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6a, 0x6c); 767 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6b, 0x0c); 768 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6d, 0x00); 769 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6e, 0x00); 770 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x88); 771 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x75, 0xbb); 772 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x76, 0x00); 773 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x77, 0x05); 774 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x78, 0x2a); 775 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xe0, 0x04); 776 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x0e); 777 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x02, 0xb3); 778 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x09, 0x61); 779 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0e, 0x48); 780 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xe0, 0x00); 781 + 782 + return dsi_ctx.accum_err; 783 + }; 784 + 785 + static const struct jadard_panel_desc kingdisplay_kd101ne3_40ti_desc = { 786 + .mode = { 787 + .clock = (800 + 24 + 24 + 24) * (1280 + 30 + 4 + 8) * 60 / 1000, 788 + 789 + .hdisplay = 800, 790 + .hsync_start = 800 + 24, 791 + .hsync_end = 800 + 24 + 24, 792 + .htotal = 800 + 24 + 24 + 24, 793 + 794 + .vdisplay = 1280, 795 + .vsync_start = 1280 + 30, 796 + .vsync_end = 1280 + 30 + 4, 797 + .vtotal = 1280 + 30 + 4 + 8, 798 + 799 + .width_mm = 135, 800 + .height_mm = 216, 801 + .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, 802 + }, 803 + .lanes = 4, 804 + .format = MIPI_DSI_FMT_RGB888, 805 + .init = kingdisplay_kd101ne3_init_cmds, 806 + .lp11_before_reset = true, 807 + .reset_before_power_off_vcioo = true, 808 + .vcioo_to_lp11_delay_ms = 5, 809 + .lp11_to_reset_delay_ms = 10, 810 + .exit_sleep_to_display_on_delay_ms = 120, 811 + .display_on_delay_ms = 20, 812 + .backlight_off_to_display_off_delay_ms = 100, 813 + .display_off_to_enter_sleep_delay_ms = 50, 814 + .enter_sleep_to_reset_down_delay_ms = 100, 621 815 }; 622 816 623 817 static int jadard_dsi_probe(struct mipi_dsi_device *dsi) ··· 888 622 drm_panel_init(&jadard->panel, dev, &jadard_funcs, 889 623 DRM_MODE_CONNECTOR_DSI); 890 624 625 + ret = of_drm_get_panel_orientation(dev->of_node, &jadard->orientation); 626 + if (ret < 0) 627 + return dev_err_probe(dev, ret, "failed to get orientation\n"); 628 + 891 629 ret = drm_panel_of_backlight(&jadard->panel); 892 630 if (ret) 893 631 return ret; ··· 921 651 { 922 652 .compatible = "chongzhou,cz101b4001", 923 653 .data = &cz101b4001_desc 654 + }, 655 + { 656 + .compatible = "kingdisplay,kd101ne3-40ti", 657 + .data = &kingdisplay_kd101ne3_40ti_desc 924 658 }, 925 659 { 926 660 .compatible = "radxa,display-10hd-ad001",
+27
drivers/gpu/drm/panel/panel-simple.c
··· 1067 1067 .connector_type = DRM_MODE_CONNECTOR_LVDS, 1068 1068 }; 1069 1069 1070 + static const struct drm_display_mode auo_g104stn01_mode = { 1071 + .clock = 40000, 1072 + .hdisplay = 800, 1073 + .hsync_start = 800 + 40, 1074 + .hsync_end = 800 + 40 + 88, 1075 + .htotal = 800 + 40 + 88 + 128, 1076 + .vdisplay = 600, 1077 + .vsync_start = 600 + 1, 1078 + .vsync_end = 600 + 1 + 23, 1079 + .vtotal = 600 + 1 + 23 + 4, 1080 + }; 1081 + 1082 + static const struct panel_desc auo_g104stn01 = { 1083 + .modes = &auo_g104stn01_mode, 1084 + .num_modes = 1, 1085 + .bpc = 8, 1086 + .size = { 1087 + .width = 211, 1088 + .height = 158, 1089 + }, 1090 + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, 1091 + .connector_type = DRM_MODE_CONNECTOR_LVDS, 1092 + }; 1093 + 1070 1094 static const struct display_timing auo_g121ean01_timing = { 1071 1095 .pixelclock = { 60000000, 74400000, 90000000 }, 1072 1096 .hactive = { 1280, 1280, 1280 }, ··· 4558 4534 }, { 4559 4535 .compatible = "auo,g104sn02", 4560 4536 .data = &auo_g104sn02, 4537 + }, { 4538 + .compatible = "auo,g104stn01", 4539 + .data = &auo_g104stn01, 4561 4540 }, { 4562 4541 .compatible = "auo,g121ean01", 4563 4542 .data = &auo_g121ean01,
+1
drivers/gpu/drm/panfrost/panfrost_drv.c
··· 838 838 MODULE_AUTHOR("Panfrost Project Developers"); 839 839 MODULE_DESCRIPTION("Panfrost DRM Driver"); 840 840 MODULE_LICENSE("GPL v2"); 841 + MODULE_SOFTDEP("pre: governor_simpleondemand");
+1
drivers/gpu/drm/panthor/panthor_sched.c
··· 2926 2926 pm_runtime_get(ptdev->base.dev); 2927 2927 sched->pm.has_ref = true; 2928 2928 } 2929 + panthor_devfreq_record_busy(sched->ptdev); 2929 2930 } 2930 2931 2931 2932 done_fence = dma_fence_get(job->done_fence);
+11
drivers/gpu/drm/stm/Kconfig
··· 20 20 select DRM_DW_MIPI_DSI 21 21 help 22 22 Choose this option for MIPI DSI support on STMicroelectronics SoC. 23 + 24 + config DRM_STM_LVDS 25 + tristate "STMicroelectronics LVDS Display Interface Transmitter DRM driver" 26 + depends on DRM_STM 27 + help 28 + Enable support for LVDS encoders on STMicroelectronics SoC. 29 + The STM LVDS is a bridge which serialize pixel stream onto 30 + a LVDS protocol. 31 + 32 + To compile this driver as a module, choose M here: the module will be 33 + called lvds.
+2
drivers/gpu/drm/stm/Makefile
··· 5 5 6 6 obj-$(CONFIG_DRM_STM_DSI) += dw_mipi_dsi-stm.o 7 7 8 + obj-$(CONFIG_DRM_STM_LVDS) += lvds.o 9 + 8 10 obj-$(CONFIG_DRM_STM) += stm-drm.o
+238 -41
drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
··· 7 7 */ 8 8 9 9 #include <linux/clk.h> 10 + #include <linux/clk-provider.h> 10 11 #include <linux/iopoll.h> 12 + #include <linux/kernel.h> 11 13 #include <linux/mod_devicetable.h> 12 14 #include <linux/module.h> 13 15 #include <linux/platform_device.h> 16 + #include <linux/pm_runtime.h> 14 17 #include <linux/regulator/consumer.h> 15 18 16 19 #include <video/mipi_display.h> ··· 79 76 80 77 struct dw_mipi_dsi_stm { 81 78 void __iomem *base; 79 + struct device *dev; 82 80 struct clk *pllref_clk; 81 + struct clk *pclk; 82 + struct clk_hw txbyte_clk; 83 83 struct dw_mipi_dsi *dsi; 84 + struct dw_mipi_dsi_plat_data pdata; 84 85 u32 hw_version; 85 86 int lane_min_kbps; 86 87 int lane_max_kbps; ··· 201 194 return 0; 202 195 } 203 196 204 - static int dw_mipi_dsi_phy_init(void *priv_data) 197 + #define clk_to_dw_mipi_dsi_stm(clk) \ 198 + container_of(clk, struct dw_mipi_dsi_stm, txbyte_clk) 199 + 200 + static void dw_mipi_dsi_clk_disable(struct clk_hw *clk) 205 201 { 206 - struct dw_mipi_dsi_stm *dsi = priv_data; 202 + struct dw_mipi_dsi_stm *dsi = clk_to_dw_mipi_dsi_stm(clk); 203 + 204 + DRM_DEBUG_DRIVER("\n"); 205 + 206 + /* Disable the DSI PLL */ 207 + dsi_clear(dsi, DSI_WRPCR, WRPCR_PLLEN); 208 + 209 + /* Disable the regulator */ 210 + dsi_clear(dsi, DSI_WRPCR, WRPCR_REGEN | WRPCR_BGREN); 211 + } 212 + 213 + static int dw_mipi_dsi_clk_enable(struct clk_hw *clk) 214 + { 215 + struct dw_mipi_dsi_stm *dsi = clk_to_dw_mipi_dsi_stm(clk); 207 216 u32 val; 208 217 int ret; 209 218 219 + DRM_DEBUG_DRIVER("\n"); 220 + 210 221 /* Enable the regulator */ 211 222 dsi_set(dsi, DSI_WRPCR, WRPCR_REGEN | WRPCR_BGREN); 212 - ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_RRS, 213 - SLEEP_US, TIMEOUT_US); 223 + ret = readl_poll_timeout_atomic(dsi->base + DSI_WISR, val, val & WISR_RRS, 224 + SLEEP_US, TIMEOUT_US); 214 225 if (ret) 215 226 DRM_DEBUG_DRIVER("!TIMEOUT! waiting REGU, let's continue\n"); 216 227 217 228 /* Enable the DSI PLL & wait for its lock */ 218 229 dsi_set(dsi, DSI_WRPCR, WRPCR_PLLEN); 219 - ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_PLLLS, 220 - SLEEP_US, TIMEOUT_US); 230 + ret = readl_poll_timeout_atomic(dsi->base + DSI_WISR, val, val & WISR_PLLLS, 231 + SLEEP_US, TIMEOUT_US); 221 232 if (ret) 222 233 DRM_DEBUG_DRIVER("!TIMEOUT! waiting PLL, let's continue\n"); 223 234 224 235 return 0; 236 + } 237 + 238 + static int dw_mipi_dsi_clk_is_enabled(struct clk_hw *hw) 239 + { 240 + struct dw_mipi_dsi_stm *dsi = clk_to_dw_mipi_dsi_stm(hw); 241 + 242 + return dsi_read(dsi, DSI_WRPCR) & WRPCR_PLLEN; 243 + } 244 + 245 + static unsigned long dw_mipi_dsi_clk_recalc_rate(struct clk_hw *hw, 246 + unsigned long parent_rate) 247 + { 248 + struct dw_mipi_dsi_stm *dsi = clk_to_dw_mipi_dsi_stm(hw); 249 + unsigned int idf, ndiv, odf, pll_in_khz, pll_out_khz; 250 + u32 val; 251 + 252 + DRM_DEBUG_DRIVER("\n"); 253 + 254 + pll_in_khz = (unsigned int)(parent_rate / 1000); 255 + 256 + val = dsi_read(dsi, DSI_WRPCR); 257 + 258 + idf = (val & WRPCR_IDF) >> 11; 259 + if (!idf) 260 + idf = 1; 261 + ndiv = (val & WRPCR_NDIV) >> 2; 262 + odf = int_pow(2, (val & WRPCR_ODF) >> 16); 263 + 264 + /* Get the adjusted pll out value */ 265 + pll_out_khz = dsi_pll_get_clkout_khz(pll_in_khz, idf, ndiv, odf); 266 + 267 + return (unsigned long)pll_out_khz * 1000; 268 + } 269 + 270 + static long dw_mipi_dsi_clk_round_rate(struct clk_hw *hw, unsigned long rate, 271 + unsigned long *parent_rate) 272 + { 273 + struct dw_mipi_dsi_stm *dsi = clk_to_dw_mipi_dsi_stm(hw); 274 + unsigned int idf, ndiv, odf, pll_in_khz, pll_out_khz; 275 + int ret; 276 + 277 + DRM_DEBUG_DRIVER("\n"); 278 + 279 + pll_in_khz = (unsigned int)(*parent_rate / 1000); 280 + 281 + /* Compute best pll parameters */ 282 + idf = 0; 283 + ndiv = 0; 284 + odf = 0; 285 + 286 + ret = dsi_pll_get_params(dsi, pll_in_khz, rate / 1000, 287 + &idf, &ndiv, &odf); 288 + if (ret) 289 + DRM_WARN("Warning dsi_pll_get_params(): bad params\n"); 290 + 291 + /* Get the adjusted pll out value */ 292 + pll_out_khz = dsi_pll_get_clkout_khz(pll_in_khz, idf, ndiv, odf); 293 + 294 + return pll_out_khz * 1000; 295 + } 296 + 297 + static int dw_mipi_dsi_clk_set_rate(struct clk_hw *hw, unsigned long rate, 298 + unsigned long parent_rate) 299 + { 300 + struct dw_mipi_dsi_stm *dsi = clk_to_dw_mipi_dsi_stm(hw); 301 + unsigned int idf, ndiv, odf, pll_in_khz, pll_out_khz; 302 + int ret; 303 + u32 val; 304 + 305 + DRM_DEBUG_DRIVER("\n"); 306 + 307 + pll_in_khz = (unsigned int)(parent_rate / 1000); 308 + 309 + /* Compute best pll parameters */ 310 + idf = 0; 311 + ndiv = 0; 312 + odf = 0; 313 + 314 + ret = dsi_pll_get_params(dsi, pll_in_khz, rate / 1000, &idf, &ndiv, &odf); 315 + if (ret) 316 + DRM_WARN("Warning dsi_pll_get_params(): bad params\n"); 317 + 318 + /* Get the adjusted pll out value */ 319 + pll_out_khz = dsi_pll_get_clkout_khz(pll_in_khz, idf, ndiv, odf); 320 + 321 + /* Set the PLL division factors */ 322 + dsi_update_bits(dsi, DSI_WRPCR, WRPCR_NDIV | WRPCR_IDF | WRPCR_ODF, 323 + (ndiv << 2) | (idf << 11) | ((ffs(odf) - 1) << 16)); 324 + 325 + /* Compute uix4 & set the bit period in high-speed mode */ 326 + val = 4000000 / pll_out_khz; 327 + dsi_update_bits(dsi, DSI_WPCR0, WPCR0_UIX4, val); 328 + 329 + return 0; 330 + } 331 + 332 + static void dw_mipi_dsi_clk_unregister(void *data) 333 + { 334 + struct dw_mipi_dsi_stm *dsi = data; 335 + 336 + DRM_DEBUG_DRIVER("\n"); 337 + 338 + of_clk_del_provider(dsi->dev->of_node); 339 + clk_hw_unregister(&dsi->txbyte_clk); 340 + } 341 + 342 + static const struct clk_ops dw_mipi_dsi_stm_clk_ops = { 343 + .enable = dw_mipi_dsi_clk_enable, 344 + .disable = dw_mipi_dsi_clk_disable, 345 + .is_enabled = dw_mipi_dsi_clk_is_enabled, 346 + .recalc_rate = dw_mipi_dsi_clk_recalc_rate, 347 + .round_rate = dw_mipi_dsi_clk_round_rate, 348 + .set_rate = dw_mipi_dsi_clk_set_rate, 349 + }; 350 + 351 + static struct clk_init_data cdata_init = { 352 + .name = "ck_dsi_phy", 353 + .ops = &dw_mipi_dsi_stm_clk_ops, 354 + .parent_names = (const char * []) {"ck_hse"}, 355 + .num_parents = 1, 356 + }; 357 + 358 + static int dw_mipi_dsi_clk_register(struct dw_mipi_dsi_stm *dsi, 359 + struct device *dev) 360 + { 361 + struct device_node *node = dev->of_node; 362 + int ret; 363 + 364 + DRM_DEBUG_DRIVER("Registering clk\n"); 365 + 366 + dsi->txbyte_clk.init = &cdata_init; 367 + 368 + ret = clk_hw_register(dev, &dsi->txbyte_clk); 369 + if (ret) 370 + return ret; 371 + 372 + ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, 373 + &dsi->txbyte_clk); 374 + if (ret) 375 + clk_hw_unregister(&dsi->txbyte_clk); 376 + 377 + return ret; 378 + } 379 + 380 + static int dw_mipi_dsi_phy_init(void *priv_data) 381 + { 382 + struct dw_mipi_dsi_stm *dsi = priv_data; 383 + int ret; 384 + 385 + ret = clk_prepare_enable(dsi->txbyte_clk.clk); 386 + return ret; 225 387 } 226 388 227 389 static void dw_mipi_dsi_phy_power_on(void *priv_data) ··· 409 233 410 234 DRM_DEBUG_DRIVER("\n"); 411 235 236 + clk_disable_unprepare(dsi->txbyte_clk.clk); 237 + 412 238 /* Disable the DSI wrapper */ 413 239 dsi_clear(dsi, DSI_WCR, WCR_DSIEN); 414 240 } ··· 421 243 unsigned int *lane_mbps) 422 244 { 423 245 struct dw_mipi_dsi_stm *dsi = priv_data; 424 - unsigned int idf, ndiv, odf, pll_in_khz, pll_out_khz; 246 + unsigned int pll_in_khz, pll_out_khz; 425 247 int ret, bpp; 426 - u32 val; 427 248 428 249 pll_in_khz = (unsigned int)(clk_get_rate(dsi->pllref_clk) / 1000); 429 250 ··· 443 266 DRM_WARN("Warning min phy mbps is used\n"); 444 267 } 445 268 446 - /* Compute best pll parameters */ 447 - idf = 0; 448 - ndiv = 0; 449 - odf = 0; 450 - ret = dsi_pll_get_params(dsi, pll_in_khz, pll_out_khz, 451 - &idf, &ndiv, &odf); 269 + ret = clk_set_rate((dsi->txbyte_clk.clk), pll_out_khz * 1000); 452 270 if (ret) 453 - DRM_WARN("Warning dsi_pll_get_params(): bad params\n"); 454 - 455 - /* Get the adjusted pll out value */ 456 - pll_out_khz = dsi_pll_get_clkout_khz(pll_in_khz, idf, ndiv, odf); 457 - 458 - /* Set the PLL division factors */ 459 - dsi_update_bits(dsi, DSI_WRPCR, WRPCR_NDIV | WRPCR_IDF | WRPCR_ODF, 460 - (ndiv << 2) | (idf << 11) | ((ffs(odf) - 1) << 16)); 461 - 462 - /* Compute uix4 & set the bit period in high-speed mode */ 463 - val = 4000000 / pll_out_khz; 464 - dsi_update_bits(dsi, DSI_WPCR0, WPCR0_UIX4, val); 271 + DRM_DEBUG_DRIVER("ERROR Could not set rate of %d to %s clk->name", 272 + pll_out_khz, clk_hw_get_name(&dsi->txbyte_clk)); 465 273 466 274 /* Select video mode by resetting DSIM bit */ 467 275 dsi_clear(dsi, DSI_WCFGR, WCFGR_DSIM); ··· 605 443 { 606 444 struct device *dev = &pdev->dev; 607 445 struct dw_mipi_dsi_stm *dsi; 608 - struct clk *pclk; 446 + const struct dw_mipi_dsi_plat_data *pdata = of_device_get_match_data(dev); 609 447 int ret; 610 448 611 449 dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL); ··· 645 483 goto err_clk_get; 646 484 } 647 485 648 - pclk = devm_clk_get(dev, "pclk"); 649 - if (IS_ERR(pclk)) { 650 - ret = PTR_ERR(pclk); 486 + dsi->pclk = devm_clk_get(dev, "pclk"); 487 + if (IS_ERR(dsi->pclk)) { 488 + ret = PTR_ERR(dsi->pclk); 651 489 DRM_ERROR("Unable to get peripheral clock: %d\n", ret); 652 490 goto err_dsi_probe; 653 491 } 654 492 655 - ret = clk_prepare_enable(pclk); 493 + ret = clk_prepare_enable(dsi->pclk); 656 494 if (ret) { 657 495 DRM_ERROR("%s: Failed to enable peripheral clk\n", __func__); 658 496 goto err_dsi_probe; 659 497 } 660 498 661 499 dsi->hw_version = dsi_read(dsi, DSI_VERSION) & VERSION; 662 - clk_disable_unprepare(pclk); 500 + clk_disable_unprepare(dsi->pclk); 663 501 664 502 if (dsi->hw_version != HWVER_130 && dsi->hw_version != HWVER_131) { 665 503 ret = -ENODEV; ··· 675 513 dsi->lane_max_kbps *= 2; 676 514 } 677 515 678 - dw_mipi_dsi_stm_plat_data.base = dsi->base; 679 - dw_mipi_dsi_stm_plat_data.priv_data = dsi; 516 + dsi->pdata = *pdata; 517 + dsi->pdata.base = dsi->base; 518 + dsi->pdata.priv_data = dsi; 519 + 520 + dsi->pdata.max_data_lanes = 2; 521 + dsi->pdata.phy_ops = &dw_mipi_dsi_stm_phy_ops; 680 522 681 523 platform_set_drvdata(pdev, dsi); 682 524 683 - dsi->dsi = dw_mipi_dsi_probe(pdev, &dw_mipi_dsi_stm_plat_data); 525 + dsi->dsi = dw_mipi_dsi_probe(pdev, &dsi->pdata); 684 526 if (IS_ERR(dsi->dsi)) { 685 527 ret = PTR_ERR(dsi->dsi); 686 528 dev_err_probe(dev, ret, "Failed to initialize mipi dsi host\n"); 687 529 goto err_dsi_probe; 688 530 } 531 + 532 + /* 533 + * We need to wait for the generic bridge to probe before enabling and 534 + * register the internal pixel clock. 535 + */ 536 + ret = clk_prepare_enable(dsi->pclk); 537 + if (ret) { 538 + DRM_ERROR("%s: Failed to enable peripheral clk\n", __func__); 539 + goto err_dsi_probe; 540 + } 541 + 542 + ret = dw_mipi_dsi_clk_register(dsi, dev); 543 + if (ret) { 544 + DRM_ERROR("Failed to register DSI pixel clock: %d\n", ret); 545 + clk_disable_unprepare(dsi->pclk); 546 + goto err_dsi_probe; 547 + } 548 + 549 + clk_disable_unprepare(dsi->pclk); 689 550 690 551 return 0; 691 552 ··· 726 541 727 542 dw_mipi_dsi_remove(dsi->dsi); 728 543 clk_disable_unprepare(dsi->pllref_clk); 544 + dw_mipi_dsi_clk_unregister(dsi); 729 545 regulator_disable(dsi->vdd_supply); 730 546 } 731 547 732 - static int __maybe_unused dw_mipi_dsi_stm_suspend(struct device *dev) 548 + static int dw_mipi_dsi_stm_suspend(struct device *dev) 733 549 { 734 - struct dw_mipi_dsi_stm *dsi = dw_mipi_dsi_stm_plat_data.priv_data; 550 + struct dw_mipi_dsi_stm *dsi = dev_get_drvdata(dev); 735 551 736 552 DRM_DEBUG_DRIVER("\n"); 737 553 738 554 clk_disable_unprepare(dsi->pllref_clk); 555 + clk_disable_unprepare(dsi->pclk); 739 556 regulator_disable(dsi->vdd_supply); 740 557 741 558 return 0; 742 559 } 743 560 744 - static int __maybe_unused dw_mipi_dsi_stm_resume(struct device *dev) 561 + static int dw_mipi_dsi_stm_resume(struct device *dev) 745 562 { 746 - struct dw_mipi_dsi_stm *dsi = dw_mipi_dsi_stm_plat_data.priv_data; 563 + struct dw_mipi_dsi_stm *dsi = dev_get_drvdata(dev); 747 564 int ret; 748 565 749 566 DRM_DEBUG_DRIVER("\n"); ··· 756 569 return ret; 757 570 } 758 571 572 + ret = clk_prepare_enable(dsi->pclk); 573 + if (ret) { 574 + regulator_disable(dsi->vdd_supply); 575 + DRM_ERROR("Failed to enable pclk: %d\n", ret); 576 + return ret; 577 + } 578 + 759 579 ret = clk_prepare_enable(dsi->pllref_clk); 760 580 if (ret) { 581 + clk_disable_unprepare(dsi->pclk); 761 582 regulator_disable(dsi->vdd_supply); 762 583 DRM_ERROR("Failed to enable pllref_clk: %d\n", ret); 763 584 return ret; ··· 775 580 } 776 581 777 582 static const struct dev_pm_ops dw_mipi_dsi_stm_pm_ops = { 778 - SET_SYSTEM_SLEEP_PM_OPS(dw_mipi_dsi_stm_suspend, 779 - dw_mipi_dsi_stm_resume) 583 + SYSTEM_SLEEP_PM_OPS(dw_mipi_dsi_stm_suspend, 584 + dw_mipi_dsi_stm_resume) 585 + RUNTIME_PM_OPS(dw_mipi_dsi_stm_suspend, 586 + dw_mipi_dsi_stm_resume, NULL) 780 587 }; 781 588 782 589 static struct platform_driver dw_mipi_dsi_stm_driver = {
+1226
drivers/gpu/drm/stm/lvds.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (C) 2023, STMicroelectronics - All Rights Reserved 4 + * Author(s): Raphaël GALLAIS-POU <raphael.gallais-pou@foss.st.com> for STMicroelectronics. 5 + */ 6 + 7 + #include <drm/drm_atomic_helper.h> 8 + #include <drm/drm_bridge.h> 9 + #include <drm/drm_device.h> 10 + #include <drm/drm_of.h> 11 + #include <drm/drm_panel.h> 12 + #include <drm/drm_print.h> 13 + #include <drm/drm_probe_helper.h> 14 + 15 + #include <linux/clk.h> 16 + #include <linux/clk-provider.h> 17 + #include <linux/io.h> 18 + #include <linux/iopoll.h> 19 + #include <linux/media-bus-format.h> 20 + #include <linux/module.h> 21 + #include <linux/of_device.h> 22 + #include <linux/platform_device.h> 23 + #include <linux/reset.h> 24 + 25 + /* LVDS Host registers */ 26 + #define LVDS_CR 0x0000 /* configuration register */ 27 + #define LVDS_DMLCR0 0x0004 /* data mapping lsb configuration register 0 */ 28 + #define LVDS_DMMCR0 0x0008 /* data mapping msb configuration register 0 */ 29 + #define LVDS_DMLCR1 0x000C /* data mapping lsb configuration register 1 */ 30 + #define LVDS_DMMCR1 0x0010 /* data mapping msb configuration register 1 */ 31 + #define LVDS_DMLCR2 0x0014 /* data mapping lsb configuration register 2 */ 32 + #define LVDS_DMMCR2 0x0018 /* data mapping msb configuration register 2 */ 33 + #define LVDS_DMLCR3 0x001C /* data mapping lsb configuration register 3 */ 34 + #define LVDS_DMMCR3 0x0020 /* data mapping msb configuration register 3 */ 35 + #define LVDS_DMLCR4 0x0024 /* data mapping lsb configuration register 4 */ 36 + #define LVDS_DMMCR4 0x0028 /* data mapping msb configuration register 4 */ 37 + #define LVDS_CDL1CR 0x002C /* channel distrib link 1 configuration register */ 38 + #define LVDS_CDL2CR 0x0030 /* channel distrib link 2 configuration register */ 39 + 40 + #define CDL1CR_DEFAULT 0x04321 /* Default value for CDL1CR */ 41 + #define CDL2CR_DEFAULT 0x59876 /* Default value for CDL2CR */ 42 + 43 + #define LVDS_DMLCR(bit) (LVDS_DMLCR0 + 0x8 * (bit)) 44 + #define LVDS_DMMCR(bit) (LVDS_DMMCR0 + 0x8 * (bit)) 45 + 46 + /* LVDS Wrapper registers */ 47 + #define LVDS_WCLKCR 0x11B0 /* Wrapper clock control register */ 48 + 49 + #define LVDS_HWCFGR 0x1FF0 /* HW configuration register */ 50 + #define LVDS_VERR 0x1FF4 /* Version register */ 51 + #define LVDS_IPIDR 0x1FF8 /* Identification register */ 52 + #define LVDS_SIDR 0x1FFC /* Size Identification register */ 53 + 54 + /* Bitfield description */ 55 + #define CR_LVDSEN BIT(0) /* LVDS PHY Enable */ 56 + #define CR_HSPOL BIT(1) /* Horizontal Synchronization Polarity */ 57 + #define CR_VSPOL BIT(2) /* Vertical Synchronization Polarity */ 58 + #define CR_DEPOL BIT(3) /* Data Enable Polarity */ 59 + #define CR_CI BIT(4) /* Control Internal (software controlled bit) */ 60 + #define CR_LKMOD BIT(5) /* Link Mode, for both Links */ 61 + #define CR_LKPHA BIT(6) /* Link Phase, for both Links */ 62 + #define CR_LK1POL GENMASK(20, 16) /* Link-1 output Polarity */ 63 + #define CR_LK2POL GENMASK(25, 21) /* Link-2 output Polarity */ 64 + 65 + #define DMMCR_MAP0 GENMASK(4, 0) /* Mapping for bit 0 of datalane x */ 66 + #define DMMCR_MAP1 GENMASK(9, 5) /* Mapping for bit 1 of datalane x */ 67 + #define DMMCR_MAP2 GENMASK(14, 10) /* Mapping for bit 2 of datalane x */ 68 + #define DMMCR_MAP3 GENMASK(19, 15) /* Mapping for bit 3 of datalane x */ 69 + #define DMLCR_MAP4 GENMASK(4, 0) /* Mapping for bit 4 of datalane x */ 70 + #define DMLCR_MAP5 GENMASK(9, 5) /* Mapping for bit 5 of datalane x */ 71 + #define DMLCR_MAP6 GENMASK(14, 10) /* Mapping for bit 6 of datalane x */ 72 + 73 + #define CDLCR_DISTR0 GENMASK(3, 0) /* Channel distribution for lane 0 */ 74 + #define CDLCR_DISTR1 GENMASK(7, 4) /* Channel distribution for lane 1 */ 75 + #define CDLCR_DISTR2 GENMASK(11, 8) /* Channel distribution for lane 2 */ 76 + #define CDLCR_DISTR3 GENMASK(15, 12) /* Channel distribution for lane 3 */ 77 + #define CDLCR_DISTR4 GENMASK(19, 16) /* Channel distribution for lane 4 */ 78 + 79 + #define PHY_GCR_BIT_CLK_OUT BIT(0) /* BIT clock enable */ 80 + #define PHY_GCR_LS_CLK_OUT BIT(4) /* LS clock enable */ 81 + #define PHY_GCR_DP_CLK_OUT BIT(8) /* DP clock enable */ 82 + #define PHY_GCR_RSTZ BIT(24) /* LVDS PHY digital reset */ 83 + #define PHY_GCR_DIV_RSTN BIT(25) /* Output divider reset */ 84 + #define PHY_SCR_TX_EN BIT(16) /* Transmission mode enable */ 85 + /* Current mode driver enable */ 86 + #define PHY_CMCR_CM_EN_DL (BIT(28) | BIT(20) | BIT(12) | BIT(4)) 87 + #define PHY_CMCR_CM_EN_DL4 BIT(4) 88 + /* Bias enable */ 89 + #define PHY_BCR1_EN_BIAS_DL (BIT(16) | BIT(12) | BIT(8) | BIT(4) | BIT(0)) 90 + #define PHY_BCR2_BIAS_EN BIT(28) 91 + /* Voltage mode driver enable */ 92 + #define PHY_BCR3_VM_EN_DL (BIT(16) | BIT(12) | BIT(8) | BIT(4) | BIT(0)) 93 + #define PHY_DCR_POWER_OK BIT(12) 94 + #define PHY_CFGCR_EN_DIG_DL GENMASK(4, 0) /* LVDS PHY digital lane enable */ 95 + #define PHY_PLLCR1_PLL_EN BIT(0) /* LVDS PHY PLL enable */ 96 + #define PHY_PLLCR1_EN_SD BIT(1) /* LVDS PHY PLL sigma-delta signal enable */ 97 + #define PHY_PLLCR1_EN_TWG BIT(2) /* LVDS PHY PLL triangular wave generator enable */ 98 + #define PHY_PLLCR1_DIV_EN BIT(8) /* LVDS PHY PLL dividers enable */ 99 + #define PHY_PLLCR2_NDIV GENMASK(25, 16) /* NDIV mask value */ 100 + #define PHY_PLLCR2_BDIV GENMASK(9, 0) /* BDIV mask value */ 101 + #define PHY_PLLSR_PLL_LOCK BIT(0) /* LVDS PHY PLL lock status */ 102 + #define PHY_PLLSDCR1_MDIV GENMASK(9, 0) /* MDIV mask value */ 103 + #define PHY_PLLTESTCR_TDIV GENMASK(25, 16) /* TDIV mask value */ 104 + #define PHY_PLLTESTCR_CLK_EN BIT(0) /* Test clock enable */ 105 + #define PHY_PLLTESTCR_EN BIT(8) /* Test divider output enable */ 106 + 107 + #define WCLKCR_SECND_CLKPIX_SEL BIT(0) /* Pixel clock selection */ 108 + #define WCLKCR_SRCSEL BIT(8) /* Source selection for the pixel clock */ 109 + 110 + /* Sleep & timeout for pll lock/unlock */ 111 + #define SLEEP_US 1000 112 + #define TIMEOUT_US 200000 113 + 114 + /* 115 + * The link phase defines whether an ODD pixel is carried over together with 116 + * the next EVEN pixel or together with the previous EVEN pixel. 117 + * 118 + * LVDS_DUAL_LINK_EVEN_ODD_PIXELS (LKPHA = 0) 119 + * 120 + * ,--------. ,--------. ,--------. ,--------. ,---------. 121 + * | ODD LK \/ PIXEL 3 \/ PIXEL 1 \/ PIXEL' 1 \/ PIXEL' 3 | 122 + * | EVEN LK /\ PIXEL 2 /\ PIXEL' 0 /\ PIXEL' 2 /\ PIXEL' 4 | 123 + * `--------' `--------' `--------' `--------' `---------' 124 + * 125 + * LVDS_DUAL_LINK_ODD_EVEN_PIXELS (LKPHA = 1) 126 + * 127 + * ,--------. ,--------. ,--------. ,--------. ,---------. 128 + * | ODD LK \/ PIXEL 3 \/ PIXEL 1 \/ PIXEL' 1 \/ PIXEL' 3 | 129 + * | EVEN LK /\ PIXEL 4 /\ PIXEL 2 /\ PIXEL' 0 /\ PIXEL' 2 | 130 + * `--------' `--------' `--------' `--------' `---------' 131 + * 132 + */ 133 + enum lvds_link_type { 134 + LVDS_SINGLE_LINK_PRIMARY = 0, 135 + LVDS_SINGLE_LINK_SECONDARY, 136 + LVDS_DUAL_LINK_EVEN_ODD_PIXELS, 137 + LVDS_DUAL_LINK_ODD_EVEN_PIXELS, 138 + }; 139 + 140 + enum lvds_pixel { 141 + PIX_R_0 = 0, 142 + PIX_R_1, 143 + PIX_R_2, 144 + PIX_R_3, 145 + PIX_R_4, 146 + PIX_R_5, 147 + PIX_R_6, 148 + PIX_R_7, 149 + PIX_G_0, 150 + PIX_G_1, 151 + PIX_G_2, 152 + PIX_G_3, 153 + PIX_G_4, 154 + PIX_G_5, 155 + PIX_G_6, 156 + PIX_G_7, 157 + PIX_B_0, 158 + PIX_B_1, 159 + PIX_B_2, 160 + PIX_B_3, 161 + PIX_B_4, 162 + PIX_B_5, 163 + PIX_B_6, 164 + PIX_B_7, 165 + PIX_H_S, 166 + PIX_V_S, 167 + PIX_D_E, 168 + PIX_C_E, 169 + PIX_C_I, 170 + PIX_TOG, 171 + PIX_ONE, 172 + PIX_ZER, 173 + }; 174 + 175 + struct phy_reg_offsets { 176 + u32 GCR; /* Global Control Register */ 177 + u32 CMCR1; /* Current Mode Control Register 1 */ 178 + u32 CMCR2; /* Current Mode Control Register 2 */ 179 + u32 SCR; /* Serial Control Register */ 180 + u32 BCR1; /* Bias Control Register 1 */ 181 + u32 BCR2; /* Bias Control Register 2 */ 182 + u32 BCR3; /* Bias Control Register 3 */ 183 + u32 MPLCR; /* Monitor PLL Lock Control Register */ 184 + u32 DCR; /* Debug Control Register */ 185 + u32 SSR1; /* Spare Status Register 1 */ 186 + u32 CFGCR; /* Configuration Control Register */ 187 + u32 PLLCR1; /* PLL_MODE 1 Control Register */ 188 + u32 PLLCR2; /* PLL_MODE 2 Control Register */ 189 + u32 PLLSR; /* PLL Status Register */ 190 + u32 PLLSDCR1; /* PLL_SD_1 Control Register */ 191 + u32 PLLSDCR2; /* PLL_SD_2 Control Register */ 192 + u32 PLLTWGCR1;/* PLL_TWG_1 Control Register */ 193 + u32 PLLTWGCR2;/* PLL_TWG_2 Control Register */ 194 + u32 PLLCPCR; /* PLL_CP Control Register */ 195 + u32 PLLTESTCR;/* PLL_TEST Control Register */ 196 + }; 197 + 198 + struct lvds_phy_info { 199 + u32 base; 200 + struct phy_reg_offsets ofs; 201 + }; 202 + 203 + static struct lvds_phy_info lvds_phy_16ff_primary = { 204 + .base = 0x1000, 205 + .ofs = { 206 + .GCR = 0x0, 207 + .CMCR1 = 0xC, 208 + .CMCR2 = 0x10, 209 + .SCR = 0x20, 210 + .BCR1 = 0x2C, 211 + .BCR2 = 0x30, 212 + .BCR3 = 0x34, 213 + .MPLCR = 0x64, 214 + .DCR = 0x84, 215 + .SSR1 = 0x88, 216 + .CFGCR = 0xA0, 217 + .PLLCR1 = 0xC0, 218 + .PLLCR2 = 0xC4, 219 + .PLLSR = 0xC8, 220 + .PLLSDCR1 = 0xCC, 221 + .PLLSDCR2 = 0xD0, 222 + .PLLTWGCR1 = 0xD4, 223 + .PLLTWGCR2 = 0xD8, 224 + .PLLCPCR = 0xE0, 225 + .PLLTESTCR = 0xE8, 226 + } 227 + }; 228 + 229 + static struct lvds_phy_info lvds_phy_16ff_secondary = { 230 + .base = 0x1100, 231 + .ofs = { 232 + .GCR = 0x0, 233 + .CMCR1 = 0xC, 234 + .CMCR2 = 0x10, 235 + .SCR = 0x20, 236 + .BCR1 = 0x2C, 237 + .BCR2 = 0x30, 238 + .BCR3 = 0x34, 239 + .MPLCR = 0x64, 240 + .DCR = 0x84, 241 + .SSR1 = 0x88, 242 + .CFGCR = 0xA0, 243 + .PLLCR1 = 0xC0, 244 + .PLLCR2 = 0xC4, 245 + .PLLSR = 0xC8, 246 + .PLLSDCR1 = 0xCC, 247 + .PLLSDCR2 = 0xD0, 248 + .PLLTWGCR1 = 0xD4, 249 + .PLLTWGCR2 = 0xD8, 250 + .PLLCPCR = 0xE0, 251 + .PLLTESTCR = 0xE8, 252 + } 253 + }; 254 + 255 + struct stm_lvds { 256 + void __iomem *base; 257 + struct device *dev; 258 + struct clk *pclk; /* APB peripheral clock */ 259 + struct clk *pllref_clk; /* Reference clock for the internal PLL */ 260 + struct clk_hw lvds_ck_px; /* Pixel clock */ 261 + u32 pixel_clock_rate; /* Pixel clock rate */ 262 + 263 + struct lvds_phy_info *primary; 264 + struct lvds_phy_info *secondary; 265 + 266 + struct drm_bridge lvds_bridge; 267 + struct drm_bridge *next_bridge; 268 + struct drm_connector connector; 269 + struct drm_encoder *encoder; 270 + struct drm_panel *panel; 271 + 272 + u32 hw_version; 273 + u32 link_type; 274 + }; 275 + 276 + #define bridge_to_stm_lvds(b) \ 277 + container_of(b, struct stm_lvds, lvds_bridge) 278 + 279 + #define connector_to_stm_lvds(c) \ 280 + container_of(c, struct stm_lvds, connector) 281 + 282 + #define lvds_is_dual_link(lvds) \ 283 + ({ \ 284 + typeof(lvds) __lvds = (lvds); \ 285 + __lvds == LVDS_DUAL_LINK_EVEN_ODD_PIXELS || \ 286 + __lvds == LVDS_DUAL_LINK_ODD_EVEN_PIXELS; \ 287 + }) 288 + 289 + static inline void lvds_write(struct stm_lvds *lvds, u32 reg, u32 val) 290 + { 291 + writel(val, lvds->base + reg); 292 + } 293 + 294 + static inline u32 lvds_read(struct stm_lvds *lvds, u32 reg) 295 + { 296 + return readl(lvds->base + reg); 297 + } 298 + 299 + static inline void lvds_set(struct stm_lvds *lvds, u32 reg, u32 mask) 300 + { 301 + lvds_write(lvds, reg, lvds_read(lvds, reg) | mask); 302 + } 303 + 304 + static inline void lvds_clear(struct stm_lvds *lvds, u32 reg, u32 mask) 305 + { 306 + lvds_write(lvds, reg, lvds_read(lvds, reg) & ~mask); 307 + } 308 + 309 + /* 310 + * Expected JEIDA-RGB888 data to be sent in LSB format 311 + * bit6 ............................bit0 312 + * CHAN0 {ONE, ONE, ZERO, ZERO, ZERO, ONE, ONE} 313 + * CHAN1 {G2, R7, R6, R5, R4, R3, R2} 314 + * CHAN2 {B3, B2, G7, G6, G5, G4, G3} 315 + * CHAN3 {DE, VS, HS, B7, B6, B5, B4} 316 + * CHAN4 {CE, B1, B0, G1, G0, R1, R0} 317 + */ 318 + static enum lvds_pixel lvds_bitmap_jeida_rgb888[5][7] = { 319 + { PIX_ONE, PIX_ONE, PIX_ZER, PIX_ZER, PIX_ZER, PIX_ONE, PIX_ONE }, 320 + { PIX_G_2, PIX_R_7, PIX_R_6, PIX_R_5, PIX_R_4, PIX_R_3, PIX_R_2 }, 321 + { PIX_B_3, PIX_B_2, PIX_G_7, PIX_G_6, PIX_G_5, PIX_G_4, PIX_G_3 }, 322 + { PIX_D_E, PIX_V_S, PIX_H_S, PIX_B_7, PIX_B_6, PIX_B_5, PIX_B_4 }, 323 + { PIX_C_E, PIX_B_1, PIX_B_0, PIX_G_1, PIX_G_0, PIX_R_1, PIX_R_0 } 324 + }; 325 + 326 + /* 327 + * Expected VESA-RGB888 data to be sent in LSB format 328 + * bit6 ............................bit0 329 + * CHAN0 {ONE, ONE, ZERO, ZERO, ZERO, ONE, ONE} 330 + * CHAN1 {G0, R5, R4, R3, R2, R1, R0} 331 + * CHAN2 {B1, B0, G5, G4, G3, G2, G1} 332 + * CHAN3 {DE, VS, HS, B5, B4, B3, B2} 333 + * CHAN4 {CE, B7, B6, G7, G6, R7, R6} 334 + */ 335 + static enum lvds_pixel lvds_bitmap_vesa_rgb888[5][7] = { 336 + { PIX_ONE, PIX_ONE, PIX_ZER, PIX_ZER, PIX_ZER, PIX_ONE, PIX_ONE }, 337 + { PIX_G_0, PIX_R_5, PIX_R_4, PIX_R_3, PIX_R_2, PIX_R_1, PIX_R_0 }, 338 + { PIX_B_1, PIX_B_0, PIX_G_5, PIX_G_4, PIX_G_3, PIX_G_2, PIX_G_1 }, 339 + { PIX_D_E, PIX_V_S, PIX_H_S, PIX_B_5, PIX_B_4, PIX_B_3, PIX_B_2 }, 340 + { PIX_C_E, PIX_B_7, PIX_B_6, PIX_G_7, PIX_G_6, PIX_R_7, PIX_R_6 } 341 + }; 342 + 343 + /* 344 + * Clocks and PHY related functions 345 + */ 346 + static int lvds_pll_enable(struct stm_lvds *lvds, struct lvds_phy_info *phy) 347 + { 348 + struct drm_device *drm = lvds->lvds_bridge.dev; 349 + u32 lvds_gcr; 350 + int val, ret; 351 + 352 + /* 353 + * PLL lock timing control for the monitor unmask after startup (pll_en) 354 + * Adjusted value so that the masking window is opened at start-up 355 + */ 356 + lvds_write(lvds, phy->base + phy->ofs.MPLCR, (0x200 - 0x160) << 16); 357 + 358 + /* Enable bias */ 359 + lvds_write(lvds, phy->base + phy->ofs.BCR2, PHY_BCR2_BIAS_EN); 360 + 361 + /* Enable DP, LS, BIT clock output */ 362 + lvds_gcr = PHY_GCR_DP_CLK_OUT | PHY_GCR_LS_CLK_OUT | PHY_GCR_BIT_CLK_OUT; 363 + lvds_set(lvds, phy->base + phy->ofs.GCR, lvds_gcr); 364 + 365 + /* Power up all output dividers */ 366 + lvds_set(lvds, phy->base + phy->ofs.PLLTESTCR, PHY_PLLTESTCR_EN); 367 + lvds_set(lvds, phy->base + phy->ofs.PLLCR1, PHY_PLLCR1_DIV_EN); 368 + 369 + /* Set PHY in serial transmission mode */ 370 + lvds_set(lvds, phy->base + phy->ofs.SCR, PHY_SCR_TX_EN); 371 + 372 + /* Enable the LVDS PLL & wait for its lock */ 373 + lvds_set(lvds, phy->base + phy->ofs.PLLCR1, PHY_PLLCR1_PLL_EN); 374 + ret = readl_poll_timeout_atomic(lvds->base + phy->base + phy->ofs.PLLSR, 375 + val, val & PHY_PLLSR_PLL_LOCK, 376 + SLEEP_US, TIMEOUT_US); 377 + if (ret) 378 + drm_err(drm, "!TIMEOUT! waiting PLL, let's continue\n"); 379 + 380 + /* WCLKCR_SECND_CLKPIX_SEL is for dual link */ 381 + lvds_write(lvds, LVDS_WCLKCR, WCLKCR_SECND_CLKPIX_SEL); 382 + 383 + lvds_set(lvds, phy->ofs.PLLTESTCR, PHY_PLLTESTCR_CLK_EN); 384 + 385 + return ret; 386 + } 387 + 388 + static int pll_get_clkout_khz(int clkin_khz, int bdiv, int mdiv, int ndiv) 389 + { 390 + int divisor = ndiv * bdiv; 391 + 392 + /* Prevents from division by 0 */ 393 + if (!divisor) 394 + return 0; 395 + 396 + return clkin_khz * mdiv / divisor; 397 + } 398 + 399 + #define TDIV 70 400 + #define NDIV_MIN 2 401 + #define NDIV_MAX 6 402 + #define BDIV_MIN 2 403 + #define BDIV_MAX 6 404 + #define MDIV_MIN 1 405 + #define MDIV_MAX 1023 406 + 407 + static int lvds_pll_get_params(struct stm_lvds *lvds, 408 + unsigned int clkin_khz, unsigned int clkout_khz, 409 + unsigned int *bdiv, unsigned int *mdiv, unsigned int *ndiv) 410 + { 411 + int delta, best_delta; /* all in khz */ 412 + int i, o, n; 413 + 414 + /* Early checks preventing division by 0 & odd results */ 415 + if (clkin_khz <= 0 || clkout_khz <= 0) 416 + return -EINVAL; 417 + 418 + best_delta = 1000000; /* big started value (1000000khz) */ 419 + 420 + for (i = NDIV_MIN; i <= NDIV_MAX; i++) { 421 + for (o = BDIV_MIN; o <= BDIV_MAX; o++) { 422 + n = DIV_ROUND_CLOSEST(i * o * clkout_khz, clkin_khz); 423 + /* Check ndiv according to vco range */ 424 + if (n < MDIV_MIN || n > MDIV_MAX) 425 + continue; 426 + /* Check if new delta is better & saves parameters */ 427 + delta = pll_get_clkout_khz(clkin_khz, i, n, o) - clkout_khz; 428 + if (delta < 0) 429 + delta = -delta; 430 + if (delta < best_delta) { 431 + *ndiv = i; 432 + *mdiv = n; 433 + *bdiv = o; 434 + best_delta = delta; 435 + } 436 + /* fast return in case of "perfect result" */ 437 + if (!delta) 438 + return 0; 439 + } 440 + } 441 + 442 + return 0; 443 + } 444 + 445 + static void lvds_pll_config(struct stm_lvds *lvds, struct lvds_phy_info *phy) 446 + { 447 + unsigned int pll_in_khz, bdiv = 0, mdiv = 0, ndiv = 0; 448 + struct clk_hw *hwclk; 449 + int multiplier; 450 + 451 + /* 452 + * The LVDS PHY includes a low power low jitter high performance and 453 + * highly configuration Phase Locked Loop supporting integer and 454 + * fractional multiplication ratios and Spread Spectrum Clocking. In 455 + * integer mode, the only software supported feature for now, the PLL is 456 + * made of a pre-divider NDIV, a feedback multiplier MDIV, followed by 457 + * several post-dividers, each one with a specific application. 458 + * 459 + * ,------. ,-----. ,-----. 460 + * Fref --> | NDIV | -Fpdf-> | PFD | --> | VCO | --------> Fvco 461 + * `------' ,-> | | `-----' | 462 + * | `-----' | 463 + * | ,------. | 464 + * `-------- | MDIV | <-----' 465 + * `------' 466 + * 467 + * From the output of the VCO, the clock can be optionally extracted on 468 + * the RCC clock observer, with a divider TDIV, for testing purpose, or 469 + * is passed through a programmable post-divider BDIV. Finally, the 470 + * frequency can be divided further with two fixed dividers. 471 + * 472 + * ,--------. 473 + * ,-----> | DP div | ----------------> Fdp 474 + * ,------. | `--------' 475 + * Fvco --> | BDIV | ------------------------------------> Fbit 476 + * | `------' ,------. | 477 + * `-------------> | TDIV | --.---------------------> ClkObs 478 + * '------' | ,--------. 479 + * `--> | LS div | ------> Fls 480 + * '--------' 481 + * 482 + * The LS and DP clock dividers operate at a fixed ratio of 7 and 3.5 483 + * respectively with regards to fbit. LS divider converts the bit clock 484 + * to a pixel clock per lane per clock sample (Fls). This is useful 485 + * when used to generate a dot clock for the display unit RGB output, 486 + * and DP divider is. 487 + */ 488 + 489 + hwclk = __clk_get_hw(lvds->pllref_clk); 490 + if (!hwclk) 491 + return; 492 + 493 + pll_in_khz = clk_hw_get_rate(hwclk) / 1000; 494 + 495 + if (lvds_is_dual_link(lvds->link_type)) 496 + multiplier = 2; 497 + else 498 + multiplier = 1; 499 + 500 + lvds_pll_get_params(lvds, pll_in_khz, 501 + lvds->pixel_clock_rate * 7 / 1000 / multiplier, 502 + &bdiv, &mdiv, &ndiv); 503 + 504 + /* Set BDIV, MDIV and NDIV */ 505 + lvds_write(lvds, phy->base + phy->ofs.PLLCR2, ndiv << 16); 506 + lvds_set(lvds, phy->base + phy->ofs.PLLCR2, bdiv); 507 + lvds_write(lvds, phy->base + phy->ofs.PLLSDCR1, mdiv); 508 + 509 + /* Hardcode TDIV as dynamic values are not yet implemented */ 510 + lvds_write(lvds, phy->base + phy->ofs.PLLTESTCR, TDIV << 16); 511 + 512 + /* 513 + * For now, PLL just needs to be in integer mode 514 + * Fractional and spread spectrum clocking are not yet implemented 515 + * 516 + * PLL integer mode: 517 + * - PMRY_PLL_TWG_STEP = PMRY_PLL_SD_INT_RATIO 518 + * - EN_TWG = 0 519 + * - EN_SD = 0 520 + * - DOWN_SPREAD = 0 521 + * 522 + * PLL fractional mode: 523 + * - EN_TWG = 0 524 + * - EN_SD = 1 525 + * - DOWN_SPREAD = 0 526 + * 527 + * Spread Spectrum Clocking 528 + * - EN_TWG = 1 529 + * - EN_SD = 1 530 + */ 531 + 532 + /* Disable TWG and SD */ 533 + lvds_clear(lvds, phy->base + phy->ofs.PLLCR1, PHY_PLLCR1_EN_TWG | PHY_PLLCR1_EN_SD); 534 + 535 + /* Power up bias and PLL dividers */ 536 + lvds_set(lvds, phy->base + phy->ofs.DCR, PHY_DCR_POWER_OK); 537 + lvds_set(lvds, phy->base + phy->ofs.CMCR1, PHY_CMCR_CM_EN_DL); 538 + lvds_set(lvds, phy->base + phy->ofs.CMCR2, PHY_CMCR_CM_EN_DL4); 539 + 540 + /* Set up voltage mode */ 541 + lvds_set(lvds, phy->base + phy->ofs.PLLCPCR, 0x1); 542 + lvds_set(lvds, phy->base + phy->ofs.BCR3, PHY_BCR3_VM_EN_DL); 543 + lvds_set(lvds, phy->base + phy->ofs.BCR1, PHY_BCR1_EN_BIAS_DL); 544 + /* Enable digital datalanes */ 545 + lvds_set(lvds, phy->base + phy->ofs.CFGCR, PHY_CFGCR_EN_DIG_DL); 546 + } 547 + 548 + static int lvds_pixel_clk_enable(struct clk_hw *hw) 549 + { 550 + struct stm_lvds *lvds = container_of(hw, struct stm_lvds, lvds_ck_px); 551 + struct drm_device *drm = lvds->lvds_bridge.dev; 552 + struct lvds_phy_info *phy; 553 + int ret; 554 + 555 + ret = clk_prepare_enable(lvds->pclk); 556 + if (ret) { 557 + drm_err(drm, "Failed to enable lvds peripheral clk\n"); 558 + return ret; 559 + } 560 + 561 + ret = clk_prepare_enable(lvds->pllref_clk); 562 + if (ret) { 563 + drm_err(drm, "Failed to enable lvds reference clk\n"); 564 + clk_disable_unprepare(lvds->pclk); 565 + return ret; 566 + } 567 + 568 + /* In case we are operating in dual link the second PHY is set before the primary PHY. */ 569 + if (lvds->secondary) { 570 + phy = lvds->secondary; 571 + 572 + /* Release LVDS PHY from reset mode */ 573 + lvds_set(lvds, phy->base + phy->ofs.GCR, PHY_GCR_DIV_RSTN | PHY_GCR_RSTZ); 574 + lvds_pll_config(lvds, phy); 575 + 576 + ret = lvds_pll_enable(lvds, phy); 577 + if (ret) { 578 + drm_err(drm, "Failed to enable secondary PHY PLL: %d\n", ret); 579 + return ret; 580 + } 581 + } 582 + 583 + if (lvds->primary) { 584 + phy = lvds->primary; 585 + 586 + /* Release LVDS PHY from reset mode */ 587 + lvds_set(lvds, phy->base + phy->ofs.GCR, PHY_GCR_DIV_RSTN | PHY_GCR_RSTZ); 588 + lvds_pll_config(lvds, phy); 589 + 590 + ret = lvds_pll_enable(lvds, phy); 591 + if (ret) { 592 + drm_err(drm, "Failed to enable primary PHY PLL: %d\n", ret); 593 + return ret; 594 + } 595 + } 596 + 597 + return 0; 598 + } 599 + 600 + static void lvds_pixel_clk_disable(struct clk_hw *hw) 601 + { 602 + struct stm_lvds *lvds = container_of(hw, struct stm_lvds, lvds_ck_px); 603 + 604 + /* 605 + * For each PHY: 606 + * Disable DP, LS, BIT clock outputs 607 + * Shutdown the PLL 608 + * Assert LVDS PHY in reset mode 609 + */ 610 + 611 + if (lvds->primary) { 612 + lvds_clear(lvds, lvds->primary->base + lvds->primary->ofs.GCR, 613 + (PHY_GCR_DP_CLK_OUT | PHY_GCR_LS_CLK_OUT | PHY_GCR_BIT_CLK_OUT)); 614 + lvds_clear(lvds, lvds->primary->base + lvds->primary->ofs.PLLCR1, 615 + PHY_PLLCR1_PLL_EN); 616 + lvds_clear(lvds, lvds->primary->base + lvds->primary->ofs.GCR, 617 + PHY_GCR_DIV_RSTN | PHY_GCR_RSTZ); 618 + } 619 + 620 + if (lvds->secondary) { 621 + lvds_clear(lvds, lvds->secondary->base + lvds->secondary->ofs.GCR, 622 + (PHY_GCR_DP_CLK_OUT | PHY_GCR_LS_CLK_OUT | PHY_GCR_BIT_CLK_OUT)); 623 + lvds_clear(lvds, lvds->secondary->base + lvds->secondary->ofs.PLLCR1, 624 + PHY_PLLCR1_PLL_EN); 625 + lvds_clear(lvds, lvds->secondary->base + lvds->secondary->ofs.GCR, 626 + PHY_GCR_DIV_RSTN | PHY_GCR_RSTZ); 627 + } 628 + 629 + clk_disable_unprepare(lvds->pllref_clk); 630 + clk_disable_unprepare(lvds->pclk); 631 + } 632 + 633 + static unsigned long lvds_pixel_clk_recalc_rate(struct clk_hw *hw, 634 + unsigned long parent_rate) 635 + { 636 + struct stm_lvds *lvds = container_of(hw, struct stm_lvds, lvds_ck_px); 637 + struct drm_device *drm = lvds->lvds_bridge.dev; 638 + unsigned int pll_in_khz, bdiv, mdiv, ndiv; 639 + int ret, multiplier, pll_out_khz; 640 + u32 val; 641 + 642 + ret = clk_prepare_enable(lvds->pclk); 643 + if (ret) { 644 + drm_err(drm, "Failed to enable lvds peripheral clk\n"); 645 + return 0; 646 + } 647 + 648 + if (lvds_is_dual_link(lvds->link_type)) 649 + multiplier = 2; 650 + else 651 + multiplier = 1; 652 + 653 + val = lvds_read(lvds, lvds->primary->base + lvds->primary->ofs.PLLCR2); 654 + 655 + ndiv = (val & PHY_PLLCR2_NDIV) >> 16; 656 + bdiv = (val & PHY_PLLCR2_BDIV) >> 0; 657 + 658 + mdiv = (unsigned int)lvds_read(lvds, 659 + lvds->primary->base + lvds->primary->ofs.PLLSDCR1); 660 + 661 + pll_in_khz = (unsigned int)(parent_rate / 1000); 662 + 663 + /* Compute values if not yet accessible */ 664 + if (val == 0 || mdiv == 0) { 665 + lvds_pll_get_params(lvds, pll_in_khz, 666 + lvds->pixel_clock_rate * 7 / 1000 / multiplier, 667 + &bdiv, &mdiv, &ndiv); 668 + } 669 + 670 + pll_out_khz = pll_get_clkout_khz(pll_in_khz, bdiv, mdiv, ndiv); 671 + drm_dbg(drm, "ndiv %d , bdiv %d, mdiv %d, pll_out_khz %d\n", 672 + ndiv, bdiv, mdiv, pll_out_khz); 673 + 674 + /* 675 + * 1/7 because for each pixel in 1 lane there is 7 bits 676 + * We want pixclk, not bitclk 677 + */ 678 + lvds->pixel_clock_rate = pll_out_khz * 1000 * multiplier / 7; 679 + 680 + clk_disable_unprepare(lvds->pclk); 681 + 682 + return (unsigned long)lvds->pixel_clock_rate; 683 + } 684 + 685 + static long lvds_pixel_clk_round_rate(struct clk_hw *hw, unsigned long rate, 686 + unsigned long *parent_rate) 687 + { 688 + struct stm_lvds *lvds = container_of(hw, struct stm_lvds, lvds_ck_px); 689 + unsigned int pll_in_khz, bdiv = 0, mdiv = 0, ndiv = 0; 690 + const struct drm_connector *connector; 691 + const struct drm_display_mode *mode; 692 + int multiplier; 693 + 694 + connector = &lvds->connector; 695 + if (!connector) 696 + return -EINVAL; 697 + 698 + if (list_empty(&connector->modes)) { 699 + drm_dbg(connector->dev, "connector: empty modes list\n"); 700 + return -EINVAL; 701 + } 702 + 703 + mode = list_first_entry(&connector->modes, 704 + struct drm_display_mode, head); 705 + 706 + pll_in_khz = (unsigned int)(*parent_rate / 1000); 707 + 708 + if (lvds_is_dual_link(lvds->link_type)) 709 + multiplier = 2; 710 + else 711 + multiplier = 1; 712 + 713 + lvds_pll_get_params(lvds, pll_in_khz, mode->clock * 7 / multiplier, &bdiv, &mdiv, &ndiv); 714 + 715 + /* 716 + * 1/7 because for each pixel in 1 lane there is 7 bits 717 + * We want pixclk, not bitclk 718 + */ 719 + lvds->pixel_clock_rate = (unsigned long)pll_get_clkout_khz(pll_in_khz, bdiv, mdiv, ndiv) 720 + * 1000 * multiplier / 7; 721 + 722 + return lvds->pixel_clock_rate; 723 + } 724 + 725 + static const struct clk_ops lvds_pixel_clk_ops = { 726 + .enable = lvds_pixel_clk_enable, 727 + .disable = lvds_pixel_clk_disable, 728 + .recalc_rate = lvds_pixel_clk_recalc_rate, 729 + .round_rate = lvds_pixel_clk_round_rate, 730 + }; 731 + 732 + static const struct clk_init_data clk_data = { 733 + .name = "clk_pix_lvds", 734 + .ops = &lvds_pixel_clk_ops, 735 + .parent_names = (const char * []) {"ck_ker_lvdsphy"}, 736 + .num_parents = 1, 737 + .flags = CLK_IGNORE_UNUSED, 738 + }; 739 + 740 + static void lvds_pixel_clk_unregister(void *data) 741 + { 742 + struct stm_lvds *lvds = data; 743 + 744 + of_clk_del_provider(lvds->dev->of_node); 745 + clk_hw_unregister(&lvds->lvds_ck_px); 746 + } 747 + 748 + static int lvds_pixel_clk_register(struct stm_lvds *lvds) 749 + { 750 + struct device_node *node = lvds->dev->of_node; 751 + int ret; 752 + 753 + lvds->lvds_ck_px.init = &clk_data; 754 + 755 + /* set the rate by default at 148500000 */ 756 + lvds->pixel_clock_rate = 148500000; 757 + 758 + ret = clk_hw_register(lvds->dev, &lvds->lvds_ck_px); 759 + if (ret) 760 + return ret; 761 + 762 + ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, 763 + &lvds->lvds_ck_px); 764 + if (ret) 765 + clk_hw_unregister(&lvds->lvds_ck_px); 766 + 767 + return ret; 768 + } 769 + 770 + /* 771 + * Host configuration related 772 + */ 773 + static void lvds_config_data_mapping(struct stm_lvds *lvds) 774 + { 775 + struct drm_device *drm = lvds->lvds_bridge.dev; 776 + const struct drm_display_info *info; 777 + enum lvds_pixel (*bitmap)[7]; 778 + u32 lvds_dmlcr, lvds_dmmcr; 779 + int i; 780 + 781 + info = &(&lvds->connector)->display_info; 782 + if (!info->num_bus_formats || !info->bus_formats) { 783 + drm_warn(drm, "No LVDS bus format reported\n"); 784 + return; 785 + } 786 + 787 + switch (info->bus_formats[0]) { 788 + case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: /* VESA-RGB666 */ 789 + drm_warn(drm, "Pixel format with data mapping not yet supported.\n"); 790 + return; 791 + case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: /* VESA-RGB888 */ 792 + bitmap = lvds_bitmap_vesa_rgb888; 793 + break; 794 + case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: /* JEIDA-RGB888 */ 795 + bitmap = lvds_bitmap_jeida_rgb888; 796 + break; 797 + default: 798 + drm_warn(drm, "Unsupported LVDS bus format 0x%04x\n", info->bus_formats[0]); 799 + return; 800 + } 801 + 802 + /* Set bitmap for each lane */ 803 + for (i = 0; i < 5; i++) { 804 + lvds_dmlcr = ((bitmap[i][0]) 805 + + (bitmap[i][1] << 5) 806 + + (bitmap[i][2] << 10) 807 + + (bitmap[i][3] << 15)); 808 + lvds_dmmcr = ((bitmap[i][4]) 809 + + (bitmap[i][5] << 5) 810 + + (bitmap[i][6] << 10)); 811 + 812 + lvds_write(lvds, LVDS_DMLCR(i), lvds_dmlcr); 813 + lvds_write(lvds, LVDS_DMMCR(i), lvds_dmmcr); 814 + } 815 + } 816 + 817 + static void lvds_config_mode(struct stm_lvds *lvds) 818 + { 819 + u32 bus_flags, lvds_cr = 0, lvds_cdl1cr = 0, lvds_cdl2cr = 0; 820 + const struct drm_display_mode *mode; 821 + const struct drm_connector *connector; 822 + 823 + connector = &lvds->connector; 824 + if (!connector) 825 + return; 826 + 827 + if (list_empty(&connector->modes)) { 828 + drm_dbg(connector->dev, "connector: empty modes list\n"); 829 + return; 830 + } 831 + 832 + bus_flags = connector->display_info.bus_flags; 833 + mode = list_first_entry(&connector->modes, 834 + struct drm_display_mode, head); 835 + 836 + lvds_clear(lvds, LVDS_CR, CR_LKMOD); 837 + lvds_clear(lvds, LVDS_CDL1CR, CDLCR_DISTR0 | CDLCR_DISTR1 | CDLCR_DISTR2 | 838 + CDLCR_DISTR3 | CDLCR_DISTR4); 839 + lvds_clear(lvds, LVDS_CDL2CR, CDLCR_DISTR0 | CDLCR_DISTR1 | CDLCR_DISTR2 | 840 + CDLCR_DISTR3 | CDLCR_DISTR4); 841 + 842 + /* Set channel distribution */ 843 + if (lvds->primary) 844 + lvds_cdl1cr = CDL1CR_DEFAULT; 845 + 846 + if (lvds->secondary) { 847 + lvds_cr |= CR_LKMOD; 848 + lvds_cdl2cr = CDL2CR_DEFAULT; 849 + } 850 + 851 + /* Set signal polarity */ 852 + if (bus_flags & DRM_BUS_FLAG_DE_LOW) 853 + lvds_cr |= CR_DEPOL; 854 + 855 + if (mode->flags & DRM_MODE_FLAG_NHSYNC) 856 + lvds_cr |= CR_HSPOL; 857 + 858 + if (mode->flags & DRM_MODE_FLAG_NVSYNC) 859 + lvds_cr |= CR_VSPOL; 860 + 861 + switch (lvds->link_type) { 862 + case LVDS_DUAL_LINK_EVEN_ODD_PIXELS: /* LKPHA = 0 */ 863 + lvds_cr &= ~CR_LKPHA; 864 + break; 865 + case LVDS_DUAL_LINK_ODD_EVEN_PIXELS: /* LKPHA = 1 */ 866 + lvds_cr |= CR_LKPHA; 867 + break; 868 + default: 869 + drm_notice(lvds->lvds_bridge.dev, "No phase precised, setting default\n"); 870 + lvds_cr &= ~CR_LKPHA; 871 + break; 872 + } 873 + 874 + /* Write config to registers */ 875 + lvds_set(lvds, LVDS_CR, lvds_cr); 876 + lvds_write(lvds, LVDS_CDL1CR, lvds_cdl1cr); 877 + lvds_write(lvds, LVDS_CDL2CR, lvds_cdl2cr); 878 + } 879 + 880 + static int lvds_connector_get_modes(struct drm_connector *connector) 881 + { 882 + struct stm_lvds *lvds = connector_to_stm_lvds(connector); 883 + 884 + return drm_panel_get_modes(lvds->panel, connector); 885 + } 886 + 887 + static int lvds_connector_atomic_check(struct drm_connector *connector, 888 + struct drm_atomic_state *state) 889 + { 890 + const struct drm_display_mode *panel_mode; 891 + struct drm_connector_state *conn_state; 892 + struct drm_crtc_state *crtc_state; 893 + 894 + conn_state = drm_atomic_get_new_connector_state(state, connector); 895 + if (!conn_state) 896 + return -EINVAL; 897 + 898 + if (list_empty(&connector->modes)) { 899 + drm_dbg(connector->dev, "connector: empty modes list\n"); 900 + return -EINVAL; 901 + } 902 + 903 + if (!conn_state->crtc) 904 + return -EINVAL; 905 + 906 + panel_mode = list_first_entry(&connector->modes, 907 + struct drm_display_mode, head); 908 + 909 + /* We're not allowed to modify the resolution. */ 910 + crtc_state = drm_atomic_get_crtc_state(state, conn_state->crtc); 911 + if (IS_ERR(crtc_state)) 912 + return PTR_ERR(crtc_state); 913 + 914 + if (crtc_state->mode.hdisplay != panel_mode->hdisplay || 915 + crtc_state->mode.vdisplay != panel_mode->vdisplay) 916 + return -EINVAL; 917 + 918 + /* The flat panel mode is fixed, just copy it to the adjusted mode. */ 919 + drm_mode_copy(&crtc_state->adjusted_mode, panel_mode); 920 + 921 + return 0; 922 + } 923 + 924 + static const struct drm_connector_helper_funcs lvds_conn_helper_funcs = { 925 + .get_modes = lvds_connector_get_modes, 926 + .atomic_check = lvds_connector_atomic_check, 927 + }; 928 + 929 + static const struct drm_connector_funcs lvds_conn_funcs = { 930 + .reset = drm_atomic_helper_connector_reset, 931 + .fill_modes = drm_helper_probe_single_connector_modes, 932 + .destroy = drm_connector_cleanup, 933 + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 934 + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 935 + }; 936 + 937 + static int lvds_attach(struct drm_bridge *bridge, 938 + enum drm_bridge_attach_flags flags) 939 + { 940 + struct stm_lvds *lvds = bridge_to_stm_lvds(bridge); 941 + struct drm_connector *connector = &lvds->connector; 942 + struct drm_encoder *encoder = bridge->encoder; 943 + int ret; 944 + 945 + if (!bridge->encoder) { 946 + drm_err(bridge->dev, "Parent encoder object not found\n"); 947 + return -ENODEV; 948 + } 949 + 950 + /* Set the encoder type as caller does not know it */ 951 + bridge->encoder->encoder_type = DRM_MODE_ENCODER_LVDS; 952 + 953 + /* No cloning support */ 954 + bridge->encoder->possible_clones = 0; 955 + 956 + /* If we have a next bridge just attach it. */ 957 + if (lvds->next_bridge) 958 + return drm_bridge_attach(bridge->encoder, lvds->next_bridge, 959 + bridge, flags); 960 + 961 + if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) { 962 + drm_err(bridge->dev, "Fix bridge driver to make connector optional!"); 963 + return -EINVAL; 964 + } 965 + 966 + /* Otherwise if we have a panel, create a connector. */ 967 + if (!lvds->panel) 968 + return 0; 969 + 970 + ret = drm_connector_init(bridge->dev, connector, 971 + &lvds_conn_funcs, DRM_MODE_CONNECTOR_LVDS); 972 + if (ret < 0) 973 + return ret; 974 + 975 + drm_connector_helper_add(connector, &lvds_conn_helper_funcs); 976 + 977 + ret = drm_connector_attach_encoder(connector, encoder); 978 + 979 + return ret; 980 + } 981 + 982 + static void lvds_atomic_enable(struct drm_bridge *bridge, 983 + struct drm_bridge_state *old_bridge_state) 984 + { 985 + struct drm_atomic_state *state = old_bridge_state->base.state; 986 + struct stm_lvds *lvds = bridge_to_stm_lvds(bridge); 987 + struct drm_connector_state *conn_state; 988 + struct drm_connector *connector; 989 + int ret; 990 + 991 + ret = clk_prepare_enable(lvds->pclk); 992 + if (ret) { 993 + drm_err(bridge->dev, "Failed to enable lvds peripheral clk\n"); 994 + return; 995 + } 996 + 997 + connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); 998 + if (!connector) 999 + return; 1000 + 1001 + conn_state = drm_atomic_get_new_connector_state(state, connector); 1002 + if (!conn_state) 1003 + return; 1004 + 1005 + lvds_config_mode(lvds); 1006 + 1007 + /* Set Data Mapping */ 1008 + lvds_config_data_mapping(lvds); 1009 + 1010 + /* Turn the output on. */ 1011 + lvds_set(lvds, LVDS_CR, CR_LVDSEN); 1012 + 1013 + if (lvds->panel) { 1014 + drm_panel_prepare(lvds->panel); 1015 + drm_panel_enable(lvds->panel); 1016 + } 1017 + } 1018 + 1019 + static void lvds_atomic_disable(struct drm_bridge *bridge, 1020 + struct drm_bridge_state *old_bridge_state) 1021 + { 1022 + struct stm_lvds *lvds = bridge_to_stm_lvds(bridge); 1023 + 1024 + if (lvds->panel) { 1025 + drm_panel_disable(lvds->panel); 1026 + drm_panel_unprepare(lvds->panel); 1027 + } 1028 + 1029 + /* Disable LVDS module */ 1030 + lvds_clear(lvds, LVDS_CR, CR_LVDSEN); 1031 + 1032 + clk_disable_unprepare(lvds->pclk); 1033 + } 1034 + 1035 + static const struct drm_bridge_funcs lvds_bridge_funcs = { 1036 + .attach = lvds_attach, 1037 + .atomic_enable = lvds_atomic_enable, 1038 + .atomic_disable = lvds_atomic_disable, 1039 + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, 1040 + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, 1041 + .atomic_reset = drm_atomic_helper_bridge_reset, 1042 + }; 1043 + 1044 + static int lvds_probe(struct platform_device *pdev) 1045 + { 1046 + struct device_node *port1, *port2, *remote; 1047 + struct device *dev = &pdev->dev; 1048 + struct reset_control *rstc; 1049 + struct stm_lvds *lvds; 1050 + int ret, dual_link; 1051 + 1052 + dev_dbg(dev, "Probing LVDS driver...\n"); 1053 + 1054 + lvds = devm_kzalloc(dev, sizeof(*lvds), GFP_KERNEL); 1055 + if (!lvds) 1056 + return -ENOMEM; 1057 + 1058 + lvds->dev = dev; 1059 + 1060 + ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, 1061 + &lvds->panel, &lvds->next_bridge); 1062 + if (ret) { 1063 + dev_err_probe(dev, ret, "Panel not found\n"); 1064 + return ret; 1065 + } 1066 + 1067 + lvds->base = devm_platform_ioremap_resource(pdev, 0); 1068 + if (IS_ERR(lvds->base)) { 1069 + ret = PTR_ERR(lvds->base); 1070 + dev_err(dev, "Unable to get regs %d\n", ret); 1071 + return ret; 1072 + } 1073 + 1074 + lvds->pclk = devm_clk_get(dev, "pclk"); 1075 + if (IS_ERR(lvds->pclk)) { 1076 + ret = PTR_ERR(lvds->pclk); 1077 + dev_err(dev, "Unable to get peripheral clock: %d\n", ret); 1078 + return ret; 1079 + } 1080 + 1081 + ret = clk_prepare_enable(lvds->pclk); 1082 + if (ret) { 1083 + dev_err(dev, "%s: Failed to enable peripheral clk\n", __func__); 1084 + return ret; 1085 + } 1086 + 1087 + rstc = devm_reset_control_get_exclusive(dev, NULL); 1088 + 1089 + if (IS_ERR(rstc)) { 1090 + ret = PTR_ERR(rstc); 1091 + goto err_lvds_probe; 1092 + } 1093 + 1094 + reset_control_assert(rstc); 1095 + usleep_range(10, 20); 1096 + reset_control_deassert(rstc); 1097 + 1098 + port1 = of_graph_get_port_by_id(dev->of_node, 1); 1099 + port2 = of_graph_get_port_by_id(dev->of_node, 2); 1100 + dual_link = drm_of_lvds_get_dual_link_pixel_order(port1, port2); 1101 + 1102 + switch (dual_link) { 1103 + case DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS: 1104 + lvds->link_type = LVDS_DUAL_LINK_ODD_EVEN_PIXELS; 1105 + lvds->primary = &lvds_phy_16ff_primary; 1106 + lvds->secondary = &lvds_phy_16ff_secondary; 1107 + break; 1108 + case DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS: 1109 + lvds->link_type = LVDS_DUAL_LINK_EVEN_ODD_PIXELS; 1110 + lvds->primary = &lvds_phy_16ff_primary; 1111 + lvds->secondary = &lvds_phy_16ff_secondary; 1112 + break; 1113 + case -EINVAL: 1114 + /* 1115 + * drm_of_lvds_get_dual_pixel_order returns 4 possible values. 1116 + * In the case where the returned value is an error, it can be 1117 + * either ENODEV or EINVAL. Seeing the structure of this 1118 + * function, EINVAL means that either port1 or port2 is not 1119 + * present in the device tree. 1120 + * In that case, the lvds panel can be a single link panel, or 1121 + * there is a semantical error in the device tree code. 1122 + */ 1123 + remote = of_get_next_available_child(port1, NULL); 1124 + if (remote) { 1125 + if (of_graph_get_remote_endpoint(remote)) { 1126 + lvds->link_type = LVDS_SINGLE_LINK_PRIMARY; 1127 + lvds->primary = &lvds_phy_16ff_primary; 1128 + lvds->secondary = NULL; 1129 + } else { 1130 + ret = -EINVAL; 1131 + } 1132 + 1133 + of_node_put(remote); 1134 + } 1135 + 1136 + remote = of_get_next_available_child(port2, NULL); 1137 + if (remote) { 1138 + if (of_graph_get_remote_endpoint(remote)) { 1139 + lvds->link_type = LVDS_SINGLE_LINK_SECONDARY; 1140 + lvds->primary = NULL; 1141 + lvds->secondary = &lvds_phy_16ff_secondary; 1142 + } else { 1143 + ret = (ret == -EINVAL) ? -EINVAL : 0; 1144 + } 1145 + 1146 + of_node_put(remote); 1147 + } 1148 + break; 1149 + default: 1150 + ret = -EINVAL; 1151 + goto err_lvds_probe; 1152 + } 1153 + of_node_put(port1); 1154 + of_node_put(port2); 1155 + 1156 + lvds->pllref_clk = devm_clk_get(dev, "ref"); 1157 + if (IS_ERR(lvds->pllref_clk)) { 1158 + ret = PTR_ERR(lvds->pllref_clk); 1159 + dev_err(dev, "Unable to get reference clock: %d\n", ret); 1160 + goto err_lvds_probe; 1161 + } 1162 + 1163 + ret = lvds_pixel_clk_register(lvds); 1164 + if (ret) { 1165 + dev_err(dev, "Failed to register LVDS pixel clock: %d\n", ret); 1166 + goto err_lvds_probe; 1167 + } 1168 + 1169 + lvds->lvds_bridge.funcs = &lvds_bridge_funcs; 1170 + lvds->lvds_bridge.of_node = dev->of_node; 1171 + lvds->hw_version = lvds_read(lvds, LVDS_VERR); 1172 + 1173 + dev_info(dev, "version 0x%02x initialized\n", lvds->hw_version); 1174 + 1175 + drm_bridge_add(&lvds->lvds_bridge); 1176 + 1177 + platform_set_drvdata(pdev, lvds); 1178 + 1179 + clk_disable_unprepare(lvds->pclk); 1180 + 1181 + return 0; 1182 + 1183 + err_lvds_probe: 1184 + clk_disable_unprepare(lvds->pclk); 1185 + 1186 + return ret; 1187 + } 1188 + 1189 + static int lvds_remove(struct platform_device *pdev) 1190 + { 1191 + struct stm_lvds *lvds = platform_get_drvdata(pdev); 1192 + 1193 + lvds_pixel_clk_unregister(lvds); 1194 + 1195 + drm_bridge_remove(&lvds->lvds_bridge); 1196 + 1197 + return 0; 1198 + } 1199 + 1200 + static const struct of_device_id lvds_dt_ids[] = { 1201 + { 1202 + .compatible = "st,stm32mp25-lvds", 1203 + .data = NULL 1204 + }, 1205 + { /* sentinel */ } 1206 + }; 1207 + 1208 + MODULE_DEVICE_TABLE(of, lvds_dt_ids); 1209 + 1210 + static struct platform_driver lvds_platform_driver = { 1211 + .probe = lvds_probe, 1212 + .remove = lvds_remove, 1213 + .driver = { 1214 + .name = "stm32-display-lvds", 1215 + .owner = THIS_MODULE, 1216 + .of_match_table = lvds_dt_ids, 1217 + }, 1218 + }; 1219 + 1220 + module_platform_driver(lvds_platform_driver); 1221 + 1222 + MODULE_AUTHOR("Raphaël Gallais-Pou <raphael.gallais-pou@foss.st.com>"); 1223 + MODULE_AUTHOR("Philippe Cornu <philippe.cornu@foss.st.com>"); 1224 + MODULE_AUTHOR("Yannick Fertre <yannick.fertre@foss.st.com>"); 1225 + MODULE_DESCRIPTION("STMicroelectronics LVDS Display Interface Transmitter DRM driver"); 1226 + MODULE_LICENSE("GPL");
+11
drivers/gpu/drm/tests/drm_cmdline_parser_test.c
··· 992 992 TV_OPT_TEST(PAL_M, "720x480i,tv_mode=PAL-M", drm_mode_analog_ntsc_480i), 993 993 TV_OPT_TEST(PAL_N, "720x576i,tv_mode=PAL-N", drm_mode_analog_pal_576i), 994 994 TV_OPT_TEST(SECAM, "720x576i,tv_mode=SECAM", drm_mode_analog_pal_576i), 995 + { 996 + .name = "MONO_525", 997 + .cmdline = "720x480i,tv_mode=Mono", 998 + .mode_fn = drm_mode_analog_ntsc_480i, 999 + .tv_mode = DRM_MODE_TV_MODE_MONOCHROME, 1000 + }, { 1001 + .name = "MONO_625", 1002 + .cmdline = "720x576i,tv_mode=Mono", 1003 + .mode_fn = drm_mode_analog_pal_576i, 1004 + .tv_mode = DRM_MODE_TV_MODE_MONOCHROME, 1005 + }, 995 1006 }; 996 1007 997 1008 static void drm_cmdline_tv_option_desc(const struct drm_cmdline_tv_option_test *t,
+1
drivers/gpu/drm/tests/drm_connector_test.c
··· 777 777 TV_MODE_NAME("PAL-M", DRM_MODE_TV_MODE_PAL_M), 778 778 TV_MODE_NAME("PAL-N", DRM_MODE_TV_MODE_PAL_N), 779 779 TV_MODE_NAME("SECAM", DRM_MODE_TV_MODE_SECAM), 780 + TV_MODE_NAME("Mono", DRM_MODE_TV_MODE_MONOCHROME), 780 781 }; 781 782 782 783 static void
+31
drivers/gpu/drm/tests/drm_modes_test.c
··· 130 130 KUNIT_EXPECT_TRUE(test, drm_mode_equal(expected, mode)); 131 131 } 132 132 133 + static void drm_test_modes_analog_tv_mono_576i(struct kunit *test) 134 + { 135 + struct drm_test_modes_priv *priv = test->priv; 136 + struct drm_display_mode *mode; 137 + 138 + mode = drm_analog_tv_mode(priv->drm, 139 + DRM_MODE_TV_MODE_MONOCHROME, 140 + 13500 * HZ_PER_KHZ, 720, 576, 141 + true); 142 + KUNIT_ASSERT_NOT_NULL(test, mode); 143 + 144 + KUNIT_EXPECT_EQ(test, drm_mode_vrefresh(mode), 50); 145 + KUNIT_EXPECT_EQ(test, mode->hdisplay, 720); 146 + 147 + /* BT.601 defines hsync_start at 732 for 576i */ 148 + KUNIT_EXPECT_EQ(test, mode->hsync_start, 732); 149 + 150 + /* 151 + * The PAL standard expects a line to take 64us. With a pixel 152 + * clock of 13.5 MHz, a pixel takes around 74ns, so we need to 153 + * have 64000ns / 74ns = 864. 154 + * 155 + * This is also mandated by BT.601. 156 + */ 157 + KUNIT_EXPECT_EQ(test, mode->htotal, 864); 158 + 159 + KUNIT_EXPECT_EQ(test, mode->vdisplay, 576); 160 + KUNIT_EXPECT_EQ(test, mode->vtotal, 625); 161 + } 162 + 133 163 static struct kunit_case drm_modes_analog_tv_tests[] = { 164 + KUNIT_CASE(drm_test_modes_analog_tv_mono_576i), 134 165 KUNIT_CASE(drm_test_modes_analog_tv_ntsc_480i), 135 166 KUNIT_CASE(drm_test_modes_analog_tv_ntsc_480i_inlined), 136 167 KUNIT_CASE(drm_test_modes_analog_tv_pal_576i),
+3
include/drm/display/drm_dsc_helper.h
··· 17 17 DRM_DSC_1_2_420, 18 18 }; 19 19 20 + struct drm_printer; 21 + 20 22 void drm_dsc_dp_pps_header_init(struct dp_sdp_header *pps_header); 21 23 int drm_dsc_dp_rc_buffer_size(u8 rc_buffer_block_size, u8 rc_buffer_size); 22 24 void drm_dsc_pps_payload_pack(struct drm_dsc_picture_parameter_set *pps_sdp, ··· 30 28 u8 drm_dsc_initial_scale_value(const struct drm_dsc_config *dsc); 31 29 u32 drm_dsc_flatness_det_thresh(const struct drm_dsc_config *dsc); 32 30 u32 drm_dsc_get_bpp_int(const struct drm_dsc_config *vdsc_cfg); 31 + void drm_dsc_dump_config(struct drm_printer *p, int indent, const struct drm_dsc_config *cfg); 33 32 34 33 #endif /* _DRM_DSC_HELPER_H_ */ 35 34
+23
include/drm/drm_fixed.h
··· 214 214 return sum; 215 215 } 216 216 217 + static inline int fxp_q4_from_int(int val_int) 218 + { 219 + return val_int << 4; 220 + } 221 + 222 + static inline int fxp_q4_to_int(int val_q4) 223 + { 224 + return val_q4 >> 4; 225 + } 226 + 227 + static inline int fxp_q4_to_int_roundup(int val_q4) 228 + { 229 + return (val_q4 + 0xf) >> 4; 230 + } 231 + 232 + static inline int fxp_q4_to_frac(int val_q4) 233 + { 234 + return val_q4 & 0xf; 235 + } 236 + 237 + #define FXP_Q4_FMT "%d.%04d" 238 + #define FXP_Q4_ARGS(val_q4) fxp_q4_to_int(val_q4), (fxp_q4_to_frac(val_q4) * 625) 239 + 217 240 #endif