static int hdmi_core_ddc_init(struct hdmi_core_data *core) { void __iomem *base = core->base; /* Turn on CLK for DDC */ REG_FLD_MOD(base, HDMI_CORE_AV_DPD, 0x7, 2, 0); /* IN_PROG */ if (REG_GET(base, HDMI_CORE_DDC_STATUS, 4, 4) == 1) { /* Abort transaction */ REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0xf, 3, 0); /* IN_PROG */ if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS, 4, 4, 0) != 0) { DSSERR("Timeout aborting DDC transaction\n"); return -ETIMEDOUT; } } /* Clk SCL Devices */ REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0xA, 3, 0); /* HDMI_CORE_DDC_STATUS_IN_PROG */ if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS, 4, 4, 0) != 0) { DSSERR("Timeout starting SCL clock\n"); return -ETIMEDOUT; } /* Clear FIFO */ REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x9, 3, 0); /* HDMI_CORE_DDC_STATUS_IN_PROG */ if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS, 4, 4, 0) != 0) { DSSERR("Timeout clearing DDC fifo\n"); return -ETIMEDOUT; } return 0; }
/* PLL_PWR_CMD */ int hdmi_wp_set_pll_pwr(struct hdmi_wp_data *wp, enum hdmi_pll_pwr val) { /* Command for power control of HDMI PLL */ REG_FLD_MOD(wp->base, HDMI_WP_PWR_CTRL, val, 3, 2); /* wait till PHY_PWR_STATUS is set */ if (hdmi_wait_for_bit_change(wp->base, HDMI_WP_PWR_CTRL, 1, 0, val) != val) { DSSERR("Failed to set PLL_PWR_STATUS\n"); return -ETIMEDOUT; } return 0; }
static int hdmi_pll_reset(struct hdmi_pll_data *pll) { /* SYSRESET controlled by power FSM */ REG_FLD_MOD(pll->base, PLLCTRL_PLL_CONTROL, pll_feat->sys_reset, 3, 3); /* READ 0x0 reset is in progress */ if (hdmi_wait_for_bit_change(pll->base, PLLCTRL_PLL_STATUS, 0, 0, 1) != 1) { DSSERR("Failed to sysreset PLL\n"); return -ETIMEDOUT; } return 0; }
/* PHY_PWR_CMD */ int hdmi_wp_set_phy_pwr(struct hdmi_wp_data *wp, enum hdmi_phy_pwr val) { /* Return if already the state */ if (REG_GET(wp->base, HDMI_WP_PWR_CTRL, 5, 4) == val) return 0; /* Command for power control of HDMI PHY */ REG_FLD_MOD(wp->base, HDMI_WP_PWR_CTRL, val, 7, 6); /* Status of the power control of HDMI PHY */ if (hdmi_wait_for_bit_change(wp->base, HDMI_WP_PWR_CTRL, 5, 4, val) != val) { DSSERR("Failed to set PHY power mode to %d\n", val); return -ETIMEDOUT; } return 0; }
static int hdmi_core_ddc_edid(struct hdmi_core_data *core, u8 *pedid, int ext) { void __iomem *base = core->base; u32 i; char checksum; u32 offset = 0; /* HDMI_CORE_DDC_STATUS_IN_PROG */ if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS, 4, 4, 0) != 0) { DSSERR("Timeout waiting DDC to be ready\n"); return -ETIMEDOUT; } if (ext % 2 != 0) offset = 0x80; /* Load Segment Address Register */ REG_FLD_MOD(base, HDMI_CORE_DDC_SEGM, ext / 2, 7, 0); /* Load Slave Address Register */ REG_FLD_MOD(base, HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1); /* Load Offset Address Register */ REG_FLD_MOD(base, HDMI_CORE_DDC_OFFSET, offset, 7, 0); /* Load Byte Count */ REG_FLD_MOD(base, HDMI_CORE_DDC_COUNT1, 0x80, 7, 0); REG_FLD_MOD(base, HDMI_CORE_DDC_COUNT2, 0x0, 1, 0); /* Set DDC_CMD */ if (ext) REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x4, 3, 0); else REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x2, 3, 0); /* HDMI_CORE_DDC_STATUS_BUS_LOW */ if (REG_GET(base, HDMI_CORE_DDC_STATUS, 6, 6) == 1) { DSSERR("I2C Bus Low?\n"); return -EIO; } /* HDMI_CORE_DDC_STATUS_NO_ACK */ if (REG_GET(base, HDMI_CORE_DDC_STATUS, 5, 5) == 1) { DSSERR("I2C No Ack\n"); return -EIO; } for (i = 0; i < 0x80; ++i) { int t; /* IN_PROG */ if (REG_GET(base, HDMI_CORE_DDC_STATUS, 4, 4) == 0) { DSSERR("operation stopped when reading edid\n"); return -EIO; } t = 0; /* FIFO_EMPTY */ while (REG_GET(base, HDMI_CORE_DDC_STATUS, 2, 2) == 1) { if (t++ > 10000) { DSSERR("timeout reading edid\n"); return -ETIMEDOUT; } udelay(1); } pedid[i] = REG_GET(base, HDMI_CORE_DDC_DATA, 7, 0); } checksum = 0; for (i = 0; i < 0x80; ++i) checksum += pedid[i]; if (checksum != 0) { DSSERR("E-EDID checksum failed!!\n"); return -EIO; } return 0; }
static int hdmi_pll_config(struct hdmi_pll_data *pll) { u32 r; struct hdmi_pll_info *fmt = &pll->info; /* PLL start always use manual mode */ REG_FLD_MOD(pll->base, PLLCTRL_PLL_CONTROL, 0x0, 0, 0); r = hdmi_read_reg(pll->base, PLLCTRL_CFG1); r = FLD_MOD(r, fmt->regm, 20, 9); /* CFG1_PLL_REGM */ r = FLD_MOD(r, fmt->regn - 1, 8, 1); /* CFG1_PLL_REGN */ hdmi_write_reg(pll->base, PLLCTRL_CFG1, r); r = hdmi_read_reg(pll->base, PLLCTRL_CFG2); r = FLD_MOD(r, 0x0, 12, 12); /* PLL_HIGHFREQ divide by 2 */ r = FLD_MOD(r, 0x1, 13, 13); /* PLL_REFEN */ r = FLD_MOD(r, 0x0, 14, 14); /* PHY_CLKINEN de-assert during locking */ r = FLD_MOD(r, fmt->refsel, 22, 21); /* REFSEL */ if (fmt->dcofreq) r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */ else r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */ hdmi_write_reg(pll->base, PLLCTRL_CFG2, r); REG_FLD_MOD(pll->base, PLLCTRL_CFG3, fmt->regsd, 17, 10); r = hdmi_read_reg(pll->base, PLLCTRL_CFG4); r = FLD_MOD(r, fmt->regm2, 24, 18); r = FLD_MOD(r, fmt->regmf, 17, 0); hdmi_write_reg(pll->base, PLLCTRL_CFG4, r); /* go now */ REG_FLD_MOD(pll->base, PLLCTRL_PLL_GO, 0x1, 0, 0); /* wait for bit change */ if (hdmi_wait_for_bit_change(pll->base, PLLCTRL_PLL_GO, 0, 0, 0) != 0) { DSSERR("PLL GO bit not clearing\n"); return -ETIMEDOUT; } /* Wait till the lock bit is set in PLL status */ if (hdmi_wait_for_bit_change(pll->base, PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) { DSSERR("cannot lock PLL\n"); DSSERR("CFG1 0x%x\n", hdmi_read_reg(pll->base, PLLCTRL_CFG1)); DSSERR("CFG2 0x%x\n", hdmi_read_reg(pll->base, PLLCTRL_CFG2)); DSSERR("CFG4 0x%x\n", hdmi_read_reg(pll->base, PLLCTRL_CFG4)); return -ETIMEDOUT; } DSSDBG("PLL locked!\n"); return 0; }