xref: /rk3399_rockchip-uboot/drivers/video/drm/rockchip_rgb.c (revision b8fa3d2a17dce6006a8a5f46cbc978a19a3fdf82)
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 
14 #include "rockchip_display.h"
15 #include "rockchip_crtc.h"
16 #include "rockchip_connector.h"
17 
18 #define PX30_GRF_PD_VO_CON1	0x0438
19 #define PX30_LCDC_DCLK_INV(v)	HIWORD_UPDATE(v, 4, 4)
20 #define PX30_RGB_SYNC_BYPASS(v)	HIWORD_UPDATE(v, 3, 3)
21 #define PX30_RGB_VOP_SEL(v)	HIWORD_UPDATE(v, 2, 2)
22 
23 struct rockchip_rgb_priv {
24 	struct regmap *grf;
25 };
26 
27 static int rockchip_rgb_prepare(struct display_state *state)
28 {
29 	struct connector_state *conn_state = &state->conn_state;
30 	struct rockchip_rgb_priv *priv = dev_get_priv(conn_state->dev);
31 	struct crtc_state *crtc_state = &state->crtc_state;
32 	int pipe = crtc_state->crtc_id;
33 
34 	if (!IS_ERR_OR_NULL(priv->grf)) {
35 		regmap_write(priv->grf, PX30_GRF_PD_VO_CON1,
36 			     PX30_RGB_VOP_SEL(pipe));
37 		regmap_write(priv->grf, PX30_GRF_PD_VO_CON1,
38 			     PX30_RGB_SYNC_BYPASS(1));
39 	}
40 
41 	return 0;
42 }
43 
44 static int rockchip_rgb_unprepare(struct display_state *state)
45 {
46 	return 0;
47 }
48 
49 static int to_output_mode(const char *s)
50 {
51 	const struct {
52 		const char *name;
53 		int format;
54 	} formats[] = {
55 		{ "p888", ROCKCHIP_OUT_MODE_P888 },
56 		{ "p666", ROCKCHIP_OUT_MODE_P666 },
57 		{ "p565", ROCKCHIP_OUT_MODE_P565 },
58 		{ "s888", ROCKCHIP_OUT_MODE_S888 },
59 		{ "s888_dummy", ROCKCHIP_OUT_MODE_S888_DUMMY }
60 	};
61 	int i;
62 
63 	for (i = 0; i < ARRAY_SIZE(formats); i++)
64 		if (!strncmp(s, formats[i].name, strlen(formats[i].name)))
65 			return formats[i].format;
66 
67 	return ROCKCHIP_OUT_MODE_P888;
68 }
69 
70 static int rockchip_rgb_init(struct display_state *state)
71 {
72 	struct connector_state *conn_state = &state->conn_state;
73 	struct panel_state *panel_state = &state->panel_state;
74 	const char *mode;
75 
76 	conn_state->type = DRM_MODE_CONNECTOR_LVDS;
77 	conn_state->color_space = V4L2_COLORSPACE_DEFAULT;
78 
79 	mode = dev_read_string(panel_state->dev, "rgb-mode");
80 	if (mode)
81 		conn_state->output_mode = to_output_mode(mode);
82 	else
83 		conn_state->output_mode = ROCKCHIP_OUT_MODE_P888;
84 
85 	return 0;
86 }
87 
88 static const struct rockchip_connector_funcs rockchip_rgb_funcs = {
89 	.init = rockchip_rgb_init,
90 	.enable = rockchip_rgb_prepare,
91 	.disable = rockchip_rgb_unprepare,
92 };
93 
94 static int rockchip_rgb_probe(struct udevice *dev)
95 {
96 	struct rockchip_rgb_priv *priv = dev_get_priv(dev);
97 
98 	priv->grf = syscon_get_regmap(dev_get_parent(dev));
99 
100 	return 0;
101 }
102 
103 static const struct rockchip_connector rockchip_rgb_data = {
104 	 .funcs = &rockchip_rgb_funcs,
105 };
106 
107 static const struct udevice_id rockchip_rgb_ids[] = {
108 	{
109 		.compatible = "rockchip,px30-rgb",
110 		.data = (ulong)&rockchip_rgb_data,
111 	},
112 	{
113 		.compatible = "rockchip,rk3066-rgb",
114 		.data = (ulong)&rockchip_rgb_data,
115 	},
116 	{
117 		.compatible = "rockchip,rk3308-rgb",
118 		.data = (ulong)&rockchip_rgb_data,
119 	},
120 	{
121 		.compatible = "rockchip,rv1108-rgb",
122 		.data = (ulong)&rockchip_rgb_data,
123 	},
124 	{}
125 };
126 
127 U_BOOT_DRIVER(rockchip_rgb) = {
128 	.name = "rockchip_rgb",
129 	.id = UCLASS_DISPLAY,
130 	.of_match = rockchip_rgb_ids,
131 	.probe = rockchip_rgb_probe,
132 	.priv_auto_alloc_size = sizeof(struct rockchip_rgb_priv),
133 };
134