enum dw_hdmi_devtype dev_type;
struct clk *vpll_clk;
struct clk *grf_clk;
- struct clk *hdmiphy_pclk;
- struct clk *hdmiphy_clk;
struct clk *hclk_vio;
- struct clk_hw hdmiphy_clkhw;
struct phy *phy;
};
#define to_rockchip_hdmi(x) container_of(x, struct rockchip_hdmi, x)
-/*
- * Inno HDMI phy pre pll output 4 clock: tmdsclock_tx/tmdsclock_ctrl/
- * preclock_ctrl/pclk_vop.
- * tmdsclock_tx is used for transmit hdmi signal, it's is equal to
- * tmdsclock.
- * Ftmdsclock_tx = Fvco / (4 * tmds_div_a * tmds_div_b)
- * tmdsclock_ctrl is output to dw-hdmi controller, it's is equal to
- * tmdsclock.
- * Ftmdsclock_ctrl = Fvco / (4 * tmds_div_a * tmds_div_c)
- * preclock_ctrl is output to dw-hdmi controller, it's equal to mode
- * pixel clock.
- * Fpreclock_ctrl = (pclk_div_a == 1) ?
- * Fvco / (pclk_div_b * pclk_div_c) :
- * Fvco / (pclk_div_a * pclk_div_c) :
- * pclk_vop is clock source of dclk_lcdc, it's equal to mode pixel clock.
- * Fpclk_vop = (vco_div_5 == 1) ? Fvco / 5 : (pclk_div_a == 1) ?
- * Fvco / (2 * pclk_div_b * pclk_div_d) :
- * Fvco / (2 * pclk_div_a * pclk_div_d)
- * Fvco = Fref * (nf + frac / (1 << 24)) / nd
- */
-struct inno_pre_pll_config {
- unsigned long pixclock;
- u32 tmdsclock;
- u8 nd;
- u16 nf;
- u8 tmds_div_a;
- u8 tmds_div_b;
- u8 tmds_div_c;
- u8 pclk_div_a;
- u8 pclk_div_b;
- u8 pclk_div_c;
- u8 pclk_div_d;
- u8 vco_div_5;
- u32 frac;
-};
-
-struct inno_post_pll_config {
- unsigned long tmdsclock;
- u8 nd;
- u16 nf;
- u8 no;
- u8 version;
-};
-
-struct inno_phy_config {
- unsigned long tmdsclock;
- u8 regs[14];
-};
-
-static const struct inno_pre_pll_config inno_pre_pll_cfg[] = {
- {27000000, 27000000, 1, 90, 3, 2,
- 2, 10, 3, 3, 4, 0, 0},
- {27000000, 33750000, 1, 90, 1, 3,
- 3, 10, 3, 3, 4, 0, 0},
- {40000000, 40000000, 1, 80, 2, 2,
- 2, 12, 2, 2, 2, 0, 0},
- {59341000, 59341000, 1, 98, 3, 1,
- 2, 1, 3, 3, 4, 0, 0xE6AE6B},
- {59400000, 59400000, 1, 99, 3, 1,
- 1, 1, 3, 3, 4, 0, 0},
- {59341000, 74176250, 1, 98, 0, 3,
- 3, 1, 3, 3, 4, 0, 0xE6AE6B},
- {59400000, 74250000, 1, 99, 1, 2,
- 2, 1, 3, 3, 4, 0, 0},
- {74176000, 74176000, 1, 98, 1, 2,
- 2, 1, 2, 3, 4, 0, 0xE6AE6B},
- {74250000, 74250000, 1, 99, 1, 2,
- 2, 1, 2, 3, 4, 0, 0},
- {74176000, 92720000, 4, 494, 1, 2,
- 2, 1, 3, 3, 4, 0, 0x816817},
- {74250000, 92812500, 4, 495, 1, 2,
- 2, 1, 3, 3, 4, 0, 0},
- {148352000, 148352000, 1, 98, 1, 1,
- 1, 1, 2, 2, 2, 0, 0xE6AE6B},
- {148500000, 148500000, 1, 99, 1, 1,
- 1, 1, 2, 2, 2, 0, 0},
- {148352000, 185440000, 4, 494, 0, 2,
- 2, 1, 3, 2, 2, 0, 0x816817},
- {148500000, 185625000, 4, 495, 0, 2,
- 2, 1, 3, 2, 2, 0, 0},
- {296703000, 296703000, 1, 98, 0, 1,
- 1, 1, 0, 2, 2, 0, 0xE6AE6B},
- {297000000, 297000000, 1, 99, 0, 1,
- 1, 1, 0, 2, 2, 0, 0},
- {296703000, 370878750, 4, 494, 1, 2,
- 0, 1, 3, 1, 1, 0, 0x816817},
- {297000000, 371250000, 4, 495, 1, 2,
- 0, 1, 3, 1, 1, 0, 0},
- {593407000, 296703500, 1, 98, 0, 1,
- 1, 1, 0, 2, 1, 0, 0xE6AE6B},
- {594000000, 297000000, 1, 99, 0, 1,
- 1, 1, 0, 2, 1, 0, 0},
- {593407000, 370879375, 4, 494, 1, 2,
- 0, 1, 3, 1, 1, 1, 0x816817},
- {594000000, 371250000, 4, 495, 1, 2,
- 0, 1, 3, 1, 1, 1, 0},
- {593407000, 593407000, 1, 98, 0, 2,
- 0, 1, 0, 1, 1, 0, 0xE6AE6B},
- {594000000, 594000000, 1, 99, 0, 2,
- 0, 1, 0, 1, 1, 0, 0},
- {~0UL, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0},
-};
-
-static const struct inno_post_pll_config inno_post_pll_cfg[] = {
- {33750000, 1, 40, 8, 1},
- {33750000, 1, 80, 8, 2},
- {74250000, 1, 40, 8, 1},
- {74250000, 18, 80, 8, 2},
- {148500000, 2, 40, 4, 3},
- {297000000, 4, 40, 2, 3},
- {371250000, 8, 40, 1, 3},
- {~0UL, 0, 0, 0, 0},
-};
-
-static const struct inno_phy_config inno_phy_cfg[] = {
- { 165000000, {
- 0x07, 0x08, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x08,
- 0x00, 0xac, 0xcc, 0xcc, 0xcc,
- },
- }, {
- 340000000, {
- 0x0b, 0x0d, 0x0d, 0x0d, 0x07, 0x15, 0x08, 0x08, 0x08,
- 0x3f, 0xac, 0xcc, 0xcd, 0xdd,
- },
- }, {
- 594000000, {
- 0x10, 0x1a, 0x1a, 0x1a, 0x07, 0x15, 0x08, 0x08, 0x08,
- 0x00, 0xac, 0xcc, 0xcc, 0xcc,
- },
- }, {
- ~0UL, {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- },
- }
-};
-
-static void inno_phy_writel(struct rockchip_hdmi *hdmi, int offset, u8 val)
-{
- writel(val, hdmi->hdmiphy + (offset << 2));
-}
-
-static u8 inno_phy_readl(struct rockchip_hdmi *hdmi, int offset)
-{
- return readl(hdmi->hdmiphy + (offset << 2));
-}
-
-static void
-inno_phy_modeb(struct rockchip_hdmi *hdmi, u8 data, u8 mask, int offset)
-{
- u8 val = inno_phy_readl(hdmi, offset) & ~mask;
-
- val |= data & mask;
- inno_phy_writel(hdmi, offset, val);
-}
-
-static int inno_dw_hdmi_phy_read(struct dw_hdmi *hdmi, void *data, int offset)
-{
- struct rockchip_hdmi *rockchip_hdmi = (struct rockchip_hdmi *)data;
-
- return inno_phy_readl(rockchip_hdmi, offset);
-}
-
-static void
-inno_dw_hdmi_phy_write(struct dw_hdmi *hdmi, void *data, int val, int offset)
-{
- struct rockchip_hdmi *rockchip_hdmi = (struct rockchip_hdmi *)data;
-
- inno_phy_writel(rockchip_hdmi, offset, val);
-}
-
static int
inno_dw_hdmi_phy_init(struct dw_hdmi *dw_hdmi, void *data,
struct drm_display_mode *mode)
{
struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
- const struct inno_post_pll_config *inno_pll_config = inno_post_pll_cfg;
- const struct inno_phy_config *inno_phy_config = inno_phy_cfg;
- u32 val, i, chipversion = 1;
-
- if (hdmi->dev_type == RK3228_HDMI) {
- phy_power_on(hdmi->phy);
- return 0;
- }
-
- if (rockchip_get_cpu_version())
- chipversion = 2;
-
- for (; inno_pll_config->tmdsclock != ~0UL; inno_pll_config++)
- if (inno_pll_config->tmdsclock >= (mode->crtc_clock * 1000) &&
- inno_pll_config->version & chipversion)
- break;
- for (; inno_phy_config->tmdsclock != ~0UL; inno_phy_config++)
- if (inno_phy_config->tmdsclock >= (mode->crtc_clock * 1000))
- break;
- if (inno_pll_config->tmdsclock == ~0UL &&
- inno_phy_config->tmdsclock == ~0UL)
- return -EINVAL;
-
- /* set pdata_en to 0 */
- inno_phy_modeb(hdmi, 0, 1, 0x02);
- /* Power off post PLL */
- inno_phy_modeb(hdmi, 1, 1, 0xaa);
-
- val = inno_pll_config->nf & 0xff;
- inno_phy_writel(hdmi, 0xac, val);
- if (inno_pll_config->no == 1) {
- inno_phy_writel(hdmi, 0xaa, 2);
- val = (inno_pll_config->nf >> 8) |
- inno_pll_config->nd;
- inno_phy_writel(hdmi, 0xab, val);
- } else {
- val = (inno_pll_config->no / 2) - 1;
- inno_phy_writel(hdmi, 0xad, val);
- val = (inno_pll_config->nf >> 8) |
- inno_pll_config->nd;
- inno_phy_writel(hdmi, 0xab, val);
- inno_phy_writel(hdmi, 0xaa, 0x0e);
- }
- for (i = 0; i < 14; i++)
- inno_phy_writel(hdmi, 0xb5 + i, inno_phy_config->regs[i]);
-
- /* bit[7:6] of reg c8/c9/ca/c8 is ESD detect threshold:
- * 00 - 340mV
- * 01 - 280mV
- * 10 - 260mV
- * 11 - 240mV
- * default is 240mV, now we set it to 340mV
- */
- inno_phy_writel(hdmi, 0xc8, 0);
- inno_phy_writel(hdmi, 0xc9, 0);
- inno_phy_writel(hdmi, 0xca, 0);
- inno_phy_writel(hdmi, 0xcb, 0);
-
- if (inno_phy_config->tmdsclock > 340000000) {
- /* Set termination resistor to 100ohm */
- val = clk_get_rate(hdmi->hdmiphy_pclk) / 100000;
- inno_phy_writel(hdmi, 0xc5, ((val >> 8) & 0xff) | 0x80);
- inno_phy_writel(hdmi, 0xc6, val & 0xff);
- inno_phy_writel(hdmi, 0xc7, 3 << 1);
- inno_phy_writel(hdmi, 0xc5, ((val >> 8) & 0xff));
- } else if (inno_phy_config->tmdsclock > 165000000) {
- inno_phy_writel(hdmi, 0xc5, 0x81);
- /* clk termination resistor is 50ohm
- * data termination resistor is 150ohm
- */
- inno_phy_writel(hdmi, 0xc8, 0x30);
- inno_phy_writel(hdmi, 0xc9, 0x10);
- inno_phy_writel(hdmi, 0xca, 0x10);
- inno_phy_writel(hdmi, 0xcb, 0x10);
- } else {
- inno_phy_writel(hdmi, 0xc5, 0x81);
- }
-
- /* Power up post PLL */
- inno_phy_modeb(hdmi, 0, 1, 0xaa);
- /* Power up tmds driver */
- inno_phy_modeb(hdmi, 4, 4, 0xb0);
- inno_phy_writel(hdmi, 0xb2, 0x0f);
-
- /* Wait for post PLL lock */
- for (i = 0; i < 5; ++i) {
- if (inno_phy_readl(hdmi, 0xaf) & 1)
- break;
- usleep_range(1000, 2000);
- }
- if (!(inno_phy_readl(hdmi, 0xaf) & 1)) {
- dev_err(hdmi->dev, "HDMI PHY Post PLL unlock\n");
- return -ETIMEDOUT;
- }
- if (inno_phy_config->tmdsclock > 340000000)
- msleep(100);
- /* set pdata_en to 1 */
- inno_phy_modeb(hdmi, 1, 1, 0x02);
- return 0;
+ return phy_power_on(hdmi->phy);
}
static void inno_dw_hdmi_phy_disable(struct dw_hdmi *dw_hdmi, void *data)
{
struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
- if (hdmi->dev_type == RK3228_HDMI) {
- phy_power_off(hdmi->phy);
- return;
- }
-
- /* Power off driver */
- inno_phy_writel(hdmi, 0xb2, 0);
- /* Power off band gap */
- inno_phy_modeb(hdmi, 0, 4, 0xb0);
- /* Power off post pll */
- inno_phy_modeb(hdmi, 1, 1, 0xaa);
+ phy_power_off(hdmi->phy);
}
static enum drm_connector_status
return status;
}
-static int inno_dw_hdmi_phy_pll_prepare(struct clk_hw *hw)
-{
- struct rockchip_hdmi *hdmi =
- container_of(hw, struct rockchip_hdmi, hdmiphy_clkhw);
-
- if (inno_phy_readl(hdmi, 0xa0) & 1)
- inno_phy_modeb(hdmi, 0, 1, 0xa0);
- return 0;
-}
-
-static void inno_dw_hdmi_phy_pll_unprepare(struct clk_hw *hw)
-{
- struct rockchip_hdmi *hdmi =
- container_of(hw, struct rockchip_hdmi, hdmiphy_clkhw);
-
- if ((inno_phy_readl(hdmi, 0xa0) & 1) == 0)
- inno_phy_modeb(hdmi, 1, 1, 0xa0);
-}
-
-static int inno_dw_hdmi_phy_is_prepared(struct clk_hw *hw)
-{
- struct rockchip_hdmi *hdmi =
- container_of(hw, struct rockchip_hdmi, hdmiphy_clkhw);
-
- return (inno_phy_readl(hdmi, 0xa0) & 1) ? 0 : 1;
-}
-
-static unsigned long
-inno_dw_hdmi_phy_pll_recalc_rate(struct clk_hw *hw,
- unsigned long parent_rate)
-{
- struct rockchip_hdmi *hdmi =
- container_of(hw, struct rockchip_hdmi, hdmiphy_clkhw);
- unsigned long rate, vco, frac;
- u8 nd, no_a, no_b, no_c, no_d;
- u16 nf;
-
- nd = inno_phy_readl(hdmi, 0xa1) & 0x3f;
- nf = ((inno_phy_readl(hdmi, 0xa2) & 0x0f) << 8) |
- inno_phy_readl(hdmi, 0xa3);
- vco = parent_rate * nf;
- if ((inno_phy_readl(hdmi, 0xa2) & 0x30) == 0) {
- frac = inno_phy_readl(hdmi, 0xd3) |
- (inno_phy_readl(hdmi, 0xd2) << 8) |
- (inno_phy_readl(hdmi, 0xd1) << 16);
- vco += DIV_ROUND_CLOSEST(parent_rate * frac, (1 << 24));
- }
- if (inno_phy_readl(hdmi, 0xa0) & 2) {
- rate = vco / (nd * 5);
- } else {
- no_a = inno_phy_readl(hdmi, 0xa5) & 0x1f;
- no_b = ((inno_phy_readl(hdmi, 0xa5) >> 5) & 7) + 2;
- no_c = (1 << ((inno_phy_readl(hdmi, 0xa6) >> 5) & 7));
- no_d = inno_phy_readl(hdmi, 0xa6) & 0x1f;
- if (no_a == 1)
- rate = vco / (nd * no_b * no_d * 2);
- else
- rate = vco / (nd * no_a * no_d * 2);
- }
-
- return rate;
-}
-
-static long
-inno_dw_hdmi_phy_pll_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *parent_rate)
-{
- const struct inno_pre_pll_config *inno_pll_config = inno_pre_pll_cfg;
-
- for (; inno_pll_config->pixclock != ~0UL; inno_pll_config++)
- if (inno_pll_config->pixclock == rate)
- break;
- /* XXX: Limit pixel clock under 300MHz */
- if (inno_pll_config->pixclock < 300000000)
- return inno_pll_config->pixclock;
- else
- return ~0UL;
-}
-
-static int
-inno_dw_hdmi_phy_pll_set_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long parent_rate)
-{
- struct rockchip_hdmi *hdmi =
- container_of(hw, struct rockchip_hdmi, hdmiphy_clkhw);
- const struct inno_pre_pll_config *inno_pll_config = inno_pre_pll_cfg;
- u32 val, i;
-
- for (; inno_pll_config->pixclock != ~0UL; inno_pll_config++)
- if (inno_pll_config->pixclock == rate &&
- inno_pll_config->tmdsclock == rate)
- break;
- if (inno_pll_config->pixclock == ~0UL) {
- dev_err(hdmi->dev, "unsupported rate %lu\n", rate);
- return -EINVAL;
- }
- /* Power off PLL */
- inno_phy_modeb(hdmi, 1, 1, 0xa0);
- /* Configure pre-pll */
- inno_phy_modeb(hdmi, (inno_pll_config->vco_div_5 & 1) << 1, 2, 0xa0);
- inno_phy_writel(hdmi, 0xa1, inno_pll_config->nd);
- if (inno_pll_config->frac)
- val = ((inno_pll_config->nf >> 8) & 0x0f) | 0xc0;
- else
- val = ((inno_pll_config->nf >> 8) & 0x0f) | 0xf0;
- inno_phy_writel(hdmi, 0xa2, val);
- val = inno_pll_config->nf & 0xff;
- inno_phy_writel(hdmi, 0xa3, val);
- val = (inno_pll_config->pclk_div_a & 0x1f) |
- ((inno_pll_config->pclk_div_b & 3) << 5);
- inno_phy_writel(hdmi, 0xa5, val);
- val = (inno_pll_config->pclk_div_d & 0x1f) |
- ((inno_pll_config->pclk_div_c & 3) << 5);
- inno_phy_writel(hdmi, 0xa6, val);
- val = ((inno_pll_config->tmds_div_a & 3) << 4) |
- ((inno_pll_config->tmds_div_b & 3) << 2) |
- (inno_pll_config->tmds_div_c & 3);
- inno_phy_writel(hdmi, 0xa4, val);
-
- if (inno_pll_config->frac) {
- val = inno_pll_config->frac & 0xff;
- inno_phy_writel(hdmi, 0xd3, val);
- val = (inno_pll_config->frac >> 8) & 0xff;
- inno_phy_writel(hdmi, 0xd2, val);
- val = (inno_pll_config->frac >> 16) & 0xff;
- inno_phy_writel(hdmi, 0xd1, val);
- } else {
- inno_phy_writel(hdmi, 0xd3, 0);
- inno_phy_writel(hdmi, 0xd2, 0);
- inno_phy_writel(hdmi, 0xd1, 0);
- }
-
- /* Power up PLL */
- inno_phy_modeb(hdmi, 0, 1, 0xa0);
-
- /* Wait for PLL lock */
- for (i = 0; i < 5; ++i) {
- if (inno_phy_readl(hdmi, 0xa9) & 1)
- break;
- usleep_range(1000, 2000);
- }
- return 0;
-}
-
-static const struct clk_ops inno_dw_hdmi_phy_pll_clk_norate_ops = {
- .prepare = inno_dw_hdmi_phy_pll_prepare,
- .unprepare = inno_dw_hdmi_phy_pll_unprepare,
- .is_prepared = inno_dw_hdmi_phy_is_prepared,
- .recalc_rate = inno_dw_hdmi_phy_pll_recalc_rate,
- .round_rate = inno_dw_hdmi_phy_pll_round_rate,
- .set_rate = inno_dw_hdmi_phy_pll_set_rate,
-};
-
-static void inno_dw_hdmi_phy_clk_unregister(void *data)
-{
- struct rockchip_hdmi *hdmi = data;
-
- of_clk_del_provider(hdmi->dev->of_node);
- clk_unregister(hdmi->hdmiphy_clk);
-}
-
-static int inno_dw_hdmi_phy_clk_register(struct rockchip_hdmi *hdmi)
-{
- struct device_node *node = hdmi->dev->of_node;
- struct clk_init_data init;
- const char *clk_name = "xin24m";
- int ret;
-
- init.flags = 0;
- init.name = "hdmi_phy";
- init.ops = &inno_dw_hdmi_phy_pll_clk_norate_ops;
- init.parent_names = &clk_name;
- init.num_parents = 1;
-
- /* optional override of the clockname */
- of_property_read_string(node, "clock-output-names", &init.name);
-
- hdmi->hdmiphy_clkhw.init = &init;
-
- /* register the clock */
- hdmi->hdmiphy_clk = clk_register(hdmi->dev, &hdmi->hdmiphy_clkhw);
- if (IS_ERR(hdmi->hdmiphy_clk)) {
- ret = PTR_ERR(hdmi->hdmiphy_clk);
- goto err_ret;
- }
- ret = of_clk_add_provider(node, of_clk_src_simple_get,
- hdmi->hdmiphy_clk);
- if (ret < 0)
- goto err_clk_provider;
-
- ret = devm_add_action(hdmi->dev, inno_dw_hdmi_phy_clk_unregister,
- hdmi);
- if (ret < 0)
- goto err_unreg_action;
- return 0;
-err_unreg_action:
- of_clk_del_provider(node);
-err_clk_provider:
- clk_unregister(hdmi->hdmiphy_clk);
-err_ret:
- return ret;
-}
-
-static int rk3328_hdmi_init(struct rockchip_hdmi *hdmi)
+static int inno_dw_hdmi_init(struct rockchip_hdmi *hdmi)
{
int ret;
dev_err(hdmi->dev, "failed to enable grfclk %d\n", ret);
return -EPROBE_DEFER;
}
- /* Map HPD pin to 3V io */
- regmap_write(hdmi->regmap,
- RK3328_GRF_SOC_CON4,
- RK3328_IO_3V_DOMAIN |
- RK3328_HPD_3V);
- /* Map ddc pin to 5V io */
- regmap_write(hdmi->regmap,
- RK3328_GRF_SOC_CON3,
- RK3328_IO_CTRL_BY_HDMI);
- regmap_write(hdmi->regmap,
- RK3328_GRF_SOC_CON2,
- RK3328_DDC_MASK_EN |
- BIT(18));
+ if (hdmi->dev_type == RK3328_HDMI) {
+ /* Map HPD pin to 3V io */
+ regmap_write(hdmi->regmap,
+ RK3328_GRF_SOC_CON4,
+ RK3328_IO_3V_DOMAIN |
+ RK3328_HPD_3V);
+ /* Map ddc pin to 5V io */
+ regmap_write(hdmi->regmap,
+ RK3328_GRF_SOC_CON3,
+ RK3328_IO_CTRL_BY_HDMI);
+ regmap_write(hdmi->regmap,
+ RK3328_GRF_SOC_CON2,
+ RK3328_DDC_MASK_EN |
+ BIT(18));
+ } else {
+ regmap_write(hdmi->regmap, RK3228_GRF_SOC_CON2,
+ RK3228_DDC_MASK_EN);
+ regmap_write(hdmi->regmap, RK3228_GRF_SOC_CON6,
+ RK3228_IO_3V_DOMAIN);
+ }
clk_disable_unprepare(hdmi->grf_clk);
- /*
- * Use phy internal register control
- * rxsense/poweron/pllpd/pdataen signal.
- */
- inno_phy_writel(hdmi, 0x01, 0x07);
- inno_phy_writel(hdmi, 0x02, 0x91);
return 0;
}
return PTR_ERR(hdmi->hclk_vio);
}
- hdmi->hdmiphy_pclk = devm_clk_get(hdmi->dev, "pclk_hdmiphy");
- if (PTR_ERR(hdmi->hdmiphy_pclk) == -ENOENT) {
- hdmi->hdmiphy_pclk = NULL;
- } else if (PTR_ERR(hdmi->hdmiphy_pclk) == -EPROBE_DEFER) {
- return -EPROBE_DEFER;
- } else if (IS_ERR(hdmi->hdmiphy_pclk)) {
- dev_err(hdmi->dev, "failed to get pclk_hdmiphy clock\n");
- return PTR_ERR(hdmi->hdmiphy_pclk);
- }
-
ret = clk_prepare_enable(hdmi->vpll_clk);
if (ret) {
dev_err(hdmi->dev, "Failed to enable HDMI vpll: %d\n", ret);
return ret;
}
- ret = clk_prepare_enable(hdmi->hdmiphy_pclk);
- if (ret) {
- dev_err(hdmi->dev, "Failed to eanble HDMI pclk_hdmiphy: %d\n",
- ret);
- return ret;
- }
-
if (of_get_property(np, "rockchip,phy-table", &val)) {
phy_config = kmalloc(val, GFP_KERNEL);
if (!phy_config) {
.init = inno_dw_hdmi_phy_init,
.disable = inno_dw_hdmi_phy_disable,
.read_hpd = inno_dw_hdmi_phy_read_hpd,
- .read = inno_dw_hdmi_phy_read,
- .write = inno_dw_hdmi_phy_write,
};
static const struct dw_hdmi_plat_data rk3228_hdmi_drv_data = {
struct drm_device *drm = data;
struct drm_encoder *encoder;
struct rockchip_hdmi *hdmi;
- struct resource *iores, *phyres;
+ struct resource *iores;
int irq;
int ret;
return ret;
}
- if (hdmi->dev_type == RK3328_HDMI) {
- phyres = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- hdmi->hdmiphy = devm_ioremap_resource(dev, phyres);
- if (IS_ERR(hdmi->hdmiphy))
- return PTR_ERR(hdmi->hdmiphy);
- plat_data->phy_data = hdmi;
- ret = rk3328_hdmi_init(hdmi);
- if (ret < 0)
- return ret;
- inno_dw_hdmi_phy_clk_register(hdmi);
- } else if (hdmi->dev_type == RK3228_HDMI) {
+ if (hdmi->dev_type == RK3328_HDMI || hdmi->dev_type == RK3228_HDMI) {
hdmi->phy = devm_phy_get(dev, "hdmi_phy");
if (IS_ERR(hdmi->phy)) {
ret = PTR_ERR(hdmi->phy);
return ret;
}
plat_data->phy_data = hdmi;
- regmap_write(hdmi->regmap, RK3228_GRF_SOC_CON2,
- RK3228_DDC_MASK_EN);
- regmap_write(hdmi->regmap, RK3228_GRF_SOC_CON6,
- RK3228_IO_3V_DOMAIN);
+ ret = inno_dw_hdmi_init(hdmi);
+ if (ret < 0)
+ return ret;
}
drm_encoder_helper_add(encoder, &dw_hdmi_rockchip_encoder_helper_funcs);