blob: 4f2bb0930a7f039c40e268efb4c1e8fb9c2d9428 [file] [log] [blame]
Sachin Bhayareeeb88892018-01-02 16:36:01 +05301/* Copyright (c) 2010-2018, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#include <linux/bitops.h>
15#include <linux/delay.h>
16#include <linux/module.h>
17#include <linux/mutex.h>
18#include <linux/iopoll.h>
19#include <linux/of_address.h>
20#include <linux/of_gpio.h>
21#include <linux/of_platform.h>
22#include <linux/types.h>
23#include <linux/hdcp_qseecom.h>
24#include <linux/clk.h>
25
26#define REG_DUMP 0
27
28#include "mdss_debug.h"
29#include "mdss_fb.h"
30#include "mdss_hdmi_cec.h"
31#include "mdss_hdmi_edid.h"
32#include "mdss_hdmi_hdcp.h"
33#include "mdss_hdmi_tx.h"
34#include "mdss_hdmi_audio.h"
35#include "mdss.h"
36#include "mdss_panel.h"
37#include "mdss_hdmi_mhl.h"
38
39#define DRV_NAME "hdmi-tx"
40#define COMPATIBLE_NAME "qcom,hdmi-tx"
41
42#define HDMI_TX_EVT_STR(x) #x
43#define DEFAULT_VIDEO_RESOLUTION HDMI_VFRMT_640x480p60_4_3
44#define DEFAULT_HDMI_PRIMARY_RESOLUTION HDMI_VFRMT_1920x1080p60_16_9
45
46/* HDMI PHY/PLL bit field macros */
47#define SW_RESET BIT(2)
48#define SW_RESET_PLL BIT(0)
49
50#define HPD_DISCONNECT_POLARITY 0
51#define HPD_CONNECT_POLARITY 1
52
53/*
54 * Audio engine may take 1 to 3 sec to shutdown
55 * in normal cases. To handle worst cases, making
56 * timeout for audio engine shutdown as 5 sec.
57 */
58#define AUDIO_POLL_SLEEP_US (5 * 1000)
59#define AUDIO_POLL_TIMEOUT_US (AUDIO_POLL_SLEEP_US * 1000)
60
61#define HDMI_TX_YUV420_24BPP_PCLK_TMDS_CH_RATE_RATIO 2
62#define HDMI_TX_YUV422_24BPP_PCLK_TMDS_CH_RATE_RATIO 1
63#define HDMI_TX_RGB_24BPP_PCLK_TMDS_CH_RATE_RATIO 1
64
65#define HDMI_TX_SCRAMBLER_THRESHOLD_RATE_KHZ 340000
66#define HDMI_TX_SCRAMBLER_TIMEOUT_MSEC 200
67
68/* Maximum pixel clock rates for hdmi tx */
69#define HDMI_DEFAULT_MAX_PCLK_RATE 148500
70#define HDMI_TX_3_MAX_PCLK_RATE 297000
71#define HDMI_TX_4_MAX_PCLK_RATE 600000
72
73#define hdmi_tx_get_fd(x) (x ? hdmi_ctrl->feature_data[ffs(x) - 1] : 0)
74#define hdmi_tx_set_fd(x, y) {if (x) hdmi_ctrl->feature_data[ffs(x) - 1] = y; }
75
76#define MAX_EDID_READ_RETRY 5
77
78#define HDMI_TX_MIN_FPS 20000
79#define HDMI_TX_MAX_FPS 120000
80
81/* Enable HDCP by default */
82static bool hdcp_feature_on = true;
83
84/*
85 * CN represents IT content type, if ITC bit in infoframe data byte 3
86 * is set, CN bits will represent content type as below:
87 * 0b00 Graphics
88 * 0b01 Photo
89 * 0b10 Cinema
90 * 0b11 Game
91 */
92#define CONFIG_CN_BITS(bits, byte) \
93 (byte = (byte & ~(BIT(4) | BIT(5))) |\
94 ((bits & (BIT(0) | BIT(1))) << 4))
95
96enum hdmi_tx_hpd_states {
97 HPD_OFF,
98 HPD_ON,
99 HPD_ON_CONDITIONAL_MTP,
100 HPD_DISABLE,
101 HPD_ENABLE
102};
103
104static int hdmi_tx_set_mhl_hpd(struct platform_device *pdev, uint8_t on);
105static int hdmi_tx_sysfs_enable_hpd(struct hdmi_tx_ctrl *hdmi_ctrl, int on);
106static irqreturn_t hdmi_tx_isr(int irq, void *data);
107static void hdmi_tx_hpd_off(struct hdmi_tx_ctrl *hdmi_ctrl);
108static int hdmi_tx_hpd_on(struct hdmi_tx_ctrl *hdmi_ctrl);
109static int hdmi_tx_enable_power(struct hdmi_tx_ctrl *hdmi_ctrl,
110 enum hdmi_tx_power_module_type module, int enable);
111static int hdmi_tx_setup_tmds_clk_rate(struct hdmi_tx_ctrl *hdmi_ctrl);
112static void hdmi_tx_fps_work(struct work_struct *work);
113
114static struct mdss_hw hdmi_tx_hw = {
115 .hw_ndx = MDSS_HW_HDMI,
116 .ptr = NULL,
117 .irq_handler = hdmi_tx_isr,
118};
119
Sachin Bhayare5076e252018-01-18 14:56:45 +0530120static struct mdss_gpio hpd_gpio_config[] = {
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530121 {0, 1, COMPATIBLE_NAME "-hpd"},
122 {0, 1, COMPATIBLE_NAME "-mux-en"},
123 {0, 0, COMPATIBLE_NAME "-mux-sel"},
124 {0, 1, COMPATIBLE_NAME "-mux-lpm"}
125};
126
Sachin Bhayare5076e252018-01-18 14:56:45 +0530127static struct mdss_gpio ddc_gpio_config[] = {
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530128 {0, 1, COMPATIBLE_NAME "-ddc-mux-sel"},
129 {0, 1, COMPATIBLE_NAME "-ddc-clk"},
130 {0, 1, COMPATIBLE_NAME "-ddc-data"}
131};
132
Sachin Bhayare5076e252018-01-18 14:56:45 +0530133static struct mdss_gpio core_gpio_config[] = {
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530134};
135
Sachin Bhayare5076e252018-01-18 14:56:45 +0530136static struct mdss_gpio cec_gpio_config[] = {
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530137 {0, 1, COMPATIBLE_NAME "-cec"}
138};
139
140const char *hdmi_pm_name(enum hdmi_tx_power_module_type module)
141{
142 switch (module) {
143 case HDMI_TX_HPD_PM: return "HDMI_TX_HPD_PM";
144 case HDMI_TX_DDC_PM: return "HDMI_TX_DDC_PM";
145 case HDMI_TX_CORE_PM: return "HDMI_TX_CORE_PM";
146 case HDMI_TX_CEC_PM: return "HDMI_TX_CEC_PM";
147 default: return "???";
148 }
149} /* hdmi_pm_name */
150
151static int hdmi_tx_get_version(struct hdmi_tx_ctrl *hdmi_ctrl)
152{
153 int rc;
154 int reg_val;
Sachin Bhayare5076e252018-01-18 14:56:45 +0530155 struct mdss_io_data *io;
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530156
157 rc = hdmi_tx_enable_power(hdmi_ctrl, HDMI_TX_HPD_PM, true);
158 if (rc) {
159 DEV_ERR("%s: Failed to read HDMI version\n", __func__);
160 goto fail;
161 }
162
163 io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
164 if (!io->base) {
165 DEV_ERR("%s: core io not inititalized\n", __func__);
166 rc = -EINVAL;
167 goto fail;
168 }
169
170 reg_val = DSS_REG_R(io, HDMI_VERSION);
171 reg_val = (reg_val & 0xF0000000) >> 28;
172 hdmi_ctrl->hdmi_tx_ver = reg_val;
173
174 switch (hdmi_ctrl->hdmi_tx_ver) {
175 case (HDMI_TX_VERSION_3):
176 hdmi_ctrl->max_pclk_khz = HDMI_TX_3_MAX_PCLK_RATE;
177 break;
178 case (HDMI_TX_VERSION_4):
179 hdmi_ctrl->max_pclk_khz = HDMI_TX_4_MAX_PCLK_RATE;
180 break;
181 default:
182 hdmi_ctrl->max_pclk_khz = HDMI_DEFAULT_MAX_PCLK_RATE;
183 break;
184 }
185
186 rc = hdmi_tx_enable_power(hdmi_ctrl, HDMI_TX_HPD_PM, false);
187 if (rc) {
188 DEV_ERR("%s: FAILED to disable power\n", __func__);
189 goto fail;
190 }
191
192fail:
193 return rc;
194}
195
196int register_hdmi_cable_notification(struct hdmi_cable_notify *handler)
197{
198 struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
199 struct list_head *pos;
200
201 if (!hdmi_tx_hw.ptr) {
202 DEV_WARN("%s: HDMI Tx core not ready\n", __func__);
203 return -EPROBE_DEFER;
204 }
205
206 if (!handler) {
207 DEV_ERR("%s: Empty handler\n", __func__);
208 return -ENODEV;
209 }
210
211 hdmi_ctrl = (struct hdmi_tx_ctrl *) hdmi_tx_hw.ptr;
212
213 mutex_lock(&hdmi_ctrl->tx_lock);
214 handler->status = hdmi_ctrl->hpd_state;
215 list_for_each(pos, &hdmi_ctrl->cable_notify_handlers);
216 list_add_tail(&handler->link, pos);
217 mutex_unlock(&hdmi_ctrl->tx_lock);
218
219 return handler->status;
220} /* register_hdmi_cable_notification */
221
222int unregister_hdmi_cable_notification(struct hdmi_cable_notify *handler)
223{
224 struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
225
226 if (!hdmi_tx_hw.ptr) {
227 DEV_WARN("%s: HDMI Tx core not ready\n", __func__);
228 return -ENODEV;
229 }
230
231 if (!handler) {
232 DEV_ERR("%s: Empty handler\n", __func__);
233 return -ENODEV;
234 }
235
236 hdmi_ctrl = (struct hdmi_tx_ctrl *) hdmi_tx_hw.ptr;
237
238 mutex_lock(&hdmi_ctrl->tx_lock);
239 list_del(&handler->link);
240 mutex_unlock(&hdmi_ctrl->tx_lock);
241
242 return 0;
243} /* unregister_hdmi_cable_notification */
244
245static void hdmi_tx_cable_notify_work(struct work_struct *work)
246{
247 struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
248 struct hdmi_cable_notify *pos;
249
250 hdmi_ctrl = container_of(work, struct hdmi_tx_ctrl, cable_notify_work);
251
252 if (!hdmi_ctrl) {
253 DEV_ERR("%s: invalid hdmi data\n", __func__);
254 return;
255 }
256
257 mutex_lock(&hdmi_ctrl->tx_lock);
258 list_for_each_entry(pos, &hdmi_ctrl->cable_notify_handlers, link) {
259 if (pos->status != hdmi_ctrl->hpd_state) {
260 pos->status = hdmi_ctrl->hpd_state;
261 pos->hpd_notify(pos);
262 }
263 }
264 mutex_unlock(&hdmi_ctrl->tx_lock);
265} /* hdmi_tx_cable_notify_work */
266
267static bool hdmi_tx_is_cea_format(int mode)
268{
269 bool cea_fmt;
270
271 if ((mode > 0) && (mode <= HDMI_EVFRMT_END))
272 cea_fmt = true;
273 else
274 cea_fmt = false;
275
276 DEV_DBG("%s: %s\n", __func__, cea_fmt ? "Yes" : "No");
277
278 return cea_fmt;
279}
280
281static inline bool hdmi_tx_is_hdcp_enabled(struct hdmi_tx_ctrl *hdmi_ctrl)
282{
283 return hdmi_ctrl->hdcp_feature_on &&
284 (hdmi_ctrl->hdcp14_present || hdmi_ctrl->hdcp22_present) &&
285 hdmi_ctrl->hdcp_ops;
286}
287
288static const char *hdmi_tx_pm_name(enum hdmi_tx_power_module_type module)
289{
290 switch (module) {
291 case HDMI_TX_HPD_PM: return "HDMI_TX_HPD_PM";
292 case HDMI_TX_DDC_PM: return "HDMI_TX_DDC_PM";
293 case HDMI_TX_CORE_PM: return "HDMI_TX_CORE_PM";
294 case HDMI_TX_CEC_PM: return "HDMI_TX_CEC_PM";
295 default: return "???";
296 }
297} /* hdmi_tx_pm_name */
298
299static const char *hdmi_tx_io_name(u32 type)
300{
301 switch (type) {
302 case HDMI_TX_CORE_IO: return "core_physical";
303 case HDMI_TX_QFPROM_IO: return "qfprom_physical";
304 case HDMI_TX_HDCP_IO: return "hdcp_physical";
305 default: return NULL;
306 }
307} /* hdmi_tx_io_name */
308
309static void hdmi_tx_audio_setup(struct hdmi_tx_ctrl *hdmi_ctrl)
310{
311 if (hdmi_ctrl && hdmi_ctrl->audio_ops.on) {
312 u32 pclk = hdmi_tx_setup_tmds_clk_rate(hdmi_ctrl);
313
314 hdmi_ctrl->audio_ops.on(hdmi_ctrl->audio_data,
315 pclk, &hdmi_ctrl->audio_params);
316 }
317}
318
319static inline u32 hdmi_tx_is_dvi_mode(struct hdmi_tx_ctrl *hdmi_ctrl)
320{
321 return hdmi_edid_get_sink_mode(
322 hdmi_tx_get_fd(HDMI_TX_FEAT_EDID)) ? 0 : 1;
323} /* hdmi_tx_is_dvi_mode */
324
325static inline bool hdmi_tx_is_panel_on(struct hdmi_tx_ctrl *hdmi_ctrl)
326{
327 return hdmi_ctrl->hpd_state && hdmi_ctrl->panel_power_on;
328}
329
330static inline bool hdmi_tx_is_cec_wakeup_en(struct hdmi_tx_ctrl *hdmi_ctrl)
331{
332 void *fd = NULL;
333
334 if (!hdmi_ctrl)
335 return false;
336
337 fd = hdmi_tx_get_fd(HDMI_TX_FEAT_CEC_HW);
338
339 if (!fd)
340 return false;
341
342 return hdmi_cec_is_wakeup_en(fd);
343}
344
345static inline void hdmi_tx_cec_device_suspend(struct hdmi_tx_ctrl *hdmi_ctrl)
346{
347 void *fd = NULL;
348
349 if (!hdmi_ctrl)
350 return;
351
352 fd = hdmi_tx_get_fd(HDMI_TX_FEAT_CEC_HW);
353
354 if (!fd)
355 return;
356
357 hdmi_cec_device_suspend(fd, hdmi_ctrl->panel_suspend);
358}
359
360
361static inline void hdmi_tx_send_cable_notification(
362 struct hdmi_tx_ctrl *hdmi_ctrl, int val)
363{
364 int state = 0;
365
366 if (!hdmi_ctrl) {
367 DEV_ERR("%s: invalid input\n", __func__);
368 return;
369 }
370 state = hdmi_ctrl->sdev.state;
371
Sachin Bhayare3d3767e2018-01-02 21:10:57 +0530372 extcon_set_state_sync(&hdmi_ctrl->sdev, EXTCON_DISP_HDMI, state);
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530373
374 DEV_INFO("%s: cable state %s %d\n", __func__,
375 hdmi_ctrl->sdev.state == state ?
376 "is same" : "switched to",
377 hdmi_ctrl->sdev.state);
378
379 /* Notify all registered modules of cable connection status */
380 schedule_work(&hdmi_ctrl->cable_notify_work);
381} /* hdmi_tx_send_cable_notification */
382
383static inline void hdmi_tx_set_audio_switch_node(
384 struct hdmi_tx_ctrl *hdmi_ctrl, int val)
385{
386 if (hdmi_ctrl && hdmi_ctrl->audio_ops.notify &&
387 !hdmi_tx_is_dvi_mode(hdmi_ctrl))
388 hdmi_ctrl->audio_ops.notify(hdmi_ctrl->audio_data, val);
389}
390
391static void hdmi_tx_wait_for_audio_engine(struct hdmi_tx_ctrl *hdmi_ctrl)
392{
393 u64 status = 0;
394 u32 wait_for_vote = 50;
Sachin Bhayare5076e252018-01-18 14:56:45 +0530395 struct mdss_io_data *io = NULL;
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530396
397 if (!hdmi_ctrl) {
398 DEV_ERR("%s: invalid input\n", __func__);
399 return;
400 }
401
402 io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
403 if (!io->base) {
404 DEV_ERR("%s: core io not inititalized\n", __func__);
405 return;
406 }
407
408 /*
409 * wait for 5 sec max for audio engine to acknowledge if hdmi tx core
410 * can be safely turned off. Sleep for a reasonable time to make sure
411 * vote_hdmi_core_on variable is updated properly by audio.
412 */
413 while (hdmi_ctrl->vote_hdmi_core_on && --wait_for_vote)
414 msleep(100);
415
416
417 if (!wait_for_vote)
418 DEV_ERR("%s: HDMI core still voted for power on\n", __func__);
419
420 if (readl_poll_timeout(io->base + HDMI_AUDIO_PKT_CTRL, status,
421 (status & BIT(0)) == 0, AUDIO_POLL_SLEEP_US,
422 AUDIO_POLL_TIMEOUT_US))
423 DEV_ERR("%s: Error turning off audio packet transmission.\n",
424 __func__);
425
426 if (readl_poll_timeout(io->base + HDMI_AUDIO_CFG, status,
427 (status & BIT(0)) == 0, AUDIO_POLL_SLEEP_US,
428 AUDIO_POLL_TIMEOUT_US))
429 DEV_ERR("%s: Error turning off audio engine.\n", __func__);
430}
431
432static struct hdmi_tx_ctrl *hdmi_tx_get_drvdata_from_panel_data(
433 struct mdss_panel_data *mpd)
434{
435 struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
436
437 if (mpd) {
438 hdmi_ctrl = container_of(mpd, struct hdmi_tx_ctrl, panel_data);
439 if (!hdmi_ctrl)
440 DEV_ERR("%s: hdmi_ctrl = NULL\n", __func__);
441 } else {
442 DEV_ERR("%s: mdss_panel_data = NULL\n", __func__);
443 }
444 return hdmi_ctrl;
445} /* hdmi_tx_get_drvdata_from_panel_data */
446
447static struct hdmi_tx_ctrl *hdmi_tx_get_drvdata_from_sysfs_dev(
448 struct device *device)
449{
450 struct msm_fb_data_type *mfd = NULL;
451 struct mdss_panel_data *panel_data = NULL;
452 struct fb_info *fbi = dev_get_drvdata(device);
453
454 if (fbi) {
455 mfd = (struct msm_fb_data_type *)fbi->par;
456 panel_data = dev_get_platdata(&mfd->pdev->dev);
457
458 return hdmi_tx_get_drvdata_from_panel_data(panel_data);
459 }
460 DEV_ERR("%s: fbi = NULL\n", __func__);
461 return NULL;
462} /* hdmi_tx_get_drvdata_from_sysfs_dev */
463
464/* todo: Fix this. Right now this is declared in hdmi_util.h */
465void *hdmi_get_featuredata_from_sysfs_dev(struct device *device,
466 u32 feature_type)
467{
468 struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
469
470 if (!device || feature_type >= HDMI_TX_FEAT_MAX) {
471 DEV_ERR("%s: invalid input\n", __func__);
472 return NULL;
473 }
474
475 hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(device);
476 if (hdmi_ctrl)
477 return hdmi_tx_get_fd(feature_type);
478 else
479 return NULL;
480
481} /* hdmi_tx_get_featuredata_from_sysfs_dev */
482EXPORT_SYMBOL(hdmi_get_featuredata_from_sysfs_dev);
483
484static int hdmi_tx_config_5v(struct hdmi_tx_ctrl *hdmi_ctrl, bool enable)
485{
Sachin Bhayare5076e252018-01-18 14:56:45 +0530486 struct mdss_module_power *pd = NULL;
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530487 int ret = 0;
488
489 if (!hdmi_ctrl) {
490 DEV_ERR("%s: invalid input\n", __func__);
491 ret = -EINVAL;
492 goto end;
493 }
494
495 pd = &hdmi_ctrl->pdata.power_data[HDMI_TX_HPD_PM];
496 if (!pd || !pd->gpio_config) {
497 DEV_ERR("%s: Error: invalid power data\n", __func__);
498 ret = -EINVAL;
499 goto end;
500 }
501
502 gpio_set_value(pd->gpio_config->gpio, enable);
503end:
504 return ret;
505}
506
507static ssize_t hdmi_tx_sysfs_rda_connected(struct device *dev,
508 struct device_attribute *attr, char *buf)
509{
510 ssize_t ret;
511 struct hdmi_tx_ctrl *hdmi_ctrl =
512 hdmi_tx_get_drvdata_from_sysfs_dev(dev);
513
514 if (!hdmi_ctrl) {
515 DEV_ERR("%s: invalid input\n", __func__);
516 return -EINVAL;
517 }
518
519 mutex_lock(&hdmi_ctrl->tx_lock);
520 ret = snprintf(buf, PAGE_SIZE, "%d\n", hdmi_ctrl->hpd_state);
521 DEV_DBG("%s: '%d'\n", __func__, hdmi_ctrl->hpd_state);
522 mutex_unlock(&hdmi_ctrl->tx_lock);
523
524 return ret;
525} /* hdmi_tx_sysfs_rda_connected */
526
527static ssize_t hdmi_tx_sysfs_wta_edid(struct device *dev,
528 struct device_attribute *attr, const char *buf, size_t count)
529{
530 int ret = 0;
531 struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
532 int i = 0;
533 const char *buf_t = buf;
534 const int char_to_nib = 2;
535 int edid_size = count / char_to_nib;
536
537 hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev);
538
539 if (!hdmi_ctrl || !hdmi_ctrl->edid_buf) {
540 DEV_ERR("%s: invalid data\n", __func__);
541 return -EINVAL;
542 }
543
544 mutex_lock(&hdmi_ctrl->tx_lock);
545 if ((edid_size < EDID_BLOCK_SIZE) ||
546 (edid_size > hdmi_ctrl->edid_buf_size)) {
547 DEV_DBG("%s: disabling custom edid\n", __func__);
548
549 ret = -EINVAL;
550 hdmi_ctrl->custom_edid = false;
551 goto end;
552 }
553
554 memset(hdmi_ctrl->edid_buf, 0, hdmi_ctrl->edid_buf_size);
555
556 while (edid_size--) {
557 char t[char_to_nib + 1];
558 int d;
559
560 memcpy(t, buf_t, sizeof(char) * char_to_nib);
561 t[char_to_nib] = '\0';
562
563 ret = kstrtoint(t, 16, &d);
564 if (ret) {
565 pr_err("kstrtoint error %d\n", ret);
566 goto end;
567 }
568
569 memcpy(hdmi_ctrl->edid_buf + i++, &d,
570 sizeof(*hdmi_ctrl->edid_buf));
571
572 buf_t += char_to_nib;
573 }
574
575 ret = strnlen(buf, PAGE_SIZE);
576 hdmi_ctrl->custom_edid = true;
577end:
578 mutex_unlock(&hdmi_ctrl->tx_lock);
579 return ret;
580}
581
582static ssize_t hdmi_tx_sysfs_rda_edid(struct device *dev,
583 struct device_attribute *attr, char *buf)
584{
585 struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
586 u32 size;
587 u32 cea_blks;
588
589 hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev);
590
591 if (!hdmi_ctrl || !hdmi_ctrl->edid_buf) {
592 DEV_ERR("%s: invalid data\n", __func__);
593 return -EINVAL;
594 }
595
596 mutex_lock(&hdmi_ctrl->tx_lock);
597 cea_blks = hdmi_ctrl->edid_buf[EDID_BLOCK_SIZE - 2];
598 if (cea_blks >= MAX_EDID_BLOCKS) {
599 DEV_ERR("%s: invalid cea blocks\n", __func__);
600 mutex_unlock(&hdmi_ctrl->tx_lock);
601 return -EINVAL;
602 }
603 size = (cea_blks + 1) * EDID_BLOCK_SIZE;
604 size = min_t(u32, size, PAGE_SIZE);
605
606 DEV_DBG("%s: edid size %d\n", __func__, size);
607
608 memcpy(buf, hdmi_ctrl->edid_buf, size);
609
610 print_hex_dump(KERN_DEBUG, "HDMI EDID: ", DUMP_PREFIX_NONE,
611 16, 1, buf, size, false);
612
613 mutex_unlock(&hdmi_ctrl->tx_lock);
614 return size;
615}
616
617static ssize_t hdmi_tx_sysfs_wta_audio_cb(struct device *dev,
618 struct device_attribute *attr, const char *buf, size_t count)
619{
620 int ack, rc = 0;
621 ssize_t ret = strnlen(buf, PAGE_SIZE);
622 struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
623
624 hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev);
625
626 if (!hdmi_ctrl) {
627 DEV_ERR("%s: invalid input\n", __func__);
628 ret = -EINVAL;
629 goto end;
630 }
631
632 rc = kstrtoint(buf, 10, &ack);
633 if (rc) {
634 DEV_ERR("%s: kstrtoint failed. rc=%d\n", __func__, rc);
635 goto end;
636 }
637
638 if (hdmi_ctrl->audio_ops.ack)
639 hdmi_ctrl->audio_ops.ack(hdmi_ctrl->audio_data,
640 ack, hdmi_ctrl->hpd_state);
641end:
642 return ret;
643}
644
645static int hdmi_tx_update_pixel_clk(struct hdmi_tx_ctrl *hdmi_ctrl)
646{
Sachin Bhayare5076e252018-01-18 14:56:45 +0530647 struct mdss_module_power *power_data = NULL;
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530648 struct mdss_panel_info *pinfo;
649 int rc = 0;
650
651 if (!hdmi_ctrl) {
652 DEV_ERR("%s: invalid input\n", __func__);
653 rc = -EINVAL;
654 goto end;
655 }
656
657 pinfo = &hdmi_ctrl->panel_data.panel_info;
658
659 power_data = &hdmi_ctrl->pdata.power_data[HDMI_TX_CORE_PM];
660 if (!power_data) {
661 DEV_ERR("%s: Error: invalid power data\n", __func__);
662 rc = -EINVAL;
663 goto end;
664 }
665
666 if (power_data->clk_config->rate == pinfo->clk_rate) {
667 rc = -EINVAL;
668 goto end;
669 }
670
671 power_data->clk_config->rate = pinfo->clk_rate;
672
673 if (pinfo->out_format == MDP_Y_CBCR_H2V2)
674 power_data->clk_config->rate /= 2;
675
676 DEV_DBG("%s: rate %ld\n", __func__, power_data->clk_config->rate);
677
Sachin Bhayare5076e252018-01-18 14:56:45 +0530678 msm_mdss_clk_set_rate(power_data->clk_config, power_data->num_clk);
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530679end:
680 return rc;
681}
682
683static ssize_t hdmi_tx_sysfs_wta_hot_plug(struct device *dev,
684 struct device_attribute *attr, const char *buf, size_t count)
685{
686 int hot_plug, rc;
687 struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
688
689 hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev);
690
691 if (!hdmi_ctrl) {
692 DEV_ERR("%s: invalid input\n", __func__);
693 return -EINVAL;
694 }
695
696 mutex_lock(&hdmi_ctrl->tx_lock);
697
698 rc = kstrtoint(buf, 10, &hot_plug);
699 if (rc) {
700 DEV_ERR("%s: kstrtoint failed. rc=%d\n", __func__, rc);
701 goto end;
702 }
703
704 hdmi_ctrl->hpd_state = !!hot_plug;
705
706 queue_work(hdmi_ctrl->workq, &hdmi_ctrl->hpd_int_work);
707
708 rc = strnlen(buf, PAGE_SIZE);
709end:
710 mutex_unlock(&hdmi_ctrl->tx_lock);
711 return rc;
712}
713
714static ssize_t hdmi_tx_sysfs_rda_sim_mode(struct device *dev,
715 struct device_attribute *attr, char *buf)
716{
717 ssize_t ret;
718 struct hdmi_tx_ctrl *hdmi_ctrl =
719 hdmi_tx_get_drvdata_from_sysfs_dev(dev);
720
721 if (!hdmi_ctrl) {
722 DEV_ERR("%s: invalid input\n", __func__);
723 return -EINVAL;
724 }
725
726 mutex_lock(&hdmi_ctrl->tx_lock);
727 ret = snprintf(buf, PAGE_SIZE, "%d\n", hdmi_ctrl->sim_mode);
728 DEV_DBG("%s: '%d'\n", __func__, hdmi_ctrl->sim_mode);
729 mutex_unlock(&hdmi_ctrl->tx_lock);
730
731 return ret;
732}
733
734static ssize_t hdmi_tx_sysfs_wta_sim_mode(struct device *dev,
735 struct device_attribute *attr, const char *buf, size_t count)
736{
737 int sim_mode, rc;
738 struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
Sachin Bhayare5076e252018-01-18 14:56:45 +0530739 struct mdss_io_data *io = NULL;
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530740
741 hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev);
742
743 if (!hdmi_ctrl) {
744 DEV_ERR("%s: invalid input\n", __func__);
745 return -EINVAL;
746 }
747
748 mutex_lock(&hdmi_ctrl->tx_lock);
749 io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
750 if (!io->base) {
751 DEV_ERR("%s: core io is not initialized\n", __func__);
752 rc = -EINVAL;
753 goto end;
754 }
755
756 if (!hdmi_ctrl->hpd_initialized) {
757 DEV_ERR("%s: hpd not enabled\n", __func__);
758 rc = -EINVAL;
759 goto end;
760 }
761
762 rc = kstrtoint(buf, 10, &sim_mode);
763 if (rc) {
764 DEV_ERR("%s: kstrtoint failed. rc=%d\n", __func__, rc);
765 goto end;
766 }
767
768 hdmi_ctrl->sim_mode = !!sim_mode;
769
770 if (hdmi_ctrl->sim_mode) {
771 DSS_REG_W(io, HDMI_HPD_INT_CTRL, BIT(0));
772 } else {
773 int cable_sense = DSS_REG_R(io, HDMI_HPD_INT_STATUS) & BIT(1);
774
775 DSS_REG_W(io, HDMI_HPD_INT_CTRL, BIT(0) | BIT(2) |
776 (cable_sense ? 0 : BIT(1)));
777 }
778
779 rc = strnlen(buf, PAGE_SIZE);
780end:
781 mutex_unlock(&hdmi_ctrl->tx_lock);
782 return rc;
783}
784
785static ssize_t hdmi_tx_sysfs_rda_video_mode(struct device *dev,
786 struct device_attribute *attr, char *buf)
787{
788 ssize_t ret;
789 struct hdmi_tx_ctrl *hdmi_ctrl =
790 hdmi_tx_get_drvdata_from_sysfs_dev(dev);
791
792 if (!hdmi_ctrl) {
793 DEV_ERR("%s: invalid input\n", __func__);
794 return -EINVAL;
795 }
796
797 mutex_lock(&hdmi_ctrl->tx_lock);
798 ret = snprintf(buf, PAGE_SIZE, "%d\n", hdmi_ctrl->vic);
799 DEV_DBG("%s: '%d'\n", __func__, hdmi_ctrl->vic);
800 mutex_unlock(&hdmi_ctrl->tx_lock);
801
802 return ret;
803} /* hdmi_tx_sysfs_rda_video_mode */
804
805static ssize_t hdmi_tx_sysfs_rda_hpd(struct device *dev,
806 struct device_attribute *attr, char *buf)
807{
808 ssize_t ret;
809 struct hdmi_tx_ctrl *hdmi_ctrl =
810 hdmi_tx_get_drvdata_from_sysfs_dev(dev);
811
812 if (!hdmi_ctrl) {
813 DEV_ERR("%s: invalid input\n", __func__);
814 return -EINVAL;
815 }
816
817 mutex_lock(&hdmi_ctrl->tx_lock);
818 ret = snprintf(buf, PAGE_SIZE, "%d\n", hdmi_ctrl->hpd_feature_on);
819 DEV_DBG("%s: '%d'\n", __func__, hdmi_ctrl->hpd_feature_on);
820 mutex_unlock(&hdmi_ctrl->tx_lock);
821
822 return ret;
823} /* hdmi_tx_sysfs_rda_hpd */
824
825static ssize_t hdmi_tx_sysfs_wta_hpd(struct device *dev,
826 struct device_attribute *attr, const char *buf, size_t count)
827{
828 int hpd, rc = 0;
829 ssize_t ret = strnlen(buf, PAGE_SIZE);
830 struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
831
832 hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev);
833
834 if (!hdmi_ctrl) {
835 DEV_ERR("%s: invalid input\n", __func__);
836 return -EINVAL;
837 }
838
839 mutex_lock(&hdmi_ctrl->tx_lock);
840
841 rc = kstrtoint(buf, 10, &hpd);
842 if (rc) {
843 DEV_ERR("%s: kstrtoint failed. rc=%d\n", __func__, rc);
844 goto end;
845 }
846
847 DEV_DBG("%s: %d\n", __func__, hpd);
848
849 if (hdmi_ctrl->ds_registered && hpd &&
850 (!hdmi_ctrl->mhl_hpd_on || hdmi_ctrl->hpd_feature_on)) {
851 DEV_DBG("%s: DS registered, HPD on not allowed\n", __func__);
852 goto end;
853 }
854
855 switch (hpd) {
856 case HPD_OFF:
857 case HPD_DISABLE:
858 if (hpd == HPD_DISABLE)
859 hdmi_ctrl->hpd_disabled = true;
860
861 if (!hdmi_ctrl->hpd_feature_on) {
862 DEV_DBG("%s: HPD is already off\n", __func__);
863 goto end;
864 }
865
866 /* disable audio ack feature */
867 if (hdmi_ctrl->audio_ops.ack)
868 hdmi_ctrl->audio_ops.ack(hdmi_ctrl->audio_data,
869 AUDIO_ACK_SET_ENABLE, hdmi_ctrl->hpd_state);
870
871 if (hdmi_ctrl->panel_power_on) {
872 hdmi_ctrl->hpd_off_pending = true;
873 hdmi_tx_config_5v(hdmi_ctrl, false);
874 } else {
875 hdmi_tx_hpd_off(hdmi_ctrl);
876
877 hdmi_ctrl->sdev.state = 0;
878 hdmi_tx_set_audio_switch_node(hdmi_ctrl, 0);
879 }
880
881 break;
882 case HPD_ON:
883 if (hdmi_ctrl->hpd_disabled == true) {
884 DEV_ERR("%s: hpd is disabled, state %d not allowed\n",
885 __func__, hpd);
886 goto end;
887 }
888
889 if (hdmi_ctrl->pdata.cond_power_on) {
890 DEV_ERR("%s: hpd state %d not allowed w/ cond. hpd\n",
891 __func__, hpd);
892 goto end;
893 }
894
895 if (hdmi_ctrl->hpd_feature_on) {
896 DEV_DBG("%s: HPD is already on\n", __func__);
897 goto end;
898 }
899
900 rc = hdmi_tx_sysfs_enable_hpd(hdmi_ctrl, true);
901 break;
902 case HPD_ON_CONDITIONAL_MTP:
903 if (hdmi_ctrl->hpd_disabled == true) {
904 DEV_ERR("%s: hpd is disabled, state %d not allowed\n",
905 __func__, hpd);
906 goto end;
907 }
908
909 if (!hdmi_ctrl->pdata.cond_power_on) {
910 DEV_ERR("%s: hpd state %d not allowed w/o cond. hpd\n",
911 __func__, hpd);
912 goto end;
913 }
914
915 if (hdmi_ctrl->hpd_feature_on) {
916 DEV_DBG("%s: HPD is already on\n", __func__);
917 goto end;
918 }
919
920 rc = hdmi_tx_sysfs_enable_hpd(hdmi_ctrl, true);
921 break;
922 case HPD_ENABLE:
923 hdmi_ctrl->hpd_disabled = false;
924
925 rc = hdmi_tx_sysfs_enable_hpd(hdmi_ctrl, true);
926 break;
927 default:
928 DEV_ERR("%s: Invalid HPD state requested\n", __func__);
929 goto end;
930 }
931
932 if (!rc) {
933 hdmi_ctrl->hpd_feature_on =
934 (~hdmi_ctrl->hpd_feature_on) & BIT(0);
935 DEV_DBG("%s: '%d'\n", __func__, hdmi_ctrl->hpd_feature_on);
936 } else {
937 DEV_ERR("%s: failed to '%s' hpd. rc = %d\n", __func__,
938 hpd ? "enable" : "disable", rc);
939 ret = rc;
940 }
941
942end:
943 mutex_unlock(&hdmi_ctrl->tx_lock);
944 return ret;
945} /* hdmi_tx_sysfs_wta_hpd */
946
947static ssize_t hdmi_tx_sysfs_wta_vendor_name(struct device *dev,
948 struct device_attribute *attr, const char *buf, size_t count)
949{
950 ssize_t ret, sz;
951 u8 *s = (u8 *) buf;
952 u8 *d = NULL;
953 struct hdmi_tx_ctrl *hdmi_ctrl =
954 hdmi_tx_get_drvdata_from_sysfs_dev(dev);
955
956 if (!hdmi_ctrl) {
957 DEV_ERR("%s: invalid input\n", __func__);
958 return -EINVAL;
959 }
960
961 mutex_lock(&hdmi_ctrl->tx_lock);
962 d = hdmi_ctrl->spd_vendor_name;
963 ret = strnlen(buf, PAGE_SIZE);
964 ret = (ret > 8) ? 8 : ret;
965
966 sz = sizeof(hdmi_ctrl->spd_vendor_name);
967 memset(hdmi_ctrl->spd_vendor_name, 0, sz);
968 while (*s) {
969 if (*s & 0x60 && *s ^ 0x7f) {
970 *d = *s;
971 } else {
972 /* stop copying if control character found */
973 break;
974 }
975
976 if (++s > (u8 *) (buf + ret))
977 break;
978
979 d++;
980 }
981 hdmi_ctrl->spd_vendor_name[sz - 1] = 0;
982
983 DEV_DBG("%s: '%s'\n", __func__, hdmi_ctrl->spd_vendor_name);
984 mutex_unlock(&hdmi_ctrl->tx_lock);
985
986 return ret;
987} /* hdmi_tx_sysfs_wta_vendor_name */
988
989static ssize_t hdmi_tx_sysfs_rda_vendor_name(struct device *dev,
990 struct device_attribute *attr, char *buf)
991{
992 ssize_t ret;
993 struct hdmi_tx_ctrl *hdmi_ctrl =
994 hdmi_tx_get_drvdata_from_sysfs_dev(dev);
995
996 if (!hdmi_ctrl) {
997 DEV_ERR("%s: invalid input\n", __func__);
998 return -EINVAL;
999 }
1000
1001 mutex_lock(&hdmi_ctrl->tx_lock);
1002 ret = snprintf(buf, PAGE_SIZE, "%s\n", hdmi_ctrl->spd_vendor_name);
1003 DEV_DBG("%s: '%s'\n", __func__, hdmi_ctrl->spd_vendor_name);
1004 mutex_unlock(&hdmi_ctrl->tx_lock);
1005
1006 return ret;
1007} /* hdmi_tx_sysfs_rda_vendor_name */
1008
1009static ssize_t hdmi_tx_sysfs_wta_product_description(struct device *dev,
1010 struct device_attribute *attr, const char *buf, size_t count)
1011{
1012 ssize_t ret, sz;
1013 u8 *s = (u8 *) buf;
1014 u8 *d = NULL;
1015 struct hdmi_tx_ctrl *hdmi_ctrl =
1016 hdmi_tx_get_drvdata_from_sysfs_dev(dev);
1017
1018 if (!hdmi_ctrl) {
1019 DEV_ERR("%s: invalid input\n", __func__);
1020 return -EINVAL;
1021 }
1022
1023 mutex_lock(&hdmi_ctrl->tx_lock);
1024 d = hdmi_ctrl->spd_product_description;
1025 ret = strnlen(buf, PAGE_SIZE);
1026 ret = (ret > 16) ? 16 : ret;
1027
1028 sz = sizeof(hdmi_ctrl->spd_product_description);
1029 memset(hdmi_ctrl->spd_product_description, 0, sz);
1030 while (*s) {
1031 if (*s & 0x60 && *s ^ 0x7f) {
1032 *d = *s;
1033 } else {
1034 /* stop copying if control character found */
1035 break;
1036 }
1037
1038 if (++s > (u8 *) (buf + ret))
1039 break;
1040
1041 d++;
1042 }
1043 hdmi_ctrl->spd_product_description[sz - 1] = 0;
1044
1045 DEV_DBG("%s: '%s'\n", __func__, hdmi_ctrl->spd_product_description);
1046 mutex_unlock(&hdmi_ctrl->tx_lock);
1047
1048 return ret;
1049} /* hdmi_tx_sysfs_wta_product_description */
1050
1051static ssize_t hdmi_tx_sysfs_rda_product_description(struct device *dev,
1052 struct device_attribute *attr, char *buf)
1053{
1054 ssize_t ret;
1055 struct hdmi_tx_ctrl *hdmi_ctrl =
1056 hdmi_tx_get_drvdata_from_sysfs_dev(dev);
1057
1058 if (!hdmi_ctrl) {
1059 DEV_ERR("%s: invalid input\n", __func__);
1060 return -EINVAL;
1061 }
1062
1063 mutex_lock(&hdmi_ctrl->tx_lock);
1064 ret = snprintf(buf, PAGE_SIZE, "%s\n",
1065 hdmi_ctrl->spd_product_description);
1066 DEV_DBG("%s: '%s'\n", __func__, hdmi_ctrl->spd_product_description);
1067 mutex_unlock(&hdmi_ctrl->tx_lock);
1068
1069 return ret;
1070} /* hdmi_tx_sysfs_rda_product_description */
1071
1072static ssize_t hdmi_tx_sysfs_wta_avi_itc(struct device *dev,
1073 struct device_attribute *attr, const char *buf, size_t count)
1074{
1075 int ret;
1076 struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
1077 int itc = 0;
1078
1079 hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev);
1080
1081 if (!hdmi_ctrl) {
1082 DEV_ERR("%s: invalid input\n", __func__);
1083 return -EINVAL;
1084 }
1085
1086 mutex_lock(&hdmi_ctrl->tx_lock);
1087
1088 ret = kstrtoint(buf, 10, &itc);
1089 if (ret) {
1090 DEV_ERR("%s: kstrtoint failed. rc =%d\n", __func__, ret);
1091 goto end;
1092 }
1093
1094 if (itc < 0 || itc > 1) {
1095 DEV_ERR("%s: Invalid ITC %d\n", __func__, itc);
1096 ret = -EINVAL;
1097 goto end;
1098 }
1099
1100 hdmi_ctrl->panel.is_it_content = itc ? true : false;
1101
1102 ret = strnlen(buf, PAGE_SIZE);
1103end:
1104 mutex_unlock(&hdmi_ctrl->tx_lock);
1105 return ret;
1106} /* hdmi_tx_sysfs_wta_avi_itc */
1107
1108static ssize_t hdmi_tx_sysfs_wta_avi_cn_bits(struct device *dev,
1109 struct device_attribute *attr, const char *buf, size_t count)
1110{
1111 int ret;
1112 struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
1113 int cn_bits = 0;
1114
1115 hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev);
1116
1117 if (!hdmi_ctrl) {
1118 DEV_ERR("%s: invalid input\n", __func__);
1119 return -EINVAL;
1120 }
1121
1122 mutex_lock(&hdmi_ctrl->tx_lock);
1123
1124 ret = kstrtoint(buf, 10, &cn_bits);
1125 if (ret) {
1126 DEV_ERR("%s: kstrtoint failed. rc=%d\n", __func__, ret);
1127 goto end;
1128 }
1129
1130 /* As per CEA-861-E, CN is a positive number and can be max 3 */
1131 if (cn_bits < 0 || cn_bits > 3) {
1132 DEV_ERR("%s: Invalid CN %d\n", __func__, cn_bits);
1133 ret = -EINVAL;
1134 goto end;
1135 }
1136
1137 hdmi_ctrl->panel.content_type = cn_bits;
1138
1139 ret = strnlen(buf, PAGE_SIZE);
1140end:
1141 mutex_unlock(&hdmi_ctrl->tx_lock);
1142
1143 return ret;
1144} /* hdmi_tx_sysfs_wta_cn_bits */
1145
1146static ssize_t hdmi_tx_sysfs_wta_s3d_mode(struct device *dev,
1147 struct device_attribute *attr, const char *buf, size_t count)
1148{
1149 int ret, s3d_mode;
1150 struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
1151 void *pdata;
1152
1153 hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev);
1154
1155 if (!hdmi_ctrl) {
1156 DEV_ERR("%s: invalid input\n", __func__);
1157 return -EINVAL;
1158 }
1159
1160 pdata = hdmi_tx_get_fd(HDMI_TX_FEAT_PANEL);
1161
1162 mutex_lock(&hdmi_ctrl->tx_lock);
1163
1164 ret = kstrtoint(buf, 10, &s3d_mode);
1165 if (ret) {
1166 DEV_ERR("%s: kstrtoint failed. rc=%d\n", __func__, ret);
1167 goto end;
1168 }
1169
1170 if (s3d_mode < HDMI_S3D_NONE || s3d_mode >= HDMI_S3D_MAX) {
1171 DEV_ERR("%s: invalid s3d mode = %d\n", __func__, s3d_mode);
1172 ret = -EINVAL;
1173 goto end;
1174 }
1175
1176 if (s3d_mode > HDMI_S3D_NONE &&
1177 !hdmi_edid_is_s3d_mode_supported(
1178 hdmi_tx_get_fd(HDMI_TX_FEAT_EDID),
1179 hdmi_ctrl->vic, s3d_mode)) {
1180 DEV_ERR("%s: s3d mode not supported in current video mode\n",
1181 __func__);
1182 ret = -EPERM;
1183 hdmi_ctrl->panel.s3d_support = false;
1184 goto end;
1185 }
1186
1187 hdmi_ctrl->panel.s3d_mode = s3d_mode;
1188 hdmi_ctrl->panel.s3d_support = true;
1189
1190 if (hdmi_ctrl->panel_ops.vendor)
1191 hdmi_ctrl->panel_ops.vendor(pdata);
1192
1193 ret = strnlen(buf, PAGE_SIZE);
1194 DEV_DBG("%s: %d\n", __func__, hdmi_ctrl->s3d_mode);
1195end:
1196 mutex_unlock(&hdmi_ctrl->tx_lock);
1197 return ret;
1198}
1199
1200static ssize_t hdmi_tx_sysfs_rda_s3d_mode(struct device *dev,
1201 struct device_attribute *attr, char *buf)
1202{
1203 ssize_t ret;
1204 struct hdmi_tx_ctrl *hdmi_ctrl =
1205 hdmi_tx_get_drvdata_from_sysfs_dev(dev);
1206
1207 if (!hdmi_ctrl) {
1208 DEV_ERR("%s: invalid input\n", __func__);
1209 return -EINVAL;
1210 }
1211
1212 mutex_lock(&hdmi_ctrl->tx_lock);
1213 ret = snprintf(buf, PAGE_SIZE, "%d\n", hdmi_ctrl->s3d_mode);
1214 DEV_DBG("%s: '%d'\n", __func__, hdmi_ctrl->s3d_mode);
1215 mutex_unlock(&hdmi_ctrl->tx_lock);
1216
1217 return ret;
1218}
1219
1220static ssize_t hdmi_tx_sysfs_wta_5v(struct device *dev,
1221 struct device_attribute *attr, const char *buf, size_t count)
1222{
1223 int read, ret;
1224 struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
Sachin Bhayare5076e252018-01-18 14:56:45 +05301225 struct mdss_module_power *pd = NULL;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05301226
1227 hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev);
1228 if (!hdmi_ctrl) {
1229 DEV_ERR("%s: invalid input\n", __func__);
1230 ret = -EINVAL;
1231 goto end;
1232 }
1233
1234 mutex_lock(&hdmi_ctrl->tx_lock);
1235 pd = &hdmi_ctrl->pdata.power_data[HDMI_TX_HPD_PM];
1236 if (!pd || !pd->gpio_config) {
1237 DEV_ERR("%s: Error: invalid power data\n", __func__);
1238 ret = -EINVAL;
1239 goto end;
1240 }
1241
1242 ret = kstrtoint(buf, 10, &read);
1243 if (ret) {
1244 DEV_ERR("%s: kstrtoint failed. rc=%d\n", __func__, ret);
1245 goto end;
1246 }
1247
1248 read = ~(!!read ^ pd->gpio_config->value) & BIT(0);
1249
1250 ret = hdmi_tx_config_5v(hdmi_ctrl, read);
1251 if (ret)
1252 goto end;
1253
1254 ret = strnlen(buf, PAGE_SIZE);
1255end:
1256 mutex_unlock(&hdmi_ctrl->tx_lock);
1257 return ret;
1258}
1259
1260static DEVICE_ATTR(connected, 0444, hdmi_tx_sysfs_rda_connected, NULL);
1261static DEVICE_ATTR(hdmi_audio_cb, 0200, NULL, hdmi_tx_sysfs_wta_audio_cb);
1262static DEVICE_ATTR(hot_plug, 0200, NULL, hdmi_tx_sysfs_wta_hot_plug);
1263static DEVICE_ATTR(sim_mode, 0644, hdmi_tx_sysfs_rda_sim_mode,
1264 hdmi_tx_sysfs_wta_sim_mode);
1265static DEVICE_ATTR(edid, 0644, hdmi_tx_sysfs_rda_edid,
1266 hdmi_tx_sysfs_wta_edid);
1267static DEVICE_ATTR(video_mode, 0444, hdmi_tx_sysfs_rda_video_mode, NULL);
1268static DEVICE_ATTR(hpd, 0644, hdmi_tx_sysfs_rda_hpd,
1269 hdmi_tx_sysfs_wta_hpd);
1270static DEVICE_ATTR(vendor_name, 0644,
1271 hdmi_tx_sysfs_rda_vendor_name, hdmi_tx_sysfs_wta_vendor_name);
1272static DEVICE_ATTR(product_description, 0644,
1273 hdmi_tx_sysfs_rda_product_description,
1274 hdmi_tx_sysfs_wta_product_description);
1275static DEVICE_ATTR(avi_itc, 0200, NULL, hdmi_tx_sysfs_wta_avi_itc);
1276static DEVICE_ATTR(avi_cn0_1, 0200, NULL, hdmi_tx_sysfs_wta_avi_cn_bits);
1277static DEVICE_ATTR(s3d_mode, 0644, hdmi_tx_sysfs_rda_s3d_mode,
1278 hdmi_tx_sysfs_wta_s3d_mode);
1279static DEVICE_ATTR(5v, 0200, NULL, hdmi_tx_sysfs_wta_5v);
1280
1281static struct attribute *hdmi_tx_fs_attrs[] = {
1282 &dev_attr_connected.attr,
1283 &dev_attr_hdmi_audio_cb.attr,
1284 &dev_attr_hot_plug.attr,
1285 &dev_attr_sim_mode.attr,
1286 &dev_attr_edid.attr,
1287 &dev_attr_video_mode.attr,
1288 &dev_attr_hpd.attr,
1289 &dev_attr_vendor_name.attr,
1290 &dev_attr_product_description.attr,
1291 &dev_attr_avi_itc.attr,
1292 &dev_attr_avi_cn0_1.attr,
1293 &dev_attr_s3d_mode.attr,
1294 &dev_attr_5v.attr,
1295 NULL,
1296};
1297static struct attribute_group hdmi_tx_fs_attrs_group = {
1298 .attrs = hdmi_tx_fs_attrs,
1299};
1300
1301static int hdmi_tx_sysfs_create(struct hdmi_tx_ctrl *hdmi_ctrl,
1302 struct fb_info *fbi)
1303{
1304 int rc;
1305
1306 if (!hdmi_ctrl || !fbi) {
1307 DEV_ERR("%s: invalid input\n", __func__);
1308 return -ENODEV;
1309 }
1310
1311 rc = sysfs_create_group(&fbi->dev->kobj,
1312 &hdmi_tx_fs_attrs_group);
1313 if (rc) {
1314 DEV_ERR("%s: failed, rc=%d\n", __func__, rc);
1315 return rc;
1316 }
1317 hdmi_ctrl->kobj = &fbi->dev->kobj;
1318 DEV_DBG("%s: sysfs group %pK\n", __func__, hdmi_ctrl->kobj);
1319
1320 return 0;
1321} /* hdmi_tx_sysfs_create */
1322
1323static void hdmi_tx_sysfs_remove(struct hdmi_tx_ctrl *hdmi_ctrl)
1324{
1325 if (!hdmi_ctrl) {
1326 DEV_ERR("%s: invalid input\n", __func__);
1327 return;
1328 }
1329 if (hdmi_ctrl->kobj)
1330 sysfs_remove_group(hdmi_ctrl->kobj, &hdmi_tx_fs_attrs_group);
1331 hdmi_ctrl->kobj = NULL;
1332} /* hdmi_tx_sysfs_remove */
1333
1334static int hdmi_tx_config_avmute(struct hdmi_tx_ctrl *hdmi_ctrl, bool set)
1335{
Sachin Bhayare5076e252018-01-18 14:56:45 +05301336 struct mdss_io_data *io;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05301337 u32 av_mute_status;
1338 bool av_pkt_en = false;
1339
1340 if (!hdmi_ctrl) {
1341 DEV_ERR("%s: invalid input\n", __func__);
1342 return -EINVAL;
1343 }
1344
1345 io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
1346 if (!io->base) {
1347 DEV_ERR("%s: Core io is not initialized\n", __func__);
1348 return -EINVAL;
1349 }
1350
1351 av_mute_status = DSS_REG_R(io, HDMI_GC);
1352
1353 if (set) {
1354 if (!(av_mute_status & BIT(0))) {
1355 DSS_REG_W(io, HDMI_GC, av_mute_status | BIT(0));
1356 av_pkt_en = true;
1357 }
1358 } else {
1359 if (av_mute_status & BIT(0)) {
1360 DSS_REG_W(io, HDMI_GC, av_mute_status & ~BIT(0));
1361 av_pkt_en = true;
1362 }
1363 }
1364
1365 /* Enable AV Mute tranmission here */
1366 if (av_pkt_en)
1367 DSS_REG_W(io, HDMI_VBI_PKT_CTRL,
1368 DSS_REG_R(io, HDMI_VBI_PKT_CTRL) | (BIT(4) & BIT(5)));
1369
1370 DEV_DBG("%s: AVMUTE %s\n", __func__, set ? "set" : "cleared");
1371
1372 return 0;
1373} /* hdmi_tx_config_avmute */
1374
1375static bool hdmi_tx_is_encryption_set(struct hdmi_tx_ctrl *hdmi_ctrl)
1376{
Sachin Bhayare5076e252018-01-18 14:56:45 +05301377 struct mdss_io_data *io;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05301378 bool enc_en = true;
1379 u32 reg_val;
1380
1381 if (!hdmi_ctrl) {
1382 DEV_ERR("%s: invalid input\n", __func__);
1383 goto end;
1384 }
1385
1386 io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
1387 if (!io->base) {
1388 DEV_ERR("%s: Core io is not initialized\n", __func__);
1389 goto end;
1390 }
1391
1392 reg_val = DSS_REG_R_ND(io, HDMI_HDCP_CTRL2);
1393 if ((reg_val & BIT(0)) && (reg_val & BIT(1)))
1394 goto end;
1395
1396 if (DSS_REG_R_ND(io, HDMI_CTRL) & BIT(2))
1397 goto end;
1398
1399 return false;
1400
1401end:
1402 return enc_en;
1403} /* hdmi_tx_is_encryption_set */
1404
1405static void hdmi_tx_hdcp_cb(void *ptr, enum hdmi_hdcp_state status)
1406{
1407 struct hdmi_tx_ctrl *hdmi_ctrl = (struct hdmi_tx_ctrl *)ptr;
1408
1409 if (!hdmi_ctrl) {
1410 DEV_ERR("%s: invalid input\n", __func__);
1411 return;
1412 }
1413
1414 hdmi_ctrl->hdcp_status = status;
1415
1416 queue_delayed_work(hdmi_ctrl->workq, &hdmi_ctrl->hdcp_cb_work, HZ/4);
1417}
1418
1419static inline bool hdmi_tx_is_stream_shareable(struct hdmi_tx_ctrl *hdmi_ctrl)
1420{
1421 bool ret;
1422
1423 switch (hdmi_ctrl->enc_lvl) {
1424 case HDCP_STATE_AUTH_ENC_NONE:
1425 ret = true;
1426 break;
1427 case HDCP_STATE_AUTH_ENC_1X:
1428 ret = hdmi_tx_is_hdcp_enabled(hdmi_ctrl) &&
1429 hdmi_ctrl->auth_state;
1430 break;
1431 case HDCP_STATE_AUTH_ENC_2P2:
1432 ret = hdmi_ctrl->hdcp_feature_on &&
1433 hdmi_ctrl->hdcp22_present &&
1434 hdmi_ctrl->auth_state;
1435 break;
1436 default:
1437 ret = false;
1438 }
1439
1440 return ret;
1441}
1442
1443static void hdmi_tx_hdcp_cb_work(struct work_struct *work)
1444{
1445 struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
1446 struct delayed_work *dw = to_delayed_work(work);
1447 int rc = 0;
1448
1449 hdmi_ctrl = container_of(dw, struct hdmi_tx_ctrl, hdcp_cb_work);
1450 if (!hdmi_ctrl) {
1451 DEV_DBG("%s: invalid input\n", __func__);
1452 return;
1453 }
1454
1455 mutex_lock(&hdmi_ctrl->tx_lock);
1456
1457 switch (hdmi_ctrl->hdcp_status) {
1458 case HDCP_STATE_AUTHENTICATED:
1459 hdmi_ctrl->auth_state = true;
1460
1461 if (hdmi_tx_is_panel_on(hdmi_ctrl) &&
1462 hdmi_tx_is_stream_shareable(hdmi_ctrl)) {
1463 rc = hdmi_tx_config_avmute(hdmi_ctrl, false);
1464 hdmi_tx_set_audio_switch_node(hdmi_ctrl, 1);
1465 }
1466
1467 if (hdmi_ctrl->hdcp1_use_sw_keys && hdmi_ctrl->hdcp14_present)
1468 hdcp1_set_enc(true);
1469 break;
1470 case HDCP_STATE_AUTH_FAIL:
1471 if (hdmi_ctrl->hdcp1_use_sw_keys && hdmi_ctrl->hdcp14_present) {
1472 if (hdmi_ctrl->auth_state)
1473 hdcp1_set_enc(false);
1474 }
1475
1476 hdmi_ctrl->auth_state = false;
1477
1478 if (hdmi_tx_is_panel_on(hdmi_ctrl)) {
1479 DEV_DBG("%s: Reauthenticating\n", __func__);
1480
1481 if (hdmi_tx_is_encryption_set(hdmi_ctrl) ||
1482 !hdmi_tx_is_stream_shareable(hdmi_ctrl)) {
1483 hdmi_tx_set_audio_switch_node(hdmi_ctrl, 0);
1484 rc = hdmi_tx_config_avmute(hdmi_ctrl, true);
1485 }
1486
1487 rc = hdmi_ctrl->hdcp_ops->hdmi_hdcp_reauthenticate(
1488 hdmi_ctrl->hdcp_data);
1489 if (rc)
1490 DEV_ERR("%s: HDCP reauth failed. rc=%d\n",
1491 __func__, rc);
1492 } else {
1493 DEV_DBG("%s: Not reauthenticating. Cable not conn\n",
1494 __func__);
1495 }
1496
1497 break;
1498 case HDCP_STATE_AUTH_ENC_NONE:
1499 hdmi_ctrl->enc_lvl = HDCP_STATE_AUTH_ENC_NONE;
1500
1501 if (hdmi_tx_is_panel_on(hdmi_ctrl)) {
1502 rc = hdmi_tx_config_avmute(hdmi_ctrl, false);
1503 hdmi_tx_set_audio_switch_node(hdmi_ctrl, 1);
1504 }
1505 break;
1506 case HDCP_STATE_AUTH_ENC_1X:
1507 case HDCP_STATE_AUTH_ENC_2P2:
1508 hdmi_ctrl->enc_lvl = hdmi_ctrl->hdcp_status;
1509
1510 if (hdmi_tx_is_panel_on(hdmi_ctrl) &&
1511 hdmi_tx_is_stream_shareable(hdmi_ctrl)) {
1512 rc = hdmi_tx_config_avmute(hdmi_ctrl, false);
1513 hdmi_tx_set_audio_switch_node(hdmi_ctrl, 1);
1514 } else {
1515 hdmi_tx_set_audio_switch_node(hdmi_ctrl, 0);
1516 rc = hdmi_tx_config_avmute(hdmi_ctrl, true);
1517 }
1518 break;
1519 default:
1520 break;
1521 /* do nothing */
1522 }
1523
1524 mutex_unlock(&hdmi_ctrl->tx_lock);
1525}
1526
1527static u32 hdmi_tx_ddc_read(struct hdmi_tx_ddc_ctrl *ddc_ctrl,
1528 u32 block, u8 *edid_buf)
1529{
1530 u32 block_size = EDID_BLOCK_SIZE;
1531 struct hdmi_tx_ddc_data ddc_data;
1532 u32 status = 0, retry_cnt = 0, i;
1533
1534 if (!ddc_ctrl || !edid_buf) {
1535 DEV_ERR("%s: invalid input\n", __func__);
1536 return -EINVAL;
1537 }
1538
1539 do {
1540 DEV_DBG("EDID: reading block(%d) with block-size=%d\n",
1541 block, block_size);
1542
1543 for (i = 0; i < EDID_BLOCK_SIZE; i += block_size) {
1544 memset(&ddc_data, 0, sizeof(ddc_data));
1545
1546 ddc_data.dev_addr = EDID_BLOCK_ADDR;
1547 ddc_data.offset = block * EDID_BLOCK_SIZE + i;
1548 ddc_data.data_buf = edid_buf + i;
1549 ddc_data.data_len = block_size;
1550 ddc_data.request_len = block_size;
1551 ddc_data.retry = 1;
1552 ddc_data.what = "EDID";
1553 ddc_data.retry_align = true;
1554
1555 ddc_ctrl->ddc_data = ddc_data;
1556
1557 /* Read EDID twice with 32bit alighnment too */
1558 if (block < 2)
1559 status = hdmi_ddc_read(ddc_ctrl);
1560 else
1561 status = hdmi_ddc_read_seg(ddc_ctrl);
1562
1563 if (status)
1564 break;
1565 }
1566 if (retry_cnt++ >= MAX_EDID_READ_RETRY)
1567 block_size /= 2;
1568
1569 } while (status && (block_size >= 16));
1570
1571 return status;
1572}
1573
1574static int hdmi_tx_read_edid_retry(struct hdmi_tx_ctrl *hdmi_ctrl, u8 block)
1575{
1576 u32 checksum_retry = 0;
1577 u8 *ebuf;
1578 int ret = 0;
1579 struct hdmi_tx_ddc_ctrl *ddc_ctrl;
1580
1581 if (!hdmi_ctrl) {
1582 DEV_ERR("%s: invalid input\n", __func__);
1583 ret = -EINVAL;
1584 goto end;
1585 }
1586
1587 ebuf = hdmi_ctrl->edid_buf;
1588 if (!ebuf) {
1589 DEV_ERR("%s: invalid edid buf\n", __func__);
1590 ret = -EINVAL;
1591 goto end;
1592 }
1593
1594 ddc_ctrl = &hdmi_ctrl->ddc_ctrl;
1595
1596 while (checksum_retry++ < MAX_EDID_READ_RETRY) {
1597 ret = hdmi_tx_ddc_read(ddc_ctrl, block,
1598 ebuf + (block * EDID_BLOCK_SIZE));
1599 if (ret)
1600 continue;
1601 else
1602 break;
1603 }
1604end:
1605 return ret;
1606}
1607
1608static int hdmi_tx_read_edid(struct hdmi_tx_ctrl *hdmi_ctrl)
1609{
1610 int ndx, check_sum;
1611 int cea_blks = 0, block = 0, total_blocks = 0;
1612 int ret = 0;
1613 u8 *ebuf;
1614 struct hdmi_tx_ddc_ctrl *ddc_ctrl;
1615
1616 if (!hdmi_ctrl) {
1617 DEV_ERR("%s: invalid input\n", __func__);
1618 ret = -EINVAL;
1619 goto end;
1620 }
1621
1622 ebuf = hdmi_ctrl->edid_buf;
1623 if (!ebuf) {
1624 DEV_ERR("%s: invalid edid buf\n", __func__);
1625 ret = -EINVAL;
1626 goto end;
1627 }
1628
1629 memset(ebuf, 0, hdmi_ctrl->edid_buf_size);
1630
1631 ddc_ctrl = &hdmi_ctrl->ddc_ctrl;
1632
1633 do {
1634 if (block * EDID_BLOCK_SIZE > hdmi_ctrl->edid_buf_size) {
1635 DEV_ERR("%s: no mem for block %d, max mem %d\n",
1636 __func__, block, hdmi_ctrl->edid_buf_size);
1637 ret = -ENOMEM;
1638 goto end;
1639 }
1640
1641 ret = hdmi_tx_read_edid_retry(hdmi_ctrl, block);
1642 if (ret) {
1643 DEV_ERR("%s: edid read failed\n", __func__);
1644 goto end;
1645 }
1646
1647 /* verify checksum to validate edid block */
1648 check_sum = 0;
1649 for (ndx = 0; ndx < EDID_BLOCK_SIZE; ++ndx)
1650 check_sum += ebuf[ndx];
1651
1652 if (check_sum & 0xFF) {
1653 DEV_ERR("%s: checksum mismatch\n", __func__);
1654 ret = -EINVAL;
1655 goto end;
1656 }
1657
1658 /* get number of cea extension blocks as given in block 0*/
1659 if (block == 0) {
1660 cea_blks = ebuf[EDID_BLOCK_SIZE - 2];
1661 if (cea_blks < 0 || cea_blks >= MAX_EDID_BLOCKS) {
1662 cea_blks = 0;
1663 DEV_ERR("%s: invalid cea blocks %d\n",
1664 __func__, cea_blks);
1665 ret = -EINVAL;
1666 goto end;
1667 }
1668
1669 total_blocks = cea_blks + 1;
1670 }
1671 } while ((cea_blks-- > 0) && (block++ < MAX_EDID_BLOCKS));
1672end:
1673
1674 return ret;
1675}
1676
1677/* Enable HDMI features */
1678static int hdmi_tx_init_panel(struct hdmi_tx_ctrl *hdmi_ctrl)
1679{
1680 struct hdmi_panel_init_data panel_init_data = {0};
1681 void *panel_data;
1682 int rc = 0;
1683
1684 hdmi_ctrl->panel.pinfo = &hdmi_ctrl->panel_data.panel_info;
1685
1686 panel_init_data.io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
1687 panel_init_data.ds_data = &hdmi_ctrl->ds_data;
1688 panel_init_data.ops = &hdmi_ctrl->panel_ops;
1689 panel_init_data.panel_data = &hdmi_ctrl->panel;
1690 panel_init_data.spd_vendor_name = hdmi_ctrl->spd_vendor_name;
1691 panel_init_data.spd_product_description =
1692 hdmi_ctrl->spd_product_description;
1693 panel_init_data.version = hdmi_ctrl->hdmi_tx_ver;
1694 panel_init_data.ddc = &hdmi_ctrl->ddc_ctrl;
1695 panel_init_data.timing = &hdmi_ctrl->timing;
1696
1697 panel_data = hdmi_panel_init(&panel_init_data);
1698 if (IS_ERR_OR_NULL(panel_data)) {
1699 DEV_ERR("%s: panel init failed\n", __func__);
1700 rc = -EINVAL;
1701 } else {
1702 hdmi_tx_set_fd(HDMI_TX_FEAT_PANEL, panel_data);
1703 DEV_DBG("%s: panel initialized\n", __func__);
1704 }
1705
1706 return rc;
1707}
1708
1709static int hdmi_tx_init_edid(struct hdmi_tx_ctrl *hdmi_ctrl)
1710{
1711 struct hdmi_edid_init_data edid_init_data = {0};
1712 void *edid_data;
1713 int rc = 0;
1714
1715 edid_init_data.kobj = hdmi_ctrl->kobj;
1716 edid_init_data.ds_data = hdmi_ctrl->ds_data;
1717 edid_init_data.max_pclk_khz = hdmi_ctrl->max_pclk_khz;
1718
1719 edid_data = hdmi_edid_init(&edid_init_data);
1720 if (!edid_data) {
1721 DEV_ERR("%s: edid init failed\n", __func__);
1722 rc = -ENODEV;
1723 goto end;
1724 }
1725
1726 hdmi_ctrl->panel_data.panel_info.edid_data = edid_data;
1727 hdmi_tx_set_fd(HDMI_TX_FEAT_EDID, edid_data);
1728
1729 /* get edid buffer from edid parser */
1730 hdmi_ctrl->edid_buf = edid_init_data.buf;
1731 hdmi_ctrl->edid_buf_size = edid_init_data.buf_size;
1732
1733 hdmi_edid_set_video_resolution(edid_data, hdmi_ctrl->vic, true);
1734end:
1735 return rc;
1736}
1737
1738static int hdmi_tx_init_hdcp(struct hdmi_tx_ctrl *hdmi_ctrl)
1739{
1740 struct hdmi_hdcp_init_data hdcp_init_data = {0};
1741 struct resource *res;
1742 void *hdcp_data;
1743 int rc = 0;
1744
1745 res = platform_get_resource_byname(hdmi_ctrl->pdev,
1746 IORESOURCE_MEM, hdmi_tx_io_name(HDMI_TX_CORE_IO));
1747 if (!res) {
1748 DEV_ERR("%s: Error getting HDMI tx core resource\n", __func__);
1749 rc = -EINVAL;
1750 goto end;
1751 }
1752
1753 hdcp_init_data.phy_addr = res->start;
1754 hdcp_init_data.core_io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
1755 hdcp_init_data.qfprom_io = &hdmi_ctrl->pdata.io[HDMI_TX_QFPROM_IO];
1756 hdcp_init_data.hdcp_io = &hdmi_ctrl->pdata.io[HDMI_TX_HDCP_IO];
1757 hdcp_init_data.mutex = &hdmi_ctrl->mutex;
1758 hdcp_init_data.sysfs_kobj = hdmi_ctrl->kobj;
1759 hdcp_init_data.ddc_ctrl = &hdmi_ctrl->ddc_ctrl;
1760 hdcp_init_data.workq = hdmi_ctrl->workq;
1761 hdcp_init_data.notify_status = hdmi_tx_hdcp_cb;
1762 hdcp_init_data.cb_data = (void *)hdmi_ctrl;
1763 hdcp_init_data.hdmi_tx_ver = hdmi_ctrl->hdmi_tx_ver;
1764 hdcp_init_data.timing = &hdmi_ctrl->timing;
1765
1766 if (hdmi_ctrl->hdcp14_present) {
1767 hdcp_data = hdmi_hdcp_init(&hdcp_init_data);
1768
1769 if (IS_ERR_OR_NULL(hdcp_data)) {
1770 DEV_ERR("%s: hdcp 1.4 init failed\n", __func__);
1771 rc = -EINVAL;
1772 goto end;
1773 } else {
1774 hdmi_tx_set_fd(HDMI_TX_FEAT_HDCP, hdcp_data);
1775 DEV_DBG("%s: HDCP 1.4 initialized\n", __func__);
1776 }
1777 }
1778
1779 hdcp_data = hdmi_hdcp2p2_init(&hdcp_init_data);
1780
1781 if (IS_ERR_OR_NULL(hdcp_data)) {
1782 DEV_ERR("%s: hdcp 2.2 init failed\n", __func__);
1783 rc = -EINVAL;
1784 goto end;
1785 } else {
1786 hdmi_tx_set_fd(HDMI_TX_FEAT_HDCP2P2, hdcp_data);
1787 DEV_DBG("%s: HDCP 2.2 initialized\n", __func__);
1788 }
1789end:
1790 return rc;
1791}
1792
1793static int hdmi_tx_init_cec_hw(struct hdmi_tx_ctrl *hdmi_ctrl)
1794{
1795 struct hdmi_cec_init_data cec_init_data = {0};
1796 void *cec_hw_data;
1797 int rc = 0;
1798
1799 cec_init_data.io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
1800 cec_init_data.workq = hdmi_ctrl->workq;
1801 cec_init_data.pinfo = &hdmi_ctrl->panel_data.panel_info;
1802 cec_init_data.ops = &hdmi_ctrl->hdmi_cec_ops;
1803 cec_init_data.cbs = &hdmi_ctrl->hdmi_cec_cbs;
1804
1805 cec_hw_data = hdmi_cec_init(&cec_init_data);
1806 if (IS_ERR_OR_NULL(cec_hw_data)) {
1807 DEV_ERR("%s: cec init failed\n", __func__);
1808 rc = -EINVAL;
1809 } else {
1810 hdmi_ctrl->panel_data.panel_info.is_cec_supported = true;
1811 hdmi_tx_set_fd(HDMI_TX_FEAT_CEC_HW, cec_hw_data);
1812 DEV_DBG("%s: cec hw initialized\n", __func__);
1813 }
1814
1815 return rc;
1816}
1817
1818static int hdmi_tx_init_cec_abst(struct hdmi_tx_ctrl *hdmi_ctrl)
1819{
1820 struct cec_abstract_init_data cec_abst_init_data = {0};
1821 void *cec_abst_data;
1822 int rc = 0;
1823
1824 cec_abst_init_data.kobj = hdmi_ctrl->kobj;
1825 cec_abst_init_data.ops = &hdmi_ctrl->hdmi_cec_ops;
1826 cec_abst_init_data.cbs = &hdmi_ctrl->hdmi_cec_cbs;
1827
1828 cec_abst_data = cec_abstract_init(&cec_abst_init_data);
1829 if (IS_ERR_OR_NULL(cec_abst_data)) {
1830 DEV_ERR("%s: cec abst init failed\n", __func__);
1831 rc = -EINVAL;
1832 } else {
1833 hdmi_tx_set_fd(HDMI_TX_FEAT_CEC_ABST, cec_abst_data);
1834 hdmi_ctrl->panel_data.panel_info.cec_data = cec_abst_data;
1835 DEV_DBG("%s: cec abst initialized\n", __func__);
1836 }
1837
1838 return rc;
1839}
1840
1841static int hdmi_tx_init_audio(struct hdmi_tx_ctrl *hdmi_ctrl)
1842{
1843 struct hdmi_audio_init_data audio_init_data = {0};
1844 void *audio_data;
1845 int rc = 0;
1846
1847 audio_init_data.io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
1848 audio_init_data.ops = &hdmi_ctrl->audio_ops;
1849
1850 audio_data = hdmi_audio_register(&audio_init_data);
1851 if (!audio_data) {
1852 rc = -EINVAL;
1853 DEV_ERR("%s: audio init failed\n", __func__);
1854 } else {
1855 hdmi_ctrl->audio_data = audio_data;
1856 DEV_DBG("%s: audio initialized\n", __func__);
1857 }
1858
1859 return rc;
1860}
1861
1862static void hdmi_tx_deinit_features(struct hdmi_tx_ctrl *hdmi_ctrl,
1863 u32 features)
1864{
1865 void *fd;
1866
1867 if (features & HDMI_TX_FEAT_CEC_ABST) {
1868 fd = hdmi_tx_get_fd(HDMI_TX_FEAT_CEC_ABST);
1869
1870 cec_abstract_deinit(fd);
1871
1872 hdmi_ctrl->panel_data.panel_info.cec_data = NULL;
1873 hdmi_tx_set_fd(HDMI_TX_FEAT_CEC_ABST, 0);
1874 }
1875
1876 if (features & HDMI_TX_FEAT_CEC_HW) {
1877 fd = hdmi_tx_get_fd(HDMI_TX_FEAT_CEC_HW);
1878
1879 hdmi_cec_deinit(fd);
1880 hdmi_ctrl->panel_data.panel_info.is_cec_supported = false;
1881 hdmi_tx_set_fd(HDMI_TX_FEAT_CEC_HW, 0);
1882 }
1883
1884 if (features & HDMI_TX_FEAT_HDCP2P2) {
1885 fd = hdmi_tx_get_fd(HDMI_TX_FEAT_HDCP2P2);
1886
1887 hdmi_hdcp2p2_deinit(fd);
1888 hdmi_tx_set_fd(HDMI_TX_FEAT_HDCP2P2, 0);
1889 }
1890
1891 if (features & HDMI_TX_FEAT_HDCP) {
1892 fd = hdmi_tx_get_fd(HDMI_TX_FEAT_HDCP);
1893
1894 hdmi_hdcp_deinit(fd);
1895 hdmi_tx_set_fd(HDMI_TX_FEAT_HDCP, 0);
1896 }
1897
1898 if (features & HDMI_TX_FEAT_EDID) {
1899 fd = hdmi_tx_get_fd(HDMI_TX_FEAT_EDID);
1900
1901 hdmi_edid_deinit(fd);
1902 hdmi_ctrl->edid_buf = NULL;
1903 hdmi_ctrl->edid_buf_size = 0;
1904 hdmi_tx_set_fd(HDMI_TX_FEAT_EDID, 0);
1905 }
1906} /* hdmi_tx_init_features */
1907
1908static int hdmi_tx_init_features(struct hdmi_tx_ctrl *hdmi_ctrl,
1909 struct fb_info *fbi)
1910{
1911 int ret = 0;
1912 u32 deinit_features = 0;
1913
1914 if (!hdmi_ctrl || !fbi) {
1915 DEV_ERR("%s: invalid input\n", __func__);
1916 ret = -EINVAL;
1917 goto end;
1918 }
1919
1920 ret = hdmi_tx_init_panel(hdmi_ctrl);
1921 if (ret)
1922 goto end;
1923
1924 ret = hdmi_tx_init_edid(hdmi_ctrl);
1925 if (ret) {
1926 deinit_features |= HDMI_TX_FEAT_PANEL;
1927 goto err;
1928 }
1929
1930 ret = hdmi_tx_init_hdcp(hdmi_ctrl);
1931 if (ret) {
1932 deinit_features |= HDMI_TX_FEAT_EDID;
1933 goto err;
1934 }
1935
1936 ret = hdmi_tx_init_cec_hw(hdmi_ctrl);
1937 if (ret) {
1938 deinit_features |= HDMI_TX_FEAT_HDCP;
1939 goto err;
1940 }
1941
1942 ret = hdmi_tx_init_cec_abst(hdmi_ctrl);
1943 if (ret) {
1944 deinit_features |= HDMI_TX_FEAT_CEC_HW;
1945 goto err;
1946 }
1947
1948 ret = hdmi_tx_init_audio(hdmi_ctrl);
1949 if (ret) {
1950 deinit_features |= HDMI_TX_FEAT_CEC_ABST;
1951 goto err;
1952 }
1953
1954 return 0;
1955err:
1956 hdmi_tx_deinit_features(hdmi_ctrl, deinit_features);
1957end:
1958 return ret;
1959}
1960
1961static inline u32 hdmi_tx_is_controller_on(struct hdmi_tx_ctrl *hdmi_ctrl)
1962{
Sachin Bhayare5076e252018-01-18 14:56:45 +05301963 struct mdss_io_data *io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
Sachin Bhayareeeb88892018-01-02 16:36:01 +05301964
1965 return DSS_REG_R_ND(io, HDMI_CTRL) & BIT(0);
1966} /* hdmi_tx_is_controller_on */
1967
1968static int hdmi_tx_init_panel_info(struct hdmi_tx_ctrl *hdmi_ctrl)
1969{
1970 struct mdss_panel_info *pinfo;
1971 struct msm_hdmi_mode_timing_info timing = {0};
1972 u32 ret;
1973
1974 if (!hdmi_ctrl) {
1975 DEV_ERR("%s: invalid input\n", __func__);
1976 return -EINVAL;
1977 }
1978
1979 ret = hdmi_get_supported_mode(&timing, &hdmi_ctrl->ds_data,
1980 hdmi_ctrl->vic);
1981 pinfo = &hdmi_ctrl->panel_data.panel_info;
1982
1983 if (ret || !timing.supported || !pinfo) {
1984 DEV_ERR("%s: invalid timing data\n", __func__);
1985 return -EINVAL;
1986 }
1987
1988 pinfo->xres = timing.active_h;
1989 pinfo->yres = timing.active_v;
1990 pinfo->clk_rate = timing.pixel_freq * 1000;
1991
1992 pinfo->lcdc.h_back_porch = timing.back_porch_h;
1993 pinfo->lcdc.h_front_porch = timing.front_porch_h;
1994 pinfo->lcdc.h_pulse_width = timing.pulse_width_h;
1995 pinfo->lcdc.v_back_porch = timing.back_porch_v;
1996 pinfo->lcdc.v_front_porch = timing.front_porch_v;
1997 pinfo->lcdc.v_pulse_width = timing.pulse_width_v;
1998 pinfo->lcdc.frame_rate = timing.refresh_rate;
1999
2000 pinfo->type = DTV_PANEL;
2001 pinfo->pdest = DISPLAY_3;
2002 pinfo->wait_cycle = 0;
2003 pinfo->out_format = MDP_RGB_888;
2004 pinfo->bpp = 24;
2005 pinfo->fb_num = 1;
2006
2007 pinfo->min_fps = HDMI_TX_MIN_FPS;
2008 pinfo->max_fps = HDMI_TX_MAX_FPS;
2009
2010 pinfo->lcdc.border_clr = 0; /* blk */
2011 pinfo->lcdc.underflow_clr = 0xff; /* blue */
2012 pinfo->lcdc.hsync_skew = 0;
2013
2014 pinfo->is_pluggable = hdmi_ctrl->pdata.pluggable;
2015
2016 hdmi_ctrl->timing = timing;
2017
2018 return 0;
2019} /* hdmi_tx_init_panel_info */
2020
2021static int hdmi_tx_read_sink_info(struct hdmi_tx_ctrl *hdmi_ctrl)
2022{
2023 int status = 0;
2024 void *data;
2025
2026 if (!hdmi_ctrl) {
2027 DEV_ERR("%s: invalid input\n", __func__);
2028 return -EINVAL;
2029 }
2030
2031 data = hdmi_tx_get_fd(HDMI_TX_FEAT_EDID);
2032
2033 if (!hdmi_tx_is_controller_on(hdmi_ctrl)) {
2034 DEV_ERR("%s: failed: HDMI controller is off", __func__);
2035 status = -ENXIO;
2036 goto error;
2037 }
2038
2039 if (!hdmi_ctrl->custom_edid && !hdmi_ctrl->sim_mode) {
2040 hdmi_ddc_config(&hdmi_ctrl->ddc_ctrl);
2041
2042 status = hdmi_tx_read_edid(hdmi_ctrl);
2043 if (status) {
2044 DEV_ERR("%s: error reading edid\n", __func__);
2045 goto error;
2046 }
2047 }
2048
2049 /* parse edid if a valid edid buffer is present */
2050 if (hdmi_ctrl->custom_edid || !hdmi_ctrl->sim_mode) {
2051 status = hdmi_edid_parser(data);
2052 if (status)
2053 DEV_ERR("%s: edid parse failed\n", __func__);
2054 }
2055
2056error:
2057 return status;
2058} /* hdmi_tx_read_sink_info */
2059
2060static void hdmi_tx_update_hdcp_info(struct hdmi_tx_ctrl *hdmi_ctrl)
2061{
2062 void *fd = NULL;
2063 struct hdmi_hdcp_ops *ops = NULL;
2064
2065 if (!hdmi_ctrl) {
2066 DEV_ERR("%s: invalid input\n", __func__);
2067 return;
2068 }
2069
2070 /* check first if hdcp2p2 is supported */
2071 fd = hdmi_tx_get_fd(HDMI_TX_FEAT_HDCP2P2);
2072 if (fd)
2073 ops = hdmi_hdcp2p2_start(fd);
2074
2075 if (ops && ops->feature_supported)
2076 hdmi_ctrl->hdcp22_present = ops->feature_supported(fd);
2077 else
2078 hdmi_ctrl->hdcp22_present = false;
2079
2080 if (!hdmi_ctrl->hdcp22_present) {
2081 if (hdmi_ctrl->hdcp1_use_sw_keys)
2082 hdmi_ctrl->hdcp14_present =
2083 hdcp1_check_if_supported_load_app();
2084
2085 if (hdmi_ctrl->hdcp14_present) {
2086 fd = hdmi_tx_get_fd(HDMI_TX_FEAT_HDCP);
2087 ops = hdmi_hdcp_start(fd);
2088 }
2089 }
2090
2091 /* update internal data about hdcp */
2092 hdmi_ctrl->hdcp_data = fd;
2093 hdmi_ctrl->hdcp_ops = ops;
2094}
2095
2096static void hdmi_tx_hpd_int_work(struct work_struct *work)
2097{
2098 struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
Sachin Bhayare5076e252018-01-18 14:56:45 +05302099 struct mdss_io_data *io;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302100 int rc = -EINVAL;
2101 int retry = MAX_EDID_READ_RETRY;
2102
2103 hdmi_ctrl = container_of(work, struct hdmi_tx_ctrl, hpd_int_work);
2104 if (!hdmi_ctrl) {
2105 DEV_DBG("%s: invalid input\n", __func__);
2106 return;
2107 }
2108 io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
2109
2110 mutex_lock(&hdmi_ctrl->tx_lock);
2111
2112 if (!hdmi_ctrl->hpd_initialized) {
2113 DEV_DBG("hpd not initialized\n");
2114 goto end;
2115 }
2116
2117 DEV_DBG("%s: %s\n", __func__,
2118 hdmi_ctrl->hpd_state ? "CONNECT" : "DISCONNECT");
2119
2120 if (hdmi_ctrl->hpd_state) {
2121 if (hdmi_tx_enable_power(hdmi_ctrl, HDMI_TX_DDC_PM, true)) {
2122 DEV_ERR("%s: Failed to enable ddc power\n", __func__);
2123 goto end;
2124 }
2125
2126 /* Enable SW DDC before EDID read */
2127 DSS_REG_W_ND(io, HDMI_DDC_ARBITRATION,
2128 DSS_REG_R(io, HDMI_DDC_ARBITRATION) & ~(BIT(4)));
2129
2130 while (rc && retry--)
2131 rc = hdmi_tx_read_sink_info(hdmi_ctrl);
2132 if (!retry && rc)
2133 pr_warn_ratelimited("%s: EDID read failed\n", __func__);
2134
2135 if (hdmi_tx_enable_power(hdmi_ctrl, HDMI_TX_DDC_PM, false))
2136 DEV_ERR("%s: Failed to disable ddc power\n", __func__);
2137
2138 hdmi_tx_send_cable_notification(hdmi_ctrl, true);
2139 } else {
2140 hdmi_tx_set_audio_switch_node(hdmi_ctrl, 0);
2141 hdmi_tx_wait_for_audio_engine(hdmi_ctrl);
2142
2143 hdmi_tx_send_cable_notification(hdmi_ctrl, false);
2144 }
2145end:
2146 mutex_unlock(&hdmi_ctrl->tx_lock);
2147} /* hdmi_tx_hpd_int_work */
2148
2149static int hdmi_tx_check_capability(struct hdmi_tx_ctrl *hdmi_ctrl)
2150{
2151 u32 hdmi_disabled, hdcp_disabled, reg_val;
Sachin Bhayare5076e252018-01-18 14:56:45 +05302152 struct mdss_io_data *io = NULL;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302153 int ret = 0;
2154
2155 if (!hdmi_ctrl) {
2156 DEV_ERR("%s: invalid input\n", __func__);
2157 ret = -EINVAL;
2158 goto end;
2159 }
2160
2161 io = &hdmi_ctrl->pdata.io[HDMI_TX_QFPROM_IO];
2162 if (!io->base) {
2163 DEV_ERR("%s: QFPROM io is not initialized\n", __func__);
2164 ret = -EINVAL;
2165 goto end;
2166 }
2167
2168 /* check if hdmi and hdcp are disabled */
2169 if (hdmi_ctrl->hdmi_tx_ver < HDMI_TX_VERSION_4) {
2170 hdcp_disabled = DSS_REG_R_ND(io,
2171 QFPROM_RAW_FEAT_CONFIG_ROW0_LSB) & BIT(31);
2172
2173 hdmi_disabled = DSS_REG_R_ND(io,
2174 QFPROM_RAW_FEAT_CONFIG_ROW0_MSB) & BIT(0);
2175 } else {
2176 reg_val = DSS_REG_R_ND(io,
2177 QFPROM_RAW_FEAT_CONFIG_ROW0_LSB + QFPROM_RAW_VERSION_4);
2178 hdcp_disabled = reg_val & BIT(12);
2179 hdmi_disabled = reg_val & BIT(13);
2180
2181 reg_val = DSS_REG_R_ND(io, SEC_CTRL_HW_VERSION);
2182 /*
2183 * With HDCP enabled on capable hardware, check if HW
2184 * or SW keys should be used.
2185 */
2186 if (!hdcp_disabled && (reg_val >= HDCP_SEL_MIN_SEC_VERSION)) {
2187 reg_val = DSS_REG_R_ND(io,
2188 QFPROM_RAW_FEAT_CONFIG_ROW0_MSB +
2189 QFPROM_RAW_VERSION_4);
2190 if (!(reg_val & BIT(23)))
2191 hdmi_ctrl->hdcp1_use_sw_keys = true;
2192 }
2193 }
2194
2195 DEV_DBG("%s: Features <HDMI:%s, HDCP:%s>\n", __func__,
2196 hdmi_disabled ? "OFF" : "ON", hdcp_disabled ? "OFF" : "ON");
2197
2198 if (hdmi_disabled) {
2199 DEV_ERR("%s: HDMI disabled\n", __func__);
2200 ret = -ENODEV;
2201 goto end;
2202 }
2203
2204 hdmi_ctrl->hdcp14_present = !hdcp_disabled;
2205end:
2206 return ret;
2207} /* hdmi_tx_check_capability */
2208
2209static void hdmi_tx_set_mode(struct hdmi_tx_ctrl *hdmi_ctrl, u32 power_on)
2210{
Sachin Bhayare5076e252018-01-18 14:56:45 +05302211 struct mdss_io_data *io = NULL;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302212 /* Defaults: Disable block, HDMI mode */
2213 u32 reg_val = BIT(1);
2214
2215 if (!hdmi_ctrl) {
2216 DEV_ERR("%s: invalid input\n", __func__);
2217 return;
2218 }
2219 io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
2220 if (!io->base) {
2221 DEV_ERR("%s: Core io is not initialized\n", __func__);
2222 return;
2223 }
2224
2225 if (power_on) {
2226 /* Enable the block */
2227 reg_val |= BIT(0);
2228
2229 /**
2230 * HDMI Encryption, if HDCP is enabled
2231 * The ENC_REQUIRED bit is only available on HDMI Tx major
2232 * version less than 4. From 4 onwards, this bit is controlled
2233 * by TZ
2234 */
2235 if (hdmi_ctrl->hdmi_tx_ver < 4 &&
2236 hdmi_tx_is_hdcp_enabled(hdmi_ctrl) &&
2237 !hdmi_ctrl->pdata.primary)
2238 reg_val |= BIT(2);
2239
2240 /* Set transmission mode to DVI based in EDID info */
2241 if (!hdmi_edid_get_sink_mode(hdmi_tx_get_fd(HDMI_TX_FEAT_EDID)))
2242 reg_val &= ~BIT(1); /* DVI mode */
2243
2244 /*
2245 * Use DATAPATH_MODE as 1 always, the new mode that also
2246 * supports scrambler and HDCP 2.2. The legacy mode should no
2247 * longer be used
2248 */
2249 reg_val |= BIT(31);
2250 }
2251
2252 DSS_REG_W(io, HDMI_CTRL, reg_val);
2253
2254 DEV_DBG("HDMI Core: %s, HDMI_CTRL=0x%08x\n",
2255 power_on ? "Enable" : "Disable", reg_val);
2256} /* hdmi_tx_set_mode */
2257
2258static int hdmi_tx_pinctrl_set_state(struct hdmi_tx_ctrl *hdmi_ctrl,
2259 enum hdmi_tx_power_module_type module, bool active)
2260{
2261 struct pinctrl_state *pin_state = NULL;
2262 int rc = -EFAULT;
Sachin Bhayare5076e252018-01-18 14:56:45 +05302263 struct mdss_module_power *power_data = NULL;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302264 u64 cur_pin_states;
2265
2266 if (!hdmi_ctrl) {
2267 DEV_ERR("%s: invalid input\n", __func__);
2268 return -ENODEV;
2269 }
2270
2271 if (IS_ERR_OR_NULL(hdmi_ctrl->pin_res.pinctrl))
2272 return 0;
2273
2274 power_data = &hdmi_ctrl->pdata.power_data[module];
2275
2276 cur_pin_states = active ? (hdmi_ctrl->pdata.pin_states | BIT(module))
2277 : (hdmi_ctrl->pdata.pin_states & ~BIT(module));
2278
2279 if (cur_pin_states & BIT(HDMI_TX_HPD_PM)) {
2280 if (cur_pin_states & BIT(HDMI_TX_DDC_PM)) {
2281 if (cur_pin_states & BIT(HDMI_TX_CEC_PM))
2282 pin_state = hdmi_ctrl->pin_res.state_active;
2283 else
2284 pin_state =
2285 hdmi_ctrl->pin_res.state_ddc_active;
2286 } else if (cur_pin_states & BIT(HDMI_TX_CEC_PM)) {
2287 pin_state = hdmi_ctrl->pin_res.state_cec_active;
2288 } else {
2289 pin_state = hdmi_ctrl->pin_res.state_hpd_active;
2290 }
2291 } else {
2292 pin_state = hdmi_ctrl->pin_res.state_suspend;
2293 }
2294
2295 if (!IS_ERR_OR_NULL(pin_state)) {
2296 rc = pinctrl_select_state(hdmi_ctrl->pin_res.pinctrl,
2297 pin_state);
2298 if (rc)
2299 pr_err("%s: cannot set pins\n", __func__);
2300 else
2301 hdmi_ctrl->pdata.pin_states = cur_pin_states;
2302 } else {
2303 pr_err("%s: pinstate not found\n", __func__);
2304 }
2305
2306 return rc;
2307}
2308
2309static int hdmi_tx_pinctrl_init(struct platform_device *pdev)
2310{
2311 struct hdmi_tx_ctrl *hdmi_ctrl;
2312
2313 hdmi_ctrl = platform_get_drvdata(pdev);
2314 if (!hdmi_ctrl) {
2315 DEV_ERR("%s: invalid input\n", __func__);
2316 return -ENODEV;
2317 }
2318
2319 hdmi_ctrl->pin_res.pinctrl = devm_pinctrl_get(&pdev->dev);
2320 if (IS_ERR_OR_NULL(hdmi_ctrl->pin_res.pinctrl)) {
2321 pr_err("%s: failed to get pinctrl\n", __func__);
2322 return PTR_ERR(hdmi_ctrl->pin_res.pinctrl);
2323 }
2324
2325 hdmi_ctrl->pin_res.state_active =
2326 pinctrl_lookup_state(hdmi_ctrl->pin_res.pinctrl, "hdmi_active");
2327 if (IS_ERR_OR_NULL(hdmi_ctrl->pin_res.state_active))
2328 pr_debug("%s: cannot get active pinstate\n", __func__);
2329
2330 hdmi_ctrl->pin_res.state_hpd_active =
2331 pinctrl_lookup_state(hdmi_ctrl->pin_res.pinctrl,
2332 "hdmi_hpd_active");
2333 if (IS_ERR_OR_NULL(hdmi_ctrl->pin_res.state_hpd_active))
2334 pr_debug("%s: cannot get hpd active pinstate\n", __func__);
2335
2336 hdmi_ctrl->pin_res.state_cec_active =
2337 pinctrl_lookup_state(hdmi_ctrl->pin_res.pinctrl,
2338 "hdmi_cec_active");
2339 if (IS_ERR_OR_NULL(hdmi_ctrl->pin_res.state_cec_active))
2340 pr_debug("%s: cannot get cec active pinstate\n", __func__);
2341
2342 hdmi_ctrl->pin_res.state_ddc_active =
2343 pinctrl_lookup_state(hdmi_ctrl->pin_res.pinctrl,
2344 "hdmi_ddc_active");
2345 if (IS_ERR_OR_NULL(hdmi_ctrl->pin_res.state_ddc_active))
2346 pr_debug("%s: cannot get ddc active pinstate\n", __func__);
2347
2348 hdmi_ctrl->pin_res.state_suspend =
2349 pinctrl_lookup_state(hdmi_ctrl->pin_res.pinctrl, "hdmi_sleep");
2350 if (IS_ERR_OR_NULL(hdmi_ctrl->pin_res.state_suspend))
2351 pr_debug("%s: cannot get sleep pinstate\n", __func__);
2352
2353 return 0;
2354}
2355
2356static int hdmi_tx_config_power(struct hdmi_tx_ctrl *hdmi_ctrl,
2357 enum hdmi_tx_power_module_type module, int config)
2358{
2359 int rc = 0;
Sachin Bhayare5076e252018-01-18 14:56:45 +05302360 struct mdss_module_power *power_data = NULL;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302361 char name[MAX_CLIENT_NAME_LEN];
2362
2363 if (!hdmi_ctrl || module >= HDMI_TX_MAX_PM) {
2364 DEV_ERR("%s: Error: invalid input\n", __func__);
2365 rc = -EINVAL;
2366 goto exit;
2367 }
2368
2369 power_data = &hdmi_ctrl->pdata.power_data[module];
2370 if (!power_data) {
2371 DEV_ERR("%s: Error: invalid power data\n", __func__);
2372 rc = -EINVAL;
2373 goto exit;
2374 }
2375
2376 if (config) {
Sachin Bhayare5076e252018-01-18 14:56:45 +05302377 rc = msm_mdss_config_vreg(&hdmi_ctrl->pdev->dev,
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302378 power_data->vreg_config, power_data->num_vreg, 1);
2379 if (rc) {
2380 DEV_ERR("%s: Failed to config %s vreg. Err=%d\n",
2381 __func__, hdmi_tx_pm_name(module), rc);
2382 goto exit;
2383 }
2384
2385 snprintf(name, MAX_CLIENT_NAME_LEN, "hdmi:%u", module);
2386 hdmi_ctrl->pdata.reg_bus_clt[module] =
2387 mdss_reg_bus_vote_client_create(name);
2388 if (IS_ERR(hdmi_ctrl->pdata.reg_bus_clt[module])) {
2389 pr_err("reg bus client create failed\n");
Sachin Bhayare5076e252018-01-18 14:56:45 +05302390 msm_mdss_config_vreg(&hdmi_ctrl->pdev->dev,
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302391 power_data->vreg_config, power_data->num_vreg, 0);
2392 rc = PTR_ERR(hdmi_ctrl->pdata.reg_bus_clt[module]);
2393 goto exit;
2394 }
2395
Sachin Bhayare5076e252018-01-18 14:56:45 +05302396 rc = msm_mdss_get_clk(&hdmi_ctrl->pdev->dev,
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302397 power_data->clk_config, power_data->num_clk);
2398 if (rc) {
2399 DEV_ERR("%s: Failed to get %s clk. Err=%d\n",
2400 __func__, hdmi_tx_pm_name(module), rc);
2401
2402 mdss_reg_bus_vote_client_destroy(
2403 hdmi_ctrl->pdata.reg_bus_clt[module]);
2404 hdmi_ctrl->pdata.reg_bus_clt[module] = NULL;
Sachin Bhayare5076e252018-01-18 14:56:45 +05302405 msm_mdss_config_vreg(&hdmi_ctrl->pdev->dev,
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302406 power_data->vreg_config, power_data->num_vreg, 0);
2407 }
2408 } else {
Sachin Bhayare5076e252018-01-18 14:56:45 +05302409 msm_mdss_put_clk(power_data->clk_config, power_data->num_clk);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302410 mdss_reg_bus_vote_client_destroy(
2411 hdmi_ctrl->pdata.reg_bus_clt[module]);
2412 hdmi_ctrl->pdata.reg_bus_clt[module] = NULL;
2413
Sachin Bhayare5076e252018-01-18 14:56:45 +05302414 rc = msm_mdss_config_vreg(&hdmi_ctrl->pdev->dev,
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302415 power_data->vreg_config, power_data->num_vreg, 0);
2416 if (rc)
2417 DEV_ERR("%s: Fail to deconfig %s vreg. Err=%d\n",
2418 __func__, hdmi_tx_pm_name(module), rc);
2419 }
2420
2421exit:
2422 return rc;
2423} /* hdmi_tx_config_power */
2424
2425static int hdmi_tx_check_clk_state(struct hdmi_tx_ctrl *hdmi_ctrl,
2426 enum hdmi_tx_power_module_type module)
2427{
2428 int i;
2429 int rc = 0;
Sachin Bhayare5076e252018-01-18 14:56:45 +05302430 struct mdss_module_power *pd = NULL;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302431
2432 if (!hdmi_ctrl || module >= HDMI_TX_MAX_PM) {
2433 DEV_ERR("%s: Error: invalid input\n", __func__);
2434 rc = -EINVAL;
2435 goto error;
2436 }
2437
2438 pd = &hdmi_ctrl->pdata.power_data[module];
2439 if (!pd) {
2440 DEV_ERR("%s: Error: invalid power data\n", __func__);
2441 rc = -EINVAL;
2442 goto error;
2443 }
2444
2445 for (i = 0; i < pd->num_clk; i++) {
2446 struct clk *clk = pd->clk_config[i].clk;
2447
2448 if (clk) {
2449 u32 rate = clk_get_rate(clk);
2450
2451 DEV_DBG("%s: clk %s: rate %d\n", __func__,
2452 pd->clk_config[i].clk_name, rate);
2453
2454 if (!rate) {
2455 rc = -EINVAL;
2456 goto error;
2457 }
2458 } else {
2459 DEV_ERR("%s: clk %s: not configured\n", __func__,
2460 pd->clk_config[i].clk_name);
2461
2462 rc = -EINVAL;
2463 goto error;
2464 }
2465 }
2466
2467 return 0;
2468error:
2469 return rc;
2470}
2471
2472static int hdmi_tx_enable_power(struct hdmi_tx_ctrl *hdmi_ctrl,
2473 enum hdmi_tx_power_module_type module, int enable)
2474{
2475 int rc = 0;
Sachin Bhayare5076e252018-01-18 14:56:45 +05302476 struct mdss_module_power *power_data = NULL;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302477
2478 if (!hdmi_ctrl || module >= HDMI_TX_MAX_PM) {
2479 DEV_ERR("%s: Error: invalid input\n", __func__);
2480 rc = -EINVAL;
2481 goto error;
2482 }
2483
2484 power_data = &hdmi_ctrl->pdata.power_data[module];
2485 if (!power_data) {
2486 DEV_ERR("%s: Error: invalid power data\n", __func__);
2487 rc = -EINVAL;
2488 goto error;
2489 }
2490
2491 if (hdmi_ctrl->panel_data.panel_info.cont_splash_enabled) {
2492 DEV_DBG("%s: %s enabled by splash.\n",
2493 __func__, hdmi_pm_name(module));
2494 return 0;
2495 }
2496
2497 if (enable && !hdmi_ctrl->power_data_enable[module]) {
Sachin Bhayare5076e252018-01-18 14:56:45 +05302498 rc = msm_mdss_enable_vreg(power_data->vreg_config,
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302499 power_data->num_vreg, 1);
2500 if (rc) {
2501 DEV_ERR("%s: Failed to enable %s vreg. Error=%d\n",
2502 __func__, hdmi_tx_pm_name(module), rc);
2503 goto error;
2504 }
2505
2506 rc = hdmi_tx_pinctrl_set_state(hdmi_ctrl, module, enable);
2507 if (rc) {
2508 DEV_ERR("%s: Failed to set %s pinctrl state\n",
2509 __func__, hdmi_tx_pm_name(module));
2510 goto error;
2511 }
2512
Sachin Bhayare5076e252018-01-18 14:56:45 +05302513 rc = msm_mdss_enable_gpio(power_data->gpio_config,
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302514 power_data->num_gpio, 1);
2515 if (rc) {
2516 DEV_ERR("%s: Failed to enable %s gpio. Error=%d\n",
2517 __func__, hdmi_tx_pm_name(module), rc);
2518 goto disable_vreg;
2519 }
2520 mdss_update_reg_bus_vote(hdmi_ctrl->pdata.reg_bus_clt[module],
2521 VOTE_INDEX_LOW);
2522
Sachin Bhayare5076e252018-01-18 14:56:45 +05302523 rc = msm_mdss_clk_set_rate(power_data->clk_config,
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302524 power_data->num_clk);
2525 if (rc) {
2526 DEV_ERR("%s: failed to set clks rate for %s. err=%d\n",
2527 __func__, hdmi_tx_pm_name(module), rc);
2528 goto disable_gpio;
2529 }
2530
Sachin Bhayare5076e252018-01-18 14:56:45 +05302531 rc = msm_mdss_enable_clk(power_data->clk_config,
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302532 power_data->num_clk, 1);
2533 if (rc) {
2534 DEV_ERR("%s: Failed to enable clks for %s. Error=%d\n",
2535 __func__, hdmi_tx_pm_name(module), rc);
2536 goto disable_gpio;
2537 }
2538 hdmi_ctrl->power_data_enable[module] = true;
2539 } else if (!enable && hdmi_ctrl->power_data_enable[module] &&
2540 (!hdmi_tx_is_cec_wakeup_en(hdmi_ctrl) ||
2541 ((module != HDMI_TX_HPD_PM) && (module != HDMI_TX_CEC_PM)))) {
Sachin Bhayare5076e252018-01-18 14:56:45 +05302542 msm_mdss_enable_clk(power_data->clk_config,
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302543 power_data->num_clk, 0);
2544 mdss_update_reg_bus_vote(hdmi_ctrl->pdata.reg_bus_clt[module],
2545 VOTE_INDEX_DISABLE);
Sachin Bhayare5076e252018-01-18 14:56:45 +05302546 msm_mdss_enable_gpio(power_data->gpio_config,
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302547 power_data->num_gpio, 0);
2548 hdmi_tx_pinctrl_set_state(hdmi_ctrl, module, 0);
Sachin Bhayare5076e252018-01-18 14:56:45 +05302549 msm_mdss_enable_vreg(power_data->vreg_config,
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302550 power_data->num_vreg, 0);
2551 hdmi_ctrl->power_data_enable[module] = false;
2552 }
2553
2554 return rc;
2555
2556disable_gpio:
2557 mdss_update_reg_bus_vote(hdmi_ctrl->pdata.reg_bus_clt[module],
2558 VOTE_INDEX_DISABLE);
Sachin Bhayare5076e252018-01-18 14:56:45 +05302559 msm_mdss_enable_gpio(power_data->gpio_config, power_data->num_gpio, 0);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302560disable_vreg:
Sachin Bhayare5076e252018-01-18 14:56:45 +05302561 msm_mdss_enable_vreg(power_data->vreg_config, power_data->num_vreg, 0);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302562error:
2563 return rc;
2564} /* hdmi_tx_enable_power */
2565
2566static void hdmi_tx_core_off(struct hdmi_tx_ctrl *hdmi_ctrl)
2567{
2568 if (!hdmi_ctrl) {
2569 DEV_ERR("%s: invalid input\n", __func__);
2570 return;
2571 }
2572
2573 hdmi_tx_enable_power(hdmi_ctrl, HDMI_TX_CEC_PM, 0);
2574 hdmi_tx_enable_power(hdmi_ctrl, HDMI_TX_CORE_PM, 0);
2575} /* hdmi_tx_core_off */
2576
2577static int hdmi_tx_core_on(struct hdmi_tx_ctrl *hdmi_ctrl)
2578{
2579 int rc = 0;
2580
2581 if (!hdmi_ctrl) {
2582 DEV_ERR("%s: invalid input\n", __func__);
2583 return -EINVAL;
2584 }
2585
2586 rc = hdmi_tx_enable_power(hdmi_ctrl, HDMI_TX_CORE_PM, 1);
2587 if (rc) {
2588 DEV_ERR("%s: core hdmi_msm_enable_power failed rc = %d\n",
2589 __func__, rc);
2590 return rc;
2591 }
2592 rc = hdmi_tx_enable_power(hdmi_ctrl, HDMI_TX_CEC_PM, 1);
2593 if (rc) {
2594 DEV_ERR("%s: cec hdmi_msm_enable_power failed rc = %d\n",
2595 __func__, rc);
2596 goto disable_core_power;
2597 }
2598
2599 return rc;
2600disable_core_power:
2601 hdmi_tx_enable_power(hdmi_ctrl, HDMI_TX_CORE_PM, 0);
2602 return rc;
2603} /* hdmi_tx_core_on */
2604
2605static void hdmi_tx_phy_reset(struct hdmi_tx_ctrl *hdmi_ctrl)
2606{
2607 unsigned int phy_reset_polarity = 0x0;
2608 unsigned int pll_reset_polarity = 0x0;
2609 unsigned int val;
Sachin Bhayare5076e252018-01-18 14:56:45 +05302610 struct mdss_io_data *io = NULL;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302611
2612 if (!hdmi_ctrl) {
2613 DEV_ERR("%s: invalid input\n", __func__);
2614 return;
2615 }
2616
2617 io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
2618 if (!io->base) {
2619 DEV_ERR("%s: core io not inititalized\n", __func__);
2620 return;
2621 }
2622
2623 val = DSS_REG_R_ND(io, HDMI_PHY_CTRL);
2624
2625 phy_reset_polarity = val >> 3 & 0x1;
2626 pll_reset_polarity = val >> 1 & 0x1;
2627
2628 if (phy_reset_polarity == 0)
2629 DSS_REG_W_ND(io, HDMI_PHY_CTRL, val | SW_RESET);
2630 else
2631 DSS_REG_W_ND(io, HDMI_PHY_CTRL, val & (~SW_RESET));
2632
2633 if (pll_reset_polarity == 0)
2634 DSS_REG_W_ND(io, HDMI_PHY_CTRL, val | SW_RESET_PLL);
2635 else
2636 DSS_REG_W_ND(io, HDMI_PHY_CTRL, val & (~SW_RESET_PLL));
2637
2638 if (phy_reset_polarity == 0)
2639 DSS_REG_W_ND(io, HDMI_PHY_CTRL, val & (~SW_RESET));
2640 else
2641 DSS_REG_W_ND(io, HDMI_PHY_CTRL, val | SW_RESET);
2642
2643 if (pll_reset_polarity == 0)
2644 DSS_REG_W_ND(io, HDMI_PHY_CTRL, val & (~SW_RESET_PLL));
2645 else
2646 DSS_REG_W_ND(io, HDMI_PHY_CTRL, val | SW_RESET_PLL);
2647} /* hdmi_tx_phy_reset */
2648
2649static int hdmi_tx_audio_info_setup(struct platform_device *pdev,
2650 struct msm_hdmi_audio_setup_params *params)
2651{
2652 int rc = 0;
2653 struct hdmi_tx_ctrl *hdmi_ctrl = platform_get_drvdata(pdev);
2654 u32 is_mode_dvi;
2655
2656 if (!hdmi_ctrl || !params) {
2657 DEV_ERR("%s: invalid input\n", __func__);
2658 return -ENODEV;
2659 }
2660
2661 mutex_lock(&hdmi_ctrl->tx_lock);
2662
2663 is_mode_dvi = hdmi_tx_is_dvi_mode(hdmi_ctrl);
2664
2665 if (!is_mode_dvi && hdmi_tx_is_panel_on(hdmi_ctrl)) {
2666 memcpy(&hdmi_ctrl->audio_params, params,
2667 sizeof(struct msm_hdmi_audio_setup_params));
2668
2669 hdmi_tx_audio_setup(hdmi_ctrl);
2670 } else {
2671 rc = -EPERM;
2672 }
2673
2674 if (rc) {
2675 struct hdmi_audio_status status = {0};
2676
2677 if (hdmi_ctrl->audio_ops.status)
2678 hdmi_ctrl->audio_ops.status(hdmi_ctrl->audio_data,
2679 &status);
2680
2681 dev_err_ratelimited(&hdmi_ctrl->pdev->dev,
2682 "%s: hpd %d, ack %d, switch %d, mode %s, power %d\n",
2683 __func__, hdmi_ctrl->hpd_state,
2684 status.ack_pending, status.switched,
2685 is_mode_dvi ? "dvi" : "hdmi",
2686 hdmi_ctrl->panel_power_on);
2687 }
2688 mutex_unlock(&hdmi_ctrl->tx_lock);
2689 return rc;
2690}
2691
2692static int hdmi_tx_get_audio_edid_blk(struct platform_device *pdev,
2693 struct msm_hdmi_audio_edid_blk *blk)
2694{
2695 struct hdmi_tx_ctrl *hdmi_ctrl = platform_get_drvdata(pdev);
2696
2697 if (!hdmi_ctrl) {
2698 DEV_ERR("%s: invalid input\n", __func__);
2699 return -ENODEV;
2700 }
2701
2702 return hdmi_edid_get_audio_blk(
2703 hdmi_tx_get_fd(HDMI_TX_FEAT_EDID), blk);
2704} /* hdmi_tx_get_audio_edid_blk */
2705
2706static u8 hdmi_tx_tmds_enabled(struct platform_device *pdev)
2707{
2708 struct hdmi_tx_ctrl *hdmi_ctrl = platform_get_drvdata(pdev);
2709
2710 if (!hdmi_ctrl) {
2711 DEV_ERR("%s: invalid input\n", __func__);
2712 return -ENODEV;
2713 }
2714
2715 /* status of tmds */
2716 return (hdmi_ctrl->timing_gen_on == true);
2717}
2718
2719static int hdmi_tx_set_mhl_max_pclk(struct platform_device *pdev, u32 max_val)
2720{
2721 struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
2722
2723 hdmi_ctrl = platform_get_drvdata(pdev);
2724
2725 if (!hdmi_ctrl) {
2726 DEV_ERR("%s: invalid input\n", __func__);
2727 return -ENODEV;
2728 }
2729 if (max_val) {
2730 hdmi_ctrl->ds_data.ds_max_clk = max_val;
2731 hdmi_ctrl->ds_data.ds_registered = true;
2732 } else {
2733 DEV_ERR("%s: invalid max pclk val\n", __func__);
2734 return -EINVAL;
2735 }
2736
2737 return 0;
2738}
2739
2740int msm_hdmi_register_mhl(struct platform_device *pdev,
2741 struct msm_hdmi_mhl_ops *ops, void *data)
2742{
2743 struct hdmi_tx_ctrl *hdmi_ctrl = platform_get_drvdata(pdev);
2744
2745 if (!hdmi_ctrl) {
2746 DEV_ERR("%s: invalid pdev\n", __func__);
2747 return -ENODEV;
2748 }
2749
2750 if (!ops) {
2751 DEV_ERR("%s: invalid ops\n", __func__);
2752 return -EINVAL;
2753 }
2754
2755 ops->tmds_enabled = hdmi_tx_tmds_enabled;
2756 ops->set_mhl_max_pclk = hdmi_tx_set_mhl_max_pclk;
2757 ops->set_upstream_hpd = hdmi_tx_set_mhl_hpd;
2758
2759 hdmi_ctrl->ds_registered = true;
2760
2761 return 0;
2762}
2763
2764static int hdmi_tx_get_cable_status(struct platform_device *pdev, u32 vote)
2765{
2766 struct hdmi_tx_ctrl *hdmi_ctrl = platform_get_drvdata(pdev);
2767 unsigned long flags;
2768 u32 hpd;
2769
2770 if (!hdmi_ctrl) {
2771 DEV_ERR("%s: invalid input\n", __func__);
2772 return -ENODEV;
2773 }
2774
2775 spin_lock_irqsave(&hdmi_ctrl->hpd_state_lock, flags);
2776 hpd = hdmi_tx_is_panel_on(hdmi_ctrl);
2777 spin_unlock_irqrestore(&hdmi_ctrl->hpd_state_lock, flags);
2778
2779 hdmi_ctrl->vote_hdmi_core_on = false;
2780
2781 if (vote && hpd)
2782 hdmi_ctrl->vote_hdmi_core_on = true;
2783
2784 /*
2785 * if cable is not connected and audio calls this function,
2786 * consider this as an error as it will result in whole
2787 * audio path to fail.
2788 */
2789 if (!hpd) {
2790 struct hdmi_audio_status status = {0};
2791
2792 if (hdmi_ctrl->audio_ops.status)
2793 hdmi_ctrl->audio_ops.status(hdmi_ctrl->audio_data,
2794 &status);
2795
2796 dev_err_ratelimited(&hdmi_ctrl->pdev->dev,
2797 "%s: hpd %d, ack %d, switch %d, power %d\n",
2798 __func__, hdmi_ctrl->hpd_state,
2799 status.ack_pending, status.switched,
2800 hdmi_ctrl->panel_power_on);
2801 }
2802
2803 return hpd;
2804}
2805
Sachin Bhayare3d3767e2018-01-02 21:10:57 +05302806int msm_mdss_hdmi_register_audio_codec(struct platform_device *pdev,
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302807 struct msm_hdmi_audio_codec_ops *ops)
2808{
2809 struct hdmi_tx_ctrl *hdmi_ctrl = platform_get_drvdata(pdev);
2810
2811 if (!hdmi_ctrl || !ops) {
2812 DEV_ERR("%s: invalid input\n", __func__);
2813 return -ENODEV;
2814 }
2815
2816 ops->audio_info_setup = hdmi_tx_audio_info_setup;
2817 ops->get_audio_edid_blk = hdmi_tx_get_audio_edid_blk;
2818 ops->hdmi_cable_status = hdmi_tx_get_cable_status;
2819
2820 return 0;
2821} /* hdmi_tx_audio_register */
Sachin Bhayare3d3767e2018-01-02 21:10:57 +05302822EXPORT_SYMBOL(msm_mdss_hdmi_register_audio_codec);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302823
2824static int hdmi_tx_setup_tmds_clk_rate(struct hdmi_tx_ctrl *hdmi_ctrl)
2825{
2826 u32 rate = 0;
2827 struct msm_hdmi_mode_timing_info *timing = NULL;
2828 u32 rate_ratio;
2829
2830 if (!hdmi_ctrl) {
2831 DEV_ERR("%s: Bad input parameters\n", __func__);
2832 goto end;
2833 }
2834
2835 timing = &hdmi_ctrl->timing;
2836 if (!timing) {
2837 DEV_ERR("%s: Invalid timing info\n", __func__);
2838 goto end;
2839 }
2840
2841 switch (hdmi_ctrl->panel_data.panel_info.out_format) {
2842 case MDP_Y_CBCR_H2V2:
2843 rate_ratio = HDMI_TX_YUV420_24BPP_PCLK_TMDS_CH_RATE_RATIO;
2844 break;
2845 case MDP_Y_CBCR_H2V1:
2846 rate_ratio = HDMI_TX_YUV422_24BPP_PCLK_TMDS_CH_RATE_RATIO;
2847 break;
2848 default:
2849 rate_ratio = HDMI_TX_RGB_24BPP_PCLK_TMDS_CH_RATE_RATIO;
2850 break;
2851 }
2852
2853 rate = timing->pixel_freq / rate_ratio;
2854
2855end:
2856 return rate;
2857}
2858
2859static inline bool hdmi_tx_hw_is_cable_connected(struct hdmi_tx_ctrl *hdmi_ctrl)
2860{
2861 return DSS_REG_R(&hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO],
2862 HDMI_HPD_INT_STATUS) & BIT(1) ? true : false;
2863}
2864
2865static void hdmi_tx_hpd_polarity_setup(struct hdmi_tx_ctrl *hdmi_ctrl,
2866 bool polarity)
2867{
Sachin Bhayare5076e252018-01-18 14:56:45 +05302868 struct mdss_io_data *io = NULL;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302869 bool cable_sense;
2870
2871 if (!hdmi_ctrl) {
2872 DEV_ERR("%s: invalid input\n", __func__);
2873 return;
2874 }
2875 io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
2876 if (!io->base) {
2877 DEV_ERR("%s: core io is not initialized\n", __func__);
2878 return;
2879 }
2880
2881 if (hdmi_ctrl->sim_mode) {
2882 DEV_DBG("%s: sim mode enabled\n", __func__);
2883 return;
2884 }
2885
2886 if (polarity)
2887 DSS_REG_W(io, HDMI_HPD_INT_CTRL, BIT(2) | BIT(1));
2888 else
2889 DSS_REG_W(io, HDMI_HPD_INT_CTRL, BIT(2));
2890
2891 cable_sense = hdmi_tx_hw_is_cable_connected(hdmi_ctrl);
2892 DEV_DBG("%s: listen = %s, sense = %s\n", __func__,
2893 polarity ? "connect" : "disconnect",
2894 cable_sense ? "connect" : "disconnect");
2895
2896 if (cable_sense == polarity) {
2897 u32 reg_val = DSS_REG_R(io, HDMI_HPD_CTRL);
2898
2899 /* Toggle HPD circuit to trigger HPD sense */
2900 DSS_REG_W(io, HDMI_HPD_CTRL, reg_val & ~BIT(28));
2901 DSS_REG_W(io, HDMI_HPD_CTRL, reg_val | BIT(28));
2902 }
2903} /* hdmi_tx_hpd_polarity_setup */
2904
2905static inline void hdmi_tx_audio_off(struct hdmi_tx_ctrl *hdmi_ctrl)
2906{
2907 if (hdmi_ctrl && hdmi_ctrl->audio_ops.off)
2908 hdmi_ctrl->audio_ops.off(hdmi_ctrl->audio_data);
2909
2910 memset(&hdmi_ctrl->audio_params, 0,
2911 sizeof(struct msm_hdmi_audio_setup_params));
2912}
2913
2914static int hdmi_tx_power_off(struct hdmi_tx_ctrl *hdmi_ctrl)
2915{
Sachin Bhayare5076e252018-01-18 14:56:45 +05302916 struct mdss_io_data *io = NULL;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302917 void *pdata = NULL;
2918
2919 if (!hdmi_ctrl) {
2920 DEV_ERR("%s: invalid input\n", __func__);
2921 return -EINVAL;
2922 }
2923
2924 pdata = hdmi_tx_get_fd(HDMI_TX_FEAT_PANEL);
2925 if (!pdata) {
2926 DEV_ERR("%s: invalid panel data\n", __func__);
2927 return -EINVAL;
2928 }
2929
2930 io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
2931 if (!io->base) {
2932 DEV_ERR("%s: Core io is not initialized\n", __func__);
2933 goto end;
2934 }
2935
2936 if (!hdmi_ctrl->panel_power_on) {
2937 DEV_DBG("%s: hdmi_ctrl is already off\n", __func__);
2938 goto end;
2939 }
2940
2941 if (!hdmi_tx_is_dvi_mode(hdmi_ctrl))
2942 hdmi_tx_audio_off(hdmi_ctrl);
2943
2944 if (hdmi_ctrl->panel_ops.off)
2945 hdmi_ctrl->panel_ops.off(pdata);
2946
2947 hdmi_tx_core_off(hdmi_ctrl);
2948
2949 hdmi_ctrl->panel_power_on = false;
2950
2951 if (hdmi_ctrl->hpd_off_pending || hdmi_ctrl->panel_suspend ||
2952 !hdmi_ctrl->pdata.pluggable)
2953 hdmi_tx_hpd_off(hdmi_ctrl);
2954
2955 if (hdmi_ctrl->hdmi_tx_hpd_done)
2956 hdmi_ctrl->hdmi_tx_hpd_done(
2957 hdmi_ctrl->downstream_data);
2958end:
2959 DEV_INFO("%s: HDMI Core: OFF\n", __func__);
2960 return 0;
2961} /* hdmi_tx_power_off */
2962
2963static int hdmi_tx_power_on(struct hdmi_tx_ctrl *hdmi_ctrl)
2964{
2965 int ret;
2966 u32 div = 0;
2967 struct mdss_panel_data *panel_data = &hdmi_ctrl->panel_data;
2968 void *pdata = hdmi_tx_get_fd(HDMI_TX_FEAT_PANEL);
2969 void *edata = hdmi_tx_get_fd(HDMI_TX_FEAT_EDID);
2970
2971 if (!hdmi_ctrl->pdata.pluggable)
2972 hdmi_tx_hpd_on(hdmi_ctrl);
2973
2974 ret = hdmi_tx_check_clk_state(hdmi_ctrl, HDMI_TX_HPD_PM);
2975 if (ret) {
2976 DEV_ERR("%s: clocks not on\n", __func__);
2977 return -EINVAL;
2978 }
2979
2980 if (hdmi_ctrl->panel_ops.get_vic)
2981 hdmi_ctrl->vic = hdmi_ctrl->panel_ops.get_vic(
2982 &panel_data->panel_info, &hdmi_ctrl->ds_data);
2983
2984 if (hdmi_ctrl->vic <= 0) {
2985 DEV_ERR("%s: invalid vic\n", __func__);
2986 return -EINVAL;
2987 }
2988
2989 ret = hdmi_get_supported_mode(&hdmi_ctrl->timing,
2990 &hdmi_ctrl->ds_data, hdmi_ctrl->vic);
2991 if (ret || !hdmi_ctrl->timing.supported) {
2992 DEV_ERR("%s: invalid timing data\n", __func__);
2993 return -EINVAL;
2994 }
2995
2996 hdmi_ctrl->panel.vic = hdmi_ctrl->vic;
2997
2998 if (!hdmi_tx_is_dvi_mode(hdmi_ctrl) &&
2999 hdmi_tx_is_cea_format(hdmi_ctrl->vic))
3000 hdmi_ctrl->panel.infoframe = true;
3001 else
3002 hdmi_ctrl->panel.infoframe = false;
3003
3004 hdmi_ctrl->panel.scan_info = hdmi_edid_get_sink_scaninfo(edata,
3005 hdmi_ctrl->vic);
3006 hdmi_ctrl->panel.scrambler = hdmi_edid_get_sink_scrambler_support(
3007 edata);
3008
3009 if (hdmi_ctrl->panel_ops.on)
3010 hdmi_ctrl->panel_ops.on(pdata);
3011
3012 if (panel_data->panel_info.out_format == MDP_Y_CBCR_H2V2)
3013 div = 1;
3014
3015 hdmi_ctrl->pdata.power_data[HDMI_TX_CORE_PM].clk_config[0].rate =
3016 (hdmi_ctrl->timing.pixel_freq * 1000) >> div;
3017
3018 hdmi_edid_set_video_resolution(hdmi_tx_get_fd(HDMI_TX_FEAT_EDID),
3019 hdmi_ctrl->vic, false);
3020
3021 hdmi_tx_core_on(hdmi_ctrl);
3022
3023 if (hdmi_ctrl->panel.infoframe &&
3024 !hdmi_tx_is_encryption_set(hdmi_ctrl) &&
3025 hdmi_tx_is_stream_shareable(hdmi_ctrl)) {
3026 hdmi_tx_set_audio_switch_node(hdmi_ctrl, 1);
3027 hdmi_tx_config_avmute(hdmi_ctrl, false);
3028 }
3029
3030 hdmi_ctrl->panel_power_on = true;
3031
3032 hdmi_tx_hpd_polarity_setup(hdmi_ctrl, HPD_DISCONNECT_POLARITY);
3033
3034 if (hdmi_ctrl->hdmi_tx_hpd_done)
3035 hdmi_ctrl->hdmi_tx_hpd_done(hdmi_ctrl->downstream_data);
3036
3037 DEV_DBG("%s: hdmi_ctrl core on\n", __func__);
3038 return 0;
3039}
3040
3041static void hdmi_tx_hpd_off(struct hdmi_tx_ctrl *hdmi_ctrl)
3042{
3043 int rc = 0;
Sachin Bhayare5076e252018-01-18 14:56:45 +05303044 struct mdss_io_data *io = NULL;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303045 unsigned long flags;
3046
3047 if (!hdmi_ctrl) {
3048 DEV_ERR("%s: invalid input\n", __func__);
3049 return;
3050 }
3051
3052 if (!hdmi_ctrl->hpd_initialized) {
3053 DEV_DBG("%s: HPD is already OFF, returning\n", __func__);
3054 return;
3055 }
3056
3057 io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
3058 if (!io->base) {
3059 DEV_ERR("%s: core io not inititalized\n", __func__);
3060 return;
3061 }
3062
3063 /* Turn off HPD interrupts */
3064 DSS_REG_W(io, HDMI_HPD_INT_CTRL, 0);
3065
3066 /* non pluggable display should not enable wakeup interrupt */
3067 if ((hdmi_tx_is_cec_wakeup_en(hdmi_ctrl) &&
3068 hdmi_ctrl->pdata.pluggable)) {
3069 hdmi_ctrl->mdss_util->enable_wake_irq(&hdmi_tx_hw);
3070 } else {
3071 hdmi_ctrl->mdss_util->disable_irq(&hdmi_tx_hw);
3072 hdmi_tx_set_mode(hdmi_ctrl, false);
3073 }
3074 hdmi_tx_config_5v(hdmi_ctrl, false);
3075 rc = hdmi_tx_enable_power(hdmi_ctrl, HDMI_TX_HPD_PM, 0);
3076 if (rc)
3077 DEV_INFO("%s: Failed to disable hpd power. Error=%d\n",
3078 __func__, rc);
3079
3080 spin_lock_irqsave(&hdmi_ctrl->hpd_state_lock, flags);
3081 hdmi_ctrl->hpd_state = false;
3082 spin_unlock_irqrestore(&hdmi_ctrl->hpd_state_lock, flags);
3083
3084 hdmi_ctrl->hpd_initialized = false;
3085 hdmi_ctrl->hpd_off_pending = false;
3086
3087 DEV_DBG("%s: HPD is now OFF\n", __func__);
3088} /* hdmi_tx_hpd_off */
3089
3090static int hdmi_tx_hpd_on(struct hdmi_tx_ctrl *hdmi_ctrl)
3091{
3092 u32 reg_val;
3093 int rc = 0;
Sachin Bhayare5076e252018-01-18 14:56:45 +05303094 struct mdss_io_data *io = NULL;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303095
3096 if (!hdmi_ctrl) {
3097 DEV_ERR("%s: invalid input\n", __func__);
3098 return -EINVAL;
3099 }
3100
3101 io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
3102 if (!io->base) {
3103 DEV_ERR("%s: core io not inititalized\n", __func__);
3104 return -EINVAL;
3105 }
3106
3107 if (hdmi_ctrl->hpd_initialized) {
3108 DEV_DBG("%s: HPD is already ON\n", __func__);
3109 } else {
3110 rc = hdmi_tx_enable_power(hdmi_ctrl, HDMI_TX_HPD_PM, true);
3111 if (rc) {
3112 DEV_ERR("%s: Failed to enable hpd power. rc=%d\n",
3113 __func__, rc);
3114 return rc;
3115 }
3116
Sachin Bhayare5076e252018-01-18 14:56:45 +05303117 mdss_reg_dump(io->base, io->len, "HDMI-INIT: ", REG_DUMP);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303118
3119 if (!hdmi_ctrl->panel_data.panel_info.cont_splash_enabled) {
3120 hdmi_tx_set_mode(hdmi_ctrl, false);
3121 hdmi_tx_phy_reset(hdmi_ctrl);
3122 hdmi_tx_set_mode(hdmi_ctrl, true);
3123 }
3124
3125 DSS_REG_W(io, HDMI_USEC_REFTIMER, 0x0001001B);
3126
3127 if (hdmi_tx_is_cec_wakeup_en(hdmi_ctrl))
3128 hdmi_ctrl->mdss_util->disable_wake_irq(&hdmi_tx_hw);
3129
3130 hdmi_ctrl->mdss_util->enable_irq(&hdmi_tx_hw);
3131
3132 hdmi_ctrl->hpd_initialized = true;
3133
3134 DEV_INFO("%s: HDMI HW version = 0x%x\n", __func__,
3135 DSS_REG_R_ND(&hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO],
3136 HDMI_VERSION));
3137
3138 /* set timeout to 4.1ms (max) for hardware debounce */
3139 reg_val = DSS_REG_R(io, HDMI_HPD_CTRL) | 0x1FFF;
3140
3141 /* Turn on HPD HW circuit */
3142 DSS_REG_W(io, HDMI_HPD_CTRL, reg_val | BIT(28));
3143
3144 hdmi_tx_hpd_polarity_setup(hdmi_ctrl, HPD_CONNECT_POLARITY);
3145 DEV_DBG("%s: HPD is now ON\n", __func__);
3146 }
3147
3148 return rc;
3149} /* hdmi_tx_hpd_on */
3150
3151static int hdmi_tx_sysfs_enable_hpd(struct hdmi_tx_ctrl *hdmi_ctrl, int on)
3152{
3153 int rc = 0;
3154
3155 if (!hdmi_ctrl) {
3156 DEV_ERR("%s: invalid input\n", __func__);
3157 return -EINVAL;
3158 }
3159
3160 DEV_DBG("%s: %d\n", __func__, on);
3161 if (on) {
3162 hdmi_ctrl->hpd_off_pending = false;
3163 rc = hdmi_tx_hpd_on(hdmi_ctrl);
3164 } else {
3165 if (!hdmi_ctrl->panel_power_on)
3166 hdmi_tx_hpd_off(hdmi_ctrl);
3167 else
3168 hdmi_ctrl->hpd_off_pending = true;
3169 }
3170
3171 return rc;
3172} /* hdmi_tx_sysfs_enable_hpd */
3173
3174static int hdmi_tx_set_mhl_hpd(struct platform_device *pdev, uint8_t on)
3175{
3176 int rc = 0;
3177 struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
3178
3179 hdmi_ctrl = platform_get_drvdata(pdev);
3180
3181 if (!hdmi_ctrl) {
3182 DEV_ERR("%s: invalid input\n", __func__);
3183 return -EINVAL;
3184 }
3185
3186 mutex_lock(&hdmi_ctrl->tx_lock);
3187
3188 /* mhl status should override */
3189 hdmi_ctrl->mhl_hpd_on = on;
3190
3191 if (!on && hdmi_ctrl->hpd_feature_on) {
3192 rc = hdmi_tx_sysfs_enable_hpd(hdmi_ctrl, false);
3193 } else if (on && !hdmi_ctrl->hpd_feature_on) {
3194 rc = hdmi_tx_sysfs_enable_hpd(hdmi_ctrl, true);
3195 } else {
3196 DEV_DBG("%s: hpd is already '%s'. return\n", __func__,
3197 hdmi_ctrl->hpd_feature_on ? "enabled" : "disabled");
3198 goto end;
3199 }
3200
3201 if (!rc) {
3202 hdmi_ctrl->hpd_feature_on =
3203 (~hdmi_ctrl->hpd_feature_on) & BIT(0);
3204 DEV_DBG("%s: '%d'\n", __func__, hdmi_ctrl->hpd_feature_on);
3205 } else {
3206 DEV_ERR("%s: failed to '%s' hpd. rc = %d\n", __func__,
3207 on ? "enable" : "disable", rc);
3208 }
3209end:
3210 mutex_unlock(&hdmi_ctrl->tx_lock);
3211 return rc;
3212}
3213
3214static irqreturn_t hdmi_tx_isr(int irq, void *data)
3215{
Sachin Bhayare5076e252018-01-18 14:56:45 +05303216 struct mdss_io_data *io = NULL;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303217 struct hdmi_tx_ctrl *hdmi_ctrl = (struct hdmi_tx_ctrl *)data;
3218 unsigned long flags;
3219 u32 hpd_current_state;
3220 u32 reg_val = 0;
3221
3222 if (!hdmi_ctrl) {
3223 DEV_WARN("%s: invalid input data, ISR ignored\n", __func__);
3224 goto end;
3225 }
3226
3227 io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
3228 if (!io->base) {
3229 DEV_WARN("%s: core io not initialized, ISR ignored\n",
3230 __func__);
3231 goto end;
3232 }
3233
3234 if (DSS_REG_R(io, HDMI_HPD_INT_STATUS) & BIT(0)) {
3235 spin_lock_irqsave(&hdmi_ctrl->hpd_state_lock, flags);
3236 hpd_current_state = hdmi_ctrl->hpd_state;
3237 hdmi_ctrl->hpd_state =
3238 (DSS_REG_R(io, HDMI_HPD_INT_STATUS) & BIT(1)) >> 1;
3239 spin_unlock_irqrestore(&hdmi_ctrl->hpd_state_lock, flags);
3240
3241 if (!completion_done(&hdmi_ctrl->hpd_int_done))
3242 complete_all(&hdmi_ctrl->hpd_int_done);
3243
3244 /*
3245 * check if this is a spurious interrupt, if yes, reset
3246 * interrupts and return
3247 */
3248 if (hpd_current_state == hdmi_ctrl->hpd_state) {
3249 DEV_DBG("%s: spurious interrupt %d\n", __func__,
3250 hpd_current_state);
3251
3252 /* enable interrupts */
3253 reg_val |= BIT(2);
3254
3255 /* set polarity, reverse of current state */
3256 reg_val |= (~hpd_current_state << 1) & BIT(1);
3257
3258 /* ack interrupt */
3259 reg_val |= BIT(0);
3260
3261 DSS_REG_W(io, HDMI_HPD_INT_CTRL, reg_val);
3262 goto end;
3263 }
3264
3265 /*
3266 * Ack the current hpd interrupt and stop listening to
3267 * new hpd interrupt.
3268 */
3269 DSS_REG_W(io, HDMI_HPD_INT_CTRL, BIT(0));
3270
3271 queue_work(hdmi_ctrl->workq, &hdmi_ctrl->hpd_int_work);
3272 }
3273
3274 if (hdmi_ddc_isr(&hdmi_ctrl->ddc_ctrl,
3275 hdmi_ctrl->hdmi_tx_ver))
3276 DEV_ERR("%s: hdmi_ddc_isr failed\n", __func__);
3277
3278 if (hdmi_tx_get_fd(HDMI_TX_FEAT_CEC_HW)) {
3279 if (hdmi_cec_isr(hdmi_tx_get_fd(HDMI_TX_FEAT_CEC_HW)))
3280 DEV_ERR("%s: hdmi_cec_isr failed\n", __func__);
3281 }
3282
3283 if (hdmi_ctrl->hdcp_ops && hdmi_ctrl->hdcp_data) {
3284 if (hdmi_ctrl->hdcp_ops->hdmi_hdcp_isr) {
3285 if (hdmi_ctrl->hdcp_ops->hdmi_hdcp_isr(
3286 hdmi_ctrl->hdcp_data))
3287 DEV_ERR("%s: hdmi_hdcp_isr failed\n",
3288 __func__);
3289 }
3290 }
3291end:
3292 return IRQ_HANDLED;
3293} /* hdmi_tx_isr */
3294
3295static void hdmi_tx_dev_deinit(struct hdmi_tx_ctrl *hdmi_ctrl)
3296{
3297 if (!hdmi_ctrl) {
3298 DEV_ERR("%s: invalid input\n", __func__);
3299 return;
3300 }
3301
3302 hdmi_tx_deinit_features(hdmi_ctrl, HDMI_TX_FEAT_MAX);
3303
3304 hdmi_ctrl->hdcp_ops = NULL;
3305 hdmi_ctrl->hdcp_data = NULL;
3306
Sachin Bhayare3d3767e2018-01-02 21:10:57 +05303307 extcon_dev_unregister(&hdmi_ctrl->sdev);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303308 if (hdmi_ctrl->workq)
3309 destroy_workqueue(hdmi_ctrl->workq);
3310 mutex_destroy(&hdmi_ctrl->tx_lock);
3311 mutex_destroy(&hdmi_ctrl->mutex);
3312
3313 hdmi_tx_hw.ptr = NULL;
3314} /* hdmi_tx_dev_deinit */
3315
3316static int hdmi_tx_dev_init(struct hdmi_tx_ctrl *hdmi_ctrl)
3317{
3318 int rc = 0;
3319 struct hdmi_tx_platform_data *pdata = NULL;
3320
3321 if (!hdmi_ctrl) {
3322 DEV_ERR("%s: invalid input\n", __func__);
3323 return -EINVAL;
3324 }
3325
3326 pdata = &hdmi_ctrl->pdata;
3327
3328 rc = hdmi_tx_check_capability(hdmi_ctrl);
3329 if (rc) {
3330 DEV_ERR("%s: no HDMI device\n", __func__);
3331 goto fail_no_hdmi;
3332 }
3333
3334 /* irq enable/disable will be handled in hpd on/off */
3335 hdmi_tx_hw.ptr = (void *)hdmi_ctrl;
3336
3337 mutex_init(&hdmi_ctrl->mutex);
3338 mutex_init(&hdmi_ctrl->tx_lock);
3339
3340 INIT_LIST_HEAD(&hdmi_ctrl->cable_notify_handlers);
3341
3342 hdmi_ctrl->workq = create_workqueue("hdmi_tx_workq");
3343 if (!hdmi_ctrl->workq) {
3344 DEV_ERR("%s: hdmi_tx_workq creation failed.\n", __func__);
3345 rc = -EPERM;
3346 goto fail_create_workq;
3347 }
3348
3349 hdmi_ctrl->ddc_ctrl.io = &pdata->io[HDMI_TX_CORE_IO];
3350 init_completion(&hdmi_ctrl->ddc_ctrl.ddc_sw_done);
3351
3352 hdmi_ctrl->panel_power_on = false;
3353 hdmi_ctrl->panel_suspend = false;
3354
3355 hdmi_ctrl->hpd_state = false;
3356 hdmi_ctrl->hpd_initialized = false;
3357 hdmi_ctrl->hpd_off_pending = false;
3358 init_completion(&hdmi_ctrl->hpd_int_done);
3359
3360 INIT_WORK(&hdmi_ctrl->hpd_int_work, hdmi_tx_hpd_int_work);
3361 INIT_WORK(&hdmi_ctrl->fps_work, hdmi_tx_fps_work);
3362 INIT_WORK(&hdmi_ctrl->cable_notify_work, hdmi_tx_cable_notify_work);
3363 INIT_DELAYED_WORK(&hdmi_ctrl->hdcp_cb_work, hdmi_tx_hdcp_cb_work);
3364
3365 spin_lock_init(&hdmi_ctrl->hpd_state_lock);
3366
3367 return 0;
3368
3369fail_create_workq:
3370 if (hdmi_ctrl->workq)
3371 destroy_workqueue(hdmi_ctrl->workq);
3372 mutex_destroy(&hdmi_ctrl->mutex);
3373fail_no_hdmi:
3374 return rc;
3375} /* hdmi_tx_dev_init */
3376
3377static int hdmi_tx_start_hdcp(struct hdmi_tx_ctrl *hdmi_ctrl)
3378{
3379 int rc;
3380
3381 if (!hdmi_ctrl) {
3382 DEV_ERR("%s: invalid input\n", __func__);
3383 return -EINVAL;
3384 }
3385
3386 if (hdmi_ctrl->panel_data.panel_info.cont_splash_enabled ||
3387 !hdmi_tx_is_hdcp_enabled(hdmi_ctrl))
3388 return 0;
3389
3390 if (hdmi_tx_is_encryption_set(hdmi_ctrl))
3391 hdmi_tx_config_avmute(hdmi_ctrl, true);
3392
3393 rc = hdmi_ctrl->hdcp_ops->hdmi_hdcp_authenticate(hdmi_ctrl->hdcp_data);
3394 if (rc)
3395 DEV_ERR("%s: hdcp auth failed. rc=%d\n", __func__, rc);
3396
3397 return rc;
3398}
3399
3400static int hdmi_tx_init_switch_dev(struct hdmi_tx_ctrl *hdmi_ctrl)
3401{
3402 int rc = -EINVAL;
3403
3404 if (!hdmi_ctrl) {
3405 DEV_ERR("%s: invalid input\n", __func__);
3406 goto end;
3407 }
3408
3409 hdmi_ctrl->sdev.name = "hdmi";
Sachin Bhayare3d3767e2018-01-02 21:10:57 +05303410 rc = extcon_set_state_sync(&hdmi_ctrl->sdev, EXTCON_DISP_HDMI, false);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303411 if (rc) {
3412 DEV_ERR("%s: display switch registration failed\n", __func__);
3413 goto end;
3414 }
3415end:
3416 return rc;
3417}
3418
3419static int hdmi_tx_hdcp_off(struct hdmi_tx_ctrl *hdmi_ctrl)
3420{
3421 int rc = 0;
3422
3423 if (!hdmi_ctrl) {
3424 DEV_ERR("%s: invalid input\n", __func__);
3425 return -EINVAL;
3426 }
3427
3428 DEV_DBG("%s: Turning off HDCP\n", __func__);
3429 hdmi_ctrl->hdcp_ops->hdmi_hdcp_off(
3430 hdmi_ctrl->hdcp_data);
3431
3432 hdmi_ctrl->hdcp_ops = NULL;
3433
3434 rc = hdmi_tx_enable_power(hdmi_ctrl, HDMI_TX_DDC_PM,
3435 false);
3436 if (rc)
3437 DEV_ERR("%s: Failed to disable ddc power\n",
3438 __func__);
3439
3440 return rc;
3441}
3442
3443static char *hdmi_tx_get_event_name(int event)
3444{
3445 switch (event) {
3446 case MDSS_EVENT_RESET:
3447 return HDMI_TX_EVT_STR(MDSS_EVENT_RESET);
3448 case MDSS_EVENT_LINK_READY:
3449 return HDMI_TX_EVT_STR(MDSS_EVENT_LINK_READY);
3450 case MDSS_EVENT_UNBLANK:
3451 return HDMI_TX_EVT_STR(MDSS_EVENT_UNBLANK);
3452 case MDSS_EVENT_PANEL_ON:
3453 return HDMI_TX_EVT_STR(MDSS_EVENT_PANEL_ON);
3454 case MDSS_EVENT_BLANK:
3455 return HDMI_TX_EVT_STR(MDSS_EVENT_BLANK);
3456 case MDSS_EVENT_PANEL_OFF:
3457 return HDMI_TX_EVT_STR(MDSS_EVENT_PANEL_OFF);
3458 case MDSS_EVENT_CLOSE:
3459 return HDMI_TX_EVT_STR(MDSS_EVENT_CLOSE);
3460 case MDSS_EVENT_SUSPEND:
3461 return HDMI_TX_EVT_STR(MDSS_EVENT_SUSPEND);
3462 case MDSS_EVENT_RESUME:
3463 return HDMI_TX_EVT_STR(MDSS_EVENT_RESUME);
3464 case MDSS_EVENT_CHECK_PARAMS:
3465 return HDMI_TX_EVT_STR(MDSS_EVENT_CHECK_PARAMS);
3466 case MDSS_EVENT_CONT_SPLASH_BEGIN:
3467 return HDMI_TX_EVT_STR(MDSS_EVENT_CONT_SPLASH_BEGIN);
3468 case MDSS_EVENT_CONT_SPLASH_FINISH:
3469 return HDMI_TX_EVT_STR(MDSS_EVENT_CONT_SPLASH_FINISH);
3470 case MDSS_EVENT_PANEL_UPDATE_FPS:
3471 return HDMI_TX_EVT_STR(MDSS_EVENT_PANEL_UPDATE_FPS);
3472 case MDSS_EVENT_FB_REGISTERED:
3473 return HDMI_TX_EVT_STR(MDSS_EVENT_FB_REGISTERED);
3474 case MDSS_EVENT_PANEL_CLK_CTRL:
3475 return HDMI_TX_EVT_STR(MDSS_EVENT_PANEL_CLK_CTRL);
3476 case MDSS_EVENT_DSI_CMDLIST_KOFF:
3477 return HDMI_TX_EVT_STR(MDSS_EVENT_DSI_CMDLIST_KOFF);
3478 case MDSS_EVENT_ENABLE_PARTIAL_ROI:
3479 return HDMI_TX_EVT_STR(MDSS_EVENT_ENABLE_PARTIAL_ROI);
3480 case MDSS_EVENT_DSI_STREAM_SIZE:
3481 return HDMI_TX_EVT_STR(MDSS_EVENT_DSI_STREAM_SIZE);
3482 case MDSS_EVENT_DSI_DYNAMIC_SWITCH:
3483 return HDMI_TX_EVT_STR(MDSS_EVENT_DSI_DYNAMIC_SWITCH);
3484 case MDSS_EVENT_REGISTER_RECOVERY_HANDLER:
3485 return HDMI_TX_EVT_STR(MDSS_EVENT_REGISTER_RECOVERY_HANDLER);
3486 default:
3487 return "unknown";
3488 }
3489}
3490
3491static void hdmi_tx_update_fps(struct hdmi_tx_ctrl *hdmi_ctrl)
3492{
3493 void *pdata = NULL;
3494 struct mdss_panel_info *pinfo;
3495
3496 if (!hdmi_ctrl) {
3497 DEV_ERR("%s: invalid input\n", __func__);
3498 return;
3499 }
3500
3501 pdata = hdmi_tx_get_fd(HDMI_TX_FEAT_PANEL);
3502 if (!pdata) {
3503 DEV_ERR("%s: invalid panel data\n", __func__);
3504 return;
3505 }
3506
3507 pinfo = &hdmi_ctrl->panel_data.panel_info;
3508
3509 if (!pinfo->dynamic_fps) {
3510 DEV_DBG("%s: Dynamic fps not enabled\n", __func__);
3511 return;
3512 }
3513
3514 DEV_DBG("%s: current fps %d, new fps %d\n", __func__,
3515 pinfo->current_fps, hdmi_ctrl->dynamic_fps);
3516
3517 if (hdmi_ctrl->dynamic_fps == pinfo->current_fps) {
3518 DEV_DBG("%s: Panel is already at this FPS: %d\n",
3519 __func__, hdmi_ctrl->dynamic_fps);
3520 return;
3521 }
3522
3523 if (hdmi_tx_is_hdcp_enabled(hdmi_ctrl))
3524 hdmi_tx_hdcp_off(hdmi_ctrl);
3525
3526 if (hdmi_ctrl->panel_ops.update_fps)
3527 hdmi_ctrl->vic = hdmi_ctrl->panel_ops.update_fps(pdata,
3528 hdmi_ctrl->dynamic_fps);
3529
3530 hdmi_tx_update_pixel_clk(hdmi_ctrl);
3531
3532 hdmi_tx_start_hdcp(hdmi_ctrl);
3533}
3534
3535static void hdmi_tx_fps_work(struct work_struct *work)
3536{
3537 struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
3538
3539 hdmi_ctrl = container_of(work, struct hdmi_tx_ctrl, fps_work);
3540 if (!hdmi_ctrl) {
3541 DEV_DBG("%s: invalid input\n", __func__);
3542 return;
3543 }
3544
3545 hdmi_tx_update_fps(hdmi_ctrl);
3546}
3547
3548static int hdmi_tx_evt_handle_register(struct hdmi_tx_ctrl *hdmi_ctrl)
3549{
3550 int rc = 0;
3551
3552 rc = hdmi_tx_sysfs_create(hdmi_ctrl, hdmi_ctrl->evt_arg);
3553 if (rc) {
3554 DEV_ERR("%s: hdmi_tx_sysfs_create failed.rc=%d\n",
3555 __func__, rc);
3556 goto sysfs_err;
3557 }
3558 rc = hdmi_tx_init_features(hdmi_ctrl, hdmi_ctrl->evt_arg);
3559 if (rc) {
3560 DEV_ERR("%s: init_features failed.rc=%d\n", __func__, rc);
3561 goto init_err;
3562 }
3563
3564 rc = hdmi_tx_init_switch_dev(hdmi_ctrl);
3565 if (rc) {
3566 DEV_ERR("%s: init switch dev failed.rc=%d\n", __func__, rc);
3567 goto switch_err;
3568 }
3569
3570 if (hdmi_ctrl->pdata.primary || !hdmi_ctrl->pdata.pluggable) {
3571 reinit_completion(&hdmi_ctrl->hpd_int_done);
3572 rc = hdmi_tx_sysfs_enable_hpd(hdmi_ctrl, true);
3573 if (rc) {
3574 DEV_ERR("%s: hpd_enable failed. rc=%d\n", __func__, rc);
3575 goto primary_err;
3576 } else {
3577 hdmi_ctrl->hpd_feature_on = true;
3578 }
3579 }
3580
3581 return 0;
3582
3583primary_err:
Sachin Bhayare3d3767e2018-01-02 21:10:57 +05303584 extcon_dev_unregister(&hdmi_ctrl->sdev);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303585switch_err:
3586 hdmi_tx_deinit_features(hdmi_ctrl, HDMI_TX_FEAT_MAX);
3587init_err:
3588 hdmi_tx_sysfs_remove(hdmi_ctrl);
3589sysfs_err:
3590 return rc;
3591}
3592
3593static int hdmi_tx_evt_handle_check_param(struct hdmi_tx_ctrl *hdmi_ctrl)
3594{
3595 int new_vic = -1;
3596 int rc = 0;
3597
3598 if (hdmi_ctrl->panel_ops.get_vic)
3599 new_vic = hdmi_ctrl->panel_ops.get_vic(
3600 hdmi_ctrl->evt_arg, &hdmi_ctrl->ds_data);
3601
3602 if ((new_vic < 0) || (new_vic > HDMI_VFRMT_MAX)) {
3603 DEV_ERR("%s: invalid or not supported vic\n", __func__);
3604 goto end;
3605 }
3606
3607 /*
3608 * return value of 1 lets mdss know that panel
3609 * needs a reconfig due to new resolution and
3610 * it will issue close and open subsequently.
3611 */
3612 if (new_vic != hdmi_ctrl->vic) {
3613 rc = 1;
3614 DEV_DBG("%s: res change %d ==> %d\n", __func__,
3615 hdmi_ctrl->vic, new_vic);
3616 }
3617end:
3618 return rc;
3619}
3620
3621static int hdmi_tx_evt_handle_resume(struct hdmi_tx_ctrl *hdmi_ctrl)
3622{
3623 int rc = 0;
3624
3625 hdmi_ctrl->panel_suspend = false;
3626 hdmi_tx_cec_device_suspend(hdmi_ctrl);
3627
3628 if (!hdmi_ctrl->hpd_feature_on)
3629 goto end;
3630
3631 rc = hdmi_tx_hpd_on(hdmi_ctrl);
3632 if (rc) {
3633 DEV_ERR("%s: hpd_on failed. rc=%d\n", __func__, rc);
3634 goto end;
3635 }
3636
3637 if (hdmi_ctrl->sdev.state &&
3638 !hdmi_tx_hw_is_cable_connected(hdmi_ctrl)) {
3639 u32 timeout;
3640
3641 reinit_completion(&hdmi_ctrl->hpd_int_done);
3642 timeout = wait_for_completion_timeout(
3643 &hdmi_ctrl->hpd_int_done, HZ/10);
3644 if (!timeout && !hdmi_ctrl->hpd_state) {
3645 DEV_DBG("%s: cable removed during suspend\n", __func__);
3646 hdmi_tx_set_audio_switch_node(hdmi_ctrl, 0);
3647 hdmi_tx_wait_for_audio_engine(hdmi_ctrl);
3648 hdmi_tx_send_cable_notification(hdmi_ctrl, 0);
3649 }
3650 }
3651end:
3652 return rc;
3653}
3654
3655static int hdmi_tx_evt_handle_reset(struct hdmi_tx_ctrl *hdmi_ctrl)
3656{
3657 if (!hdmi_ctrl->panel_data.panel_info.cont_splash_enabled &&
3658 hdmi_ctrl->hpd_initialized) {
3659 hdmi_tx_set_mode(hdmi_ctrl, false);
3660 hdmi_tx_phy_reset(hdmi_ctrl);
3661 hdmi_tx_set_mode(hdmi_ctrl, true);
3662 }
3663
3664 return 0;
3665}
3666
3667static int hdmi_tx_evt_handle_unblank(struct hdmi_tx_ctrl *hdmi_ctrl)
3668{
3669 int rc;
3670
3671 rc = hdmi_tx_enable_power(hdmi_ctrl, HDMI_TX_DDC_PM, true);
3672 if (rc) {
3673 DEV_ERR("%s: ddc power on failed. rc=%d\n", __func__, rc);
3674 goto end;
3675 }
3676
3677 rc = hdmi_tx_power_on(hdmi_ctrl);
3678 if (rc)
3679 DEV_ERR("%s: hdmi_tx_power_on failed. rc=%d\n", __func__, rc);
3680end:
3681 return rc;
3682}
3683
3684static int hdmi_tx_evt_handle_panel_on(struct hdmi_tx_ctrl *hdmi_ctrl)
3685{
3686 int rc = 0;
3687
3688 if (!hdmi_ctrl->sim_mode) {
3689 hdmi_tx_update_hdcp_info(hdmi_ctrl);
3690
3691 rc = hdmi_tx_start_hdcp(hdmi_ctrl);
3692 if (rc)
3693 DEV_ERR("%s: hdcp start failed rc=%d\n", __func__, rc);
3694 }
3695
3696 hdmi_ctrl->timing_gen_on = true;
3697
3698 if (hdmi_ctrl->panel_suspend) {
3699 DEV_DBG("%s: panel suspend has triggered\n", __func__);
3700
3701 hdmi_tx_set_audio_switch_node(hdmi_ctrl, 0);
3702 hdmi_tx_wait_for_audio_engine(hdmi_ctrl);
3703 hdmi_tx_send_cable_notification(hdmi_ctrl, 0);
3704 }
3705
3706 return rc;
3707}
3708
3709static int hdmi_tx_evt_handle_suspend(struct hdmi_tx_ctrl *hdmi_ctrl)
3710{
3711 if ((!hdmi_ctrl->hpd_feature_on) || (hdmi_ctrl->panel_suspend == true))
3712 goto end;
3713
3714 if ((!hdmi_ctrl->hpd_state && !hdmi_ctrl->panel_power_on) ||
3715 (hdmi_ctrl->hpd_state && !hdmi_ctrl->pdata.pluggable))
3716 hdmi_tx_hpd_off(hdmi_ctrl);
3717
3718 hdmi_ctrl->panel_suspend = true;
3719 hdmi_tx_cec_device_suspend(hdmi_ctrl);
3720end:
3721 return 0;
3722}
3723
3724static int hdmi_tx_evt_handle_blank(struct hdmi_tx_ctrl *hdmi_ctrl)
3725{
3726 if (hdmi_tx_is_hdcp_enabled(hdmi_ctrl))
3727 hdmi_tx_hdcp_off(hdmi_ctrl);
3728
3729 return 0;
3730}
3731
3732static int hdmi_tx_evt_handle_panel_off(struct hdmi_tx_ctrl *hdmi_ctrl)
3733{
3734 int rc;
3735
3736 rc = hdmi_tx_enable_power(hdmi_ctrl, HDMI_TX_DDC_PM, false);
3737 if (rc) {
3738 DEV_ERR("%s: Failed to disable ddc power\n", __func__);
3739 goto end;
3740 }
3741
3742 if (hdmi_ctrl->panel_power_on) {
3743 hdmi_tx_config_avmute(hdmi_ctrl, 1);
3744 rc = hdmi_tx_power_off(hdmi_ctrl);
3745 if (rc)
3746 DEV_ERR("%s: hdmi_tx_power_off failed.rc=%d\n",
3747 __func__, rc);
3748 } else {
3749 DEV_DBG("%s: hdmi_ctrl is already powered off\n", __func__);
3750 }
3751
3752 hdmi_ctrl->timing_gen_on = false;
3753end:
3754 return rc;
3755}
3756
3757static int hdmi_tx_evt_handle_close(struct hdmi_tx_ctrl *hdmi_ctrl)
3758{
3759 if (hdmi_ctrl->hpd_feature_on && hdmi_ctrl->hpd_initialized &&
3760 !hdmi_ctrl->hpd_state)
3761 hdmi_tx_hpd_polarity_setup(hdmi_ctrl, HPD_CONNECT_POLARITY);
3762
3763 return 0;
3764}
3765
3766static int hdmi_tx_event_handler(struct mdss_panel_data *panel_data,
3767 int event, void *arg)
3768{
3769 int rc = 0;
3770 hdmi_tx_evt_handler handler;
3771 struct hdmi_tx_ctrl *hdmi_ctrl =
3772 hdmi_tx_get_drvdata_from_panel_data(panel_data);
3773
3774 if (!hdmi_ctrl) {
3775 DEV_ERR("%s: invalid input\n", __func__);
3776 rc = -EINVAL;
3777 goto end;
3778 }
3779
3780 /* UPDATE FPS is called from atomic context */
3781 if (event == MDSS_EVENT_PANEL_UPDATE_FPS) {
3782 hdmi_ctrl->dynamic_fps = (u32) (unsigned long)arg;
3783 DEV_DBG("%s: fps %d\n", __func__, hdmi_ctrl->dynamic_fps);
3784 queue_work(hdmi_ctrl->workq, &hdmi_ctrl->fps_work);
3785 return rc;
3786 }
3787
3788 mutex_lock(&hdmi_ctrl->tx_lock);
3789
3790 hdmi_ctrl->evt_arg = arg;
3791
3792 DEV_DBG("%s: event = %s suspend=%d, hpd_feature=%d\n", __func__,
3793 hdmi_tx_get_event_name(event), hdmi_ctrl->panel_suspend,
3794 hdmi_ctrl->hpd_feature_on);
3795
3796 handler = hdmi_ctrl->evt_handler[event];
3797 if (handler)
3798 rc = handler(hdmi_ctrl);
3799
3800 mutex_unlock(&hdmi_ctrl->tx_lock);
3801end:
3802 return rc;
3803}
3804
3805static int hdmi_tx_register_panel(struct hdmi_tx_ctrl *hdmi_ctrl)
3806{
3807 int rc = 0;
3808
3809 if (!hdmi_ctrl) {
3810 DEV_ERR("%s: invalid input\n", __func__);
3811 return -EINVAL;
3812 }
3813
3814 hdmi_ctrl->panel_data.event_handler = hdmi_tx_event_handler;
3815
3816 if (!hdmi_ctrl->pdata.primary)
3817 hdmi_ctrl->vic = DEFAULT_VIDEO_RESOLUTION;
3818
3819 rc = hdmi_tx_init_panel_info(hdmi_ctrl);
3820 if (rc) {
3821 DEV_ERR("%s: hdmi_init_panel_info failed\n", __func__);
3822 return rc;
3823 }
3824
3825 rc = mdss_register_panel(hdmi_ctrl->pdev, &hdmi_ctrl->panel_data);
3826 if (rc) {
3827 DEV_ERR("%s: FAILED: to register HDMI panel\n", __func__);
3828 return rc;
3829 }
3830
3831 rc = hdmi_ctrl->mdss_util->register_irq(&hdmi_tx_hw);
3832 if (rc)
3833 DEV_ERR("%s: mdss_register_irq failed.\n", __func__);
3834
3835 return rc;
3836} /* hdmi_tx_register_panel */
3837
3838static void hdmi_tx_deinit_resource(struct hdmi_tx_ctrl *hdmi_ctrl)
3839{
3840 int i;
3841
3842 if (!hdmi_ctrl) {
3843 DEV_ERR("%s: invalid input\n", __func__);
3844 return;
3845 }
3846
3847 /* VREG & CLK */
3848 for (i = HDMI_TX_MAX_PM - 1; i >= 0; i--) {
3849 if (hdmi_tx_config_power(hdmi_ctrl, i, 0))
3850 DEV_ERR("%s: '%s' power deconfig fail\n",
3851 __func__, hdmi_tx_pm_name(i));
3852 }
3853
3854 /* IO */
3855 for (i = HDMI_TX_MAX_IO - 1; i >= 0; i--) {
3856 if (hdmi_ctrl->pdata.io[i].base)
Sachin Bhayare5076e252018-01-18 14:56:45 +05303857 msm_mdss_iounmap(&hdmi_ctrl->pdata.io[i]);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303858 }
3859} /* hdmi_tx_deinit_resource */
3860
3861static int hdmi_tx_init_resource(struct hdmi_tx_ctrl *hdmi_ctrl)
3862{
3863 int i, rc = 0;
3864 struct hdmi_tx_platform_data *pdata = NULL;
3865
3866 if (!hdmi_ctrl) {
3867 DEV_ERR("%s: invalid input\n", __func__);
3868 return -EINVAL;
3869 }
3870
3871 pdata = &hdmi_ctrl->pdata;
3872
3873 hdmi_tx_pinctrl_init(hdmi_ctrl->pdev);
3874
3875 /* IO */
3876 for (i = 0; i < HDMI_TX_MAX_IO; i++) {
Sachin Bhayare5076e252018-01-18 14:56:45 +05303877 rc = msm_mdss_ioremap_byname(hdmi_ctrl->pdev, &pdata->io[i],
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303878 hdmi_tx_io_name(i));
3879 if (rc) {
3880 DEV_DBG("%s: '%s' remap failed or not available\n",
3881 __func__, hdmi_tx_io_name(i));
3882 }
3883 DEV_INFO("%s: '%s': start = 0x%pK, len=0x%x\n", __func__,
3884 hdmi_tx_io_name(i), pdata->io[i].base,
3885 pdata->io[i].len);
3886 }
3887
3888 /* VREG & CLK */
3889 for (i = 0; i < HDMI_TX_MAX_PM; i++) {
3890 rc = hdmi_tx_config_power(hdmi_ctrl, i, 1);
3891 if (rc) {
3892 DEV_ERR("%s: '%s' power config failed.rc=%d\n",
3893 __func__, hdmi_tx_pm_name(i), rc);
3894 goto error;
3895 }
3896 }
3897
3898 return rc;
3899
3900error:
3901 hdmi_tx_deinit_resource(hdmi_ctrl);
3902 return rc;
3903} /* hdmi_tx_init_resource */
3904
3905static void hdmi_tx_put_dt_clk_data(struct device *dev,
Sachin Bhayare5076e252018-01-18 14:56:45 +05303906 struct mdss_module_power *module_power)
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303907{
3908 if (!module_power) {
3909 DEV_ERR("%s: invalid input\n", __func__);
3910 return;
3911 }
3912
3913 if (module_power->clk_config) {
3914 devm_kfree(dev, module_power->clk_config);
3915 module_power->clk_config = NULL;
3916 }
3917 module_power->num_clk = 0;
3918} /* hdmi_tx_put_dt_clk_data */
3919
3920/* todo: once clk are moved to device tree then change this implementation */
3921static int hdmi_tx_get_dt_clk_data(struct device *dev,
Sachin Bhayare5076e252018-01-18 14:56:45 +05303922 struct mdss_module_power *mp, u32 module_type)
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303923{
3924 int rc = 0;
3925
3926 if (!dev || !mp) {
3927 DEV_ERR("%s: invalid input\n", __func__);
3928 return -EINVAL;
3929 }
3930
3931 DEV_DBG("%s: module: '%s'\n", __func__, hdmi_tx_pm_name(module_type));
3932
3933 switch (module_type) {
3934 case HDMI_TX_HPD_PM:
3935 mp->num_clk = 4;
Sachin Bhayare5076e252018-01-18 14:56:45 +05303936 mp->clk_config = devm_kzalloc(dev, sizeof(struct mdss_clk) *
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303937 mp->num_clk, GFP_KERNEL);
3938 if (!mp->clk_config) {
3939 DEV_ERR("%s: can't alloc '%s' clk mem\n", __func__,
3940 hdmi_tx_pm_name(module_type));
3941 goto error;
3942 }
3943
3944 snprintf(mp->clk_config[0].clk_name, 32, "%s", "iface_clk");
3945 mp->clk_config[0].type = DSS_CLK_AHB;
3946 mp->clk_config[0].rate = 0;
3947
3948 snprintf(mp->clk_config[1].clk_name, 32, "%s", "core_clk");
3949 mp->clk_config[1].type = DSS_CLK_OTHER;
3950 mp->clk_config[1].rate = 19200000;
3951
3952 /*
3953 * This clock is required to clock MDSS interrupt registers
3954 * when HDMI is the only block turned on within MDSS. Since
3955 * rate for this clock is controlled by MDP driver, treat this
3956 * similar to AHB clock and do not set rate for it.
3957 */
3958 snprintf(mp->clk_config[2].clk_name, 32, "%s", "mdp_core_clk");
3959 mp->clk_config[2].type = DSS_CLK_AHB;
3960 mp->clk_config[2].rate = 0;
3961
3962 snprintf(mp->clk_config[3].clk_name, 32, "%s", "alt_iface_clk");
3963 mp->clk_config[3].type = DSS_CLK_AHB;
3964 mp->clk_config[3].rate = 0;
3965 break;
3966
3967 case HDMI_TX_CORE_PM:
3968 mp->num_clk = 1;
Sachin Bhayare5076e252018-01-18 14:56:45 +05303969 mp->clk_config = devm_kzalloc(dev, sizeof(struct mdss_clk) *
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303970 mp->num_clk, GFP_KERNEL);
3971 if (!mp->clk_config) {
3972 DEV_ERR("%s: can't alloc '%s' clk mem\n", __func__,
3973 hdmi_tx_pm_name(module_type));
3974 goto error;
3975 }
3976
3977 snprintf(mp->clk_config[0].clk_name, 32, "%s", "extp_clk");
3978 mp->clk_config[0].type = DSS_CLK_PCLK;
3979 /* This rate will be overwritten when core is powered on */
3980 mp->clk_config[0].rate = 148500000;
3981 break;
3982
3983 case HDMI_TX_DDC_PM:
3984 case HDMI_TX_CEC_PM:
3985 mp->num_clk = 0;
3986 DEV_DBG("%s: no clk\n", __func__);
3987 break;
3988
3989 default:
3990 DEV_ERR("%s: invalid module type=%d\n", __func__,
3991 module_type);
3992 return -EINVAL;
3993 }
3994
3995 return rc;
3996
3997error:
3998 if (mp->clk_config) {
3999 devm_kfree(dev, mp->clk_config);
4000 mp->clk_config = NULL;
4001 }
4002 mp->num_clk = 0;
4003
4004 return rc;
4005} /* hdmi_tx_get_dt_clk_data */
4006
4007static void hdmi_tx_put_dt_vreg_data(struct device *dev,
Sachin Bhayare5076e252018-01-18 14:56:45 +05304008 struct mdss_module_power *module_power)
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304009{
4010 if (!module_power) {
4011 DEV_ERR("%s: invalid input\n", __func__);
4012 return;
4013 }
4014
4015 if (module_power->vreg_config) {
4016 devm_kfree(dev, module_power->vreg_config);
4017 module_power->vreg_config = NULL;
4018 }
4019 module_power->num_vreg = 0;
4020} /* hdmi_tx_put_dt_vreg_data */
4021
4022static int hdmi_tx_get_dt_vreg_data(struct device *dev,
Sachin Bhayare5076e252018-01-18 14:56:45 +05304023 struct mdss_module_power *mp, u32 module_type)
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304024{
4025 int i, j, rc = 0;
4026 int dt_vreg_total = 0, mod_vreg_total = 0;
4027 u32 ndx_mask = 0;
4028 u32 *val_array = NULL;
4029 const char *mod_name = NULL;
4030 struct device_node *of_node = NULL;
4031
4032 if (!dev || !mp) {
4033 DEV_ERR("%s: invalid input\n", __func__);
4034 return -EINVAL;
4035 }
4036
4037 switch (module_type) {
4038 case HDMI_TX_HPD_PM:
4039 mod_name = "hpd";
4040 break;
4041 case HDMI_TX_DDC_PM:
4042 mod_name = "ddc";
4043 break;
4044 case HDMI_TX_CORE_PM:
4045 mod_name = "core";
4046 break;
4047 case HDMI_TX_CEC_PM:
4048 mod_name = "cec";
4049 break;
4050 default:
4051 DEV_ERR("%s: invalid module type=%d\n", __func__,
4052 module_type);
4053 return -EINVAL;
4054 }
4055
4056 DEV_DBG("%s: module: '%s'\n", __func__, hdmi_tx_pm_name(module_type));
4057
4058 of_node = dev->of_node;
4059
4060 dt_vreg_total = of_property_count_strings(of_node, "qcom,supply-names");
4061 if (dt_vreg_total < 0) {
4062 DEV_ERR("%s: vreg not found. rc=%d\n", __func__,
4063 dt_vreg_total);
4064 rc = dt_vreg_total;
4065 goto error;
4066 }
4067
4068 /* count how many vreg for particular hdmi module */
4069 for (i = 0; i < dt_vreg_total; i++) {
4070 const char *st = NULL;
4071
4072 rc = of_property_read_string_index(of_node,
4073 "qcom,supply-names", i, &st);
4074 if (rc) {
4075 DEV_ERR("%s: error reading name. i=%d, rc=%d\n",
4076 __func__, i, rc);
4077 goto error;
4078 }
4079
4080 if (strnstr(st, mod_name, strlen(st))) {
4081 ndx_mask |= BIT(i);
4082 mod_vreg_total++;
4083 }
4084 }
4085
4086 if (mod_vreg_total > 0) {
4087 mp->num_vreg = mod_vreg_total;
Sachin Bhayare5076e252018-01-18 14:56:45 +05304088 mp->vreg_config = devm_kzalloc(dev, sizeof(struct mdss_vreg) *
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304089 mod_vreg_total, GFP_KERNEL);
4090 if (!mp->vreg_config) {
4091 DEV_ERR("%s: can't alloc '%s' vreg mem\n", __func__,
4092 hdmi_tx_pm_name(module_type));
4093 goto error;
4094 }
4095 } else {
4096 DEV_DBG("%s: no vreg\n", __func__);
4097 return 0;
4098 }
4099
4100 val_array = devm_kzalloc(dev, sizeof(u32) * dt_vreg_total, GFP_KERNEL);
4101 if (!val_array) {
4102 DEV_ERR("%s: can't allocate vreg scratch mem\n", __func__);
4103 rc = -ENOMEM;
4104 goto error;
4105 }
4106
4107 for (i = 0, j = 0; (i < dt_vreg_total) && (j < mod_vreg_total); i++) {
4108 const char *st = NULL;
4109
4110 if (!(ndx_mask & BIT(0))) {
4111 ndx_mask >>= 1;
4112 continue;
4113 }
4114
4115 /* vreg-name */
4116 rc = of_property_read_string_index(of_node,
4117 "qcom,supply-names", i, &st);
4118 if (rc) {
4119 DEV_ERR("%s: error reading name. i=%d, rc=%d\n",
4120 __func__, i, rc);
4121 goto error;
4122 }
4123 snprintf(mp->vreg_config[j].vreg_name, 32, "%s", st);
4124
4125 /* vreg-min-voltage */
4126 memset(val_array, 0, sizeof(u32) * dt_vreg_total);
4127 rc = of_property_read_u32_array(of_node,
4128 "qcom,min-voltage-level", val_array,
4129 dt_vreg_total);
4130 if (rc) {
4131 DEV_ERR("%s: error read '%s' min volt. rc=%d\n",
4132 __func__, hdmi_tx_pm_name(module_type), rc);
4133 goto error;
4134 }
4135 mp->vreg_config[j].min_voltage = val_array[i];
4136
4137 /* vreg-max-voltage */
4138 memset(val_array, 0, sizeof(u32) * dt_vreg_total);
4139 rc = of_property_read_u32_array(of_node,
4140 "qcom,max-voltage-level", val_array,
4141 dt_vreg_total);
4142 if (rc) {
4143 DEV_ERR("%s: error read '%s' max volt. rc=%d\n",
4144 __func__, hdmi_tx_pm_name(module_type), rc);
4145 goto error;
4146 }
4147 mp->vreg_config[j].max_voltage = val_array[i];
4148
4149 /* vreg-op-mode */
4150 memset(val_array, 0, sizeof(u32) * dt_vreg_total);
4151 rc = of_property_read_u32_array(of_node,
4152 "qcom,enable-load", val_array,
4153 dt_vreg_total);
4154 if (rc) {
4155 DEV_ERR("%s: error read '%s' enable load. rc=%d\n",
4156 __func__, hdmi_tx_pm_name(module_type), rc);
4157 goto error;
4158 }
4159 mp->vreg_config[j].load[DSS_REG_MODE_ENABLE] = val_array[i];
4160
4161 memset(val_array, 0, sizeof(u32) * dt_vreg_total);
4162 rc = of_property_read_u32_array(of_node,
4163 "qcom,disable-load", val_array,
4164 dt_vreg_total);
4165 if (rc) {
4166 DEV_ERR("%s: error read '%s' disable load. rc=%d\n",
4167 __func__, hdmi_tx_pm_name(module_type), rc);
4168 goto error;
4169 }
4170 mp->vreg_config[j].load[DSS_REG_MODE_DISABLE] = val_array[i];
4171
4172 DEV_DBG("%s: %s min=%d, max=%d, enable=%d disable=%d\n",
4173 __func__,
4174 mp->vreg_config[j].vreg_name,
4175 mp->vreg_config[j].min_voltage,
4176 mp->vreg_config[j].max_voltage,
4177 mp->vreg_config[j].load[DSS_REG_MODE_ENABLE],
4178 mp->vreg_config[j].load[DSS_REG_MODE_DISABLE]);
4179
4180 ndx_mask >>= 1;
4181 j++;
4182 }
4183
4184 devm_kfree(dev, val_array);
4185
4186 return rc;
4187
4188error:
4189 if (mp->vreg_config) {
4190 devm_kfree(dev, mp->vreg_config);
4191 mp->vreg_config = NULL;
4192 }
4193 mp->num_vreg = 0;
4194
4195 if (val_array)
4196 devm_kfree(dev, val_array);
4197 return rc;
4198} /* hdmi_tx_get_dt_vreg_data */
4199
4200static void hdmi_tx_put_dt_gpio_data(struct device *dev,
Sachin Bhayare5076e252018-01-18 14:56:45 +05304201 struct mdss_module_power *module_power)
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304202{
4203 if (!module_power) {
4204 DEV_ERR("%s: invalid input\n", __func__);
4205 return;
4206 }
4207
4208 if (module_power->gpio_config) {
4209 devm_kfree(dev, module_power->gpio_config);
4210 module_power->gpio_config = NULL;
4211 }
4212 module_power->num_gpio = 0;
4213} /* hdmi_tx_put_dt_gpio_data */
4214
4215static int hdmi_tx_get_dt_gpio_data(struct device *dev,
Sachin Bhayare5076e252018-01-18 14:56:45 +05304216 struct mdss_module_power *mp, u32 module_type)
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304217{
4218 int i, j;
4219 int mp_gpio_cnt = 0, gpio_list_size = 0;
Sachin Bhayare5076e252018-01-18 14:56:45 +05304220 struct mdss_gpio *gpio_list = NULL;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304221 struct device_node *of_node = NULL;
4222
4223 DEV_DBG("%s: module: '%s'\n", __func__, hdmi_tx_pm_name(module_type));
4224
4225 if (!dev || !mp) {
4226 DEV_ERR("%s: invalid input\n", __func__);
4227 return -EINVAL;
4228 }
4229
4230 of_node = dev->of_node;
4231
4232 switch (module_type) {
4233 case HDMI_TX_HPD_PM:
4234 gpio_list_size = ARRAY_SIZE(hpd_gpio_config);
4235 gpio_list = hpd_gpio_config;
4236 break;
4237 case HDMI_TX_DDC_PM:
4238 gpio_list_size = ARRAY_SIZE(ddc_gpio_config);
4239 gpio_list = ddc_gpio_config;
4240 break;
4241 case HDMI_TX_CORE_PM:
4242 gpio_list_size = ARRAY_SIZE(core_gpio_config);
4243 gpio_list = core_gpio_config;
4244 break;
4245 case HDMI_TX_CEC_PM:
4246 gpio_list_size = ARRAY_SIZE(cec_gpio_config);
4247 gpio_list = cec_gpio_config;
4248 break;
4249 default:
4250 DEV_ERR("%s: invalid module type=%d\n", __func__,
4251 module_type);
4252 return -EINVAL;
4253 }
4254
4255 for (i = 0; i < gpio_list_size; i++)
4256 if (of_find_property(of_node, gpio_list[i].gpio_name, NULL))
4257 mp_gpio_cnt++;
4258
4259 if (!mp_gpio_cnt) {
4260 DEV_DBG("%s: no gpio\n", __func__);
4261 return 0;
4262 }
4263
4264 DEV_DBG("%s: mp_gpio_cnt = %d\n", __func__, mp_gpio_cnt);
4265 mp->num_gpio = mp_gpio_cnt;
4266
Sachin Bhayare5076e252018-01-18 14:56:45 +05304267 mp->gpio_config = devm_kzalloc(dev, sizeof(struct mdss_gpio) *
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304268 mp_gpio_cnt, GFP_KERNEL);
4269 if (!mp->gpio_config) {
4270 DEV_ERR("%s: can't alloc '%s' gpio mem\n", __func__,
4271 hdmi_tx_pm_name(module_type));
4272
4273 mp->num_gpio = 0;
4274 return -ENOMEM;
4275 }
4276
4277 for (i = 0, j = 0; i < gpio_list_size; i++) {
4278 int gpio = of_get_named_gpio(of_node,
4279 gpio_list[i].gpio_name, 0);
4280 if (gpio < 0) {
4281 DEV_DBG("%s: no gpio named %s\n", __func__,
4282 gpio_list[i].gpio_name);
4283 continue;
4284 }
4285 memcpy(&mp->gpio_config[j], &gpio_list[i],
Sachin Bhayare5076e252018-01-18 14:56:45 +05304286 sizeof(struct mdss_gpio));
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304287
4288 mp->gpio_config[j].gpio = (unsigned int)gpio;
4289
4290 DEV_DBG("%s: gpio num=%d, name=%s, value=%d\n",
4291 __func__, mp->gpio_config[j].gpio,
4292 mp->gpio_config[j].gpio_name,
4293 mp->gpio_config[j].value);
4294 j++;
4295 }
4296
4297 return 0;
4298} /* hdmi_tx_get_dt_gpio_data */
4299
4300static void hdmi_tx_put_dt_data(struct device *dev,
4301 struct hdmi_tx_platform_data *pdata)
4302{
4303 int i;
4304
4305 if (!dev || !pdata) {
4306 DEV_ERR("%s: invalid input\n", __func__);
4307 return;
4308 }
4309
4310 for (i = HDMI_TX_MAX_PM - 1; i >= 0; i--)
4311 hdmi_tx_put_dt_clk_data(dev, &pdata->power_data[i]);
4312
4313 for (i = HDMI_TX_MAX_PM - 1; i >= 0; i--)
4314 hdmi_tx_put_dt_vreg_data(dev, &pdata->power_data[i]);
4315
4316 for (i = HDMI_TX_MAX_PM - 1; i >= 0; i--)
4317 hdmi_tx_put_dt_gpio_data(dev, &pdata->power_data[i]);
4318} /* hdmi_tx_put_dt_data */
4319
4320static int hdmi_tx_get_dt_data(struct platform_device *pdev,
4321 struct hdmi_tx_platform_data *pdata)
4322{
4323 int i, rc = 0, len = 0;
4324 struct device_node *of_node = NULL;
4325 struct hdmi_tx_ctrl *hdmi_ctrl = platform_get_drvdata(pdev);
4326 const char *data;
4327
4328 if (!pdev || !pdata) {
4329 DEV_ERR("%s: invalid input\n", __func__);
4330 return -EINVAL;
4331 }
4332
4333 of_node = pdev->dev.of_node;
4334
4335 rc = of_property_read_u32(of_node, "cell-index", &pdev->id);
4336 if (rc) {
4337 DEV_ERR("%s: dev id from dt not found.rc=%d\n",
4338 __func__, rc);
4339 goto error;
4340 }
4341 DEV_DBG("%s: id=%d\n", __func__, pdev->id);
4342
4343 /* GPIO */
4344 for (i = 0; i < HDMI_TX_MAX_PM; i++) {
4345 rc = hdmi_tx_get_dt_gpio_data(&pdev->dev,
4346 &pdata->power_data[i], i);
4347 if (rc) {
4348 DEV_ERR("%s: '%s' get_dt_gpio_data failed.rc=%d\n",
4349 __func__, hdmi_tx_pm_name(i), rc);
4350 goto error;
4351 }
4352 }
4353
4354 /* VREG */
4355 for (i = 0; i < HDMI_TX_MAX_PM; i++) {
4356 rc = hdmi_tx_get_dt_vreg_data(&pdev->dev,
4357 &pdata->power_data[i], i);
4358 if (rc) {
4359 DEV_ERR("%s: '%s' get_dt_vreg_data failed.rc=%d\n",
4360 __func__, hdmi_tx_pm_name(i), rc);
4361 goto error;
4362 }
4363 }
4364
4365 /* CLK */
4366 for (i = 0; i < HDMI_TX_MAX_PM; i++) {
4367 rc = hdmi_tx_get_dt_clk_data(&pdev->dev,
4368 &pdata->power_data[i], i);
4369 if (rc) {
4370 DEV_ERR("%s: '%s' get_dt_clk_data failed.rc=%d\n",
4371 __func__, hdmi_tx_pm_name(i), rc);
4372 goto error;
4373 }
4374 }
4375
4376 if (!hdmi_ctrl->pdata.primary)
4377 hdmi_ctrl->pdata.primary = of_property_read_bool(
4378 pdev->dev.of_node, "qcom,primary_panel");
4379
4380 pdata->cond_power_on = of_property_read_bool(pdev->dev.of_node,
4381 "qcom,conditional-power-on");
4382
4383 pdata->pluggable = of_property_read_bool(pdev->dev.of_node,
4384 "qcom,pluggable");
4385
4386 data = of_get_property(pdev->dev.of_node, "qcom,display-id", &len);
4387 if (!data || len <= 0)
4388 pr_err("%s:%d Unable to read qcom,display-id, data=%pK,len=%d\n",
4389 __func__, __LINE__, data, len);
4390 else
4391 snprintf(hdmi_ctrl->panel_data.panel_info.display_id,
4392 MDSS_DISPLAY_ID_MAX_LEN, "%s", data);
4393
4394 return rc;
4395
4396error:
4397 hdmi_tx_put_dt_data(&pdev->dev, pdata);
4398 return rc;
4399} /* hdmi_tx_get_dt_data */
4400
4401static int hdmi_tx_init_event_handler(struct hdmi_tx_ctrl *hdmi_ctrl)
4402{
4403 hdmi_tx_evt_handler *handler;
4404
4405 if (!hdmi_ctrl)
4406 return -EINVAL;
4407
4408 handler = hdmi_ctrl->evt_handler;
4409
4410 handler[MDSS_EVENT_FB_REGISTERED] = hdmi_tx_evt_handle_register;
4411 handler[MDSS_EVENT_CHECK_PARAMS] = hdmi_tx_evt_handle_check_param;
4412 handler[MDSS_EVENT_RESUME] = hdmi_tx_evt_handle_resume;
4413 handler[MDSS_EVENT_RESET] = hdmi_tx_evt_handle_reset;
4414 handler[MDSS_EVENT_UNBLANK] = hdmi_tx_evt_handle_unblank;
4415 handler[MDSS_EVENT_PANEL_ON] = hdmi_tx_evt_handle_panel_on;
4416 handler[MDSS_EVENT_SUSPEND] = hdmi_tx_evt_handle_suspend;
4417 handler[MDSS_EVENT_BLANK] = hdmi_tx_evt_handle_blank;
4418 handler[MDSS_EVENT_PANEL_OFF] = hdmi_tx_evt_handle_panel_off;
4419 handler[MDSS_EVENT_CLOSE] = hdmi_tx_evt_handle_close;
4420
4421 return 0;
4422}
4423
4424static int hdmi_tx_probe(struct platform_device *pdev)
4425{
4426 int rc = 0, i;
4427 struct device_node *of_node = pdev->dev.of_node;
4428 struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
4429 struct mdss_panel_cfg *pan_cfg = NULL;
4430
4431 if (!of_node) {
4432 DEV_ERR("%s: FAILED: of_node not found\n", __func__);
4433 rc = -ENODEV;
4434 return rc;
4435 }
4436
4437 hdmi_ctrl = devm_kzalloc(&pdev->dev, sizeof(*hdmi_ctrl), GFP_KERNEL);
4438 if (!hdmi_ctrl) {
4439 DEV_ERR("%s: FAILED: cannot alloc hdmi tx ctrl\n", __func__);
4440 rc = -ENOMEM;
4441 goto failed_no_mem;
4442 }
4443
4444 hdmi_ctrl->mdss_util = mdss_get_util_intf();
4445 if (hdmi_ctrl->mdss_util == NULL) {
4446 pr_err("Failed to get mdss utility functions\n");
4447 rc = -ENODEV;
4448 goto failed_dt_data;
4449 }
4450
4451 platform_set_drvdata(pdev, hdmi_ctrl);
4452 hdmi_ctrl->pdev = pdev;
4453 hdmi_ctrl->enc_lvl = HDCP_STATE_AUTH_ENC_NONE;
4454
4455 pan_cfg = mdss_panel_intf_type(MDSS_PANEL_INTF_HDMI);
4456 if (IS_ERR(pan_cfg)) {
4457 return PTR_ERR(pan_cfg);
4458 } else if (pan_cfg) {
4459 int vic;
4460
4461 if (kstrtoint(pan_cfg->arg_cfg, 10, &vic) ||
4462 vic <= HDMI_VFRMT_UNKNOWN || vic >= HDMI_VFRMT_MAX)
4463 vic = DEFAULT_HDMI_PRIMARY_RESOLUTION;
4464
4465 hdmi_ctrl->pdata.primary = true;
4466 hdmi_ctrl->vic = vic;
4467 hdmi_ctrl->panel_data.panel_info.is_prim_panel = true;
4468 hdmi_ctrl->panel_data.panel_info.cont_splash_enabled =
4469 hdmi_ctrl->mdss_util->panel_intf_status(DISPLAY_1,
4470 MDSS_PANEL_INTF_HDMI) ? true : false;
4471 }
4472
4473 hdmi_tx_hw.irq_info = mdss_intr_line();
4474 if (hdmi_tx_hw.irq_info == NULL) {
4475 pr_err("Failed to get mdss irq information\n");
4476 return -ENODEV;
4477 }
4478
4479 rc = hdmi_tx_get_dt_data(pdev, &hdmi_ctrl->pdata);
4480 if (rc) {
4481 DEV_ERR("%s: FAILED: parsing device tree data. rc=%d\n",
4482 __func__, rc);
4483 goto failed_dt_data;
4484 }
4485
4486 rc = hdmi_tx_init_resource(hdmi_ctrl);
4487 if (rc) {
4488 DEV_ERR("%s: FAILED: resource init. rc=%d\n",
4489 __func__, rc);
4490 goto failed_res_init;
4491 }
4492
4493 rc = hdmi_tx_get_version(hdmi_ctrl);
4494 if (rc) {
4495 DEV_ERR("%s: FAILED: hdmi_tx_get_version. rc=%d\n",
4496 __func__, rc);
4497 goto failed_reg_panel;
4498 }
4499
4500 rc = hdmi_tx_dev_init(hdmi_ctrl);
4501 if (rc) {
4502 DEV_ERR("%s: FAILED: hdmi_tx_dev_init. rc=%d\n", __func__, rc);
4503 goto failed_dev_init;
4504 }
4505
4506 rc = hdmi_tx_init_event_handler(hdmi_ctrl);
4507 if (rc) {
4508 DEV_ERR("%s: FAILED: hdmi_tx_init_event_handler. rc=%d\n",
4509 __func__, rc);
4510 goto failed_dev_init;
4511 }
4512
4513 rc = hdmi_tx_register_panel(hdmi_ctrl);
4514 if (rc) {
4515 DEV_ERR("%s: FAILED: register_panel. rc=%d\n", __func__, rc);
4516 goto failed_reg_panel;
4517 }
4518
4519 rc = of_platform_populate(of_node, NULL, NULL, &pdev->dev);
4520 if (rc) {
4521 DEV_ERR("%s: Failed to add child devices. rc=%d\n",
4522 __func__, rc);
4523 goto failed_reg_panel;
4524 } else {
4525 DEV_DBG("%s: Add child devices.\n", __func__);
4526 }
4527
4528 if (mdss_debug_register_io("hdmi",
4529 &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO], NULL))
4530 DEV_WARN("%s: hdmi_tx debugfs register failed\n", __func__);
4531
4532 if (hdmi_ctrl->panel_data.panel_info.cont_splash_enabled) {
4533 for (i = 0; i < HDMI_TX_MAX_PM; i++) {
Sachin Bhayare5076e252018-01-18 14:56:45 +05304534 msm_mdss_enable_vreg(
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304535 hdmi_ctrl->pdata.power_data[i].vreg_config,
4536 hdmi_ctrl->pdata.power_data[i].num_vreg, 1);
4537
4538 hdmi_tx_pinctrl_set_state(hdmi_ctrl, i, 1);
4539
Sachin Bhayare5076e252018-01-18 14:56:45 +05304540 msm_mdss_enable_gpio(
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304541 hdmi_ctrl->pdata.power_data[i].gpio_config,
4542 hdmi_ctrl->pdata.power_data[i].num_gpio, 1);
4543
Sachin Bhayare5076e252018-01-18 14:56:45 +05304544 msm_mdss_enable_clk(
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304545 hdmi_ctrl->pdata.power_data[i].clk_config,
4546 hdmi_ctrl->pdata.power_data[i].num_clk, 1);
4547
4548 hdmi_ctrl->power_data_enable[i] = true;
4549 }
4550 }
4551
4552 return rc;
4553
4554failed_reg_panel:
4555 hdmi_tx_dev_deinit(hdmi_ctrl);
4556failed_dev_init:
4557 hdmi_tx_deinit_resource(hdmi_ctrl);
4558failed_res_init:
4559 hdmi_tx_put_dt_data(&pdev->dev, &hdmi_ctrl->pdata);
4560failed_dt_data:
4561 devm_kfree(&pdev->dev, hdmi_ctrl);
4562failed_no_mem:
4563 return rc;
4564} /* hdmi_tx_probe */
4565
4566static int hdmi_tx_remove(struct platform_device *pdev)
4567{
4568 struct hdmi_tx_ctrl *hdmi_ctrl = platform_get_drvdata(pdev);
4569
4570 if (!hdmi_ctrl) {
4571 DEV_ERR("%s: no driver data\n", __func__);
4572 return -ENODEV;
4573 }
4574
4575 hdmi_tx_sysfs_remove(hdmi_ctrl);
4576 hdmi_tx_dev_deinit(hdmi_ctrl);
4577 hdmi_tx_deinit_resource(hdmi_ctrl);
4578 hdmi_tx_put_dt_data(&pdev->dev, &hdmi_ctrl->pdata);
4579 devm_kfree(&hdmi_ctrl->pdev->dev, hdmi_ctrl);
4580
4581 return 0;
4582} /* hdmi_tx_remove */
4583
4584static const struct of_device_id hdmi_tx_dt_match[] = {
4585 {.compatible = COMPATIBLE_NAME,},
4586 { /* Sentinel */ },
4587};
4588MODULE_DEVICE_TABLE(of, hdmi_tx_dt_match);
4589
4590static struct platform_driver this_driver = {
4591 .probe = hdmi_tx_probe,
4592 .remove = hdmi_tx_remove,
4593 .driver = {
4594 .name = DRV_NAME,
4595 .of_match_table = hdmi_tx_dt_match,
4596 },
4597};
4598
4599static int __init hdmi_tx_drv_init(void)
4600{
4601 int rc;
4602
4603 rc = platform_driver_register(&this_driver);
4604 if (rc)
4605 DEV_ERR("%s: FAILED: rc=%d\n", __func__, rc);
4606
4607 return rc;
4608} /* hdmi_tx_drv_init */
4609
4610static void __exit hdmi_tx_drv_exit(void)
4611{
4612 platform_driver_unregister(&this_driver);
4613} /* hdmi_tx_drv_exit */
4614
4615static int set_hdcp_feature_on(const char *val, const struct kernel_param *kp)
4616{
4617 int rc = 0;
4618
4619 rc = param_set_bool(val, kp);
4620 if (!rc)
4621 pr_debug("%s: HDCP feature = %d\n", __func__, hdcp_feature_on);
4622
4623 return rc;
4624}
4625
4626static struct kernel_param_ops hdcp_feature_on_param_ops = {
4627 .set = set_hdcp_feature_on,
4628 .get = param_get_bool,
4629};
4630
4631module_param_cb(hdcp, &hdcp_feature_on_param_ops, &hdcp_feature_on,
4632 0644);
4633MODULE_PARM_DESC(hdcp, "Enable or Disable HDCP");
4634
4635module_init(hdmi_tx_drv_init);
4636module_exit(hdmi_tx_drv_exit);
4637
4638MODULE_LICENSE("GPL v2");
4639MODULE_DESCRIPTION("HDMI MSM TX driver");