drm: imx: imx-hdmi: split phy configuration to platform driver
authorAndy Yan <andy.yan@rock-chips.com>
Fri, 5 Dec 2014 06:25:50 +0000 (14:25 +0800)
committerPhilipp Zabel <p.zabel@pengutronix.de>
Tue, 6 Jan 2015 16:36:16 +0000 (17:36 +0100)
hdmi phy configuration is platform specific, which can be adjusted
according to the board to get the best SI

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
Tested-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
drivers/gpu/drm/imx/imx-hdmi.c
drivers/gpu/drm/imx/imx-hdmi.h
drivers/gpu/drm/imx/imx-hdmi_pltfm.c

index 9f2f0feb7b7593db13663e2d1ed39e3ca9ceddc5..998f3fd354eeb0280aaaeaa3236699ed5edee334 100644 (file)
@@ -713,76 +713,14 @@ static void imx_hdmi_phy_sel_interface_control(struct imx_hdmi *hdmi, u8 enable)
                         HDMI_PHY_CONF0_SELDIPIF_MASK);
 }
 
-enum {
-       RES_8,
-       RES_10,
-       RES_12,
-       RES_MAX,
-};
-
-struct mpll_config {
-       unsigned long mpixelclock;
-       struct {
-               u16 cpce;
-               u16 gmp;
-       } res[RES_MAX];
-};
-
-static const struct mpll_config mpll_config[] = {
-       {
-               45250000, {
-                       { 0x01e0, 0x0000 },
-                       { 0x21e1, 0x0000 },
-                       { 0x41e2, 0x0000 }
-               },
-       }, {
-               92500000, {
-                       { 0x0140, 0x0005 },
-                       { 0x2141, 0x0005 },
-                       { 0x4142, 0x0005 },
-               },
-       }, {
-               148500000, {
-                       { 0x00a0, 0x000a },
-                       { 0x20a1, 0x000a },
-                       { 0x40a2, 0x000a },
-               },
-       }, {
-               ~0UL, {
-                       { 0x00a0, 0x000a },
-                       { 0x2001, 0x000f },
-                       { 0x4002, 0x000f },
-               },
-       }
-};
-
-struct curr_ctrl {
-       unsigned long mpixelclock;
-       u16 curr[RES_MAX];
-};
-
-static const struct curr_ctrl curr_ctrl[] = {
-       /*      pixelclk     bpp8    bpp10   bpp12 */
-       {
-                54000000, { 0x091c, 0x091c, 0x06dc },
-       }, {
-                58400000, { 0x091c, 0x06dc, 0x06dc },
-       }, {
-                72000000, { 0x06dc, 0x06dc, 0x091c },
-       }, {
-                74250000, { 0x06dc, 0x0b5c, 0x091c },
-       }, {
-               118800000, { 0x091c, 0x091c, 0x06dc },
-       }, {
-               216000000, { 0x06dc, 0x0b5c, 0x091c },
-       }
-};
-
 static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
                              unsigned char res, int cscon)
 {
        unsigned res_idx, i;
        u8 val, msec;
+       const struct mpll_config *mpll_config = hdmi->plat_data->mpll_cfg;
+       const struct curr_ctrl   *curr_ctrl = hdmi->plat_data->cur_ctr;
+       const struct sym_term *sym_term =  hdmi->plat_data->sym_term;
 
        if (prep)
                return -EINVAL;
@@ -828,7 +766,7 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
        hdmi_phy_test_clear(hdmi, 0);
 
        /* PLL/MPLL Cfg - always match on final entry */
-       for (i = 0; i < ARRAY_SIZE(mpll_config) - 1; i++)
+       for (i = 0; mpll_config[i].mpixelclock != (~0UL); i++)
                if (hdmi->hdmi_data.video_mode.mpixelclock <=
                    mpll_config[i].mpixelclock)
                        break;
@@ -836,12 +774,12 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
        hdmi_phy_i2c_write(hdmi, mpll_config[i].res[res_idx].cpce, 0x06);
        hdmi_phy_i2c_write(hdmi, mpll_config[i].res[res_idx].gmp, 0x15);
 
-       for (i = 0; i < ARRAY_SIZE(curr_ctrl); i++)
+       for (i = 0; curr_ctrl[i].mpixelclock != (~0UL); i++)
                if (hdmi->hdmi_data.video_mode.mpixelclock <=
                    curr_ctrl[i].mpixelclock)
                        break;
 
-       if (i >= ARRAY_SIZE(curr_ctrl)) {
+       if (curr_ctrl[i].mpixelclock == (~0UL)) {
                dev_err(hdmi->dev, "Pixel clock %d - unsupported by HDMI\n",
                        hdmi->hdmi_data.video_mode.mpixelclock);
                return -EINVAL;
@@ -852,10 +790,17 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
 
        hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);  /* PLLPHBYCTRL */
        hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
+
+       for (i = 0; sym_term[i].mpixelclock != (~0UL); i++)
+               if (hdmi->hdmi_data.video_mode.mpixelclock <=
+                   sym_term[i].mpixelclock)
+                       break;
+
        /* RESISTANCE TERM 133Ohm Cfg */
-       hdmi_phy_i2c_write(hdmi, 0x0005, 0x19);  /* TXTERM */
+       hdmi_phy_i2c_write(hdmi, sym_term[i].term, 0x19);  /* TXTERM */
        /* PREEMP Cgf 0.00 */
-       hdmi_phy_i2c_write(hdmi, 0x800d, 0x09);  /* CKSYMTXCTRL */
+       hdmi_phy_i2c_write(hdmi, sym_term[i].sym_ctr, 0x09);  /* CKSYMTXCTRL */
+
        /* TX/CK LVL 10 */
        hdmi_phy_i2c_write(hdmi, 0x01ad, 0x0E);  /* VLEVCTRL */
        /* REMOVE CLK TERM */
index 86c6c5bbc95069ab35eeab6d0ddd3de9a268e517..db407f0a84f238b792d7f8eeb80ad6d24d2a8b1b 100644 (file)
@@ -1037,6 +1037,35 @@ enum imx_hdmi_devtype {
 
 struct imx_hdmi_plat_data {
        enum imx_hdmi_devtype dev_type;
+       const struct mpll_config *mpll_cfg;
+       const struct curr_ctrl *cur_ctr;
+       const struct sym_term *sym_term;
+};
+
+enum {
+       RES_8,
+       RES_10,
+       RES_12,
+       RES_MAX,
+};
+
+struct mpll_config {
+       unsigned long mpixelclock;
+       struct {
+               u16 cpce;
+               u16 gmp;
+       } res[RES_MAX];
+};
+
+struct curr_ctrl {
+       unsigned long mpixelclock;
+       u16 curr[RES_MAX];
+};
+
+struct sym_term {
+       unsigned long mpixelclock;
+       u16 sym_ctr;    /*clock symbol and transmitter control*/
+       u16 term;       /*transmission termination value*/
 };
 
 int imx_hdmi_bind(struct device *dev, struct device *master,
index 690181df71ebe4d13133ea43ba63cc07b454f95a..830531fd57f6f6247d47fa4b1104503618236ee2 100644 (file)
@@ -28,6 +28,57 @@ struct imx_hdmi_priv {
        struct regmap *regmap;
 };
 
+static const struct mpll_config imx_mpll_cfg[] = {
+       {
+               45250000, {
+                       { 0x01e0, 0x0000 },
+                       { 0x21e1, 0x0000 },
+                       { 0x41e2, 0x0000 }
+               },
+       }, {
+               92500000, {
+                       { 0x0140, 0x0005 },
+                       { 0x2141, 0x0005 },
+                       { 0x4142, 0x0005 },
+       },
+       }, {
+               148500000, {
+                       { 0x00a0, 0x000a },
+                       { 0x20a1, 0x000a },
+                       { 0x40a2, 0x000a },
+               },
+       }, {
+               ~0UL, {
+                       { 0x00a0, 0x000a },
+                       { 0x2001, 0x000f },
+                       { 0x4002, 0x000f },
+               },
+       }
+};
+
+static const struct curr_ctrl imx_cur_ctr[] = {
+       /*      pixelclk     bpp8    bpp10   bpp12 */
+       {
+               54000000, { 0x091c, 0x091c, 0x06dc },
+       }, {
+               58400000, { 0x091c, 0x06dc, 0x06dc },
+       }, {
+               72000000, { 0x06dc, 0x06dc, 0x091c },
+       }, {
+               74250000, { 0x06dc, 0x0b5c, 0x091c },
+       }, {
+               118800000, { 0x091c, 0x091c, 0x06dc },
+       }, {
+               216000000, { 0x06dc, 0x0b5c, 0x091c },
+       }
+};
+
+static const struct sym_term imx_sym_term[] = {
+       /*pixelclk   symbol   term*/
+       { 148500000, 0x800d, 0x0005 },
+       { ~0UL,      0x0000, 0x0000 }
+};
+
 static int imx_hdmi_parse_dt(struct imx_hdmi_priv *hdmi)
 {
        struct device_node *np = hdmi->dev->of_node;
@@ -88,10 +139,16 @@ static struct drm_encoder_funcs imx_hdmi_encoder_funcs = {
 };
 
 static struct imx_hdmi_plat_data imx6q_hdmi_drv_data = {
+       .mpll_cfg = imx_mpll_cfg,
+       .cur_ctr  = imx_cur_ctr,
+       .sym_term = imx_sym_term,
        .dev_type = IMX6Q_HDMI,
 };
 
 static struct imx_hdmi_plat_data imx6dl_hdmi_drv_data = {
+       .mpll_cfg = imx_mpll_cfg,
+       .cur_ctr  = imx_cur_ctr,
+       .sym_term = imx_sym_term,
        .dev_type = IMX6DL_HDMI,
 };