Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[cascardo/linux.git] / drivers / gpu / drm / msm / hdmi / hdmi_connector.c
1 /*
2  * Copyright (C) 2013 Red Hat
3  * Author: Rob Clark <robdclark@gmail.com>
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 as published by
7  * the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #include <linux/gpio.h>
19 #include <linux/pinctrl/consumer.h>
20
21 #include "msm_kms.h"
22 #include "hdmi.h"
23
24 struct hdmi_connector {
25         struct drm_connector base;
26         struct hdmi *hdmi;
27         struct work_struct hpd_work;
28 };
29 #define to_hdmi_connector(x) container_of(x, struct hdmi_connector, base)
30
31 static int gpio_config(struct hdmi *hdmi, bool on)
32 {
33         struct device *dev = &hdmi->pdev->dev;
34         const struct hdmi_platform_config *config = hdmi->config;
35         int ret;
36
37         if (on) {
38                 ret = gpio_request(config->ddc_clk_gpio, "HDMI_DDC_CLK");
39                 if (ret) {
40                         dev_err(dev, "'%s'(%d) gpio_request failed: %d\n",
41                                 "HDMI_DDC_CLK", config->ddc_clk_gpio, ret);
42                         goto error1;
43                 }
44                 gpio_set_value_cansleep(config->ddc_clk_gpio, 1);
45
46                 ret = gpio_request(config->ddc_data_gpio, "HDMI_DDC_DATA");
47                 if (ret) {
48                         dev_err(dev, "'%s'(%d) gpio_request failed: %d\n",
49                                 "HDMI_DDC_DATA", config->ddc_data_gpio, ret);
50                         goto error2;
51                 }
52                 gpio_set_value_cansleep(config->ddc_data_gpio, 1);
53
54                 ret = gpio_request(config->hpd_gpio, "HDMI_HPD");
55                 if (ret) {
56                         dev_err(dev, "'%s'(%d) gpio_request failed: %d\n",
57                                 "HDMI_HPD", config->hpd_gpio, ret);
58                         goto error3;
59                 }
60                 gpio_direction_input(config->hpd_gpio);
61                 gpio_set_value_cansleep(config->hpd_gpio, 1);
62
63                 if (config->mux_en_gpio != -1) {
64                         ret = gpio_request(config->mux_en_gpio, "HDMI_MUX_EN");
65                         if (ret) {
66                                 dev_err(dev, "'%s'(%d) gpio_request failed: %d\n",
67                                         "HDMI_MUX_EN", config->mux_en_gpio, ret);
68                                 goto error4;
69                         }
70                         gpio_set_value_cansleep(config->mux_en_gpio, 1);
71                 }
72
73                 if (config->mux_sel_gpio != -1) {
74                         ret = gpio_request(config->mux_sel_gpio, "HDMI_MUX_SEL");
75                         if (ret) {
76                                 dev_err(dev, "'%s'(%d) gpio_request failed: %d\n",
77                                         "HDMI_MUX_SEL", config->mux_sel_gpio, ret);
78                                 goto error5;
79                         }
80                         gpio_set_value_cansleep(config->mux_sel_gpio, 0);
81                 }
82
83                 if (config->mux_lpm_gpio != -1) {
84                         ret = gpio_request(config->mux_lpm_gpio,
85                                         "HDMI_MUX_LPM");
86                         if (ret) {
87                                 dev_err(dev,
88                                         "'%s'(%d) gpio_request failed: %d\n",
89                                         "HDMI_MUX_LPM",
90                                         config->mux_lpm_gpio, ret);
91                                 goto error6;
92                         }
93                         gpio_set_value_cansleep(config->mux_lpm_gpio, 1);
94                 }
95                 DBG("gpio on");
96         } else {
97                 gpio_free(config->ddc_clk_gpio);
98                 gpio_free(config->ddc_data_gpio);
99                 gpio_free(config->hpd_gpio);
100
101                 if (config->mux_en_gpio != -1) {
102                         gpio_set_value_cansleep(config->mux_en_gpio, 0);
103                         gpio_free(config->mux_en_gpio);
104                 }
105
106                 if (config->mux_sel_gpio != -1) {
107                         gpio_set_value_cansleep(config->mux_sel_gpio, 1);
108                         gpio_free(config->mux_sel_gpio);
109                 }
110
111                 if (config->mux_lpm_gpio != -1) {
112                         gpio_set_value_cansleep(config->mux_lpm_gpio, 0);
113                         gpio_free(config->mux_lpm_gpio);
114                 }
115                 DBG("gpio off");
116         }
117
118         return 0;
119
120 error6:
121         if (config->mux_sel_gpio != -1)
122                 gpio_free(config->mux_sel_gpio);
123 error5:
124         if (config->mux_en_gpio != -1)
125                 gpio_free(config->mux_en_gpio);
126 error4:
127         gpio_free(config->hpd_gpio);
128 error3:
129         gpio_free(config->ddc_data_gpio);
130 error2:
131         gpio_free(config->ddc_clk_gpio);
132 error1:
133         return ret;
134 }
135
136 static int hpd_enable(struct hdmi_connector *hdmi_connector)
137 {
138         struct hdmi *hdmi = hdmi_connector->hdmi;
139         const struct hdmi_platform_config *config = hdmi->config;
140         struct device *dev = &hdmi->pdev->dev;
141         struct hdmi_phy *phy = hdmi->phy;
142         uint32_t hpd_ctrl;
143         int i, ret;
144
145         for (i = 0; i < config->hpd_reg_cnt; i++) {
146                 ret = regulator_enable(hdmi->hpd_regs[i]);
147                 if (ret) {
148                         dev_err(dev, "failed to enable hpd regulator: %s (%d)\n",
149                                         config->hpd_reg_names[i], ret);
150                         goto fail;
151                 }
152         }
153
154         ret = pinctrl_pm_select_default_state(dev);
155         if (ret) {
156                 dev_err(dev, "pinctrl state chg failed: %d\n", ret);
157                 goto fail;
158         }
159
160         ret = gpio_config(hdmi, true);
161         if (ret) {
162                 dev_err(dev, "failed to configure GPIOs: %d\n", ret);
163                 goto fail;
164         }
165
166         for (i = 0; i < config->hpd_clk_cnt; i++) {
167                 if (config->hpd_freq && config->hpd_freq[i]) {
168                         ret = clk_set_rate(hdmi->hpd_clks[i],
169                                         config->hpd_freq[i]);
170                         if (ret)
171                                 dev_warn(dev, "failed to set clk %s (%d)\n",
172                                                 config->hpd_clk_names[i], ret);
173                 }
174
175                 ret = clk_prepare_enable(hdmi->hpd_clks[i]);
176                 if (ret) {
177                         dev_err(dev, "failed to enable hpd clk: %s (%d)\n",
178                                         config->hpd_clk_names[i], ret);
179                         goto fail;
180                 }
181         }
182
183         hdmi_set_mode(hdmi, false);
184         phy->funcs->reset(phy);
185         hdmi_set_mode(hdmi, true);
186
187         hdmi_write(hdmi, REG_HDMI_USEC_REFTIMER, 0x0001001b);
188
189         /* enable HPD events: */
190         hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL,
191                         HDMI_HPD_INT_CTRL_INT_CONNECT |
192                         HDMI_HPD_INT_CTRL_INT_EN);
193
194         /* set timeout to 4.1ms (max) for hardware debounce */
195         hpd_ctrl = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);
196         hpd_ctrl |= HDMI_HPD_CTRL_TIMEOUT(0x1fff);
197
198         /* Toggle HPD circuit to trigger HPD sense */
199         hdmi_write(hdmi, REG_HDMI_HPD_CTRL,
200                         ~HDMI_HPD_CTRL_ENABLE & hpd_ctrl);
201         hdmi_write(hdmi, REG_HDMI_HPD_CTRL,
202                         HDMI_HPD_CTRL_ENABLE | hpd_ctrl);
203
204         return 0;
205
206 fail:
207         return ret;
208 }
209
210 static void hdp_disable(struct hdmi_connector *hdmi_connector)
211 {
212         struct hdmi *hdmi = hdmi_connector->hdmi;
213         const struct hdmi_platform_config *config = hdmi->config;
214         struct device *dev = &hdmi->pdev->dev;
215         int i, ret = 0;
216
217         /* Disable HPD interrupt */
218         hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL, 0);
219
220         hdmi_set_mode(hdmi, false);
221
222         for (i = 0; i < config->hpd_clk_cnt; i++)
223                 clk_disable_unprepare(hdmi->hpd_clks[i]);
224
225         ret = gpio_config(hdmi, false);
226         if (ret)
227                 dev_warn(dev, "failed to unconfigure GPIOs: %d\n", ret);
228
229         ret = pinctrl_pm_select_sleep_state(dev);
230         if (ret)
231                 dev_warn(dev, "pinctrl state chg failed: %d\n", ret);
232
233         for (i = 0; i < config->hpd_reg_cnt; i++) {
234                 ret = regulator_disable(hdmi->hpd_regs[i]);
235                 if (ret)
236                         dev_warn(dev, "failed to disable hpd regulator: %s (%d)\n",
237                                         config->hpd_reg_names[i], ret);
238         }
239 }
240
241 static void
242 hotplug_work(struct work_struct *work)
243 {
244         struct hdmi_connector *hdmi_connector =
245                 container_of(work, struct hdmi_connector, hpd_work);
246         struct drm_connector *connector = &hdmi_connector->base;
247         drm_helper_hpd_irq_event(connector->dev);
248 }
249
250 void hdmi_connector_irq(struct drm_connector *connector)
251 {
252         struct hdmi_connector *hdmi_connector = to_hdmi_connector(connector);
253         struct msm_drm_private *priv = connector->dev->dev_private;
254         struct hdmi *hdmi = hdmi_connector->hdmi;
255         uint32_t hpd_int_status, hpd_int_ctrl;
256
257         /* Process HPD: */
258         hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS);
259         hpd_int_ctrl   = hdmi_read(hdmi, REG_HDMI_HPD_INT_CTRL);
260
261         if ((hpd_int_ctrl & HDMI_HPD_INT_CTRL_INT_EN) &&
262                         (hpd_int_status & HDMI_HPD_INT_STATUS_INT)) {
263                 bool detected = !!(hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED);
264
265                 /* ack & disable (temporarily) HPD events: */
266                 hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL,
267                         HDMI_HPD_INT_CTRL_INT_ACK);
268
269                 DBG("status=%04x, ctrl=%04x", hpd_int_status, hpd_int_ctrl);
270
271                 /* detect disconnect if we are connected or visa versa: */
272                 hpd_int_ctrl = HDMI_HPD_INT_CTRL_INT_EN;
273                 if (!detected)
274                         hpd_int_ctrl |= HDMI_HPD_INT_CTRL_INT_CONNECT;
275                 hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL, hpd_int_ctrl);
276
277                 queue_work(priv->wq, &hdmi_connector->hpd_work);
278         }
279 }
280
281 static enum drm_connector_status detect_reg(struct hdmi *hdmi)
282 {
283         uint32_t hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS);
284         return (hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED) ?
285                         connector_status_connected : connector_status_disconnected;
286 }
287
288 static enum drm_connector_status detect_gpio(struct hdmi *hdmi)
289 {
290         const struct hdmi_platform_config *config = hdmi->config;
291         return gpio_get_value(config->hpd_gpio) ?
292                         connector_status_connected :
293                         connector_status_disconnected;
294 }
295
296 static enum drm_connector_status hdmi_connector_detect(
297                 struct drm_connector *connector, bool force)
298 {
299         struct hdmi_connector *hdmi_connector = to_hdmi_connector(connector);
300         struct hdmi *hdmi = hdmi_connector->hdmi;
301         enum drm_connector_status stat_gpio, stat_reg;
302         int retry = 20;
303
304         do {
305                 stat_gpio = detect_gpio(hdmi);
306                 stat_reg  = detect_reg(hdmi);
307
308                 if (stat_gpio == stat_reg)
309                         break;
310
311                 mdelay(10);
312         } while (--retry);
313
314         /* the status we get from reading gpio seems to be more reliable,
315          * so trust that one the most if we didn't manage to get hdmi and
316          * gpio status to agree:
317          */
318         if (stat_gpio != stat_reg) {
319                 DBG("HDMI_HPD_INT_STATUS tells us: %d", stat_reg);
320                 DBG("hpd gpio tells us: %d", stat_gpio);
321         }
322
323         return stat_gpio;
324 }
325
326 static void hdmi_connector_destroy(struct drm_connector *connector)
327 {
328         struct hdmi_connector *hdmi_connector = to_hdmi_connector(connector);
329
330         hdp_disable(hdmi_connector);
331
332         drm_connector_unregister(connector);
333         drm_connector_cleanup(connector);
334
335         kfree(hdmi_connector);
336 }
337
338 static int hdmi_connector_get_modes(struct drm_connector *connector)
339 {
340         struct hdmi_connector *hdmi_connector = to_hdmi_connector(connector);
341         struct hdmi *hdmi = hdmi_connector->hdmi;
342         struct edid *edid;
343         uint32_t hdmi_ctrl;
344         int ret = 0;
345
346         hdmi_ctrl = hdmi_read(hdmi, REG_HDMI_CTRL);
347         hdmi_write(hdmi, REG_HDMI_CTRL, hdmi_ctrl | HDMI_CTRL_ENABLE);
348
349         edid = drm_get_edid(connector, hdmi->i2c);
350
351         hdmi_write(hdmi, REG_HDMI_CTRL, hdmi_ctrl);
352
353         drm_mode_connector_update_edid_property(connector, edid);
354
355         if (edid) {
356                 ret = drm_add_edid_modes(connector, edid);
357                 kfree(edid);
358         }
359
360         return ret;
361 }
362
363 static int hdmi_connector_mode_valid(struct drm_connector *connector,
364                                  struct drm_display_mode *mode)
365 {
366         struct hdmi_connector *hdmi_connector = to_hdmi_connector(connector);
367         struct hdmi *hdmi = hdmi_connector->hdmi;
368         const struct hdmi_platform_config *config = hdmi->config;
369         struct msm_drm_private *priv = connector->dev->dev_private;
370         struct msm_kms *kms = priv->kms;
371         long actual, requested;
372
373         requested = 1000 * mode->clock;
374         actual = kms->funcs->round_pixclk(kms,
375                         requested, hdmi_connector->hdmi->encoder);
376
377         /* for mdp5/apq8074, we manage our own pixel clk (as opposed to
378          * mdp4/dtv stuff where pixel clk is assigned to mdp/encoder
379          * instead):
380          */
381         if (config->pwr_clk_cnt > 0)
382                 actual = clk_round_rate(hdmi->pwr_clks[0], actual);
383
384         DBG("requested=%ld, actual=%ld", requested, actual);
385
386         if (actual != requested)
387                 return MODE_CLOCK_RANGE;
388
389         return 0;
390 }
391
392 static struct drm_encoder *
393 hdmi_connector_best_encoder(struct drm_connector *connector)
394 {
395         struct hdmi_connector *hdmi_connector = to_hdmi_connector(connector);
396         return hdmi_connector->hdmi->encoder;
397 }
398
399 static const struct drm_connector_funcs hdmi_connector_funcs = {
400         .dpms = drm_atomic_helper_connector_dpms,
401         .detect = hdmi_connector_detect,
402         .fill_modes = drm_helper_probe_single_connector_modes,
403         .destroy = hdmi_connector_destroy,
404         .reset = drm_atomic_helper_connector_reset,
405         .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
406         .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
407 };
408
409 static const struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {
410         .get_modes = hdmi_connector_get_modes,
411         .mode_valid = hdmi_connector_mode_valid,
412         .best_encoder = hdmi_connector_best_encoder,
413 };
414
415 /* initialize connector */
416 struct drm_connector *hdmi_connector_init(struct hdmi *hdmi)
417 {
418         struct drm_connector *connector = NULL;
419         struct hdmi_connector *hdmi_connector;
420         int ret;
421
422         hdmi_connector = kzalloc(sizeof(*hdmi_connector), GFP_KERNEL);
423         if (!hdmi_connector) {
424                 ret = -ENOMEM;
425                 goto fail;
426         }
427
428         hdmi_connector->hdmi = hdmi;
429         INIT_WORK(&hdmi_connector->hpd_work, hotplug_work);
430
431         connector = &hdmi_connector->base;
432
433         drm_connector_init(hdmi->dev, connector, &hdmi_connector_funcs,
434                         DRM_MODE_CONNECTOR_HDMIA);
435         drm_connector_helper_add(connector, &hdmi_connector_helper_funcs);
436
437         connector->polled = DRM_CONNECTOR_POLL_CONNECT |
438                         DRM_CONNECTOR_POLL_DISCONNECT;
439
440         connector->interlace_allowed = 0;
441         connector->doublescan_allowed = 0;
442
443         drm_connector_register(connector);
444
445         ret = hpd_enable(hdmi_connector);
446         if (ret) {
447                 dev_err(&hdmi->pdev->dev, "failed to enable HPD: %d\n", ret);
448                 goto fail;
449         }
450
451         drm_mode_connector_attach_encoder(connector, hdmi->encoder);
452
453         return connector;
454
455 fail:
456         if (connector)
457                 hdmi_connector_destroy(connector);
458
459         return ERR_PTR(ret);
460 }