xref: /rk3399_rockchip-uboot/drivers/video/drm/rockchip_rgb.c (revision f05ce84792cbd2e5573a414010d421eb8fbb7689)
1 /*
2  * (C) Copyright 2008-2017 Fuzhou Rockchip Electronics Co., Ltd
3  *
4  * SPDX-License-Identifier:	GPL-2.0+
5  */
6 
7 #include <common.h>
8 #include <errno.h>
9 #include <syscon.h>
10 #include <regmap.h>
11 #include <dm/device.h>
12 #include <dm/read.h>
13 #include <linux/media-bus-format.h>
14 
15 #include "rockchip_display.h"
16 #include "rockchip_crtc.h"
17 #include "rockchip_connector.h"
18 
19 #define PX30_GRF_PD_VO_CON1		0x0438
20 #define PX30_RGB_DATA_SYNC_BYPASS(v)	HIWORD_UPDATE(v, 3, 3)
21 #define PX30_RGB_VOP_SEL(v)		HIWORD_UPDATE(v, 2, 2)
22 
23 #define RK1808_GRF_PD_VO_CON1		0x0444
24 #define RK1808_RGB_DATA_SYNC_BYPASS(v)	HIWORD_UPDATE(v, 3, 3)
25 
26 struct rockchip_rgb;
27 
28 struct rockchip_rgb_funcs {
29 	void (*enable)(struct rockchip_rgb *rgb, int pipe);
30 	void (*disable)(struct rockchip_rgb *rgb);
31 };
32 
33 struct rockchip_rgb {
34 	struct regmap *grf;
35 	const struct rockchip_rgb_funcs *funcs;
36 };
37 
38 static inline struct rockchip_rgb *state_to_rgb(struct display_state *state)
39 {
40 	struct connector_state *conn_state = &state->conn_state;
41 
42 	return dev_get_priv(conn_state->dev);
43 }
44 
45 static int rockchip_rgb_connector_enable(struct display_state *state)
46 {
47 	struct rockchip_rgb *rgb = state_to_rgb(state);
48 	struct crtc_state *crtc_state = &state->crtc_state;
49 	int pipe = crtc_state->crtc_id;
50 
51 	if (rgb->funcs && rgb->funcs->enable)
52 		rgb->funcs->enable(rgb, pipe);
53 
54 	return 0;
55 }
56 
57 static int rockchip_rgb_connector_disable(struct display_state *state)
58 {
59 	struct rockchip_rgb *rgb = state_to_rgb(state);
60 
61 	if (rgb->funcs && rgb->funcs->disable)
62 		rgb->funcs->disable(rgb);
63 
64 	return 0;
65 }
66 
67 static int rockchip_rgb_connector_init(struct display_state *state)
68 {
69 	struct connector_state *conn_state = &state->conn_state;
70 
71 	conn_state->type = DRM_MODE_CONNECTOR_LVDS;
72 	conn_state->color_space = V4L2_COLORSPACE_DEFAULT;
73 
74 	switch (conn_state->bus_format) {
75 	case MEDIA_BUS_FMT_RGB666_1X18:
76 		conn_state->output_mode = ROCKCHIP_OUT_MODE_P666;
77 		break;
78 	case MEDIA_BUS_FMT_RGB565_1X16:
79 		conn_state->output_mode = ROCKCHIP_OUT_MODE_P565;
80 		break;
81 	case MEDIA_BUS_FMT_RGB888_1X24:
82 	case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
83 	default:
84 		conn_state->output_mode = ROCKCHIP_OUT_MODE_P888;
85 		break;
86 	}
87 
88 	return 0;
89 }
90 
91 static const struct rockchip_connector_funcs rockchip_rgb_connector_funcs = {
92 	.init = rockchip_rgb_connector_init,
93 	.enable = rockchip_rgb_connector_enable,
94 	.disable = rockchip_rgb_connector_disable,
95 };
96 
97 static int rockchip_rgb_probe(struct udevice *dev)
98 {
99 	struct rockchip_rgb *rgb = dev_get_priv(dev);
100 	const struct rockchip_connector *connector =
101 		(const struct rockchip_connector *)dev_get_driver_data(dev);
102 
103 	rgb->funcs = connector->data;
104 	rgb->grf = syscon_get_regmap(dev_get_parent(dev));
105 
106 	return 0;
107 }
108 
109 static void px30_rgb_enable(struct rockchip_rgb *rgb, int pipe)
110 {
111 	regmap_write(rgb->grf, PX30_GRF_PD_VO_CON1,
112 		     PX30_RGB_VOP_SEL(pipe));
113 	regmap_write(rgb->grf, PX30_GRF_PD_VO_CON1,
114 		     PX30_RGB_DATA_SYNC_BYPASS(1));
115 }
116 
117 static void px30_rgb_disable(struct rockchip_rgb *rgb)
118 {
119 	regmap_write(rgb->grf, PX30_GRF_PD_VO_CON1,
120 		     PX30_RGB_DATA_SYNC_BYPASS(0));
121 }
122 
123 static const struct rockchip_rgb_funcs px30_rgb_funcs = {
124 	.enable = px30_rgb_enable,
125 	.disable = px30_rgb_disable,
126 };
127 
128 static const struct rockchip_connector px30_rgb_driver_data = {
129 	 .funcs = &rockchip_rgb_connector_funcs,
130 	 .data = &px30_rgb_funcs,
131 };
132 
133 static void rk1808_rgb_enable(struct rockchip_rgb *rgb, int pipe)
134 {
135 	regmap_write(rgb->grf, RK1808_GRF_PD_VO_CON1,
136 		     RK1808_RGB_DATA_SYNC_BYPASS(1));
137 }
138 
139 static void rk1808_rgb_disable(struct rockchip_rgb *rgb)
140 {
141 	regmap_write(rgb->grf, RK1808_GRF_PD_VO_CON1,
142 		     RK1808_RGB_DATA_SYNC_BYPASS(0));
143 }
144 
145 static const struct rockchip_rgb_funcs rk1808_rgb_funcs = {
146 	.enable = rk1808_rgb_enable,
147 	.disable = rk1808_rgb_disable,
148 };
149 
150 static const struct rockchip_connector rk1808_rgb_driver_data = {
151 	.funcs = &rockchip_rgb_connector_funcs,
152 	.data = &rk1808_rgb_funcs,
153 };
154 
155 static const struct rockchip_connector rockchip_rgb_driver_data = {
156 	.funcs = &rockchip_rgb_connector_funcs,
157 };
158 
159 static const struct udevice_id rockchip_rgb_ids[] = {
160 	{
161 		.compatible = "rockchip,px30-rgb",
162 		.data = (ulong)&px30_rgb_driver_data,
163 	},
164 	{
165 		.compatible = "rockchip,rk1808-rgb",
166 		.data = (ulong)&rk1808_rgb_driver_data,
167 	},
168 	{
169 		.compatible = "rockchip,rk3066-rgb",
170 		.data = (ulong)&rockchip_rgb_driver_data,
171 	},
172 	{
173 		.compatible = "rockchip,rk3308-rgb",
174 		.data = (ulong)&rockchip_rgb_driver_data,
175 	},
176 	{
177 		.compatible = "rockchip,rv1108-rgb",
178 		.data = (ulong)&rockchip_rgb_driver_data,
179 	},
180 	{}
181 };
182 
183 U_BOOT_DRIVER(rockchip_rgb) = {
184 	.name = "rockchip_rgb",
185 	.id = UCLASS_DISPLAY,
186 	.of_match = rockchip_rgb_ids,
187 	.probe = rockchip_rgb_probe,
188 	.priv_auto_alloc_size = sizeof(struct rockchip_rgb),
189 };
190