Merge tag 'gvt-next-2020-09-10' of https://github.com/intel/gvt-linux into drm-intel...
[linux-2.6-microblaze.git] / drivers / gpu / drm / bridge / parade-ps8640.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2016 MediaTek Inc.
4  */
5
6 #include <linux/delay.h>
7 #include <linux/err.h>
8 #include <linux/gpio/consumer.h>
9 #include <linux/i2c.h>
10 #include <linux/module.h>
11 #include <linux/of_graph.h>
12 #include <linux/regulator/consumer.h>
13
14 #include <drm/drm_bridge.h>
15 #include <drm/drm_mipi_dsi.h>
16 #include <drm/drm_of.h>
17 #include <drm/drm_panel.h>
18 #include <drm/drm_print.h>
19
20 #define PAGE2_GPIO_H            0xa7
21 #define PS_GPIO9                BIT(1)
22 #define PAGE2_I2C_BYPASS        0xea
23 #define I2C_BYPASS_EN           0xd0
24 #define PAGE2_MCS_EN            0xf3
25 #define MCS_EN                  BIT(0)
26 #define PAGE3_SET_ADD           0xfe
27 #define VDO_CTL_ADD             0x13
28 #define VDO_DIS                 0x18
29 #define VDO_EN                  0x1c
30 #define DP_NUM_LANES            4
31
32 /*
33  * PS8640 uses multiple addresses:
34  * page[0]: for DP control
35  * page[1]: for VIDEO Bridge
36  * page[2]: for control top
37  * page[3]: for DSI Link Control1
38  * page[4]: for MIPI Phy
39  * page[5]: for VPLL
40  * page[6]: for DSI Link Control2
41  * page[7]: for SPI ROM mapping
42  */
43 enum page_addr_offset {
44         PAGE0_DP_CNTL = 0,
45         PAGE1_VDO_BDG,
46         PAGE2_TOP_CNTL,
47         PAGE3_DSI_CNTL1,
48         PAGE4_MIPI_PHY,
49         PAGE5_VPLL,
50         PAGE6_DSI_CNTL2,
51         PAGE7_SPI_CNTL,
52         MAX_DEVS
53 };
54
55 enum ps8640_vdo_control {
56         DISABLE = VDO_DIS,
57         ENABLE = VDO_EN,
58 };
59
60 struct ps8640 {
61         struct drm_bridge bridge;
62         struct drm_bridge *panel_bridge;
63         struct mipi_dsi_device *dsi;
64         struct i2c_client *page[MAX_DEVS];
65         struct regulator_bulk_data supplies[2];
66         struct gpio_desc *gpio_reset;
67         struct gpio_desc *gpio_powerdown;
68 };
69
70 static inline struct ps8640 *bridge_to_ps8640(struct drm_bridge *e)
71 {
72         return container_of(e, struct ps8640, bridge);
73 }
74
75 static int ps8640_bridge_vdo_control(struct ps8640 *ps_bridge,
76                                      const enum ps8640_vdo_control ctrl)
77 {
78         struct i2c_client *client = ps_bridge->page[PAGE3_DSI_CNTL1];
79         u8 vdo_ctrl_buf[] = { VDO_CTL_ADD, ctrl };
80         int ret;
81
82         ret = i2c_smbus_write_i2c_block_data(client, PAGE3_SET_ADD,
83                                              sizeof(vdo_ctrl_buf),
84                                              vdo_ctrl_buf);
85         if (ret < 0) {
86                 DRM_ERROR("failed to %sable VDO: %d\n",
87                           ctrl == ENABLE ? "en" : "dis", ret);
88                 return ret;
89         }
90
91         return 0;
92 }
93
94 static void ps8640_pre_enable(struct drm_bridge *bridge)
95 {
96         struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
97         struct i2c_client *client = ps_bridge->page[PAGE2_TOP_CNTL];
98         unsigned long timeout;
99         int ret, status;
100
101         ret = regulator_bulk_enable(ARRAY_SIZE(ps_bridge->supplies),
102                                     ps_bridge->supplies);
103         if (ret < 0) {
104                 DRM_ERROR("cannot enable regulators %d\n", ret);
105                 return;
106         }
107
108         gpiod_set_value(ps_bridge->gpio_powerdown, 0);
109         gpiod_set_value(ps_bridge->gpio_reset, 1);
110         usleep_range(2000, 2500);
111         gpiod_set_value(ps_bridge->gpio_reset, 0);
112
113         /*
114          * Wait for the ps8640 embedded MCU to be ready
115          * First wait 200ms and then check the MCU ready flag every 20ms
116          */
117         msleep(200);
118
119         timeout = jiffies + msecs_to_jiffies(200) + 1;
120
121         while (time_is_after_jiffies(timeout)) {
122                 status = i2c_smbus_read_byte_data(client, PAGE2_GPIO_H);
123                 if (status < 0) {
124                         DRM_ERROR("failed read PAGE2_GPIO_H: %d\n", status);
125                         goto err_regulators_disable;
126                 }
127                 if ((status & PS_GPIO9) == PS_GPIO9)
128                         break;
129
130                 msleep(20);
131         }
132
133         msleep(50);
134
135         /*
136          * The Manufacturer Command Set (MCS) is a device dependent interface
137          * intended for factory programming of the display module default
138          * parameters. Once the display module is configured, the MCS shall be
139          * disabled by the manufacturer. Once disabled, all MCS commands are
140          * ignored by the display interface.
141          */
142         status = i2c_smbus_read_byte_data(client, PAGE2_MCS_EN);
143         if (status < 0) {
144                 DRM_ERROR("failed read PAGE2_MCS_EN: %d\n", status);
145                 goto err_regulators_disable;
146         }
147
148         ret = i2c_smbus_write_byte_data(client, PAGE2_MCS_EN,
149                                         status & ~MCS_EN);
150         if (ret < 0) {
151                 DRM_ERROR("failed write PAGE2_MCS_EN: %d\n", ret);
152                 goto err_regulators_disable;
153         }
154
155         ret = ps8640_bridge_vdo_control(ps_bridge, ENABLE);
156         if (ret)
157                 goto err_regulators_disable;
158
159         /* Switch access edp panel's edid through i2c */
160         ret = i2c_smbus_write_byte_data(client, PAGE2_I2C_BYPASS,
161                                         I2C_BYPASS_EN);
162         if (ret < 0) {
163                 DRM_ERROR("failed write PAGE2_I2C_BYPASS: %d\n", ret);
164                 goto err_regulators_disable;
165         }
166
167         return;
168
169 err_regulators_disable:
170         regulator_bulk_disable(ARRAY_SIZE(ps_bridge->supplies),
171                                ps_bridge->supplies);
172 }
173
174 static void ps8640_post_disable(struct drm_bridge *bridge)
175 {
176         struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
177         int ret;
178
179         ps8640_bridge_vdo_control(ps_bridge, DISABLE);
180
181         gpiod_set_value(ps_bridge->gpio_reset, 1);
182         gpiod_set_value(ps_bridge->gpio_powerdown, 1);
183         ret = regulator_bulk_disable(ARRAY_SIZE(ps_bridge->supplies),
184                                      ps_bridge->supplies);
185         if (ret < 0)
186                 DRM_ERROR("cannot disable regulators %d\n", ret);
187 }
188
189 static int ps8640_bridge_attach(struct drm_bridge *bridge,
190                                 enum drm_bridge_attach_flags flags)
191 {
192         struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
193         struct device *dev = &ps_bridge->page[0]->dev;
194         struct device_node *in_ep, *dsi_node;
195         struct mipi_dsi_device *dsi;
196         struct mipi_dsi_host *host;
197         int ret;
198         const struct mipi_dsi_device_info info = { .type = "ps8640",
199                                                    .channel = 0,
200                                                    .node = NULL,
201                                                  };
202
203         if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR))
204                 return -EINVAL;
205
206         /* port@0 is ps8640 dsi input port */
207         in_ep = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
208         if (!in_ep)
209                 return -ENODEV;
210
211         dsi_node = of_graph_get_remote_port_parent(in_ep);
212         of_node_put(in_ep);
213         if (!dsi_node)
214                 return -ENODEV;
215
216         host = of_find_mipi_dsi_host_by_node(dsi_node);
217         of_node_put(dsi_node);
218         if (!host)
219                 return -ENODEV;
220
221         dsi = mipi_dsi_device_register_full(host, &info);
222         if (IS_ERR(dsi)) {
223                 dev_err(dev, "failed to create dsi device\n");
224                 ret = PTR_ERR(dsi);
225                 return ret;
226         }
227
228         ps_bridge->dsi = dsi;
229
230         dsi->host = host;
231         dsi->mode_flags = MIPI_DSI_MODE_VIDEO |
232                           MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
233         dsi->format = MIPI_DSI_FMT_RGB888;
234         dsi->lanes = DP_NUM_LANES;
235         ret = mipi_dsi_attach(dsi);
236         if (ret)
237                 goto err_dsi_attach;
238
239         /* Attach the panel-bridge to the dsi bridge */
240         return drm_bridge_attach(bridge->encoder, ps_bridge->panel_bridge,
241                                  &ps_bridge->bridge, flags);
242
243 err_dsi_attach:
244         mipi_dsi_device_unregister(dsi);
245         return ret;
246 }
247
248 static struct edid *ps8640_bridge_get_edid(struct drm_bridge *bridge,
249                                            struct drm_connector *connector)
250 {
251         struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
252
253         return drm_get_edid(connector,
254                             ps_bridge->page[PAGE0_DP_CNTL]->adapter);
255 }
256
257 static const struct drm_bridge_funcs ps8640_bridge_funcs = {
258         .attach = ps8640_bridge_attach,
259         .get_edid = ps8640_bridge_get_edid,
260         .post_disable = ps8640_post_disable,
261         .pre_enable = ps8640_pre_enable,
262 };
263
264 static int ps8640_probe(struct i2c_client *client)
265 {
266         struct device *dev = &client->dev;
267         struct device_node *np = dev->of_node;
268         struct ps8640 *ps_bridge;
269         struct drm_panel *panel;
270         int ret;
271         u32 i;
272
273         ps_bridge = devm_kzalloc(dev, sizeof(*ps_bridge), GFP_KERNEL);
274         if (!ps_bridge)
275                 return -ENOMEM;
276
277         /* port@1 is ps8640 output port */
278         ret = drm_of_find_panel_or_bridge(np, 1, 0, &panel, NULL);
279         if (ret < 0)
280                 return ret;
281         if (!panel)
282                 return -ENODEV;
283
284         ps_bridge->panel_bridge = devm_drm_panel_bridge_add(dev, panel);
285         if (IS_ERR(ps_bridge->panel_bridge))
286                 return PTR_ERR(ps_bridge->panel_bridge);
287
288         ps_bridge->supplies[0].supply = "vdd33";
289         ps_bridge->supplies[1].supply = "vdd12";
290         ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ps_bridge->supplies),
291                                       ps_bridge->supplies);
292         if (ret)
293                 return ret;
294
295         ps_bridge->gpio_powerdown = devm_gpiod_get(&client->dev, "powerdown",
296                                                    GPIOD_OUT_HIGH);
297         if (IS_ERR(ps_bridge->gpio_powerdown))
298                 return PTR_ERR(ps_bridge->gpio_powerdown);
299
300         /*
301          * Assert the reset to avoid the bridge being initialized prematurely
302          */
303         ps_bridge->gpio_reset = devm_gpiod_get(&client->dev, "reset",
304                                                GPIOD_OUT_HIGH);
305         if (IS_ERR(ps_bridge->gpio_reset))
306                 return PTR_ERR(ps_bridge->gpio_reset);
307
308         ps_bridge->bridge.funcs = &ps8640_bridge_funcs;
309         ps_bridge->bridge.of_node = dev->of_node;
310         ps_bridge->bridge.ops = DRM_BRIDGE_OP_EDID;
311         ps_bridge->bridge.type = DRM_MODE_CONNECTOR_eDP;
312
313         ps_bridge->page[PAGE0_DP_CNTL] = client;
314
315         for (i = 1; i < ARRAY_SIZE(ps_bridge->page); i++) {
316                 ps_bridge->page[i] = devm_i2c_new_dummy_device(&client->dev,
317                                                              client->adapter,
318                                                              client->addr + i);
319                 if (IS_ERR(ps_bridge->page[i])) {
320                         dev_err(dev, "failed i2c dummy device, address %02x\n",
321                                 client->addr + i);
322                         return PTR_ERR(ps_bridge->page[i]);
323                 }
324         }
325
326         i2c_set_clientdata(client, ps_bridge);
327
328         drm_bridge_add(&ps_bridge->bridge);
329
330         return 0;
331 }
332
333 static int ps8640_remove(struct i2c_client *client)
334 {
335         struct ps8640 *ps_bridge = i2c_get_clientdata(client);
336
337         drm_bridge_remove(&ps_bridge->bridge);
338
339         return 0;
340 }
341
342 static const struct of_device_id ps8640_match[] = {
343         { .compatible = "parade,ps8640" },
344         { }
345 };
346 MODULE_DEVICE_TABLE(of, ps8640_match);
347
348 static struct i2c_driver ps8640_driver = {
349         .probe_new = ps8640_probe,
350         .remove = ps8640_remove,
351         .driver = {
352                 .name = "ps8640",
353                 .of_match_table = ps8640_match,
354         },
355 };
356 module_i2c_driver(ps8640_driver);
357
358 MODULE_AUTHOR("Jitao Shi <jitao.shi@mediatek.com>");
359 MODULE_AUTHOR("CK Hu <ck.hu@mediatek.com>");
360 MODULE_AUTHOR("Enric Balletbo i Serra <enric.balletbo@collabora.com>");
361 MODULE_DESCRIPTION("PARADE ps8640 DSI-eDP converter driver");
362 MODULE_LICENSE("GPL v2");