1 /* 2 * (C) Copyright 2008-2017 Fuzhou Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <asm/unaligned.h> 8 #include <config.h> 9 #include <common.h> 10 #include <errno.h> 11 #include <dm/device.h> 12 13 #include "rockchip_display.h" 14 #include "rockchip_crtc.h" 15 #include "rockchip_connector.h" 16 #include "rockchip_panel.h" 17 18 #ifdef CONFIG_DRM_ROCKCHIP_PANEL 19 static const struct drm_display_mode auo_b125han03_mode = { 20 .clock = 146900, 21 .hdisplay = 1920, 22 .hsync_start = 1920 + 48, 23 .hsync_end = 1920 + 48 + 32, 24 .htotal = 1920 + 48 + 32 + 140, 25 .vdisplay = 1080, 26 .vsync_start = 1080 + 2, 27 .vsync_end = 1080 + 2 + 5, 28 .vtotal = 1080 + 2 + 5 + 57, 29 .vrefresh = 60, 30 .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC, 31 }; 32 33 static const struct drm_display_mode lg_lp079qx1_sp0v_mode = { 34 .clock = 200000, 35 .hdisplay = 1536, 36 .hsync_start = 1536 + 12, 37 .hsync_end = 1536 + 12 + 16, 38 .htotal = 1536 + 12 + 16 + 48, 39 .vdisplay = 2048, 40 .vsync_start = 2048 + 8, 41 .vsync_end = 2048 + 8 + 4, 42 .vtotal = 2048 + 8 + 4 + 8, 43 .vrefresh = 60, 44 .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC, 45 }; 46 47 static const struct rockchip_panel simple_panel_data = { 48 .funcs = &panel_simple_funcs, 49 }; 50 51 static const struct rockchip_panel lg_lp079qx1_sp0v_data = { 52 .funcs = &panel_simple_funcs, 53 .data = &lg_lp079qx1_sp0v_mode, 54 }; 55 56 static const struct rockchip_panel auo_b125han03_data = { 57 .funcs = &panel_simple_funcs, 58 .data = &auo_b125han03_mode, 59 }; 60 #endif 61 62 #ifdef CONFIG_DRM_ROCKCHIP_DSI_PANEL 63 static const struct rockchip_panel simple_panel_dsi_data = { 64 .funcs = &rockchip_dsi_panel_funcs, 65 }; 66 #endif 67 68 static const struct udevice_id rockchip_panel_ids[] = { 69 #ifdef CONFIG_DRM_ROCKCHIP_PANEL 70 { 71 .compatible = "simple-panel", 72 .data = (ulong)&simple_panel_data, 73 }, { 74 .compatible = "lg,lp079qx1-sp0v", 75 .data = (ulong)&lg_lp079qx1_sp0v_data, 76 }, { 77 .compatible = "auo,b125han03", 78 .data = (ulong)&auo_b125han03_data, 79 }, 80 #endif 81 #ifdef CONFIG_DRM_ROCKCHIP_DSI_PANEL 82 { 83 .compatible = "simple-panel-dsi", 84 .data = (ulong)&simple_panel_dsi_data, 85 }, 86 #endif 87 {} 88 }; 89 90 static int rockchip_panel_probe(struct udevice *dev) 91 { 92 return 0; 93 } 94 95 static int rockchip_panel_bind(struct udevice *dev) 96 { 97 return 0; 98 } 99 100 U_BOOT_DRIVER(rockchip_panel) = { 101 .name = "rockchip_panel", 102 .id = UCLASS_PANEL, 103 .of_match = rockchip_panel_ids, 104 .bind = rockchip_panel_bind, 105 .probe = rockchip_panel_probe, 106 }; 107 108 const struct drm_display_mode * 109 rockchip_get_display_mode_from_panel(struct display_state *state) 110 { 111 struct panel_state *panel_state = &state->panel_state; 112 const struct rockchip_panel *panel = panel_state->panel; 113 114 if (!panel || !panel->data) 115 return NULL; 116 117 return (const struct drm_display_mode *)panel->data; 118 } 119 120 int rockchip_panel_init(struct display_state *state) 121 { 122 struct panel_state *panel_state = &state->panel_state; 123 const struct rockchip_panel *panel = panel_state->panel; 124 125 if (!panel || !panel->funcs || !panel->funcs->init) { 126 printf("%s: failed to find panel init funcs\n", __func__); 127 return -ENODEV; 128 } 129 130 return panel->funcs->init(state); 131 } 132 133 void rockchip_panel_deinit(struct display_state *state) 134 { 135 struct panel_state *panel_state = &state->panel_state; 136 const struct rockchip_panel *panel = panel_state->panel; 137 138 if (!panel || !panel->funcs || !panel->funcs->deinit) { 139 printf("%s: failed to find panel deinit funcs\n", __func__); 140 return; 141 } 142 143 panel->funcs->deinit(state); 144 } 145 146 int rockchip_panel_prepare(struct display_state *state) 147 { 148 struct panel_state *panel_state = &state->panel_state; 149 const struct rockchip_panel *panel = panel_state->panel; 150 151 if (!panel || !panel->funcs || !panel->funcs->prepare) { 152 printf("%s: failed to find panel prepare funcs\n", __func__); 153 return -ENODEV; 154 } 155 156 return panel->funcs->prepare(state); 157 } 158 159 int rockchip_panel_unprepare(struct display_state *state) 160 { 161 struct panel_state *panel_state = &state->panel_state; 162 const struct rockchip_panel *panel = panel_state->panel; 163 164 if (!panel || !panel->funcs || !panel->funcs->unprepare) { 165 printf("%s: failed to find panel unprepare funcs\n", __func__); 166 return -ENODEV; 167 } 168 169 return panel->funcs->unprepare(state); 170 } 171 172 int rockchip_panel_enable(struct display_state *state) 173 { 174 struct panel_state *panel_state = &state->panel_state; 175 const struct rockchip_panel *panel = panel_state->panel; 176 177 if (!panel || !panel->funcs || !panel->funcs->enable) { 178 printf("%s: failed to find panel prepare funcs\n", __func__); 179 return -ENODEV; 180 } 181 182 return panel->funcs->enable(state); 183 } 184 185 int rockchip_panel_disable(struct display_state *state) 186 { 187 struct panel_state *panel_state = &state->panel_state; 188 const struct rockchip_panel *panel = panel_state->panel; 189 190 if (!panel || !panel->funcs || !panel->funcs->disable) { 191 printf("%s: failed to find panel disable funcs\n", __func__); 192 return -ENODEV; 193 } 194 195 return panel->funcs->disable(state); 196 } 197