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