xref: /rk3399_rockchip-uboot/drivers/video/drm/rockchip_panel.c (revision 785b4fbf6c5db1eb4c0ddf983292d7ab077c4212)
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