aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c')
-rw-r--r--drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c77
1 files changed, 65 insertions, 12 deletions
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
index 9af81f18f163..6847a478b459 100644
--- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
@@ -28,6 +28,7 @@
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/string.h> 29#include <linux/string.h>
30#include <linux/seq_file.h> 30#include <linux/seq_file.h>
31#include <linux/gpio.h>
31 32
32#include "ti_hdmi_4xxx_ip.h" 33#include "ti_hdmi_4xxx_ip.h"
33#include "dss.h" 34#include "dss.h"
@@ -223,6 +224,49 @@ void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data)
223 hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_ALLOFF); 224 hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_ALLOFF);
224} 225}
225 226
227static int hdmi_check_hpd_state(struct hdmi_ip_data *ip_data)
228{
229 unsigned long flags;
230 bool hpd;
231 int r;
232 /* this should be in ti_hdmi_4xxx_ip private data */
233 static DEFINE_SPINLOCK(phy_tx_lock);
234
235 spin_lock_irqsave(&phy_tx_lock, flags);
236
237 hpd = gpio_get_value(ip_data->hpd_gpio);
238
239 if (hpd == ip_data->phy_tx_enabled) {
240 spin_unlock_irqrestore(&phy_tx_lock, flags);
241 return 0;
242 }
243
244 if (hpd)
245 r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON);
246 else
247 r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON);
248
249 if (r) {
250 DSSERR("Failed to %s PHY TX power\n",
251 hpd ? "enable" : "disable");
252 goto err;
253 }
254
255 ip_data->phy_tx_enabled = hpd;
256err:
257 spin_unlock_irqrestore(&phy_tx_lock, flags);
258 return r;
259}
260
261static irqreturn_t hpd_irq_handler(int irq, void *data)
262{
263 struct hdmi_ip_data *ip_data = data;
264
265 hdmi_check_hpd_state(ip_data);
266
267 return IRQ_HANDLED;
268}
269
226int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data) 270int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data)
227{ 271{
228 u16 r = 0; 272 u16 r = 0;
@@ -232,10 +276,6 @@ int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data)
232 if (r) 276 if (r)
233 return r; 277 return r;
234 278
235 r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON);
236 if (r)
237 return r;
238
239 /* 279 /*
240 * Read address 0 in order to get the SCP reset done completed 280 * Read address 0 in order to get the SCP reset done completed
241 * Dummy access performed to make sure reset is done 281 * Dummy access performed to make sure reset is done
@@ -257,12 +297,32 @@ int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data)
257 /* Write to phy address 3 to change the polarity control */ 297 /* Write to phy address 3 to change the polarity control */
258 REG_FLD_MOD(phy_base, HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27); 298 REG_FLD_MOD(phy_base, HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27);
259 299
300 r = request_threaded_irq(gpio_to_irq(ip_data->hpd_gpio),
301 NULL, hpd_irq_handler,
302 IRQF_DISABLED | IRQF_TRIGGER_RISING |
303 IRQF_TRIGGER_FALLING, "hpd", ip_data);
304 if (r) {
305 DSSERR("HPD IRQ request failed\n");
306 hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
307 return r;
308 }
309
310 r = hdmi_check_hpd_state(ip_data);
311 if (r) {
312 free_irq(gpio_to_irq(ip_data->hpd_gpio), ip_data);
313 hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
314 return r;
315 }
316
260 return 0; 317 return 0;
261} 318}
262 319
263void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data) 320void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data)
264{ 321{
322 free_irq(gpio_to_irq(ip_data->hpd_gpio), ip_data);
323
265 hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF); 324 hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
325 ip_data->phy_tx_enabled = false;
266} 326}
267 327
268static int hdmi_core_ddc_init(struct hdmi_ip_data *ip_data) 328static int hdmi_core_ddc_init(struct hdmi_ip_data *ip_data)
@@ -419,14 +479,7 @@ int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data,
419 479
420bool ti_hdmi_4xxx_detect(struct hdmi_ip_data *ip_data) 480bool ti_hdmi_4xxx_detect(struct hdmi_ip_data *ip_data)
421{ 481{
422 int r; 482 return gpio_get_value(ip_data->hpd_gpio);
423
424 void __iomem *base = hdmi_core_sys_base(ip_data);
425
426 /* HPD */
427 r = REG_GET(base, HDMI_CORE_SYS_SYS_STAT, 1, 1);
428
429 return r == 1;
430} 483}
431 484
432static void hdmi_core_init(struct hdmi_core_video_config *video_cfg, 485static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,