config HDMI_RK30
- bool "hdmi support"
+ bool "rk30 hdmi support"
depends on LCDC_RK30
select FB_MODE_HELPERS
# default y
#ifdef CONFIG_HAS_EARLYSUSPEND\r
static void hdmi_early_suspend(struct early_suspend *h)\r
{\r
- hdmi_dbg(hdmi->dev, "hdmi enter early suspend\n");\r
+ hdmi_dbg(hdmi->dev, "hdmi enter early suspend pwr %d state %d\n", hdmi->pwr_mode, hdmi->state);\r
disable_irq(hdmi->irq);\r
hdmi->enable = 0;\r
hdmi->command = HDMI_CONFIG_ENABLE;\r
value = (HDMI_SOURCE_DEFAULT << 14) | (1 << 30);\r
writel(value, GRF_SOC_CON0 + RK30_GRF_BASE);\r
\r
- // internal hclk = hdmi_hclk/32\r
+ // internal hclk = hdmi_hclk/20\r
HDMIWrReg(0x800, 19);\r
}\r
\r
int state; // hdmi state machine status
int autoconfig; // if true, auto config hdmi output mode according to EDID.
int command; // HDMI configuration command
-
+ int display; // HDMI display status
};
extern struct hdmi *hdmi;
break;
}
hdmi->pwr_mode = mode;
- msleep(10);
+ if(mode != PWR_SAVE_MODE_A)
+ msleep(10);
hdmi_dbg(hdmi->dev, "[%s] curmode %02x\n", __FUNCTION__, HDMIRdReg(SYS_CTRL));
}
int value = HDMIRdReg(HPD_MENS_STA);
hdmi_dbg(hdmi->dev, "[%s] value %02x\n", __FUNCTION__, value);
- if( (value & (m_HOTPLUG_STATUS | m_MSEN_STATUS)) == (m_HOTPLUG_STATUS | m_MSEN_STATUS) )
+ value &= m_HOTPLUG_STATUS | m_MSEN_STATUS;
+ if(value == (m_HOTPLUG_STATUS | m_MSEN_STATUS) )
+ return HDMI_HPD_ACTIVED;
+ else if(value)
return HDMI_HPD_INSERT;
else
return HDMI_HPD_REMOVED;
char interrupt = 0, trytime = 2;
hdmi_dbg(hdmi->dev, "[%s] block %d\n", __FUNCTION__, block);
-// disable_irq(hdmi->irq);
spin_lock(&hdmi->irq_lock);
edid_result = 0;
spin_unlock(&hdmi->irq_lock);
HDMIWrReg(DDC_BUS_FREQ_H, (ddc_bus_freq >> 8) & 0xFF);
// Enable edid interrupt
- HDMIMskReg(value, INTR_MASK1, (m_INT_EDID_ERR | m_INT_EDID_READY), (m_INT_EDID_ERR | m_INT_EDID_READY));
-
+ HDMIWrReg(INTR_MASK1, m_INT_HOTPLUG | m_INT_MSENS | m_INT_EDID_ERR | m_INT_EDID_READY);
+
while(trytime--) {
// Config EDID block and segment addr
HDMIWrReg(EDID_WORD_ADDR, (block%2) * 0x80);
{
spin_lock(&hdmi->irq_lock);
interrupt = edid_result;
-// interrupt = HDMIRdReg(INTR_STATUS1);
spin_unlock(&hdmi->irq_lock);
// hdmi_dbg(hdmi->dev, "[%s] interrupt %02x value %d\n", __FUNCTION__, interrupt, value);
if(interrupt & (m_INT_EDID_ERR | m_INT_EDID_READY))
}
// Disable edid interrupt
- HDMIMskReg(value, INTR_MASK1, (m_INT_EDID_ERR|m_INT_EDID_READY), 0);
+ HDMIWrReg(INTR_MASK1, m_INT_HOTPLUG | m_INT_MSENS);
msleep(100);
-// enable_irq(hdmi->irq);
return ret;
}
static void rk30_hdmi_config_phy(unsigned char vic)
{
- hdmi_dbg(hdmi->dev, "[%s] line %d\n", __FUNCTION__, __LINE__);
HDMIWrReg(DEEP_COLOR_MODE, 0x22); // tmds frequency same as input dlck
rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_B);
switch(vic)
}
if(hdmi->pwr_mode == PWR_SAVE_MODE_D)
rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_B);
- if(hdmi->pwr_mode == PWR_SAVE_MODE_B)
+ if(hdmi->pwr_mode == PWR_SAVE_MODE_B && hdmi->state == HDMI_SLEEP)
{
HDMIWrReg(INTR_MASK1, m_INT_HOTPLUG | m_INT_MSENS);
HDMIWrReg(INTR_MASK2, 0);
// HDMI was inserted when system is sleeping, irq was triggered only once
// when wake up. So we need to check hotplug status.
- if((rk30_hdmi_detect_hotplug() == HDMI_HPD_INSERT)) {
+ if(HDMIRdReg(HPD_MENS_STA) & (m_HOTPLUG_STATUS | m_MSEN_STATUS)) {
queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(10));
}
}
{
switch(state)
{
+ case HDMI_SLEEP:
+ dev_printk(KERN_INFO, hdmi->dev, "HDMI_SLEEP\n");
+ break;
case HDMI_INITIAL:
dev_printk(KERN_INFO, hdmi->dev, "HDMI_INITIAL\n");
break;
dev_printk(KERN_INFO, hdmi->dev, "PLAY_BACK\n");
break;
default:
- dev_printk(KERN_INFO, hdmi->dev, "Unkown State\n");
+ dev_printk(KERN_INFO, hdmi->dev, "Unkown State %d\n", state);
break;
}
}
hdmi->state = HDMI_SLEEP;
hdmi->enable = HDMI_ENABLE;
hdmi->autoconfig = HDMI_AUTO_CONFIGURE;
+ hdmi->display = HDMI_DISABLE;
hdmi->vic = HDMI_VIDEO_DEFAULT_MODE;
hdmi->audio.channel = HDMI_AUDIO_DEFAULT_CHANNEL;
void hdmi_sys_remove(void)
{
- rk30_hdmi_removed();
fb_destroy_modelist(&hdmi->edid.modelist);
if(hdmi->edid.audio)
kfree(hdmi->edid.audio);
}
memset(&hdmi->edid, 0, sizeof(struct hdmi_edid));
INIT_LIST_HEAD(&hdmi->edid.modelist);
+ hdmi->display = HDMI_DISABLE;
+}
+
+static void hdmi_sys_sleep(void)
+{
+ if(hdmi->enable)
+ disable_irq(hdmi->irq);
hdmi->state = HDMI_SLEEP;
- hdmi->hotplug = HDMI_HPD_REMOVED;
+ rk30_hdmi_removed();
+ if(hdmi->enable)
+ enable_irq(hdmi->irq);
}
static int hdmi_process_command(void)
{
if(hdmi->hotplug)
hdmi_sys_remove();
+ hdmi->state = HDMI_SLEEP;
+ hdmi->hotplug = HDMI_HPD_REMOVED;
+ rk30_hdmi_removed();
state = HDMI_SLEEP;
}
if(hdmi->wait == 1) {
hotplug = rk30_hdmi_detect_hotplug();
hdmi_dbg(hdmi->dev, "[%s] hotplug %02x curvalue %d\n", __FUNCTION__, hotplug, hdmi->hotplug);
- if(hotplug == HDMI_HPD_REMOVED) {
- hdmi_sys_remove();
- if(hotplug != hdmi->hotplug) {
+ if(hotplug != hdmi->hotplug)
+ {
+ if(hotplug == HDMI_HPD_ACTIVED){
hdmi->hotplug = hotplug;
+ hdmi->state = READ_PARSE_EDID;
+ }
+ else if(hdmi->hotplug == HDMI_HPD_ACTIVED) {
+ hdmi_sys_remove();
+ hdmi->hotplug = hotplug;
+ if(hotplug == HDMI_HPD_REMOVED)
+ hdmi_sys_sleep();
+ else {
+ hdmi->state = WAIT_HOTPLUG;
+ rk30_hdmi_removed();
+ }
+ if(hdmi->wait == 1) {
+ complete(&hdmi->complete);
+ hdmi->wait = 0;
+ }
kobject_uevent_env(&hdmi->dev->kobj, KOBJ_REMOVE, envp);
+ return;
}
- if(hdmi->wait == 1) {
- complete(&hdmi->complete);
- hdmi->wait = 0;
+ else if(hotplug == HDMI_HPD_REMOVED) {
+ hdmi->state = HDMI_SLEEP;
+ rk30_hdmi_removed();
}
- return;
- }
- else if(hotplug != hdmi->hotplug) {
- hdmi->hotplug = hotplug;
- hdmi->state = READ_PARSE_EDID;
}
+ else if(hotplug == HDMI_HPD_REMOVED)
+ hdmi_sys_sleep();
do {
state_last = hdmi->state;
hdmi->state = PLAY_BACK;
break;
case PLAY_BACK:
- rk30_hdmi_control_output(1);
+ if(hdmi->display != HDMI_ENABLE) {
+ rk30_hdmi_control_output(HDMI_ENABLE);
+ hdmi->display = HDMI_ENABLE;
+ }
if(hdmi->wait == 1) {
complete(&hdmi->complete);
hdmi->wait = 0;
if(trytimes == HDMI_MAX_TRY_TIMES)
{
- if(hdmi->hotplug)
+ if(hdmi->hotplug) {
hdmi_sys_remove();
+ hdmi->hotplug = HDMI_HPD_REMOVED;
+ hdmi_sys_sleep();
+
+ }
}
+ hdmi_dbg(hdmi->dev, "[%s] done\n", __FUNCTION__);
}
\ No newline at end of file
// HDMI Hotplug status
enum {
HDMI_HPD_REMOVED = 0,
- HDMI_HPD_INSERT
+ HDMI_HPD_INSERT,
+ HDMI_HPD_ACTIVED
};
/* HDMI STATUS */