Merge branch 'CR_1287_FAT_MOUNT_FAILED_samin.guo' into 'jh7110-5.15.y-devel'
[platform/kernel/linux-starfive.git] / drivers / gpu / drm / verisilicon / vs_simple_enc.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2020 VeriSilicon Holdings Co., Ltd.
4  */
5 #include <linux/version.h>
6 #include <linux/component.h>
7 #include <linux/of_device.h>
8 #if KERNEL_VERSION(5, 5, 0) <= LINUX_VERSION_CODE
9 #include <linux/module.h>
10
11 #include <drm/drm_bridge.h>
12 #else
13 #include <drm/drmP.h>
14 #endif
15
16 #include <drm/drm_crtc_helper.h>
17 #include <drm/drm_of.h>
18 #include <linux/regmap.h>
19 #include <linux/mfd/syscon.h>
20
21 #include "vs_crtc.h"
22 #include "vs_simple_enc.h"
23
24 static const struct simple_encoder_priv hdmi_priv = {
25         .encoder_type = DRM_MODE_ENCODER_TMDS
26 };
27
28 static const struct simple_encoder_priv dsi_priv = {
29         .encoder_type = DRM_MODE_ENCODER_DSI
30 };
31
32 static const struct drm_encoder_funcs encoder_funcs = {
33         .destroy = drm_encoder_cleanup
34 };
35
36 static inline struct simple_encoder *to_simple_encoder(struct drm_encoder *enc)
37 {
38         return container_of(enc, struct simple_encoder, encoder);
39 }
40
41 #if 0
42 static int encoder_parse_dt(struct device *dev)
43 {
44         struct simple_encoder *simple = dev_get_drvdata(dev);
45         int ret = 0;
46         int cnt, i;
47         u32 *vals;
48         u32 *masks;
49
50         simple->dss_regmap = syscon_regmap_lookup_by_phandle(dev->of_node,
51                                                 "verisilicon,dss-syscon");
52
53         if (IS_ERR(simple->dss_regmap)) {
54                 if (PTR_ERR(simple->dss_regmap) != -ENODEV) {
55                         dev_err(dev, "failed to get dss-syscon\n");
56                         ret = PTR_ERR(simple->dss_regmap);
57                         goto err;
58                 }
59                 simple->dss_regmap = NULL;
60                 goto err;
61         }
62
63         cnt = of_property_count_elems_of_size(dev->of_node,
64                                 "verisilicon,mux-mask", 4);
65         if (!cnt) {
66                 ret = cnt;
67                 goto err;
68         }
69
70         simple->dss_regdatas = devm_kzalloc(dev,
71                 sizeof(*simple->dss_regdatas) * cnt, GFP_KERNEL);
72
73         masks = kcalloc(cnt, sizeof(*masks), GFP_KERNEL);
74         if (!masks) {
75                 ret = -ENOMEM;
76                 goto err;
77         }
78
79         vals = kcalloc(cnt, sizeof(*vals), GFP_KERNEL);
80         if (!vals) {
81                 ret = -ENOMEM;
82                 goto err_free_masks;
83         }
84
85         ret = of_property_read_u32_array(
86                         dev->of_node, "verisilicon,mux-mask", masks, cnt);
87         if (ret)
88                 goto err_free_vals;
89
90         ret = of_property_read_u32_array(
91                         dev->of_node, "verisilicon,mux-val", vals, cnt);
92         if (ret)
93                 goto err_free_vals;
94
95         for (i = 0; i < cnt; i++) {
96                 simple->dss_regdatas[i].mask = masks[i];
97                 simple->dss_regdatas[i].value = vals[i];
98         }
99
100 err_free_vals:
101         kfree(vals);
102 err_free_masks:
103         kfree(masks);
104 err:
105         return ret;
106 }
107 #endif
108
109 #define DOM_VOUT_SYSCON_8                                                                       0x8U
110 #define U0_LCD_DATA_MAPPING_DPI_DP_SEL_SHIFT                            0x2U
111 #define U0_LCD_DATA_MAPPING_DPI_DP_SEL_MASK                                     0x4U
112
113 #define DOM_VOUT_SYSCON_4                                                                       0x4U
114 #define U0_DISPLAY_PANEL_MUX_PANEL_SEL_SHIFT                            0x14U
115 #define U0_DISPLAY_PANEL_MUX_PANEL_SEL_MASK                                     0x100000U
116
117 void encoder_atomic_enable(struct drm_encoder *encoder,
118                                                 struct drm_atomic_state *state)
119 {
120         return;
121 }
122
123 int encoder_atomic_check(struct drm_encoder *encoder,
124                         struct drm_crtc_state *crtc_state,
125                         struct drm_connector_state *conn_state)
126 {
127         struct vs_crtc_state *vs_crtc_state = to_vs_crtc_state(crtc_state);
128         struct drm_connector *connector = conn_state->connector;
129         int ret = 0;
130 #if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE
131         struct drm_bridge *first_bridge = drm_bridge_chain_get_first_bridge(encoder);
132         struct drm_bridge_state *bridge_state = ERR_PTR(-EINVAL);
133 #endif
134
135         vs_crtc_state->encoder_type = encoder->encoder_type;
136
137 #if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE
138         if (first_bridge && first_bridge->funcs->atomic_duplicate_state)
139                 bridge_state = drm_atomic_get_bridge_state(
140                                            crtc_state->state, first_bridge);
141
142         if (IS_ERR(bridge_state)) {
143                 if (connector->display_info.num_bus_formats)
144                         vs_crtc_state->output_fmt = connector->display_info.bus_formats[0];
145                 else
146                         vs_crtc_state->output_fmt = MEDIA_BUS_FMT_FIXED;
147         } else {
148                 vs_crtc_state->output_fmt = bridge_state->input_bus_cfg.format;
149         }
150 #else
151         if (connector->display_info.num_bus_formats)
152                 vs_crtc_state->output_fmt = connector->display_info.bus_formats[0];
153         else
154                 vs_crtc_state->output_fmt = MEDIA_BUS_FMT_RGB888_1X24;
155 #endif
156
157         switch (vs_crtc_state->output_fmt) {
158         case MEDIA_BUS_FMT_FIXED:
159         case MEDIA_BUS_FMT_RGB565_1X16:
160         case MEDIA_BUS_FMT_RGB666_1X18:
161         case MEDIA_BUS_FMT_RGB888_1X24:
162         case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
163         case MEDIA_BUS_FMT_RGB101010_1X30:
164         case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
165         case MEDIA_BUS_FMT_UYVY8_1X16:
166         case MEDIA_BUS_FMT_YUV8_1X24:
167         case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
168         case MEDIA_BUS_FMT_UYVY10_1X20:
169         case MEDIA_BUS_FMT_YUV10_1X30:
170                 ret = 0;
171                 break;
172         default:
173                 ret = -EINVAL;
174                 break;
175         }
176
177         /* If MEDIA_BUS_FMT_FIXED, set it to default value */
178         if (vs_crtc_state->output_fmt == MEDIA_BUS_FMT_FIXED)
179                 vs_crtc_state->output_fmt = MEDIA_BUS_FMT_RGB888_1X24;
180
181         return ret;
182 }
183
184 static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
185         .atomic_enable = encoder_atomic_enable,
186         .atomic_check = encoder_atomic_check,
187 };
188
189 static int encoder_bind(struct device *dev, struct device *master, void *data)
190 {
191
192         struct drm_device *drm_dev = data;
193         struct simple_encoder *simple = dev_get_drvdata(dev);
194         struct drm_encoder *encoder;
195         struct drm_bridge *bridge;
196         
197         int ret;
198
199         encoder = &simple->encoder;
200
201         /* Encoder. */
202
203         ret = drm_encoder_init(drm_dev, encoder, &encoder_funcs,
204                                    simple->priv->encoder_type, NULL);
205         if (ret)
206                 return ret;
207
208         drm_encoder_helper_add(encoder, &encoder_helper_funcs);
209
210         encoder->possible_crtcs =
211                         drm_of_find_possible_crtcs(drm_dev, dev->of_node);
212         encoder->possible_crtcs = 3;
213
214         /* output port is port1*/
215
216 #ifdef CONFIG_STARFIVE_DSI
217         struct drm_panel *tmp_panel;
218
219         ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0,&tmp_panel, &bridge);
220         if (ret){
221                 printk("==no panel, %d\n",ret);
222                 //dev_err_probe(dev, ret, "endpoint returns %d\n", ret);
223                 goto err;
224         }
225         if (tmp_panel)
226                 dev_err(dev, "found panel on endpoint\n");
227 #else
228         ret = drm_of_find_panel_or_bridge(dev->of_node, 1, -1, NULL, &bridge);
229                 if (ret)
230                         goto err;
231 #endif
232 #if KERNEL_VERSION(5, 7, 0) <= LINUX_VERSION_CODE
233         ret = drm_bridge_attach(encoder, bridge, NULL, 0);
234 #else
235         ret = drm_bridge_attach(encoder, bridge, NULL);
236 #endif
237         if (ret)
238                 goto err;
239
240         return 0;
241 err:
242         drm_encoder_cleanup(encoder);
243
244         return ret;
245 }
246
247 static void encoder_unbind(struct device *dev, struct device *master,
248                                   void *data)
249 {
250         struct simple_encoder *simple = dev_get_drvdata(dev);
251
252         drm_encoder_cleanup(&simple->encoder);
253 }
254
255 static const struct component_ops encoder_component_ops = {
256         .bind = encoder_bind,
257         .unbind = encoder_unbind,
258 };
259
260 static const struct of_device_id simple_encoder_dt_match[] = {
261         { .compatible = "verisilicon,hdmi-encoder", .data = &hdmi_priv},
262         { .compatible = "verisilicon,dp-encoder", .data = &hdmi_priv},
263         { .compatible = "verisilicon,dsi-encoder", .data = &dsi_priv},
264         {},
265 };
266 MODULE_DEVICE_TABLE(of, simple_encoder_dt_match);
267
268 static int encoder_probe(struct platform_device *pdev)
269 {
270         struct device *dev = &pdev->dev;
271         struct simple_encoder *simple;
272
273         simple = devm_kzalloc(dev, sizeof(*simple), GFP_KERNEL);
274         if (!simple)
275                 return -ENOMEM;
276
277         simple->priv = of_device_get_match_data(dev);
278
279         simple->dev = dev;
280
281         dev_set_drvdata(dev, simple);
282 #if 0
283         ret = encoder_parse_dt(dev);
284         if (ret)
285                 return ret;
286 #endif
287         return component_add(dev, &encoder_component_ops);
288 }
289
290 static int encoder_remove(struct platform_device *pdev)
291 {
292         struct device *dev = &pdev->dev;
293
294         component_del(dev, &encoder_component_ops);
295
296         dev_set_drvdata(dev, NULL);
297
298         return 0;
299 }
300
301 struct platform_driver simple_encoder_driver = {
302         .probe = encoder_probe,
303         .remove = encoder_remove,
304         .driver = {
305                 .name = "vs-simple-encoder",
306                 .of_match_table = of_match_ptr(simple_encoder_dt_match),
307         },
308 };
309
310 MODULE_DESCRIPTION("Simple Encoder Driver");
311 MODULE_LICENSE("GPL v2");