From d635711daa98be86d4c7fd01499c34f566b54ccb Mon Sep 17 00:00:00 2001 From: AndrĂ© Fabian Silva Delgado Date: Fri, 10 Jun 2016 05:30:17 -0300 Subject: Linux-libre 4.6.2-gnu --- drivers/gpu/drm/msm/hdmi/hdmi.c | 174 ++++--- drivers/gpu/drm/msm/hdmi/hdmi.h | 110 +++-- drivers/gpu/drm/msm/hdmi/hdmi.xml.h | 647 ++++++++++++++++++++++--- drivers/gpu/drm/msm/hdmi/hdmi_audio.c | 10 +- drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 56 +-- drivers/gpu/drm/msm/hdmi/hdmi_connector.c | 172 +++---- drivers/gpu/drm/msm/hdmi/hdmi_hdcp.c | 166 +++---- drivers/gpu/drm/msm/hdmi/hdmi_i2c.c | 20 +- drivers/gpu/drm/msm/hdmi/hdmi_phy.c | 230 +++++++++ drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c | 503 ++------------------ drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c | 766 ++++++++++++++++++++++++++++++ drivers/gpu/drm/msm/hdmi/hdmi_phy_8x60.c | 196 +++----- drivers/gpu/drm/msm/hdmi/hdmi_phy_8x74.c | 94 +--- drivers/gpu/drm/msm/hdmi/hdmi_pll_8960.c | 461 ++++++++++++++++++ drivers/gpu/drm/msm/hdmi/qfprom.xml.h | 5 +- 15 files changed, 2537 insertions(+), 1073 deletions(-) create mode 100644 drivers/gpu/drm/msm/hdmi/hdmi_phy.c create mode 100644 drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c create mode 100644 drivers/gpu/drm/msm/hdmi/hdmi_pll_8960.c (limited to 'drivers/gpu/drm/msm/hdmi') diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index 9a0989c0b..51b9ea552 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -21,7 +21,7 @@ #include "hdmi.h" -void hdmi_set_mode(struct hdmi *hdmi, bool power_on) +void msm_hdmi_set_mode(struct hdmi *hdmi, bool power_on) { uint32_t ctrl = 0; unsigned long flags; @@ -46,29 +46,27 @@ void hdmi_set_mode(struct hdmi *hdmi, bool power_on) power_on ? "Enable" : "Disable", ctrl); } -static irqreturn_t hdmi_irq(int irq, void *dev_id) +static irqreturn_t msm_hdmi_irq(int irq, void *dev_id) { struct hdmi *hdmi = dev_id; /* Process HPD: */ - hdmi_connector_irq(hdmi->connector); + msm_hdmi_connector_irq(hdmi->connector); /* Process DDC: */ - hdmi_i2c_irq(hdmi->i2c); + msm_hdmi_i2c_irq(hdmi->i2c); /* Process HDCP: */ if (hdmi->hdcp_ctrl) - hdmi_hdcp_irq(hdmi->hdcp_ctrl); + msm_hdmi_hdcp_irq(hdmi->hdcp_ctrl); /* TODO audio.. */ return IRQ_HANDLED; } -static void hdmi_destroy(struct hdmi *hdmi) +static void msm_hdmi_destroy(struct hdmi *hdmi) { - struct hdmi_phy *phy = hdmi->phy; - /* * at this point, hpd has been disabled, * after flush workq, it's safe to deinit hdcp @@ -77,21 +75,53 @@ static void hdmi_destroy(struct hdmi *hdmi) flush_workqueue(hdmi->workq); destroy_workqueue(hdmi->workq); } - hdmi_hdcp_destroy(hdmi); - if (phy) - phy->funcs->destroy(phy); + msm_hdmi_hdcp_destroy(hdmi); + + if (hdmi->phy_dev) { + put_device(hdmi->phy_dev); + hdmi->phy = NULL; + hdmi->phy_dev = NULL; + } if (hdmi->i2c) - hdmi_i2c_destroy(hdmi->i2c); + msm_hdmi_i2c_destroy(hdmi->i2c); platform_set_drvdata(hdmi->pdev, NULL); } +static int msm_hdmi_get_phy(struct hdmi *hdmi) +{ + struct platform_device *pdev = hdmi->pdev; + struct platform_device *phy_pdev; + struct device_node *phy_node; + + phy_node = of_parse_phandle(pdev->dev.of_node, "phys", 0); + if (!phy_node) { + dev_err(&pdev->dev, "cannot find phy device\n"); + return -ENXIO; + } + + phy_pdev = of_find_device_by_node(phy_node); + if (phy_pdev) + hdmi->phy = platform_get_drvdata(phy_pdev); + + of_node_put(phy_node); + + if (!phy_pdev || !hdmi->phy) { + dev_err(&pdev->dev, "phy driver is not ready\n"); + return -EPROBE_DEFER; + } + + hdmi->phy_dev = get_device(&phy_pdev->dev); + + return 0; +} + /* construct hdmi at bind/probe time, grab all the resources. If * we are to EPROBE_DEFER we want to do it here, rather than later * at modeset_init() time */ -static struct hdmi *hdmi_init(struct platform_device *pdev) +static struct hdmi *msm_hdmi_init(struct platform_device *pdev) { struct hdmi_platform_config *config = pdev->dev.platform_data; struct hdmi *hdmi = NULL; @@ -108,18 +138,6 @@ static struct hdmi *hdmi_init(struct platform_device *pdev) hdmi->config = config; spin_lock_init(&hdmi->reg_lock); - /* not sure about which phy maps to which msm.. probably I miss some */ - if (config->phy_init) { - hdmi->phy = config->phy_init(hdmi); - - if (IS_ERR(hdmi->phy)) { - ret = PTR_ERR(hdmi->phy); - dev_err(&pdev->dev, "failed to load phy: %d\n", ret); - hdmi->phy = NULL; - goto fail; - } - } - hdmi->mmio = msm_ioremap(pdev, config->mmio_name, "HDMI"); if (IS_ERR(hdmi->mmio)) { ret = PTR_ERR(hdmi->mmio); @@ -222,7 +240,7 @@ static struct hdmi *hdmi_init(struct platform_device *pdev) hdmi->workq = alloc_ordered_workqueue("msm_hdmi", 0); - hdmi->i2c = hdmi_i2c_init(hdmi); + hdmi->i2c = msm_hdmi_i2c_init(hdmi); if (IS_ERR(hdmi->i2c)) { ret = PTR_ERR(hdmi->i2c); dev_err(&pdev->dev, "failed to get i2c: %d\n", ret); @@ -230,7 +248,13 @@ static struct hdmi *hdmi_init(struct platform_device *pdev) goto fail; } - hdmi->hdcp_ctrl = hdmi_hdcp_init(hdmi); + ret = msm_hdmi_get_phy(hdmi); + if (ret) { + dev_err(&pdev->dev, "failed to get phy\n"); + goto fail; + } + + hdmi->hdcp_ctrl = msm_hdmi_hdcp_init(hdmi); if (IS_ERR(hdmi->hdcp_ctrl)) { dev_warn(&pdev->dev, "failed to init hdcp: disabled\n"); hdmi->hdcp_ctrl = NULL; @@ -240,7 +264,7 @@ static struct hdmi *hdmi_init(struct platform_device *pdev) fail: if (hdmi) - hdmi_destroy(hdmi); + msm_hdmi_destroy(hdmi); return ERR_PTR(ret); } @@ -250,10 +274,10 @@ fail: * driver (not hdmi sub-device's probe/bind!) * * Any resource (regulator/clk/etc) which could be missing at boot - * should be handled in hdmi_init() so that failure happens from + * should be handled in msm_hdmi_init() so that failure happens from * hdmi sub-device's probe. */ -int hdmi_modeset_init(struct hdmi *hdmi, +int msm_hdmi_modeset_init(struct hdmi *hdmi, struct drm_device *dev, struct drm_encoder *encoder) { struct msm_drm_private *priv = dev->dev_private; @@ -265,7 +289,7 @@ int hdmi_modeset_init(struct hdmi *hdmi, hdmi_audio_infoframe_init(&hdmi->audio.infoframe); - hdmi->bridge = hdmi_bridge_init(hdmi); + hdmi->bridge = msm_hdmi_bridge_init(hdmi); if (IS_ERR(hdmi->bridge)) { ret = PTR_ERR(hdmi->bridge); dev_err(dev->dev, "failed to create HDMI bridge: %d\n", ret); @@ -273,7 +297,7 @@ int hdmi_modeset_init(struct hdmi *hdmi, goto fail; } - hdmi->connector = hdmi_connector_init(hdmi); + hdmi->connector = msm_hdmi_connector_init(hdmi); if (IS_ERR(hdmi->connector)) { ret = PTR_ERR(hdmi->connector); dev_err(dev->dev, "failed to create HDMI connector: %d\n", ret); @@ -289,7 +313,7 @@ int hdmi_modeset_init(struct hdmi *hdmi, } ret = devm_request_irq(&pdev->dev, hdmi->irq, - hdmi_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + msm_hdmi_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "hdmi_isr", hdmi); if (ret < 0) { dev_err(dev->dev, "failed to request IRQ%u: %d\n", @@ -309,7 +333,7 @@ int hdmi_modeset_init(struct hdmi *hdmi, fail: /* bridge is normally destroyed by drm: */ if (hdmi->bridge) { - hdmi_bridge_destroy(hdmi->bridge); + msm_hdmi_bridge_destroy(hdmi->bridge); hdmi->bridge = NULL; } if (hdmi->connector) { @@ -331,15 +355,12 @@ fail: static const char *pwr_reg_names_none[] = {}; static const char *hpd_reg_names_none[] = {}; -static struct hdmi_platform_config hdmi_tx_8660_config = { - .phy_init = hdmi_phy_8x60_init, -}; +static struct hdmi_platform_config hdmi_tx_8660_config; static const char *hpd_reg_names_8960[] = {"core-vdda", "hdmi-mux"}; static const char *hpd_clk_names_8960[] = {"core_clk", "master_iface_clk", "slave_iface_clk"}; static struct hdmi_platform_config hdmi_tx_8960_config = { - .phy_init = hdmi_phy_8960_init, HDMI_CFG(hpd_reg, 8960), HDMI_CFG(hpd_clk, 8960), }; @@ -351,7 +372,6 @@ static const char *hpd_clk_names_8x74[] = {"iface_clk", "core_clk", "mdp_core_cl static unsigned long hpd_clk_freq_8x74[] = {0, 19200000, 0}; static struct hdmi_platform_config hdmi_tx_8974_config = { - .phy_init = hdmi_phy_8x74_init, HDMI_CFG(pwr_reg, 8x74), HDMI_CFG(hpd_reg, 8x74), HDMI_CFG(pwr_clk, 8x74), @@ -362,7 +382,6 @@ static struct hdmi_platform_config hdmi_tx_8974_config = { static const char *hpd_reg_names_8084[] = {"hpd-gdsc", "hpd-5v", "hpd-5v-en"}; static struct hdmi_platform_config hdmi_tx_8084_config = { - .phy_init = hdmi_phy_8x74_init, HDMI_CFG(pwr_reg, 8x74), HDMI_CFG(hpd_reg, 8084), HDMI_CFG(pwr_clk, 8x74), @@ -371,7 +390,6 @@ static struct hdmi_platform_config hdmi_tx_8084_config = { }; static struct hdmi_platform_config hdmi_tx_8994_config = { - .phy_init = NULL, /* nothing to do for this HDMI PHY 20nm */ HDMI_CFG(pwr_reg, 8x74), HDMI_CFG(hpd_reg, none), HDMI_CFG(pwr_clk, 8x74), @@ -380,7 +398,6 @@ static struct hdmi_platform_config hdmi_tx_8994_config = { }; static struct hdmi_platform_config hdmi_tx_8996_config = { - .phy_init = NULL, HDMI_CFG(pwr_reg, none), HDMI_CFG(hpd_reg, none), HDMI_CFG(pwr_clk, 8x74), @@ -388,7 +405,21 @@ static struct hdmi_platform_config hdmi_tx_8996_config = { .hpd_freq = hpd_clk_freq_8x74, }; -static int get_gpio(struct device *dev, struct device_node *of_node, const char *name) +static const struct { + const char *name; + const bool output; + const int value; + const char *label; +} msm_hdmi_gpio_pdata[] = { + { "qcom,hdmi-tx-ddc-clk", true, 1, "HDMI_DDC_CLK" }, + { "qcom,hdmi-tx-ddc-data", true, 1, "HDMI_DDC_DATA" }, + { "qcom,hdmi-tx-hpd", false, 1, "HDMI_HPD" }, + { "qcom,hdmi-tx-mux-en", true, 1, "HDMI_MUX_EN" }, + { "qcom,hdmi-tx-mux-sel", true, 0, "HDMI_MUX_SEL" }, + { "qcom,hdmi-tx-mux-lpm", true, 1, "HDMI_MUX_LPM" }, +}; + +static int msm_hdmi_get_gpio(struct device_node *of_node, const char *name) { int gpio = of_get_named_gpio(of_node, name, 0); if (gpio < 0) { @@ -403,13 +434,14 @@ static int get_gpio(struct device *dev, struct device_node *of_node, const char return gpio; } -static int hdmi_bind(struct device *dev, struct device *master, void *data) +static int msm_hdmi_bind(struct device *dev, struct device *master, void *data) { struct drm_device *drm = dev_get_drvdata(master); struct msm_drm_private *priv = drm->dev_private; static struct hdmi_platform_config *hdmi_cfg; struct hdmi *hdmi; struct device_node *of_node = dev->of_node; + int i; hdmi_cfg = (struct hdmi_platform_config *) of_device_get_match_data(dev); @@ -420,16 +452,18 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) hdmi_cfg->mmio_name = "core_physical"; hdmi_cfg->qfprom_mmio_name = "qfprom_physical"; - hdmi_cfg->ddc_clk_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-ddc-clk"); - hdmi_cfg->ddc_data_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-ddc-data"); - hdmi_cfg->hpd_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-hpd"); - hdmi_cfg->mux_en_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-mux-en"); - hdmi_cfg->mux_sel_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-mux-sel"); - hdmi_cfg->mux_lpm_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-mux-lpm"); + + for (i = 0; i < HDMI_MAX_NUM_GPIO; i++) { + hdmi_cfg->gpios[i].num = msm_hdmi_get_gpio(of_node, + msm_hdmi_gpio_pdata[i].name); + hdmi_cfg->gpios[i].output = msm_hdmi_gpio_pdata[i].output; + hdmi_cfg->gpios[i].value = msm_hdmi_gpio_pdata[i].value; + hdmi_cfg->gpios[i].label = msm_hdmi_gpio_pdata[i].label; + } dev->platform_data = hdmi_cfg; - hdmi = hdmi_init(to_platform_device(dev)); + hdmi = msm_hdmi_init(to_platform_device(dev)); if (IS_ERR(hdmi)) return PTR_ERR(hdmi); priv->hdmi = hdmi; @@ -437,34 +471,34 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) return 0; } -static void hdmi_unbind(struct device *dev, struct device *master, +static void msm_hdmi_unbind(struct device *dev, struct device *master, void *data) { struct drm_device *drm = dev_get_drvdata(master); struct msm_drm_private *priv = drm->dev_private; if (priv->hdmi) { - hdmi_destroy(priv->hdmi); + msm_hdmi_destroy(priv->hdmi); priv->hdmi = NULL; } } -static const struct component_ops hdmi_ops = { - .bind = hdmi_bind, - .unbind = hdmi_unbind, +static const struct component_ops msm_hdmi_ops = { + .bind = msm_hdmi_bind, + .unbind = msm_hdmi_unbind, }; -static int hdmi_dev_probe(struct platform_device *pdev) +static int msm_hdmi_dev_probe(struct platform_device *pdev) { - return component_add(&pdev->dev, &hdmi_ops); + return component_add(&pdev->dev, &msm_hdmi_ops); } -static int hdmi_dev_remove(struct platform_device *pdev) +static int msm_hdmi_dev_remove(struct platform_device *pdev) { - component_del(&pdev->dev, &hdmi_ops); + component_del(&pdev->dev, &msm_hdmi_ops); return 0; } -static const struct of_device_id dt_match[] = { +static const struct of_device_id msm_hdmi_dt_match[] = { { .compatible = "qcom,hdmi-tx-8996", .data = &hdmi_tx_8996_config }, { .compatible = "qcom,hdmi-tx-8994", .data = &hdmi_tx_8994_config }, { .compatible = "qcom,hdmi-tx-8084", .data = &hdmi_tx_8084_config }, @@ -474,21 +508,23 @@ static const struct of_device_id dt_match[] = { {} }; -static struct platform_driver hdmi_driver = { - .probe = hdmi_dev_probe, - .remove = hdmi_dev_remove, +static struct platform_driver msm_hdmi_driver = { + .probe = msm_hdmi_dev_probe, + .remove = msm_hdmi_dev_remove, .driver = { .name = "hdmi_msm", - .of_match_table = dt_match, + .of_match_table = msm_hdmi_dt_match, }, }; -void __init hdmi_register(void) +void __init msm_hdmi_register(void) { - platform_driver_register(&hdmi_driver); + msm_hdmi_phy_driver_register(); + platform_driver_register(&msm_hdmi_driver); } -void __exit hdmi_unregister(void) +void __exit msm_hdmi_unregister(void) { - platform_driver_unregister(&hdmi_driver); + platform_driver_unregister(&msm_hdmi_driver); + msm_hdmi_phy_driver_unregister(); } diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h index d0e663192..65428cf23 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.h +++ b/drivers/gpu/drm/msm/hdmi/hdmi.h @@ -27,10 +27,18 @@ #include "msm_drv.h" #include "hdmi.xml.h" +#define HDMI_MAX_NUM_GPIO 6 struct hdmi_phy; struct hdmi_platform_config; +struct hdmi_gpio_data { + int num; + bool output; + int value; + const char *label; +}; + struct hdmi_audio { bool enabled; struct hdmi_audio_infoframe infoframe; @@ -62,6 +70,8 @@ struct hdmi { struct clk **pwr_clks; struct hdmi_phy *phy; + struct device *phy_dev; + struct i2c_adapter *i2c; struct drm_connector *connector; struct drm_bridge *bridge; @@ -88,7 +98,6 @@ struct hdmi { /* platform config data (ie. from DT, or pdata) */ struct hdmi_platform_config { - struct hdmi_phy *(*phy_init)(struct hdmi *hdmi); const char *mmio_name; const char *qfprom_mmio_name; @@ -110,11 +119,10 @@ struct hdmi_platform_config { int pwr_clk_cnt; /* gpio's: */ - int ddc_clk_gpio, ddc_data_gpio, hpd_gpio, mux_en_gpio, mux_sel_gpio; - int mux_lpm_gpio; + struct hdmi_gpio_data gpios[HDMI_MAX_NUM_GPIO]; }; -void hdmi_set_mode(struct hdmi *hdmi, bool power_on); +void msm_hdmi_set_mode(struct hdmi *hdmi, bool power_on); static inline void hdmi_write(struct hdmi *hdmi, u32 reg, u32 data) { @@ -132,65 +140,113 @@ static inline u32 hdmi_qfprom_read(struct hdmi *hdmi, u32 reg) } /* - * The phy appears to be different, for example between 8960 and 8x60, - * so split the phy related functions out and load the correct one at - * runtime: + * hdmi phy: */ -struct hdmi_phy_funcs { - void (*destroy)(struct hdmi_phy *phy); +enum hdmi_phy_type { + MSM_HDMI_PHY_8x60, + MSM_HDMI_PHY_8960, + MSM_HDMI_PHY_8x74, + MSM_HDMI_PHY_8996, + MSM_HDMI_PHY_MAX, +}; + +struct hdmi_phy_cfg { + enum hdmi_phy_type type; void (*powerup)(struct hdmi_phy *phy, unsigned long int pixclock); void (*powerdown)(struct hdmi_phy *phy); + const char * const *reg_names; + int num_regs; + const char * const *clk_names; + int num_clks; }; +extern const struct hdmi_phy_cfg msm_hdmi_phy_8x60_cfg; +extern const struct hdmi_phy_cfg msm_hdmi_phy_8960_cfg; +extern const struct hdmi_phy_cfg msm_hdmi_phy_8x74_cfg; +extern const struct hdmi_phy_cfg msm_hdmi_phy_8996_cfg; + struct hdmi_phy { + struct platform_device *pdev; + void __iomem *mmio; + struct hdmi_phy_cfg *cfg; const struct hdmi_phy_funcs *funcs; + struct regulator **regs; + struct clk **clks; }; -struct hdmi_phy *hdmi_phy_8960_init(struct hdmi *hdmi); -struct hdmi_phy *hdmi_phy_8x60_init(struct hdmi *hdmi); -struct hdmi_phy *hdmi_phy_8x74_init(struct hdmi *hdmi); +static inline void hdmi_phy_write(struct hdmi_phy *phy, u32 reg, u32 data) +{ + msm_writel(data, phy->mmio + reg); +} + +static inline u32 hdmi_phy_read(struct hdmi_phy *phy, u32 reg) +{ + return msm_readl(phy->mmio + reg); +} + +int msm_hdmi_phy_resource_enable(struct hdmi_phy *phy); +void msm_hdmi_phy_resource_disable(struct hdmi_phy *phy); +void msm_hdmi_phy_powerup(struct hdmi_phy *phy, unsigned long int pixclock); +void msm_hdmi_phy_powerdown(struct hdmi_phy *phy); +void __init msm_hdmi_phy_driver_register(void); +void __exit msm_hdmi_phy_driver_unregister(void); + +#ifdef CONFIG_COMMON_CLK +int msm_hdmi_pll_8960_init(struct platform_device *pdev); +int msm_hdmi_pll_8996_init(struct platform_device *pdev); +#else +static inline int msm_hdmi_pll_8960_init(struct platform_device *pdev) +{ + return -ENODEV; +} + +static inline int msm_hdmi_pll_8996_init(struct platform_device *pdev) +{ + return -ENODEV; +} +#endif /* * audio: */ -int hdmi_audio_update(struct hdmi *hdmi); -int hdmi_audio_info_setup(struct hdmi *hdmi, bool enabled, +int msm_hdmi_audio_update(struct hdmi *hdmi); +int msm_hdmi_audio_info_setup(struct hdmi *hdmi, bool enabled, uint32_t num_of_channels, uint32_t channel_allocation, uint32_t level_shift, bool down_mix); -void hdmi_audio_set_sample_rate(struct hdmi *hdmi, int rate); +void msm_hdmi_audio_set_sample_rate(struct hdmi *hdmi, int rate); /* * hdmi bridge: */ -struct drm_bridge *hdmi_bridge_init(struct hdmi *hdmi); -void hdmi_bridge_destroy(struct drm_bridge *bridge); +struct drm_bridge *msm_hdmi_bridge_init(struct hdmi *hdmi); +void msm_hdmi_bridge_destroy(struct drm_bridge *bridge); /* * hdmi connector: */ -void hdmi_connector_irq(struct drm_connector *connector); -struct drm_connector *hdmi_connector_init(struct hdmi *hdmi); +void msm_hdmi_connector_irq(struct drm_connector *connector); +struct drm_connector *msm_hdmi_connector_init(struct hdmi *hdmi); /* * i2c adapter for ddc: */ -void hdmi_i2c_irq(struct i2c_adapter *i2c); -void hdmi_i2c_destroy(struct i2c_adapter *i2c); -struct i2c_adapter *hdmi_i2c_init(struct hdmi *hdmi); +void msm_hdmi_i2c_irq(struct i2c_adapter *i2c); +void msm_hdmi_i2c_destroy(struct i2c_adapter *i2c); +struct i2c_adapter *msm_hdmi_i2c_init(struct hdmi *hdmi); /* * hdcp */ -struct hdmi_hdcp_ctrl *hdmi_hdcp_init(struct hdmi *hdmi); -void hdmi_hdcp_destroy(struct hdmi *hdmi); -void hdmi_hdcp_on(struct hdmi_hdcp_ctrl *hdcp_ctrl); -void hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl); -void hdmi_hdcp_irq(struct hdmi_hdcp_ctrl *hdcp_ctrl); +struct hdmi_hdcp_ctrl *msm_hdmi_hdcp_init(struct hdmi *hdmi); +void msm_hdmi_hdcp_destroy(struct hdmi *hdmi); +void msm_hdmi_hdcp_on(struct hdmi_hdcp_ctrl *hdcp_ctrl); +void msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl); +void msm_hdmi_hdcp_irq(struct hdmi_hdcp_ctrl *hdcp_ctrl); #endif /* __HDMI_CONNECTOR_H__ */ diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.xml.h b/drivers/gpu/drm/msm/hdmi/hdmi.xml.h index 10c45700a..34c7df654 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.xml.h +++ b/drivers/gpu/drm/msm/hdmi/hdmi.xml.h @@ -9,7 +9,7 @@ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2015-05-20 20:03:07) +- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2016-02-10 17:07:21) - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2015-05-20 20:03:14) - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2015-09-18 12:07:28) - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 37194 bytes, from 2015-09-18 12:07:28) @@ -17,11 +17,12 @@ The rules-ng-ng source files this header was generated from are: - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 602 bytes, from 2015-10-22 16:35:02) - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2015-05-20 20:03:14) - /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2015-05-20 20:03:07) -- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 29154 bytes, from 2015-08-10 21:25:43) +- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 41472 bytes, from 2016-01-22 18:18:18) - /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 10416 bytes, from 2015-05-20 20:03:14) -Copyright (C) 2013-2015 by the following authors: +Copyright (C) 2013-2016 by the following authors: - Rob Clark (robclark) +- Ilia Mirkin (imirkin) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -559,7 +560,7 @@ static inline uint32_t HDMI_VSYNC_TOTAL_F2_V_TOTAL(uint32_t val) #define REG_HDMI_CEC_WR_CHECK_CONFIG 0x00000370 -#define REG_HDMI_8x60_PHY_REG0 0x00000300 +#define REG_HDMI_8x60_PHY_REG0 0x00000000 #define HDMI_8x60_PHY_REG0_DESER_DEL_CTRL__MASK 0x0000001c #define HDMI_8x60_PHY_REG0_DESER_DEL_CTRL__SHIFT 2 static inline uint32_t HDMI_8x60_PHY_REG0_DESER_DEL_CTRL(uint32_t val) @@ -567,7 +568,7 @@ static inline uint32_t HDMI_8x60_PHY_REG0_DESER_DEL_CTRL(uint32_t val) return ((val) << HDMI_8x60_PHY_REG0_DESER_DEL_CTRL__SHIFT) & HDMI_8x60_PHY_REG0_DESER_DEL_CTRL__MASK; } -#define REG_HDMI_8x60_PHY_REG1 0x00000304 +#define REG_HDMI_8x60_PHY_REG1 0x00000004 #define HDMI_8x60_PHY_REG1_DTEST_MUX_SEL__MASK 0x000000f0 #define HDMI_8x60_PHY_REG1_DTEST_MUX_SEL__SHIFT 4 static inline uint32_t HDMI_8x60_PHY_REG1_DTEST_MUX_SEL(uint32_t val) @@ -581,7 +582,7 @@ static inline uint32_t HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL(uint32_t val) return ((val) << HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL__SHIFT) & HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL__MASK; } -#define REG_HDMI_8x60_PHY_REG2 0x00000308 +#define REG_HDMI_8x60_PHY_REG2 0x00000008 #define HDMI_8x60_PHY_REG2_PD_DESER 0x00000001 #define HDMI_8x60_PHY_REG2_PD_DRIVE_1 0x00000002 #define HDMI_8x60_PHY_REG2_PD_DRIVE_2 0x00000004 @@ -591,152 +592,152 @@ static inline uint32_t HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL(uint32_t val) #define HDMI_8x60_PHY_REG2_PD_PWRGEN 0x00000040 #define HDMI_8x60_PHY_REG2_RCV_SENSE_EN 0x00000080 -#define REG_HDMI_8x60_PHY_REG3 0x0000030c +#define REG_HDMI_8x60_PHY_REG3 0x0000000c #define HDMI_8x60_PHY_REG3_PLL_ENABLE 0x00000001 -#define REG_HDMI_8x60_PHY_REG4 0x00000310 +#define REG_HDMI_8x60_PHY_REG4 0x00000010 -#define REG_HDMI_8x60_PHY_REG5 0x00000314 +#define REG_HDMI_8x60_PHY_REG5 0x00000014 -#define REG_HDMI_8x60_PHY_REG6 0x00000318 +#define REG_HDMI_8x60_PHY_REG6 0x00000018 -#define REG_HDMI_8x60_PHY_REG7 0x0000031c +#define REG_HDMI_8x60_PHY_REG7 0x0000001c -#define REG_HDMI_8x60_PHY_REG8 0x00000320 +#define REG_HDMI_8x60_PHY_REG8 0x00000020 -#define REG_HDMI_8x60_PHY_REG9 0x00000324 +#define REG_HDMI_8x60_PHY_REG9 0x00000024 -#define REG_HDMI_8x60_PHY_REG10 0x00000328 +#define REG_HDMI_8x60_PHY_REG10 0x00000028 -#define REG_HDMI_8x60_PHY_REG11 0x0000032c +#define REG_HDMI_8x60_PHY_REG11 0x0000002c -#define REG_HDMI_8x60_PHY_REG12 0x00000330 +#define REG_HDMI_8x60_PHY_REG12 0x00000030 #define HDMI_8x60_PHY_REG12_RETIMING_EN 0x00000001 #define HDMI_8x60_PHY_REG12_PLL_LOCK_DETECT_EN 0x00000002 #define HDMI_8x60_PHY_REG12_FORCE_LOCK 0x00000010 -#define REG_HDMI_8960_PHY_REG0 0x00000400 +#define REG_HDMI_8960_PHY_REG0 0x00000000 -#define REG_HDMI_8960_PHY_REG1 0x00000404 +#define REG_HDMI_8960_PHY_REG1 0x00000004 -#define REG_HDMI_8960_PHY_REG2 0x00000408 +#define REG_HDMI_8960_PHY_REG2 0x00000008 -#define REG_HDMI_8960_PHY_REG3 0x0000040c +#define REG_HDMI_8960_PHY_REG3 0x0000000c -#define REG_HDMI_8960_PHY_REG4 0x00000410 +#define REG_HDMI_8960_PHY_REG4 0x00000010 -#define REG_HDMI_8960_PHY_REG5 0x00000414 +#define REG_HDMI_8960_PHY_REG5 0x00000014 -#define REG_HDMI_8960_PHY_REG6 0x00000418 +#define REG_HDMI_8960_PHY_REG6 0x00000018 -#define REG_HDMI_8960_PHY_REG7 0x0000041c +#define REG_HDMI_8960_PHY_REG7 0x0000001c -#define REG_HDMI_8960_PHY_REG8 0x00000420 +#define REG_HDMI_8960_PHY_REG8 0x00000020 -#define REG_HDMI_8960_PHY_REG9 0x00000424 +#define REG_HDMI_8960_PHY_REG9 0x00000024 -#define REG_HDMI_8960_PHY_REG10 0x00000428 +#define REG_HDMI_8960_PHY_REG10 0x00000028 -#define REG_HDMI_8960_PHY_REG11 0x0000042c +#define REG_HDMI_8960_PHY_REG11 0x0000002c -#define REG_HDMI_8960_PHY_REG12 0x00000430 +#define REG_HDMI_8960_PHY_REG12 0x00000030 #define HDMI_8960_PHY_REG12_SW_RESET 0x00000020 #define HDMI_8960_PHY_REG12_PWRDN_B 0x00000080 -#define REG_HDMI_8960_PHY_REG_BIST_CFG 0x00000434 +#define REG_HDMI_8960_PHY_REG_BIST_CFG 0x00000034 -#define REG_HDMI_8960_PHY_DEBUG_BUS_SEL 0x00000438 +#define REG_HDMI_8960_PHY_DEBUG_BUS_SEL 0x00000038 -#define REG_HDMI_8960_PHY_REG_MISC0 0x0000043c +#define REG_HDMI_8960_PHY_REG_MISC0 0x0000003c -#define REG_HDMI_8960_PHY_REG13 0x00000440 +#define REG_HDMI_8960_PHY_REG13 0x00000040 -#define REG_HDMI_8960_PHY_REG14 0x00000444 +#define REG_HDMI_8960_PHY_REG14 0x00000044 -#define REG_HDMI_8960_PHY_REG15 0x00000448 +#define REG_HDMI_8960_PHY_REG15 0x00000048 -#define REG_HDMI_8960_PHY_PLL_REFCLK_CFG 0x00000500 +#define REG_HDMI_8960_PHY_PLL_REFCLK_CFG 0x00000000 -#define REG_HDMI_8960_PHY_PLL_CHRG_PUMP_CFG 0x00000504 +#define REG_HDMI_8960_PHY_PLL_CHRG_PUMP_CFG 0x00000004 -#define REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 0x00000508 +#define REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 0x00000008 -#define REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 0x0000050c +#define REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 0x0000000c -#define REG_HDMI_8960_PHY_PLL_IDAC_ADJ_CFG 0x00000510 +#define REG_HDMI_8960_PHY_PLL_IDAC_ADJ_CFG 0x00000010 -#define REG_HDMI_8960_PHY_PLL_I_VI_KVCO_CFG 0x00000514 +#define REG_HDMI_8960_PHY_PLL_I_VI_KVCO_CFG 0x00000014 -#define REG_HDMI_8960_PHY_PLL_PWRDN_B 0x00000518 +#define REG_HDMI_8960_PHY_PLL_PWRDN_B 0x00000018 #define HDMI_8960_PHY_PLL_PWRDN_B_PD_PLL 0x00000002 #define HDMI_8960_PHY_PLL_PWRDN_B_PLL_PWRDN_B 0x00000008 -#define REG_HDMI_8960_PHY_PLL_SDM_CFG0 0x0000051c +#define REG_HDMI_8960_PHY_PLL_SDM_CFG0 0x0000001c -#define REG_HDMI_8960_PHY_PLL_SDM_CFG1 0x00000520 +#define REG_HDMI_8960_PHY_PLL_SDM_CFG1 0x00000020 -#define REG_HDMI_8960_PHY_PLL_SDM_CFG2 0x00000524 +#define REG_HDMI_8960_PHY_PLL_SDM_CFG2 0x00000024 -#define REG_HDMI_8960_PHY_PLL_SDM_CFG3 0x00000528 +#define REG_HDMI_8960_PHY_PLL_SDM_CFG3 0x00000028 -#define REG_HDMI_8960_PHY_PLL_SDM_CFG4 0x0000052c +#define REG_HDMI_8960_PHY_PLL_SDM_CFG4 0x0000002c -#define REG_HDMI_8960_PHY_PLL_SSC_CFG0 0x00000530 +#define REG_HDMI_8960_PHY_PLL_SSC_CFG0 0x00000030 -#define REG_HDMI_8960_PHY_PLL_SSC_CFG1 0x00000534 +#define REG_HDMI_8960_PHY_PLL_SSC_CFG1 0x00000034 -#define REG_HDMI_8960_PHY_PLL_SSC_CFG2 0x00000538 +#define REG_HDMI_8960_PHY_PLL_SSC_CFG2 0x00000038 -#define REG_HDMI_8960_PHY_PLL_SSC_CFG3 0x0000053c +#define REG_HDMI_8960_PHY_PLL_SSC_CFG3 0x0000003c -#define REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0 0x00000540 +#define REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0 0x00000040 -#define REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1 0x00000544 +#define REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1 0x00000044 -#define REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2 0x00000548 +#define REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2 0x00000048 -#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 0x0000054c +#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 0x0000004c -#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 0x00000550 +#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 0x00000050 -#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 0x00000554 +#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 0x00000054 -#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 0x00000558 +#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 0x00000058 -#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 0x0000055c +#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 0x0000005c -#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 0x00000560 +#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 0x00000060 -#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG6 0x00000564 +#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG6 0x00000064 -#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG7 0x00000568 +#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG7 0x00000068 -#define REG_HDMI_8960_PHY_PLL_DEBUG_SEL 0x0000056c +#define REG_HDMI_8960_PHY_PLL_DEBUG_SEL 0x0000006c -#define REG_HDMI_8960_PHY_PLL_MISC0 0x00000570 +#define REG_HDMI_8960_PHY_PLL_MISC0 0x00000070 -#define REG_HDMI_8960_PHY_PLL_MISC1 0x00000574 +#define REG_HDMI_8960_PHY_PLL_MISC1 0x00000074 -#define REG_HDMI_8960_PHY_PLL_MISC2 0x00000578 +#define REG_HDMI_8960_PHY_PLL_MISC2 0x00000078 -#define REG_HDMI_8960_PHY_PLL_MISC3 0x0000057c +#define REG_HDMI_8960_PHY_PLL_MISC3 0x0000007c -#define REG_HDMI_8960_PHY_PLL_MISC4 0x00000580 +#define REG_HDMI_8960_PHY_PLL_MISC4 0x00000080 -#define REG_HDMI_8960_PHY_PLL_MISC5 0x00000584 +#define REG_HDMI_8960_PHY_PLL_MISC5 0x00000084 -#define REG_HDMI_8960_PHY_PLL_MISC6 0x00000588 +#define REG_HDMI_8960_PHY_PLL_MISC6 0x00000088 -#define REG_HDMI_8960_PHY_PLL_DEBUG_BUS0 0x0000058c +#define REG_HDMI_8960_PHY_PLL_DEBUG_BUS0 0x0000008c -#define REG_HDMI_8960_PHY_PLL_DEBUG_BUS1 0x00000590 +#define REG_HDMI_8960_PHY_PLL_DEBUG_BUS1 0x00000090 -#define REG_HDMI_8960_PHY_PLL_DEBUG_BUS2 0x00000594 +#define REG_HDMI_8960_PHY_PLL_DEBUG_BUS2 0x00000094 -#define REG_HDMI_8960_PHY_PLL_STATUS0 0x00000598 +#define REG_HDMI_8960_PHY_PLL_STATUS0 0x00000098 #define HDMI_8960_PHY_PLL_STATUS0_PLL_LOCK 0x00000001 -#define REG_HDMI_8960_PHY_PLL_STATUS1 0x0000059c +#define REG_HDMI_8960_PHY_PLL_STATUS1 0x0000009c #define REG_HDMI_8x74_ANA_CFG0 0x00000000 @@ -843,5 +844,501 @@ static inline uint32_t HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL(uint32_t val) #define REG_HDMI_28nm_PHY_PLL_DEBUG_BUS_SEL 0x000000a0 +#define REG_HDMI_8996_PHY_CFG 0x00000000 + +#define REG_HDMI_8996_PHY_PD_CTL 0x00000004 + +#define REG_HDMI_8996_PHY_MODE 0x00000008 + +#define REG_HDMI_8996_PHY_MISR_CLEAR 0x0000000c + +#define REG_HDMI_8996_PHY_TX0_TX1_BIST_CFG0 0x00000010 + +#define REG_HDMI_8996_PHY_TX0_TX1_BIST_CFG1 0x00000014 + +#define REG_HDMI_8996_PHY_TX0_TX1_PRBS_SEED_BYTE0 0x00000018 + +#define REG_HDMI_8996_PHY_TX0_TX1_PRBS_SEED_BYTE1 0x0000001c + +#define REG_HDMI_8996_PHY_TX0_TX1_BIST_PATTERN0 0x00000020 + +#define REG_HDMI_8996_PHY_TX0_TX1_BIST_PATTERN1 0x00000024 + +#define REG_HDMI_8996_PHY_TX2_TX3_BIST_CFG0 0x00000028 + +#define REG_HDMI_8996_PHY_TX2_TX3_BIST_CFG1 0x0000002c + +#define REG_HDMI_8996_PHY_TX2_TX3_PRBS_SEED_BYTE0 0x00000030 + +#define REG_HDMI_8996_PHY_TX2_TX3_PRBS_SEED_BYTE1 0x00000034 + +#define REG_HDMI_8996_PHY_TX2_TX3_BIST_PATTERN0 0x00000038 + +#define REG_HDMI_8996_PHY_TX2_TX3_BIST_PATTERN1 0x0000003c + +#define REG_HDMI_8996_PHY_DEBUG_BUS_SEL 0x00000040 + +#define REG_HDMI_8996_PHY_TXCAL_CFG0 0x00000044 + +#define REG_HDMI_8996_PHY_TXCAL_CFG1 0x00000048 + +#define REG_HDMI_8996_PHY_TX0_TX1_LANE_CTL 0x0000004c + +#define REG_HDMI_8996_PHY_TX2_TX3_LANE_CTL 0x00000050 + +#define REG_HDMI_8996_PHY_LANE_BIST_CONFIG 0x00000054 + +#define REG_HDMI_8996_PHY_CLOCK 0x00000058 + +#define REG_HDMI_8996_PHY_MISC1 0x0000005c + +#define REG_HDMI_8996_PHY_MISC2 0x00000060 + +#define REG_HDMI_8996_PHY_TX0_TX1_BIST_STATUS0 0x00000064 + +#define REG_HDMI_8996_PHY_TX0_TX1_BIST_STATUS1 0x00000068 + +#define REG_HDMI_8996_PHY_TX0_TX1_BIST_STATUS2 0x0000006c + +#define REG_HDMI_8996_PHY_TX2_TX3_BIST_STATUS0 0x00000070 + +#define REG_HDMI_8996_PHY_TX2_TX3_BIST_STATUS1 0x00000074 + +#define REG_HDMI_8996_PHY_TX2_TX3_BIST_STATUS2 0x00000078 + +#define REG_HDMI_8996_PHY_PRE_MISR_STATUS0 0x0000007c + +#define REG_HDMI_8996_PHY_PRE_MISR_STATUS1 0x00000080 + +#define REG_HDMI_8996_PHY_PRE_MISR_STATUS2 0x00000084 + +#define REG_HDMI_8996_PHY_PRE_MISR_STATUS3 0x00000088 + +#define REG_HDMI_8996_PHY_POST_MISR_STATUS0 0x0000008c + +#define REG_HDMI_8996_PHY_POST_MISR_STATUS1 0x00000090 + +#define REG_HDMI_8996_PHY_POST_MISR_STATUS2 0x00000094 + +#define REG_HDMI_8996_PHY_POST_MISR_STATUS3 0x00000098 + +#define REG_HDMI_8996_PHY_STATUS 0x0000009c + +#define REG_HDMI_8996_PHY_MISC3_STATUS 0x000000a0 + +#define REG_HDMI_8996_PHY_MISC4_STATUS 0x000000a4 + +#define REG_HDMI_8996_PHY_DEBUG_BUS0 0x000000a8 + +#define REG_HDMI_8996_PHY_DEBUG_BUS1 0x000000ac + +#define REG_HDMI_8996_PHY_DEBUG_BUS2 0x000000b0 + +#define REG_HDMI_8996_PHY_DEBUG_BUS3 0x000000b4 + +#define REG_HDMI_8996_PHY_PHY_REVISION_ID0 0x000000b8 + +#define REG_HDMI_8996_PHY_PHY_REVISION_ID1 0x000000bc + +#define REG_HDMI_8996_PHY_PHY_REVISION_ID2 0x000000c0 + +#define REG_HDMI_8996_PHY_PHY_REVISION_ID3 0x000000c4 + +#define REG_HDMI_PHY_QSERDES_COM_ATB_SEL1 0x00000000 + +#define REG_HDMI_PHY_QSERDES_COM_ATB_SEL2 0x00000004 + +#define REG_HDMI_PHY_QSERDES_COM_FREQ_UPDATE 0x00000008 + +#define REG_HDMI_PHY_QSERDES_COM_BG_TIMER 0x0000000c + +#define REG_HDMI_PHY_QSERDES_COM_SSC_EN_CENTER 0x00000010 + +#define REG_HDMI_PHY_QSERDES_COM_SSC_ADJ_PER1 0x00000014 + +#define REG_HDMI_PHY_QSERDES_COM_SSC_ADJ_PER2 0x00000018 + +#define REG_HDMI_PHY_QSERDES_COM_SSC_PER1 0x0000001c + +#define REG_HDMI_PHY_QSERDES_COM_SSC_PER2 0x00000020 + +#define REG_HDMI_PHY_QSERDES_COM_SSC_STEP_SIZE1 0x00000024 + +#define REG_HDMI_PHY_QSERDES_COM_SSC_STEP_SIZE2 0x00000028 + +#define REG_HDMI_PHY_QSERDES_COM_POST_DIV 0x0000002c + +#define REG_HDMI_PHY_QSERDES_COM_POST_DIV_MUX 0x00000030 + +#define REG_HDMI_PHY_QSERDES_COM_BIAS_EN_CLKBUFLR_EN 0x00000034 + +#define REG_HDMI_PHY_QSERDES_COM_CLK_ENABLE1 0x00000038 + +#define REG_HDMI_PHY_QSERDES_COM_SYS_CLK_CTRL 0x0000003c + +#define REG_HDMI_PHY_QSERDES_COM_SYSCLK_BUF_ENABLE 0x00000040 + +#define REG_HDMI_PHY_QSERDES_COM_PLL_EN 0x00000044 + +#define REG_HDMI_PHY_QSERDES_COM_PLL_IVCO 0x00000048 + +#define REG_HDMI_PHY_QSERDES_COM_LOCK_CMP1_MODE0 0x0000004c + +#define REG_HDMI_PHY_QSERDES_COM_LOCK_CMP2_MODE0 0x00000050 + +#define REG_HDMI_PHY_QSERDES_COM_LOCK_CMP3_MODE0 0x00000054 + +#define REG_HDMI_PHY_QSERDES_COM_LOCK_CMP1_MODE1 0x00000058 + +#define REG_HDMI_PHY_QSERDES_COM_LOCK_CMP2_MODE1 0x0000005c + +#define REG_HDMI_PHY_QSERDES_COM_LOCK_CMP3_MODE1 0x00000060 + +#define REG_HDMI_PHY_QSERDES_COM_LOCK_CMP1_MODE2 0x00000064 + +#define REG_HDMI_PHY_QSERDES_COM_CMN_RSVD0 0x00000064 + +#define REG_HDMI_PHY_QSERDES_COM_LOCK_CMP2_MODE2 0x00000068 + +#define REG_HDMI_PHY_QSERDES_COM_EP_CLOCK_DETECT_CTRL 0x00000068 + +#define REG_HDMI_PHY_QSERDES_COM_LOCK_CMP3_MODE2 0x0000006c + +#define REG_HDMI_PHY_QSERDES_COM_SYSCLK_DET_COMP_STATUS 0x0000006c + +#define REG_HDMI_PHY_QSERDES_COM_BG_TRIM 0x00000070 + +#define REG_HDMI_PHY_QSERDES_COM_CLK_EP_DIV 0x00000074 + +#define REG_HDMI_PHY_QSERDES_COM_CP_CTRL_MODE0 0x00000078 + +#define REG_HDMI_PHY_QSERDES_COM_CP_CTRL_MODE1 0x0000007c + +#define REG_HDMI_PHY_QSERDES_COM_CP_CTRL_MODE2 0x00000080 + +#define REG_HDMI_PHY_QSERDES_COM_CMN_RSVD1 0x00000080 + +#define REG_HDMI_PHY_QSERDES_COM_PLL_RCTRL_MODE0 0x00000084 + +#define REG_HDMI_PHY_QSERDES_COM_PLL_RCTRL_MODE1 0x00000088 + +#define REG_HDMI_PHY_QSERDES_COM_PLL_RCTRL_MODE2 0x0000008c + +#define REG_HDMI_PHY_QSERDES_COM_CMN_RSVD2 0x0000008c + +#define REG_HDMI_PHY_QSERDES_COM_PLL_CCTRL_MODE0 0x00000090 + +#define REG_HDMI_PHY_QSERDES_COM_PLL_CCTRL_MODE1 0x00000094 + +#define REG_HDMI_PHY_QSERDES_COM_PLL_CCTRL_MODE2 0x00000098 + +#define REG_HDMI_PHY_QSERDES_COM_CMN_RSVD3 0x00000098 + +#define REG_HDMI_PHY_QSERDES_COM_PLL_CNTRL 0x0000009c + +#define REG_HDMI_PHY_QSERDES_COM_PHASE_SEL_CTRL 0x000000a0 + +#define REG_HDMI_PHY_QSERDES_COM_PHASE_SEL_DC 0x000000a4 + +#define REG_HDMI_PHY_QSERDES_COM_CORE_CLK_IN_SYNC_SEL 0x000000a8 + +#define REG_HDMI_PHY_QSERDES_COM_BIAS_EN_CTRL_BY_PSM 0x000000a8 + +#define REG_HDMI_PHY_QSERDES_COM_SYSCLK_EN_SEL 0x000000ac + +#define REG_HDMI_PHY_QSERDES_COM_CML_SYSCLK_SEL 0x000000b0 + +#define REG_HDMI_PHY_QSERDES_COM_RESETSM_CNTRL 0x000000b4 + +#define REG_HDMI_PHY_QSERDES_COM_RESETSM_CNTRL2 0x000000b8 + +#define REG_HDMI_PHY_QSERDES_COM_RESTRIM_CTRL 0x000000bc + +#define REG_HDMI_PHY_QSERDES_COM_RESTRIM_CTRL2 0x000000c0 + +#define REG_HDMI_PHY_QSERDES_COM_RESCODE_DIV_NUM 0x000000c4 + +#define REG_HDMI_PHY_QSERDES_COM_LOCK_CMP_EN 0x000000c8 + +#define REG_HDMI_PHY_QSERDES_COM_LOCK_CMP_CFG 0x000000cc + +#define REG_HDMI_PHY_QSERDES_COM_DEC_START_MODE0 0x000000d0 + +#define REG_HDMI_PHY_QSERDES_COM_DEC_START_MODE1 0x000000d4 + +#define REG_HDMI_PHY_QSERDES_COM_DEC_START_MODE2 0x000000d8 + +#define REG_HDMI_PHY_QSERDES_COM_VCOCAL_DEADMAN_CTRL 0x000000d8 + +#define REG_HDMI_PHY_QSERDES_COM_DIV_FRAC_START1_MODE0 0x000000dc + +#define REG_HDMI_PHY_QSERDES_COM_DIV_FRAC_START2_MODE0 0x000000e0 + +#define REG_HDMI_PHY_QSERDES_COM_DIV_FRAC_START3_MODE0 0x000000e4 + +#define REG_HDMI_PHY_QSERDES_COM_DIV_FRAC_START1_MODE1 0x000000e8 + +#define REG_HDMI_PHY_QSERDES_COM_DIV_FRAC_START2_MODE1 0x000000ec + +#define REG_HDMI_PHY_QSERDES_COM_DIV_FRAC_START3_MODE1 0x000000f0 + +#define REG_HDMI_PHY_QSERDES_COM_DIV_FRAC_START1_MODE2 0x000000f4 + +#define REG_HDMI_PHY_QSERDES_COM_VCO_TUNE_MINVAL1 0x000000f4 + +#define REG_HDMI_PHY_QSERDES_COM_DIV_FRAC_START2_MODE2 0x000000f8 + +#define REG_HDMI_PHY_QSERDES_COM_VCO_TUNE_MINVAL2 0x000000f8 + +#define REG_HDMI_PHY_QSERDES_COM_DIV_FRAC_START3_MODE2 0x000000fc + +#define REG_HDMI_PHY_QSERDES_COM_CMN_RSVD4 0x000000fc + +#define REG_HDMI_PHY_QSERDES_COM_INTEGLOOP_INITVAL 0x00000100 + +#define REG_HDMI_PHY_QSERDES_COM_INTEGLOOP_EN 0x00000104 + +#define REG_HDMI_PHY_QSERDES_COM_INTEGLOOP_GAIN0_MODE0 0x00000108 + +#define REG_HDMI_PHY_QSERDES_COM_INTEGLOOP_GAIN1_MODE0 0x0000010c + +#define REG_HDMI_PHY_QSERDES_COM_INTEGLOOP_GAIN0_MODE1 0x00000110 + +#define REG_HDMI_PHY_QSERDES_COM_INTEGLOOP_GAIN1_MODE1 0x00000114 + +#define REG_HDMI_PHY_QSERDES_COM_INTEGLOOP_GAIN0_MODE2 0x00000118 + +#define REG_HDMI_PHY_QSERDES_COM_VCO_TUNE_MAXVAL1 0x00000118 + +#define REG_HDMI_PHY_QSERDES_COM_INTEGLOOP_GAIN1_MODE2 0x0000011c + +#define REG_HDMI_PHY_QSERDES_COM_VCO_TUNE_MAXVAL2 0x0000011c + +#define REG_HDMI_PHY_QSERDES_COM_RES_TRIM_CONTROL2 0x00000120 + +#define REG_HDMI_PHY_QSERDES_COM_VCO_TUNE_CTRL 0x00000124 + +#define REG_HDMI_PHY_QSERDES_COM_VCO_TUNE_MAP 0x00000128 + +#define REG_HDMI_PHY_QSERDES_COM_VCO_TUNE1_MODE0 0x0000012c + +#define REG_HDMI_PHY_QSERDES_COM_VCO_TUNE2_MODE0 0x00000130 + +#define REG_HDMI_PHY_QSERDES_COM_VCO_TUNE1_MODE1 0x00000134 + +#define REG_HDMI_PHY_QSERDES_COM_VCO_TUNE2_MODE1 0x00000138 + +#define REG_HDMI_PHY_QSERDES_COM_VCO_TUNE1_MODE2 0x0000013c + +#define REG_HDMI_PHY_QSERDES_COM_VCO_TUNE_INITVAL1 0x0000013c + +#define REG_HDMI_PHY_QSERDES_COM_VCO_TUNE2_MODE2 0x00000140 + +#define REG_HDMI_PHY_QSERDES_COM_VCO_TUNE_INITVAL2 0x00000140 + +#define REG_HDMI_PHY_QSERDES_COM_VCO_TUNE_TIMER1 0x00000144 + +#define REG_HDMI_PHY_QSERDES_COM_VCO_TUNE_TIMER2 0x00000148 + +#define REG_HDMI_PHY_QSERDES_COM_SAR 0x0000014c + +#define REG_HDMI_PHY_QSERDES_COM_SAR_CLK 0x00000150 + +#define REG_HDMI_PHY_QSERDES_COM_SAR_CODE_OUT_STATUS 0x00000154 + +#define REG_HDMI_PHY_QSERDES_COM_SAR_CODE_READY_STATUS 0x00000158 + +#define REG_HDMI_PHY_QSERDES_COM_CMN_STATUS 0x0000015c + +#define REG_HDMI_PHY_QSERDES_COM_RESET_SM_STATUS 0x00000160 + +#define REG_HDMI_PHY_QSERDES_COM_RESTRIM_CODE_STATUS 0x00000164 + +#define REG_HDMI_PHY_QSERDES_COM_PLLCAL_CODE1_STATUS 0x00000168 + +#define REG_HDMI_PHY_QSERDES_COM_PLLCAL_CODE2_STATUS 0x0000016c + +#define REG_HDMI_PHY_QSERDES_COM_BG_CTRL 0x00000170 + +#define REG_HDMI_PHY_QSERDES_COM_CLK_SELECT 0x00000174 + +#define REG_HDMI_PHY_QSERDES_COM_HSCLK_SEL 0x00000178 + +#define REG_HDMI_PHY_QSERDES_COM_INTEGLOOP_BINCODE_STATUS 0x0000017c + +#define REG_HDMI_PHY_QSERDES_COM_PLL_ANALOG 0x00000180 + +#define REG_HDMI_PHY_QSERDES_COM_CORECLK_DIV 0x00000184 + +#define REG_HDMI_PHY_QSERDES_COM_SW_RESET 0x00000188 + +#define REG_HDMI_PHY_QSERDES_COM_CORE_CLK_EN 0x0000018c + +#define REG_HDMI_PHY_QSERDES_COM_C_READY_STATUS 0x00000190 + +#define REG_HDMI_PHY_QSERDES_COM_CMN_CONFIG 0x00000194 + +#define REG_HDMI_PHY_QSERDES_COM_CMN_RATE_OVERRIDE 0x00000198 + +#define REG_HDMI_PHY_QSERDES_COM_SVS_MODE_CLK_SEL 0x0000019c + +#define REG_HDMI_PHY_QSERDES_COM_DEBUG_BUS0 0x000001a0 + +#define REG_HDMI_PHY_QSERDES_COM_DEBUG_BUS1 0x000001a4 + +#define REG_HDMI_PHY_QSERDES_COM_DEBUG_BUS2 0x000001a8 + +#define REG_HDMI_PHY_QSERDES_COM_DEBUG_BUS3 0x000001ac + +#define REG_HDMI_PHY_QSERDES_COM_DEBUG_BUS_SEL 0x000001b0 + +#define REG_HDMI_PHY_QSERDES_COM_CMN_MISC1 0x000001b4 + +#define REG_HDMI_PHY_QSERDES_COM_CMN_MISC2 0x000001b8 + +#define REG_HDMI_PHY_QSERDES_COM_CORECLK_DIV_MODE1 0x000001bc + +#define REG_HDMI_PHY_QSERDES_COM_CORECLK_DIV_MODE2 0x000001c0 + +#define REG_HDMI_PHY_QSERDES_COM_CMN_RSVD5 0x000001c4 + +#define REG_HDMI_PHY_QSERDES_TX_LX_BIST_MODE_LANENO 0x00000000 + +#define REG_HDMI_PHY_QSERDES_TX_LX_BIST_INVERT 0x00000004 + +#define REG_HDMI_PHY_QSERDES_TX_LX_CLKBUF_ENABLE 0x00000008 + +#define REG_HDMI_PHY_QSERDES_TX_LX_CMN_CONTROL_ONE 0x0000000c + +#define REG_HDMI_PHY_QSERDES_TX_LX_CMN_CONTROL_TWO 0x00000010 + +#define REG_HDMI_PHY_QSERDES_TX_LX_CMN_CONTROL_THREE 0x00000014 + +#define REG_HDMI_PHY_QSERDES_TX_LX_TX_EMP_POST1_LVL 0x00000018 + +#define REG_HDMI_PHY_QSERDES_TX_LX_TX_POST2_EMPH 0x0000001c + +#define REG_HDMI_PHY_QSERDES_TX_LX_TX_BOOST_LVL_UP_DN 0x00000020 + +#define REG_HDMI_PHY_QSERDES_TX_LX_HP_PD_ENABLES 0x00000024 + +#define REG_HDMI_PHY_QSERDES_TX_LX_TX_IDLE_LVL_LARGE_AMP 0x00000028 + +#define REG_HDMI_PHY_QSERDES_TX_LX_TX_DRV_LVL 0x0000002c + +#define REG_HDMI_PHY_QSERDES_TX_LX_TX_DRV_LVL_OFFSET 0x00000030 + +#define REG_HDMI_PHY_QSERDES_TX_LX_RESET_TSYNC_EN 0x00000034 + +#define REG_HDMI_PHY_QSERDES_TX_LX_PRE_STALL_LDO_BOOST_EN 0x00000038 + +#define REG_HDMI_PHY_QSERDES_TX_LX_TX_BAND 0x0000003c + +#define REG_HDMI_PHY_QSERDES_TX_LX_SLEW_CNTL 0x00000040 + +#define REG_HDMI_PHY_QSERDES_TX_LX_INTERFACE_SELECT 0x00000044 + +#define REG_HDMI_PHY_QSERDES_TX_LX_LPB_EN 0x00000048 + +#define REG_HDMI_PHY_QSERDES_TX_LX_RES_CODE_LANE_TX 0x0000004c + +#define REG_HDMI_PHY_QSERDES_TX_LX_RES_CODE_LANE_RX 0x00000050 + +#define REG_HDMI_PHY_QSERDES_TX_LX_RES_CODE_LANE_OFFSET 0x00000054 + +#define REG_HDMI_PHY_QSERDES_TX_LX_PERL_LENGTH1 0x00000058 + +#define REG_HDMI_PHY_QSERDES_TX_LX_PERL_LENGTH2 0x0000005c + +#define REG_HDMI_PHY_QSERDES_TX_LX_SERDES_BYP_EN_OUT 0x00000060 + +#define REG_HDMI_PHY_QSERDES_TX_LX_DEBUG_BUS_SEL 0x00000064 + +#define REG_HDMI_PHY_QSERDES_TX_LX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN 0x00000068 + +#define REG_HDMI_PHY_QSERDES_TX_LX_TX_POL_INV 0x0000006c + +#define REG_HDMI_PHY_QSERDES_TX_LX_PARRATE_REC_DETECT_IDLE_EN 0x00000070 + +#define REG_HDMI_PHY_QSERDES_TX_LX_BIST_PATTERN1 0x00000074 + +#define REG_HDMI_PHY_QSERDES_TX_LX_BIST_PATTERN2 0x00000078 + +#define REG_HDMI_PHY_QSERDES_TX_LX_BIST_PATTERN3 0x0000007c + +#define REG_HDMI_PHY_QSERDES_TX_LX_BIST_PATTERN4 0x00000080 + +#define REG_HDMI_PHY_QSERDES_TX_LX_BIST_PATTERN5 0x00000084 + +#define REG_HDMI_PHY_QSERDES_TX_LX_BIST_PATTERN6 0x00000088 + +#define REG_HDMI_PHY_QSERDES_TX_LX_BIST_PATTERN7 0x0000008c + +#define REG_HDMI_PHY_QSERDES_TX_LX_BIST_PATTERN8 0x00000090 + +#define REG_HDMI_PHY_QSERDES_TX_LX_LANE_MODE 0x00000094 + +#define REG_HDMI_PHY_QSERDES_TX_LX_IDAC_CAL_LANE_MODE 0x00000098 + +#define REG_HDMI_PHY_QSERDES_TX_LX_IDAC_CAL_LANE_MODE_CONFIGURATION 0x0000009c + +#define REG_HDMI_PHY_QSERDES_TX_LX_ATB_SEL1 0x000000a0 + +#define REG_HDMI_PHY_QSERDES_TX_LX_ATB_SEL2 0x000000a4 + +#define REG_HDMI_PHY_QSERDES_TX_LX_RCV_DETECT_LVL 0x000000a8 + +#define REG_HDMI_PHY_QSERDES_TX_LX_RCV_DETECT_LVL_2 0x000000ac + +#define REG_HDMI_PHY_QSERDES_TX_LX_PRBS_SEED1 0x000000b0 + +#define REG_HDMI_PHY_QSERDES_TX_LX_PRBS_SEED2 0x000000b4 + +#define REG_HDMI_PHY_QSERDES_TX_LX_PRBS_SEED3 0x000000b8 + +#define REG_HDMI_PHY_QSERDES_TX_LX_PRBS_SEED4 0x000000bc + +#define REG_HDMI_PHY_QSERDES_TX_LX_RESET_GEN 0x000000c0 + +#define REG_HDMI_PHY_QSERDES_TX_LX_RESET_GEN_MUXES 0x000000c4 + +#define REG_HDMI_PHY_QSERDES_TX_LX_TRAN_DRVR_EMP_EN 0x000000c8 + +#define REG_HDMI_PHY_QSERDES_TX_LX_TX_INTERFACE_MODE 0x000000cc + +#define REG_HDMI_PHY_QSERDES_TX_LX_PWM_CTRL 0x000000d0 + +#define REG_HDMI_PHY_QSERDES_TX_LX_PWM_ENCODED_OR_DATA 0x000000d4 + +#define REG_HDMI_PHY_QSERDES_TX_LX_PWM_GEAR_1_DIVIDER_BAND2 0x000000d8 + +#define REG_HDMI_PHY_QSERDES_TX_LX_PWM_GEAR_2_DIVIDER_BAND2 0x000000dc + +#define REG_HDMI_PHY_QSERDES_TX_LX_PWM_GEAR_3_DIVIDER_BAND2 0x000000e0 + +#define REG_HDMI_PHY_QSERDES_TX_LX_PWM_GEAR_4_DIVIDER_BAND2 0x000000e4 + +#define REG_HDMI_PHY_QSERDES_TX_LX_PWM_GEAR_1_DIVIDER_BAND0_1 0x000000e8 + +#define REG_HDMI_PHY_QSERDES_TX_LX_PWM_GEAR_2_DIVIDER_BAND0_1 0x000000ec + +#define REG_HDMI_PHY_QSERDES_TX_LX_PWM_GEAR_3_DIVIDER_BAND0_1 0x000000f0 + +#define REG_HDMI_PHY_QSERDES_TX_LX_PWM_GEAR_4_DIVIDER_BAND0_1 0x000000f4 + +#define REG_HDMI_PHY_QSERDES_TX_LX_VMODE_CTRL1 0x000000f8 + +#define REG_HDMI_PHY_QSERDES_TX_LX_VMODE_CTRL2 0x000000fc + +#define REG_HDMI_PHY_QSERDES_TX_LX_TX_ALOG_INTF_OBSV_CNTL 0x00000100 + +#define REG_HDMI_PHY_QSERDES_TX_LX_BIST_STATUS 0x00000104 + +#define REG_HDMI_PHY_QSERDES_TX_LX_BIST_ERROR_COUNT1 0x00000108 + +#define REG_HDMI_PHY_QSERDES_TX_LX_BIST_ERROR_COUNT2 0x0000010c + +#define REG_HDMI_PHY_QSERDES_TX_LX_TX_ALOG_INTF_OBSV 0x00000110 + #endif /* HDMI_XML */ diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_audio.c b/drivers/gpu/drm/msm/hdmi/hdmi_audio.c index df232e20c..a54d3bb5b 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_audio.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_audio.c @@ -89,7 +89,7 @@ static const struct hdmi_msm_audio_arcs *get_arcs(unsigned long int pixclock) return NULL; } -int hdmi_audio_update(struct hdmi *hdmi) +int msm_hdmi_audio_update(struct hdmi *hdmi) { struct hdmi_audio *audio = &hdmi->audio; struct hdmi_audio_infoframe *info = &audio->infoframe; @@ -232,7 +232,7 @@ int hdmi_audio_update(struct hdmi *hdmi) return 0; } -int hdmi_audio_info_setup(struct hdmi *hdmi, bool enabled, +int msm_hdmi_audio_info_setup(struct hdmi *hdmi, bool enabled, uint32_t num_of_channels, uint32_t channel_allocation, uint32_t level_shift, bool down_mix) { @@ -252,10 +252,10 @@ int hdmi_audio_info_setup(struct hdmi *hdmi, bool enabled, audio->infoframe.level_shift_value = level_shift; audio->infoframe.downmix_inhibit = down_mix; - return hdmi_audio_update(hdmi); + return msm_hdmi_audio_update(hdmi); } -void hdmi_audio_set_sample_rate(struct hdmi *hdmi, int rate) +void msm_hdmi_audio_set_sample_rate(struct hdmi *hdmi, int rate) { struct hdmi_audio *audio; @@ -268,5 +268,5 @@ void hdmi_audio_set_sample_rate(struct hdmi *hdmi, int rate) return; audio->rate = rate; - hdmi_audio_update(hdmi); + msm_hdmi_audio_update(hdmi); } diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c index 92b69ae8c..bacbd5d8d 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c @@ -23,11 +23,11 @@ struct hdmi_bridge { }; #define to_hdmi_bridge(x) container_of(x, struct hdmi_bridge, base) -void hdmi_bridge_destroy(struct drm_bridge *bridge) +void msm_hdmi_bridge_destroy(struct drm_bridge *bridge) { } -static void power_on(struct drm_bridge *bridge) +static void msm_hdmi_power_on(struct drm_bridge *bridge) { struct drm_device *dev = bridge->dev; struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); @@ -86,7 +86,7 @@ static void power_off(struct drm_bridge *bridge) } } -static void hdmi_bridge_pre_enable(struct drm_bridge *bridge) +static void msm_hdmi_bridge_pre_enable(struct drm_bridge *bridge) { struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); struct hdmi *hdmi = hdmi_bridge->hdmi; @@ -95,51 +95,51 @@ static void hdmi_bridge_pre_enable(struct drm_bridge *bridge) DBG("power up"); if (!hdmi->power_on) { - power_on(bridge); + msm_hdmi_phy_resource_enable(phy); + msm_hdmi_power_on(bridge); hdmi->power_on = true; - hdmi_audio_update(hdmi); + msm_hdmi_audio_update(hdmi); } - if (phy) - phy->funcs->powerup(phy, hdmi->pixclock); + msm_hdmi_phy_powerup(phy, hdmi->pixclock); - hdmi_set_mode(hdmi, true); + msm_hdmi_set_mode(hdmi, true); if (hdmi->hdcp_ctrl) - hdmi_hdcp_on(hdmi->hdcp_ctrl); + msm_hdmi_hdcp_on(hdmi->hdcp_ctrl); } -static void hdmi_bridge_enable(struct drm_bridge *bridge) +static void msm_hdmi_bridge_enable(struct drm_bridge *bridge) { } -static void hdmi_bridge_disable(struct drm_bridge *bridge) +static void msm_hdmi_bridge_disable(struct drm_bridge *bridge) { } -static void hdmi_bridge_post_disable(struct drm_bridge *bridge) +static void msm_hdmi_bridge_post_disable(struct drm_bridge *bridge) { struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); struct hdmi *hdmi = hdmi_bridge->hdmi; struct hdmi_phy *phy = hdmi->phy; if (hdmi->hdcp_ctrl) - hdmi_hdcp_off(hdmi->hdcp_ctrl); + msm_hdmi_hdcp_off(hdmi->hdcp_ctrl); DBG("power down"); - hdmi_set_mode(hdmi, false); + msm_hdmi_set_mode(hdmi, false); - if (phy) - phy->funcs->powerdown(phy); + msm_hdmi_phy_powerdown(phy); if (hdmi->power_on) { power_off(bridge); hdmi->power_on = false; - hdmi_audio_update(hdmi); + msm_hdmi_audio_update(hdmi); + msm_hdmi_phy_resource_disable(phy); } } -static void hdmi_bridge_mode_set(struct drm_bridge *bridge, +static void msm_hdmi_bridge_mode_set(struct drm_bridge *bridge, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { @@ -196,20 +196,20 @@ static void hdmi_bridge_mode_set(struct drm_bridge *bridge, DBG("frame_ctrl=%08x", frame_ctrl); hdmi_write(hdmi, REG_HDMI_FRAME_CTRL, frame_ctrl); - hdmi_audio_update(hdmi); + msm_hdmi_audio_update(hdmi); } -static const struct drm_bridge_funcs hdmi_bridge_funcs = { - .pre_enable = hdmi_bridge_pre_enable, - .enable = hdmi_bridge_enable, - .disable = hdmi_bridge_disable, - .post_disable = hdmi_bridge_post_disable, - .mode_set = hdmi_bridge_mode_set, +static const struct drm_bridge_funcs msm_hdmi_bridge_funcs = { + .pre_enable = msm_hdmi_bridge_pre_enable, + .enable = msm_hdmi_bridge_enable, + .disable = msm_hdmi_bridge_disable, + .post_disable = msm_hdmi_bridge_post_disable, + .mode_set = msm_hdmi_bridge_mode_set, }; /* initialize bridge */ -struct drm_bridge *hdmi_bridge_init(struct hdmi *hdmi) +struct drm_bridge *msm_hdmi_bridge_init(struct hdmi *hdmi) { struct drm_bridge *bridge = NULL; struct hdmi_bridge *hdmi_bridge; @@ -225,7 +225,7 @@ struct drm_bridge *hdmi_bridge_init(struct hdmi *hdmi) hdmi_bridge->hdmi = hdmi; bridge = &hdmi_bridge->base; - bridge->funcs = &hdmi_bridge_funcs; + bridge->funcs = &msm_hdmi_bridge_funcs; ret = drm_bridge_attach(hdmi->dev, bridge); if (ret) @@ -235,7 +235,7 @@ struct drm_bridge *hdmi_bridge_init(struct hdmi *hdmi) fail: if (bridge) - hdmi_bridge_destroy(bridge); + msm_hdmi_bridge_destroy(bridge); return ERR_PTR(ret); } diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c index a3b05ae52..26129bff2 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c @@ -28,7 +28,7 @@ struct hdmi_connector { }; #define to_hdmi_connector(x) container_of(x, struct hdmi_connector, base) -static void hdmi_phy_reset(struct hdmi *hdmi) +static void msm_hdmi_phy_reset(struct hdmi *hdmi) { unsigned int val; @@ -81,114 +81,54 @@ static int gpio_config(struct hdmi *hdmi, bool on) { struct device *dev = &hdmi->pdev->dev; const struct hdmi_platform_config *config = hdmi->config; - int ret; + int ret, i; if (on) { - if (config->ddc_clk_gpio != -1) { - ret = gpio_request(config->ddc_clk_gpio, "HDMI_DDC_CLK"); - if (ret) { - dev_err(dev, "'%s'(%d) gpio_request failed: %d\n", - "HDMI_DDC_CLK", config->ddc_clk_gpio, ret); - goto error1; - } - gpio_set_value_cansleep(config->ddc_clk_gpio, 1); - } - - if (config->ddc_data_gpio != -1) { - ret = gpio_request(config->ddc_data_gpio, "HDMI_DDC_DATA"); - if (ret) { - dev_err(dev, "'%s'(%d) gpio_request failed: %d\n", - "HDMI_DDC_DATA", config->ddc_data_gpio, ret); - goto error2; - } - gpio_set_value_cansleep(config->ddc_data_gpio, 1); - } - - ret = gpio_request(config->hpd_gpio, "HDMI_HPD"); - if (ret) { - dev_err(dev, "'%s'(%d) gpio_request failed: %d\n", - "HDMI_HPD", config->hpd_gpio, ret); - goto error3; - } - gpio_direction_input(config->hpd_gpio); - gpio_set_value_cansleep(config->hpd_gpio, 1); - - if (config->mux_en_gpio != -1) { - ret = gpio_request(config->mux_en_gpio, "HDMI_MUX_EN"); - if (ret) { - dev_err(dev, "'%s'(%d) gpio_request failed: %d\n", - "HDMI_MUX_EN", config->mux_en_gpio, ret); - goto error4; - } - gpio_set_value_cansleep(config->mux_en_gpio, 1); - } - - if (config->mux_sel_gpio != -1) { - ret = gpio_request(config->mux_sel_gpio, "HDMI_MUX_SEL"); - if (ret) { - dev_err(dev, "'%s'(%d) gpio_request failed: %d\n", - "HDMI_MUX_SEL", config->mux_sel_gpio, ret); - goto error5; + for (i = 0; i < HDMI_MAX_NUM_GPIO; i++) { + struct hdmi_gpio_data gpio = config->gpios[i]; + + if (gpio.num != -1) { + ret = gpio_request(gpio.num, gpio.label); + if (ret) { + dev_err(dev, + "'%s'(%d) gpio_request failed: %d\n", + gpio.label, gpio.num, ret); + goto err; + } + + if (gpio.output) { + gpio_direction_output(gpio.num, + gpio.value); + } else { + gpio_direction_input(gpio.num); + gpio_set_value_cansleep(gpio.num, + gpio.value); + } } - gpio_set_value_cansleep(config->mux_sel_gpio, 0); } - if (config->mux_lpm_gpio != -1) { - ret = gpio_request(config->mux_lpm_gpio, - "HDMI_MUX_LPM"); - if (ret) { - dev_err(dev, - "'%s'(%d) gpio_request failed: %d\n", - "HDMI_MUX_LPM", - config->mux_lpm_gpio, ret); - goto error6; - } - gpio_set_value_cansleep(config->mux_lpm_gpio, 1); - } DBG("gpio on"); } else { - if (config->ddc_clk_gpio != -1) - gpio_free(config->ddc_clk_gpio); - - if (config->ddc_data_gpio != -1) - gpio_free(config->ddc_data_gpio); + for (i = 0; i < HDMI_MAX_NUM_GPIO; i++) { + struct hdmi_gpio_data gpio = config->gpios[i]; - gpio_free(config->hpd_gpio); + if (gpio.output) { + int value = gpio.value ? 0 : 1; - if (config->mux_en_gpio != -1) { - gpio_set_value_cansleep(config->mux_en_gpio, 0); - gpio_free(config->mux_en_gpio); - } + gpio_set_value_cansleep(gpio.num, value); + } - if (config->mux_sel_gpio != -1) { - gpio_set_value_cansleep(config->mux_sel_gpio, 1); - gpio_free(config->mux_sel_gpio); - } + gpio_free(gpio.num); + }; - if (config->mux_lpm_gpio != -1) { - gpio_set_value_cansleep(config->mux_lpm_gpio, 0); - gpio_free(config->mux_lpm_gpio); - } DBG("gpio off"); } return 0; +err: + while (i--) + gpio_free(config->gpios[i].num); -error6: - if (config->mux_sel_gpio != -1) - gpio_free(config->mux_sel_gpio); -error5: - if (config->mux_en_gpio != -1) - gpio_free(config->mux_en_gpio); -error4: - gpio_free(config->hpd_gpio); -error3: - if (config->ddc_data_gpio != -1) - gpio_free(config->ddc_data_gpio); -error2: - if (config->ddc_clk_gpio != -1) - gpio_free(config->ddc_clk_gpio); -error1: return ret; } @@ -239,9 +179,9 @@ static int hpd_enable(struct hdmi_connector *hdmi_connector) } } - hdmi_set_mode(hdmi, false); - hdmi_phy_reset(hdmi); - hdmi_set_mode(hdmi, true); + msm_hdmi_set_mode(hdmi, false); + msm_hdmi_phy_reset(hdmi); + msm_hdmi_set_mode(hdmi, true); hdmi_write(hdmi, REG_HDMI_USEC_REFTIMER, 0x0001001b); @@ -278,7 +218,7 @@ static void hdp_disable(struct hdmi_connector *hdmi_connector) /* Disable HPD interrupt */ hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL, 0); - hdmi_set_mode(hdmi, false); + msm_hdmi_set_mode(hdmi, false); for (i = 0; i < config->hpd_clk_cnt; i++) clk_disable_unprepare(hdmi->hpd_clks[i]); @@ -300,7 +240,7 @@ static void hdp_disable(struct hdmi_connector *hdmi_connector) } static void -hotplug_work(struct work_struct *work) +msm_hdmi_hotplug_work(struct work_struct *work) { struct hdmi_connector *hdmi_connector = container_of(work, struct hdmi_connector, hpd_work); @@ -308,7 +248,7 @@ hotplug_work(struct work_struct *work) drm_helper_hpd_irq_event(connector->dev); } -void hdmi_connector_irq(struct drm_connector *connector) +void msm_hdmi_connector_irq(struct drm_connector *connector) { struct hdmi_connector *hdmi_connector = to_hdmi_connector(connector); struct hdmi *hdmi = hdmi_connector->hdmi; @@ -345,10 +285,13 @@ static enum drm_connector_status detect_reg(struct hdmi *hdmi) connector_status_connected : connector_status_disconnected; } +#define HPD_GPIO_INDEX 2 static enum drm_connector_status detect_gpio(struct hdmi *hdmi) { const struct hdmi_platform_config *config = hdmi->config; - return gpio_get_value(config->hpd_gpio) ? + struct hdmi_gpio_data hpd_gpio = config->gpios[HPD_GPIO_INDEX]; + + return gpio_get_value(hpd_gpio.num) ? connector_status_connected : connector_status_disconnected; } @@ -358,9 +301,18 @@ static enum drm_connector_status hdmi_connector_detect( { struct hdmi_connector *hdmi_connector = to_hdmi_connector(connector); struct hdmi *hdmi = hdmi_connector->hdmi; + const struct hdmi_platform_config *config = hdmi->config; + struct hdmi_gpio_data hpd_gpio = config->gpios[HPD_GPIO_INDEX]; enum drm_connector_status stat_gpio, stat_reg; int retry = 20; + /* + * some platforms may not have hpd gpio. Rely only on the status + * provided by REG_HDMI_HPD_INT_STATUS in this case. + */ + if (hpd_gpio.num == -1) + return detect_reg(hdmi); + do { stat_gpio = detect_gpio(hdmi); stat_reg = detect_reg(hdmi); @@ -395,7 +347,7 @@ static void hdmi_connector_destroy(struct drm_connector *connector) kfree(hdmi_connector); } -static int hdmi_connector_get_modes(struct drm_connector *connector) +static int msm_hdmi_connector_get_modes(struct drm_connector *connector) { struct hdmi_connector *hdmi_connector = to_hdmi_connector(connector); struct hdmi *hdmi = hdmi_connector->hdmi; @@ -421,7 +373,7 @@ static int hdmi_connector_get_modes(struct drm_connector *connector) return ret; } -static int hdmi_connector_mode_valid(struct drm_connector *connector, +static int msm_hdmi_connector_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { struct hdmi_connector *hdmi_connector = to_hdmi_connector(connector); @@ -451,7 +403,7 @@ static int hdmi_connector_mode_valid(struct drm_connector *connector, } static struct drm_encoder * -hdmi_connector_best_encoder(struct drm_connector *connector) +msm_hdmi_connector_best_encoder(struct drm_connector *connector) { struct hdmi_connector *hdmi_connector = to_hdmi_connector(connector); return hdmi_connector->hdmi->encoder; @@ -467,14 +419,14 @@ static const struct drm_connector_funcs hdmi_connector_funcs = { .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; -static const struct drm_connector_helper_funcs hdmi_connector_helper_funcs = { - .get_modes = hdmi_connector_get_modes, - .mode_valid = hdmi_connector_mode_valid, - .best_encoder = hdmi_connector_best_encoder, +static const struct drm_connector_helper_funcs msm_hdmi_connector_helper_funcs = { + .get_modes = msm_hdmi_connector_get_modes, + .mode_valid = msm_hdmi_connector_mode_valid, + .best_encoder = msm_hdmi_connector_best_encoder, }; /* initialize connector */ -struct drm_connector *hdmi_connector_init(struct hdmi *hdmi) +struct drm_connector *msm_hdmi_connector_init(struct hdmi *hdmi) { struct drm_connector *connector = NULL; struct hdmi_connector *hdmi_connector; @@ -487,13 +439,13 @@ struct drm_connector *hdmi_connector_init(struct hdmi *hdmi) } hdmi_connector->hdmi = hdmi; - INIT_WORK(&hdmi_connector->hpd_work, hotplug_work); + INIT_WORK(&hdmi_connector->hpd_work, msm_hdmi_hotplug_work); connector = &hdmi_connector->base; drm_connector_init(hdmi->dev, connector, &hdmi_connector_funcs, DRM_MODE_CONNECTOR_HDMIA); - drm_connector_helper_add(connector, &hdmi_connector_helper_funcs); + drm_connector_helper_add(connector, &msm_hdmi_connector_helper_funcs); connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_hdcp.c b/drivers/gpu/drm/msm/hdmi/hdmi_hdcp.c index 1dc9c34eb..0baaaaabd 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_hdcp.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_hdcp.c @@ -84,7 +84,7 @@ struct hdmi_hdcp_ctrl { bool max_dev_exceeded; }; -static int hdmi_ddc_read(struct hdmi *hdmi, u16 addr, u8 offset, +static int msm_hdmi_ddc_read(struct hdmi *hdmi, u16 addr, u8 offset, u8 *data, u16 data_len) { int rc; @@ -122,7 +122,7 @@ retry: #define HDCP_DDC_WRITE_MAX_BYTE_NUM 32 -static int hdmi_ddc_write(struct hdmi *hdmi, u16 addr, u8 offset, +static int msm_hdmi_ddc_write(struct hdmi *hdmi, u16 addr, u8 offset, u8 *data, u16 data_len) { int rc; @@ -162,7 +162,7 @@ retry: return rc; } -static int hdmi_hdcp_scm_wr(struct hdmi_hdcp_ctrl *hdcp_ctrl, u32 *preg, +static int msm_hdmi_hdcp_scm_wr(struct hdmi_hdcp_ctrl *hdcp_ctrl, u32 *preg, u32 *pdata, u32 count) { struct hdmi *hdmi = hdcp_ctrl->hdmi; @@ -202,7 +202,7 @@ static int hdmi_hdcp_scm_wr(struct hdmi_hdcp_ctrl *hdcp_ctrl, u32 *preg, return ret; } -void hdmi_hdcp_irq(struct hdmi_hdcp_ctrl *hdcp_ctrl) +void msm_hdmi_hdcp_irq(struct hdmi_hdcp_ctrl *hdcp_ctrl) { struct hdmi *hdmi = hdcp_ctrl->hdmi; u32 reg_val, hdcp_int_status; @@ -247,7 +247,7 @@ void hdmi_hdcp_irq(struct hdmi_hdcp_ctrl *hdcp_ctrl) } } -static int hdmi_hdcp_msleep(struct hdmi_hdcp_ctrl *hdcp_ctrl, u32 ms, u32 ev) +static int msm_hdmi_hdcp_msleep(struct hdmi_hdcp_ctrl *hdcp_ctrl, u32 ms, u32 ev) { int rc; @@ -264,7 +264,7 @@ static int hdmi_hdcp_msleep(struct hdmi_hdcp_ctrl *hdcp_ctrl, u32 ms, u32 ev) return 0; } -static int hdmi_hdcp_read_validate_aksv(struct hdmi_hdcp_ctrl *hdcp_ctrl) +static int msm_hdmi_hdcp_read_validate_aksv(struct hdmi_hdcp_ctrl *hdcp_ctrl) { struct hdmi *hdmi = hdcp_ctrl->hdmi; @@ -287,7 +287,7 @@ static int hdmi_hdcp_read_validate_aksv(struct hdmi_hdcp_ctrl *hdcp_ctrl) return 0; } -static int reset_hdcp_ddc_failures(struct hdmi_hdcp_ctrl *hdcp_ctrl) +static int msm_reset_hdcp_ddc_failures(struct hdmi_hdcp_ctrl *hdcp_ctrl) { struct hdmi *hdmi = hdcp_ctrl->hdmi; u32 reg_val, failure, nack0; @@ -337,7 +337,7 @@ static int reset_hdcp_ddc_failures(struct hdmi_hdcp_ctrl *hdcp_ctrl) reg_val |= HDMI_DDC_CTRL_SW_STATUS_RESET; hdmi_write(hdmi, REG_HDMI_DDC_CTRL, reg_val); - rc = hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV); + rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV); reg_val = hdmi_read(hdmi, REG_HDMI_DDC_CTRL); reg_val &= ~HDMI_DDC_CTRL_SW_STATUS_RESET; @@ -350,7 +350,7 @@ static int reset_hdcp_ddc_failures(struct hdmi_hdcp_ctrl *hdcp_ctrl) /* If previous msleep is aborted, skip this msleep */ if (!rc) - rc = hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV); + rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV); reg_val = hdmi_read(hdmi, REG_HDMI_DDC_CTRL); reg_val &= ~HDMI_DDC_CTRL_SOFT_RESET; @@ -362,7 +362,7 @@ static int reset_hdcp_ddc_failures(struct hdmi_hdcp_ctrl *hdcp_ctrl) return rc; } -static int hdmi_hdcp_hw_ddc_clean(struct hdmi_hdcp_ctrl *hdcp_ctrl) +static int msm_hdmi_hdcp_hw_ddc_clean(struct hdmi_hdcp_ctrl *hdcp_ctrl) { int rc; u32 hdcp_ddc_status, ddc_hw_status; @@ -394,7 +394,7 @@ static int hdmi_hdcp_hw_ddc_clean(struct hdmi_hdcp_ctrl *hdcp_ctrl) return -ETIMEDOUT; } - rc = hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV); + rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV); if (rc) return rc; } while (1); @@ -402,7 +402,7 @@ static int hdmi_hdcp_hw_ddc_clean(struct hdmi_hdcp_ctrl *hdcp_ctrl) return 0; } -static void hdmi_hdcp_reauth_work(struct work_struct *work) +static void msm_hdmi_hdcp_reauth_work(struct work_struct *work) { struct hdmi_hdcp_ctrl *hdcp_ctrl = container_of(work, struct hdmi_hdcp_ctrl, hdcp_reauth_work); @@ -430,7 +430,7 @@ static void hdmi_hdcp_reauth_work(struct work_struct *work) HDMI_HDCP_RESET_LINK0_DEAUTHENTICATE); /* Wait to be clean on DDC HW engine */ - if (hdmi_hdcp_hw_ddc_clean(hdcp_ctrl)) { + if (msm_hdmi_hdcp_hw_ddc_clean(hdcp_ctrl)) { pr_info("%s: reauth work aborted\n", __func__); return; } @@ -461,7 +461,7 @@ static void hdmi_hdcp_reauth_work(struct work_struct *work) queue_work(hdmi->workq, &hdcp_ctrl->hdcp_auth_work); } -static int hdmi_hdcp_auth_prepare(struct hdmi_hdcp_ctrl *hdcp_ctrl) +static int msm_hdmi_hdcp_auth_prepare(struct hdmi_hdcp_ctrl *hdcp_ctrl) { struct hdmi *hdmi = hdcp_ctrl->hdmi; u32 link0_status; @@ -470,7 +470,7 @@ static int hdmi_hdcp_auth_prepare(struct hdmi_hdcp_ctrl *hdcp_ctrl) int rc; if (!hdcp_ctrl->aksv_valid) { - rc = hdmi_hdcp_read_validate_aksv(hdcp_ctrl); + rc = msm_hdmi_hdcp_read_validate_aksv(hdcp_ctrl); if (rc) { pr_err("%s: ASKV validation failed\n", __func__); hdcp_ctrl->hdcp_state = HDCP_STATE_NO_AKSV; @@ -538,12 +538,12 @@ static int hdmi_hdcp_auth_prepare(struct hdmi_hdcp_ctrl *hdcp_ctrl) DBG("An not ready after enabling HDCP"); /* Clear any DDC failures from previous tries before enable HDCP*/ - rc = reset_hdcp_ddc_failures(hdcp_ctrl); + rc = msm_reset_hdcp_ddc_failures(hdcp_ctrl); return rc; } -static void hdmi_hdcp_auth_fail(struct hdmi_hdcp_ctrl *hdcp_ctrl) +static void msm_hdmi_hdcp_auth_fail(struct hdmi_hdcp_ctrl *hdcp_ctrl) { struct hdmi *hdmi = hdcp_ctrl->hdmi; u32 reg_val; @@ -561,7 +561,7 @@ static void hdmi_hdcp_auth_fail(struct hdmi_hdcp_ctrl *hdcp_ctrl) queue_work(hdmi->workq, &hdcp_ctrl->hdcp_reauth_work); } -static void hdmi_hdcp_auth_done(struct hdmi_hdcp_ctrl *hdcp_ctrl) +static void msm_hdmi_hdcp_auth_done(struct hdmi_hdcp_ctrl *hdcp_ctrl) { struct hdmi *hdmi = hdcp_ctrl->hdmi; u32 reg_val; @@ -596,7 +596,7 @@ static void hdmi_hdcp_auth_done(struct hdmi_hdcp_ctrl *hdcp_ctrl) * Write An and AKSV to sink * Read BKSV from sink and write into HDCP engine */ -static int hdmi_hdcp_wait_key_an_ready(struct hdmi_hdcp_ctrl *hdcp_ctrl) +static int msm_hdmi_hdcp_wait_key_an_ready(struct hdmi_hdcp_ctrl *hdcp_ctrl) { int rc; struct hdmi *hdmi = hdcp_ctrl->hdmi; @@ -621,7 +621,7 @@ static int hdmi_hdcp_wait_key_an_ready(struct hdmi_hdcp_ctrl *hdcp_ctrl) return -ETIMEDOUT; } - rc = hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV); + rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV); if (rc) return rc; } while (1); @@ -643,7 +643,7 @@ static int hdmi_hdcp_wait_key_an_ready(struct hdmi_hdcp_ctrl *hdcp_ctrl) return -ETIMEDOUT; } - rc = hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV); + rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV); if (rc) return rc; } while (1); @@ -651,7 +651,7 @@ static int hdmi_hdcp_wait_key_an_ready(struct hdmi_hdcp_ctrl *hdcp_ctrl) return 0; } -static int hdmi_hdcp_send_aksv_an(struct hdmi_hdcp_ctrl *hdcp_ctrl) +static int msm_hdmi_hdcp_send_aksv_an(struct hdmi_hdcp_ctrl *hdcp_ctrl) { int rc = 0; struct hdmi *hdmi = hdcp_ctrl->hdmi; @@ -676,7 +676,7 @@ static int hdmi_hdcp_send_aksv_an(struct hdmi_hdcp_ctrl *hdcp_ctrl) aksv[4] = link0_aksv_1 & 0xFF; /* Write An to offset 0x18 */ - rc = hdmi_ddc_write(hdmi, HDCP_PORT_ADDR, 0x18, (u8 *)link0_an, + rc = msm_hdmi_ddc_write(hdmi, HDCP_PORT_ADDR, 0x18, (u8 *)link0_an, (u16)sizeof(link0_an)); if (rc) { pr_err("%s:An write failed\n", __func__); @@ -685,7 +685,7 @@ static int hdmi_hdcp_send_aksv_an(struct hdmi_hdcp_ctrl *hdcp_ctrl) DBG("Link0-An=%08x%08x", link0_an[0], link0_an[1]); /* Write AKSV to offset 0x10 */ - rc = hdmi_ddc_write(hdmi, HDCP_PORT_ADDR, 0x10, aksv, 5); + rc = msm_hdmi_ddc_write(hdmi, HDCP_PORT_ADDR, 0x10, aksv, 5); if (rc) { pr_err("%s:AKSV write failed\n", __func__); return rc; @@ -695,7 +695,7 @@ static int hdmi_hdcp_send_aksv_an(struct hdmi_hdcp_ctrl *hdcp_ctrl) return 0; } -static int hdmi_hdcp_recv_bksv(struct hdmi_hdcp_ctrl *hdcp_ctrl) +static int msm_hdmi_hdcp_recv_bksv(struct hdmi_hdcp_ctrl *hdcp_ctrl) { int rc = 0; struct hdmi *hdmi = hdcp_ctrl->hdmi; @@ -703,7 +703,7 @@ static int hdmi_hdcp_recv_bksv(struct hdmi_hdcp_ctrl *hdcp_ctrl) u32 reg[2], data[2]; /* Read BKSV at offset 0x00 */ - rc = hdmi_ddc_read(hdmi, HDCP_PORT_ADDR, 0x00, bksv, 5); + rc = msm_hdmi_ddc_read(hdmi, HDCP_PORT_ADDR, 0x00, bksv, 5); if (rc) { pr_err("%s:BKSV read failed\n", __func__); return rc; @@ -728,19 +728,19 @@ static int hdmi_hdcp_recv_bksv(struct hdmi_hdcp_ctrl *hdcp_ctrl) data[0] = hdcp_ctrl->bksv_lsb; reg[1] = REG_HDMI_HDCP_RCVPORT_DATA1; data[1] = hdcp_ctrl->bksv_msb; - rc = hdmi_hdcp_scm_wr(hdcp_ctrl, reg, data, 2); + rc = msm_hdmi_hdcp_scm_wr(hdcp_ctrl, reg, data, 2); return rc; } -static int hdmi_hdcp_recv_bcaps(struct hdmi_hdcp_ctrl *hdcp_ctrl) +static int msm_hdmi_hdcp_recv_bcaps(struct hdmi_hdcp_ctrl *hdcp_ctrl) { int rc = 0; struct hdmi *hdmi = hdcp_ctrl->hdmi; u32 reg, data; u8 bcaps; - rc = hdmi_ddc_read(hdmi, HDCP_PORT_ADDR, 0x40, &bcaps, 1); + rc = msm_hdmi_ddc_read(hdmi, HDCP_PORT_ADDR, 0x40, &bcaps, 1); if (rc) { pr_err("%s:BCAPS read failed\n", __func__); return rc; @@ -753,26 +753,26 @@ static int hdmi_hdcp_recv_bcaps(struct hdmi_hdcp_ctrl *hdcp_ctrl) /* Write BCAPS to the hardware */ reg = REG_HDMI_HDCP_RCVPORT_DATA12; data = (u32)bcaps; - rc = hdmi_hdcp_scm_wr(hdcp_ctrl, ®, &data, 1); + rc = msm_hdmi_hdcp_scm_wr(hdcp_ctrl, ®, &data, 1); return rc; } -static int hdmi_hdcp_auth_part1_key_exchange(struct hdmi_hdcp_ctrl *hdcp_ctrl) +static int msm_hdmi_hdcp_auth_part1_key_exchange(struct hdmi_hdcp_ctrl *hdcp_ctrl) { struct hdmi *hdmi = hdcp_ctrl->hdmi; unsigned long flags; int rc; /* Wait for AKSV key and An ready */ - rc = hdmi_hdcp_wait_key_an_ready(hdcp_ctrl); + rc = msm_hdmi_hdcp_wait_key_an_ready(hdcp_ctrl); if (rc) { pr_err("%s: wait key and an ready failed\n", __func__); return rc; }; /* Read BCAPS and send to HDCP engine */ - rc = hdmi_hdcp_recv_bcaps(hdcp_ctrl); + rc = msm_hdmi_hdcp_recv_bcaps(hdcp_ctrl); if (rc) { pr_err("%s: read bcaps error, abort\n", __func__); return rc; @@ -785,14 +785,14 @@ static int hdmi_hdcp_auth_part1_key_exchange(struct hdmi_hdcp_ctrl *hdcp_ctrl) hdmi_write(hdmi, REG_HDMI_HDCP_RCVPORT_DATA4, 0); /* Send AKSV and An to sink */ - rc = hdmi_hdcp_send_aksv_an(hdcp_ctrl); + rc = msm_hdmi_hdcp_send_aksv_an(hdcp_ctrl); if (rc) { pr_err("%s:An/Aksv write failed\n", __func__); return rc; } /* Read BKSV and send to HDCP engine*/ - rc = hdmi_hdcp_recv_bksv(hdcp_ctrl); + rc = msm_hdmi_hdcp_recv_bksv(hdcp_ctrl); if (rc) { pr_err("%s:BKSV Process failed\n", __func__); return rc; @@ -812,7 +812,7 @@ static int hdmi_hdcp_auth_part1_key_exchange(struct hdmi_hdcp_ctrl *hdcp_ctrl) } /* read R0' from sink and pass it to HDCP engine */ -static int hdmi_hdcp_auth_part1_recv_r0(struct hdmi_hdcp_ctrl *hdcp_ctrl) +static int msm_hdmi_hdcp_auth_part1_recv_r0(struct hdmi_hdcp_ctrl *hdcp_ctrl) { struct hdmi *hdmi = hdcp_ctrl->hdmi; int rc = 0; @@ -822,12 +822,12 @@ static int hdmi_hdcp_auth_part1_recv_r0(struct hdmi_hdcp_ctrl *hdcp_ctrl) * HDCP Compliance Test case 1A-01: * Wait here at least 100ms before reading R0' */ - rc = hdmi_hdcp_msleep(hdcp_ctrl, 125, AUTH_ABORT_EV); + rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 125, AUTH_ABORT_EV); if (rc) return rc; /* Read R0' at offset 0x08 */ - rc = hdmi_ddc_read(hdmi, HDCP_PORT_ADDR, 0x08, buf, 2); + rc = msm_hdmi_ddc_read(hdmi, HDCP_PORT_ADDR, 0x08, buf, 2); if (rc) { pr_err("%s:R0' read failed\n", __func__); return rc; @@ -842,14 +842,14 @@ static int hdmi_hdcp_auth_part1_recv_r0(struct hdmi_hdcp_ctrl *hdcp_ctrl) } /* Wait for authenticating result: R0/R0' are matched or not */ -static int hdmi_hdcp_auth_part1_verify_r0(struct hdmi_hdcp_ctrl *hdcp_ctrl) +static int msm_hdmi_hdcp_auth_part1_verify_r0(struct hdmi_hdcp_ctrl *hdcp_ctrl) { struct hdmi *hdmi = hdcp_ctrl->hdmi; u32 link0_status; int rc; /* wait for hdcp irq, 10 sec should be long enough */ - rc = hdmi_hdcp_msleep(hdcp_ctrl, 10000, AUTH_RESULT_RDY_EV); + rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 10000, AUTH_RESULT_RDY_EV); if (!rc) { pr_err("%s: Wait Auth IRQ timeout\n", __func__); return -ETIMEDOUT; @@ -869,7 +869,7 @@ static int hdmi_hdcp_auth_part1_verify_r0(struct hdmi_hdcp_ctrl *hdcp_ctrl) return 0; } -static int hdmi_hdcp_recv_check_bstatus(struct hdmi_hdcp_ctrl *hdcp_ctrl, +static int msm_hdmi_hdcp_recv_check_bstatus(struct hdmi_hdcp_ctrl *hdcp_ctrl, u16 *pbstatus) { int rc; @@ -880,7 +880,7 @@ static int hdmi_hdcp_recv_check_bstatus(struct hdmi_hdcp_ctrl *hdcp_ctrl, u8 buf[2]; /* Read BSTATUS at offset 0x41 */ - rc = hdmi_ddc_read(hdmi, HDCP_PORT_ADDR, 0x41, buf, 2); + rc = msm_hdmi_ddc_read(hdmi, HDCP_PORT_ADDR, 0x41, buf, 2); if (rc) { pr_err("%s: BSTATUS read failed\n", __func__); goto error; @@ -936,7 +936,7 @@ error: return rc; } -static int hdmi_hdcp_auth_part2_wait_ksv_fifo_ready( +static int msm_hdmi_hdcp_auth_part2_wait_ksv_fifo_ready( struct hdmi_hdcp_ctrl *hdcp_ctrl) { int rc; @@ -953,7 +953,7 @@ static int hdmi_hdcp_auth_part2_wait_ksv_fifo_ready( timeout_count = 100; do { /* Read BCAPS at offset 0x40 */ - rc = hdmi_ddc_read(hdmi, HDCP_PORT_ADDR, 0x40, &bcaps, 1); + rc = msm_hdmi_ddc_read(hdmi, HDCP_PORT_ADDR, 0x40, &bcaps, 1); if (rc) { pr_err("%s: BCAPS read failed\n", __func__); return rc; @@ -968,12 +968,12 @@ static int hdmi_hdcp_auth_part2_wait_ksv_fifo_ready( return -ETIMEDOUT; } - rc = hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV); + rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV); if (rc) return rc; } while (1); - rc = hdmi_hdcp_recv_check_bstatus(hdcp_ctrl, &bstatus); + rc = msm_hdmi_hdcp_recv_check_bstatus(hdcp_ctrl, &bstatus); if (rc) { pr_err("%s: bstatus error\n", __func__); return rc; @@ -982,7 +982,7 @@ static int hdmi_hdcp_auth_part2_wait_ksv_fifo_ready( /* Write BSTATUS and BCAPS to HDCP registers */ reg = REG_HDMI_HDCP_RCVPORT_DATA12; data = bcaps | (bstatus << 8); - rc = hdmi_hdcp_scm_wr(hdcp_ctrl, ®, &data, 1); + rc = msm_hdmi_hdcp_scm_wr(hdcp_ctrl, ®, &data, 1); if (rc) { pr_err("%s: BSTATUS write failed\n", __func__); return rc; @@ -997,7 +997,7 @@ static int hdmi_hdcp_auth_part2_wait_ksv_fifo_ready( * transfer V' from sink to HDCP engine * reset SHA engine */ -static int hdmi_hdcp_transfer_v_h(struct hdmi_hdcp_ctrl *hdcp_ctrl) +static int msm_hdmi_hdcp_transfer_v_h(struct hdmi_hdcp_ctrl *hdcp_ctrl) { struct hdmi *hdmi = hdcp_ctrl->hdmi; int rc = 0; @@ -1016,7 +1016,7 @@ static int hdmi_hdcp_transfer_v_h(struct hdmi_hdcp_ctrl *hdcp_ctrl) for (i = 0; i < size; i++) { rd = ®_data[i]; - rc = hdmi_ddc_read(hdmi, HDCP_PORT_ADDR, + rc = msm_hdmi_ddc_read(hdmi, HDCP_PORT_ADDR, rd->off, (u8 *)&data[i], (u16)sizeof(data[i])); if (rc) { pr_err("%s: Read %s failed\n", __func__, rd->name); @@ -1027,13 +1027,13 @@ static int hdmi_hdcp_transfer_v_h(struct hdmi_hdcp_ctrl *hdcp_ctrl) reg[i] = reg_data[i].reg_id; } - rc = hdmi_hdcp_scm_wr(hdcp_ctrl, reg, data, size); + rc = msm_hdmi_hdcp_scm_wr(hdcp_ctrl, reg, data, size); error: return rc; } -static int hdmi_hdcp_recv_ksv_fifo(struct hdmi_hdcp_ctrl *hdcp_ctrl) +static int msm_hdmi_hdcp_recv_ksv_fifo(struct hdmi_hdcp_ctrl *hdcp_ctrl) { int rc; struct hdmi *hdmi = hdcp_ctrl->hdmi; @@ -1041,7 +1041,7 @@ static int hdmi_hdcp_recv_ksv_fifo(struct hdmi_hdcp_ctrl *hdcp_ctrl) ksv_bytes = 5 * hdcp_ctrl->dev_count; - rc = hdmi_ddc_read(hdmi, HDCP_PORT_ADDR, 0x43, + rc = msm_hdmi_ddc_read(hdmi, HDCP_PORT_ADDR, 0x43, hdcp_ctrl->ksv_list, ksv_bytes); if (rc) pr_err("%s: KSV FIFO read failed\n", __func__); @@ -1049,7 +1049,7 @@ static int hdmi_hdcp_recv_ksv_fifo(struct hdmi_hdcp_ctrl *hdcp_ctrl) return rc; } -static int hdmi_hdcp_reset_sha_engine(struct hdmi_hdcp_ctrl *hdcp_ctrl) +static int msm_hdmi_hdcp_reset_sha_engine(struct hdmi_hdcp_ctrl *hdcp_ctrl) { u32 reg[2], data[2]; u32 rc = 0; @@ -1059,12 +1059,12 @@ static int hdmi_hdcp_reset_sha_engine(struct hdmi_hdcp_ctrl *hdcp_ctrl) reg[1] = REG_HDMI_HDCP_SHA_CTRL; data[1] = HDCP_REG_DISABLE; - rc = hdmi_hdcp_scm_wr(hdcp_ctrl, reg, data, 2); + rc = msm_hdmi_hdcp_scm_wr(hdcp_ctrl, reg, data, 2); return rc; } -static int hdmi_hdcp_auth_part2_recv_ksv_fifo( +static int msm_hdmi_hdcp_auth_part2_recv_ksv_fifo( struct hdmi_hdcp_ctrl *hdcp_ctrl) { int rc; @@ -1081,7 +1081,7 @@ static int hdmi_hdcp_auth_part2_recv_ksv_fifo( */ timeout_count = 100; do { - rc = hdmi_hdcp_recv_ksv_fifo(hdcp_ctrl); + rc = msm_hdmi_hdcp_recv_ksv_fifo(hdcp_ctrl); if (!rc) break; @@ -1091,19 +1091,19 @@ static int hdmi_hdcp_auth_part2_recv_ksv_fifo( return -ETIMEDOUT; } - rc = hdmi_hdcp_msleep(hdcp_ctrl, 25, AUTH_ABORT_EV); + rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 25, AUTH_ABORT_EV); if (rc) return rc; } while (1); - rc = hdmi_hdcp_transfer_v_h(hdcp_ctrl); + rc = msm_hdmi_hdcp_transfer_v_h(hdcp_ctrl); if (rc) { pr_err("%s: transfer V failed\n", __func__); return rc; } /* reset SHA engine before write ksv fifo */ - rc = hdmi_hdcp_reset_sha_engine(hdcp_ctrl); + rc = msm_hdmi_hdcp_reset_sha_engine(hdcp_ctrl); if (rc) { pr_err("%s: fail to reset sha engine\n", __func__); return rc; @@ -1120,7 +1120,7 @@ static int hdmi_hdcp_auth_part2_recv_ksv_fifo( * If the last byte is written, we need to poll for * HDCP_SHA_COMP_DONE to wait until HW finish */ -static int hdmi_hdcp_write_ksv_fifo(struct hdmi_hdcp_ctrl *hdcp_ctrl) +static int msm_hdmi_hdcp_write_ksv_fifo(struct hdmi_hdcp_ctrl *hdcp_ctrl) { int i; struct hdmi *hdmi = hdcp_ctrl->hdmi; @@ -1169,7 +1169,7 @@ static int hdmi_hdcp_write_ksv_fifo(struct hdmi_hdcp_ctrl *hdcp_ctrl) reg = REG_HDMI_HDCP_SHA_DATA; data = reg_val; - rc = hdmi_hdcp_scm_wr(hdcp_ctrl, ®, &data, 1); + rc = msm_hdmi_hdcp_scm_wr(hdcp_ctrl, ®, &data, 1); if (rc) return rc; @@ -1184,7 +1184,7 @@ static int hdmi_hdcp_write_ksv_fifo(struct hdmi_hdcp_ctrl *hdcp_ctrl) } /* write ksv fifo into HDCP engine */ -static int hdmi_hdcp_auth_part2_write_ksv_fifo( +static int msm_hdmi_hdcp_auth_part2_write_ksv_fifo( struct hdmi_hdcp_ctrl *hdcp_ctrl) { int rc; @@ -1193,7 +1193,7 @@ static int hdmi_hdcp_auth_part2_write_ksv_fifo( hdcp_ctrl->ksv_fifo_w_index = 0; timeout_count = 100; do { - rc = hdmi_hdcp_write_ksv_fifo(hdcp_ctrl); + rc = msm_hdmi_hdcp_write_ksv_fifo(hdcp_ctrl); if (!rc) break; @@ -1206,7 +1206,7 @@ static int hdmi_hdcp_auth_part2_write_ksv_fifo( return -ETIMEDOUT; } - rc = hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV); + rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV); if (rc) return rc; } while (1); @@ -1214,7 +1214,7 @@ static int hdmi_hdcp_auth_part2_write_ksv_fifo( return 0; } -static int hdmi_hdcp_auth_part2_check_v_match(struct hdmi_hdcp_ctrl *hdcp_ctrl) +static int msm_hdmi_hdcp_auth_part2_check_v_match(struct hdmi_hdcp_ctrl *hdcp_ctrl) { int rc = 0; struct hdmi *hdmi = hdcp_ctrl->hdmi; @@ -1232,7 +1232,7 @@ static int hdmi_hdcp_auth_part2_check_v_match(struct hdmi_hdcp_ctrl *hdcp_ctrl) return -ETIMEDOUT; } - rc = hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV); + rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV); if (rc) return rc; } while (1); @@ -1240,32 +1240,32 @@ static int hdmi_hdcp_auth_part2_check_v_match(struct hdmi_hdcp_ctrl *hdcp_ctrl) return 0; } -static void hdmi_hdcp_auth_work(struct work_struct *work) +static void msm_hdmi_hdcp_auth_work(struct work_struct *work) { struct hdmi_hdcp_ctrl *hdcp_ctrl = container_of(work, struct hdmi_hdcp_ctrl, hdcp_auth_work); int rc; - rc = hdmi_hdcp_auth_prepare(hdcp_ctrl); + rc = msm_hdmi_hdcp_auth_prepare(hdcp_ctrl); if (rc) { pr_err("%s: auth prepare failed %d\n", __func__, rc); goto end; } /* HDCP PartI */ - rc = hdmi_hdcp_auth_part1_key_exchange(hdcp_ctrl); + rc = msm_hdmi_hdcp_auth_part1_key_exchange(hdcp_ctrl); if (rc) { pr_err("%s: key exchange failed %d\n", __func__, rc); goto end; } - rc = hdmi_hdcp_auth_part1_recv_r0(hdcp_ctrl); + rc = msm_hdmi_hdcp_auth_part1_recv_r0(hdcp_ctrl); if (rc) { pr_err("%s: receive r0 failed %d\n", __func__, rc); goto end; } - rc = hdmi_hdcp_auth_part1_verify_r0(hdcp_ctrl); + rc = msm_hdmi_hdcp_auth_part1_verify_r0(hdcp_ctrl); if (rc) { pr_err("%s: verify r0 failed %d\n", __func__, rc); goto end; @@ -1275,25 +1275,25 @@ static void hdmi_hdcp_auth_work(struct work_struct *work) goto end; /* HDCP PartII */ - rc = hdmi_hdcp_auth_part2_wait_ksv_fifo_ready(hdcp_ctrl); + rc = msm_hdmi_hdcp_auth_part2_wait_ksv_fifo_ready(hdcp_ctrl); if (rc) { pr_err("%s: wait ksv fifo ready failed %d\n", __func__, rc); goto end; } - rc = hdmi_hdcp_auth_part2_recv_ksv_fifo(hdcp_ctrl); + rc = msm_hdmi_hdcp_auth_part2_recv_ksv_fifo(hdcp_ctrl); if (rc) { pr_err("%s: recv ksv fifo failed %d\n", __func__, rc); goto end; } - rc = hdmi_hdcp_auth_part2_write_ksv_fifo(hdcp_ctrl); + rc = msm_hdmi_hdcp_auth_part2_write_ksv_fifo(hdcp_ctrl); if (rc) { pr_err("%s: write ksv fifo failed %d\n", __func__, rc); goto end; } - rc = hdmi_hdcp_auth_part2_check_v_match(hdcp_ctrl); + rc = msm_hdmi_hdcp_auth_part2_check_v_match(hdcp_ctrl); if (rc) pr_err("%s: check v match failed %d\n", __func__, rc); @@ -1304,13 +1304,13 @@ end: pr_info("%s: hdcp is not supported\n", __func__); } else if (rc) { pr_err("%s: hdcp authentication failed\n", __func__); - hdmi_hdcp_auth_fail(hdcp_ctrl); + msm_hdmi_hdcp_auth_fail(hdcp_ctrl); } else { - hdmi_hdcp_auth_done(hdcp_ctrl); + msm_hdmi_hdcp_auth_done(hdcp_ctrl); } } -void hdmi_hdcp_on(struct hdmi_hdcp_ctrl *hdcp_ctrl) +void msm_hdmi_hdcp_on(struct hdmi_hdcp_ctrl *hdcp_ctrl) { struct hdmi *hdmi = hdcp_ctrl->hdmi; u32 reg_val; @@ -1335,7 +1335,7 @@ void hdmi_hdcp_on(struct hdmi_hdcp_ctrl *hdcp_ctrl) queue_work(hdmi->workq, &hdcp_ctrl->hdcp_auth_work); } -void hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl) +void msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl) { struct hdmi *hdmi = hdcp_ctrl->hdmi; unsigned long flags; @@ -1399,7 +1399,7 @@ void hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl) DBG("HDCP: Off"); } -struct hdmi_hdcp_ctrl *hdmi_hdcp_init(struct hdmi *hdmi) +struct hdmi_hdcp_ctrl *msm_hdmi_hdcp_init(struct hdmi *hdmi) { struct hdmi_hdcp_ctrl *hdcp_ctrl = NULL; @@ -1413,8 +1413,8 @@ struct hdmi_hdcp_ctrl *hdmi_hdcp_init(struct hdmi *hdmi) if (!hdcp_ctrl) return ERR_PTR(-ENOMEM); - INIT_WORK(&hdcp_ctrl->hdcp_auth_work, hdmi_hdcp_auth_work); - INIT_WORK(&hdcp_ctrl->hdcp_reauth_work, hdmi_hdcp_reauth_work); + INIT_WORK(&hdcp_ctrl->hdcp_auth_work, msm_hdmi_hdcp_auth_work); + INIT_WORK(&hdcp_ctrl->hdcp_reauth_work, msm_hdmi_hdcp_reauth_work); init_waitqueue_head(&hdcp_ctrl->auth_event_queue); hdcp_ctrl->hdmi = hdmi; hdcp_ctrl->hdcp_state = HDCP_STATE_INACTIVE; @@ -1428,7 +1428,7 @@ struct hdmi_hdcp_ctrl *hdmi_hdcp_init(struct hdmi *hdmi) return hdcp_ctrl; } -void hdmi_hdcp_destroy(struct hdmi *hdmi) +void msm_hdmi_hdcp_destroy(struct hdmi *hdmi) { if (hdmi && hdmi->hdcp_ctrl) { kfree(hdmi->hdcp_ctrl); diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c b/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c index f4ab7f70f..de9007e72 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c @@ -97,7 +97,7 @@ static bool sw_done(struct hdmi_i2c_adapter *hdmi_i2c) return hdmi_i2c->sw_done; } -static int hdmi_i2c_xfer(struct i2c_adapter *i2c, +static int msm_hdmi_i2c_xfer(struct i2c_adapter *i2c, struct i2c_msg *msgs, int num) { struct hdmi_i2c_adapter *hdmi_i2c = to_hdmi_i2c_adapter(i2c); @@ -216,17 +216,17 @@ static int hdmi_i2c_xfer(struct i2c_adapter *i2c, return i; } -static u32 hdmi_i2c_func(struct i2c_adapter *adapter) +static u32 msm_hdmi_i2c_func(struct i2c_adapter *adapter) { return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; } -static const struct i2c_algorithm hdmi_i2c_algorithm = { - .master_xfer = hdmi_i2c_xfer, - .functionality = hdmi_i2c_func, +static const struct i2c_algorithm msm_hdmi_i2c_algorithm = { + .master_xfer = msm_hdmi_i2c_xfer, + .functionality = msm_hdmi_i2c_func, }; -void hdmi_i2c_irq(struct i2c_adapter *i2c) +void msm_hdmi_i2c_irq(struct i2c_adapter *i2c) { struct hdmi_i2c_adapter *hdmi_i2c = to_hdmi_i2c_adapter(i2c); @@ -234,14 +234,14 @@ void hdmi_i2c_irq(struct i2c_adapter *i2c) wake_up_all(&hdmi_i2c->ddc_event); } -void hdmi_i2c_destroy(struct i2c_adapter *i2c) +void msm_hdmi_i2c_destroy(struct i2c_adapter *i2c) { struct hdmi_i2c_adapter *hdmi_i2c = to_hdmi_i2c_adapter(i2c); i2c_del_adapter(i2c); kfree(hdmi_i2c); } -struct i2c_adapter *hdmi_i2c_init(struct hdmi *hdmi) +struct i2c_adapter *msm_hdmi_i2c_init(struct hdmi *hdmi) { struct drm_device *dev = hdmi->dev; struct hdmi_i2c_adapter *hdmi_i2c; @@ -264,7 +264,7 @@ struct i2c_adapter *hdmi_i2c_init(struct hdmi *hdmi) i2c->class = I2C_CLASS_DDC; snprintf(i2c->name, sizeof(i2c->name), "msm hdmi i2c"); i2c->dev.parent = &hdmi->pdev->dev; - i2c->algo = &hdmi_i2c_algorithm; + i2c->algo = &msm_hdmi_i2c_algorithm; ret = i2c_add_adapter(i2c); if (ret) { @@ -276,6 +276,6 @@ struct i2c_adapter *hdmi_i2c_init(struct hdmi *hdmi) fail: if (i2c) - hdmi_i2c_destroy(i2c); + msm_hdmi_i2c_destroy(i2c); return ERR_PTR(ret); } diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c new file mode 100644 index 000000000..534ce5b49 --- /dev/null +++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +#include "hdmi.h" + +static int msm_hdmi_phy_resource_init(struct hdmi_phy *phy) +{ + struct hdmi_phy_cfg *cfg = phy->cfg; + struct device *dev = &phy->pdev->dev; + int i, ret; + + phy->regs = devm_kzalloc(dev, sizeof(phy->regs[0]) * cfg->num_regs, + GFP_KERNEL); + if (!phy->regs) + return -ENOMEM; + + phy->clks = devm_kzalloc(dev, sizeof(phy->clks[0]) * cfg->num_clks, + GFP_KERNEL); + if (!phy->clks) + return -ENOMEM; + + for (i = 0; i < cfg->num_regs; i++) { + struct regulator *reg; + + reg = devm_regulator_get(dev, cfg->reg_names[i]); + if (IS_ERR(reg)) { + ret = PTR_ERR(reg); + dev_err(dev, "failed to get phy regulator: %s (%d)\n", + cfg->reg_names[i], ret); + return ret; + } + + phy->regs[i] = reg; + } + + for (i = 0; i < cfg->num_clks; i++) { + struct clk *clk; + + clk = devm_clk_get(dev, cfg->clk_names[i]); + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + dev_err(dev, "failed to get phy clock: %s (%d)\n", + cfg->clk_names[i], ret); + return ret; + } + + phy->clks[i] = clk; + } + + return 0; +} + +int msm_hdmi_phy_resource_enable(struct hdmi_phy *phy) +{ + struct hdmi_phy_cfg *cfg = phy->cfg; + struct device *dev = &phy->pdev->dev; + int i, ret = 0; + + pm_runtime_get_sync(dev); + + for (i = 0; i < cfg->num_regs; i++) { + ret = regulator_enable(phy->regs[i]); + if (ret) + dev_err(dev, "failed to enable regulator: %s (%d)\n", + cfg->reg_names[i], ret); + } + + for (i = 0; i < cfg->num_clks; i++) { + ret = clk_prepare_enable(phy->clks[i]); + if (ret) + dev_err(dev, "failed to enable clock: %s (%d)\n", + cfg->clk_names[i], ret); + } + + return ret; +} + +void msm_hdmi_phy_resource_disable(struct hdmi_phy *phy) +{ + struct hdmi_phy_cfg *cfg = phy->cfg; + struct device *dev = &phy->pdev->dev; + int i; + + for (i = cfg->num_clks - 1; i >= 0; i--) + clk_disable_unprepare(phy->clks[i]); + + for (i = cfg->num_regs - 1; i >= 0; i--) + regulator_disable(phy->regs[i]); + + pm_runtime_put_sync(dev); +} + +void msm_hdmi_phy_powerup(struct hdmi_phy *phy, unsigned long int pixclock) +{ + if (!phy || !phy->cfg->powerup) + return; + + phy->cfg->powerup(phy, pixclock); +} + +void msm_hdmi_phy_powerdown(struct hdmi_phy *phy) +{ + if (!phy || !phy->cfg->powerdown) + return; + + phy->cfg->powerdown(phy); +} + +static int msm_hdmi_phy_pll_init(struct platform_device *pdev, + enum hdmi_phy_type type) +{ + int ret; + + switch (type) { + case MSM_HDMI_PHY_8960: + ret = msm_hdmi_pll_8960_init(pdev); + break; + case MSM_HDMI_PHY_8996: + ret = msm_hdmi_pll_8996_init(pdev); + break; + /* + * we don't have PLL support for these, don't report an error for now + */ + case MSM_HDMI_PHY_8x60: + case MSM_HDMI_PHY_8x74: + default: + ret = 0; + break; + } + + return ret; +} + +static int msm_hdmi_phy_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct hdmi_phy *phy; + int ret; + + phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); + if (!phy) + return -ENODEV; + + phy->cfg = (struct hdmi_phy_cfg *)of_device_get_match_data(dev); + if (!phy->cfg) + return -ENODEV; + + phy->mmio = msm_ioremap(pdev, "hdmi_phy", "HDMI_PHY"); + if (IS_ERR(phy->mmio)) { + dev_err(dev, "%s: failed to map phy base\n", __func__); + return -ENOMEM; + } + + phy->pdev = pdev; + + ret = msm_hdmi_phy_resource_init(phy); + if (ret) + return ret; + + pm_runtime_enable(&pdev->dev); + + ret = msm_hdmi_phy_resource_enable(phy); + if (ret) + return ret; + + ret = msm_hdmi_phy_pll_init(pdev, phy->cfg->type); + if (ret) { + dev_err(dev, "couldn't init PLL\n"); + msm_hdmi_phy_resource_disable(phy); + return ret; + } + + msm_hdmi_phy_resource_disable(phy); + + platform_set_drvdata(pdev, phy); + + return 0; +} + +static int msm_hdmi_phy_remove(struct platform_device *pdev) +{ + pm_runtime_disable(&pdev->dev); + + return 0; +} + +static const struct of_device_id msm_hdmi_phy_dt_match[] = { + { .compatible = "qcom,hdmi-phy-8660", + .data = &msm_hdmi_phy_8x60_cfg }, + { .compatible = "qcom,hdmi-phy-8960", + .data = &msm_hdmi_phy_8960_cfg }, + { .compatible = "qcom,hdmi-phy-8974", + .data = &msm_hdmi_phy_8x74_cfg }, + { .compatible = "qcom,hdmi-phy-8084", + .data = &msm_hdmi_phy_8x74_cfg }, + { .compatible = "qcom,hdmi-phy-8996", + .data = &msm_hdmi_phy_8996_cfg }, + {} +}; + +static struct platform_driver msm_hdmi_phy_platform_driver = { + .probe = msm_hdmi_phy_probe, + .remove = msm_hdmi_phy_remove, + .driver = { + .name = "msm_hdmi_phy", + .of_match_table = msm_hdmi_phy_dt_match, + }, +}; + +void __init msm_hdmi_phy_driver_register(void) +{ + platform_driver_register(&msm_hdmi_phy_platform_driver); +} + +void __exit msm_hdmi_phy_driver_unregister(void) +{ + platform_driver_unregister(&msm_hdmi_phy_platform_driver); +} diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c index 3a01cb505..e6ee6b745 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c @@ -15,495 +15,48 @@ * this program. If not, see . */ -#ifdef CONFIG_COMMON_CLK -#include -#include -#endif - #include "hdmi.h" -struct hdmi_phy_8960 { - struct hdmi_phy base; - struct hdmi *hdmi; -#ifdef CONFIG_COMMON_CLK - struct clk_hw pll_hw; - struct clk *pll; - unsigned long pixclk; -#endif -}; -#define to_hdmi_phy_8960(x) container_of(x, struct hdmi_phy_8960, base) - -#ifdef CONFIG_COMMON_CLK -#define clk_to_phy(x) container_of(x, struct hdmi_phy_8960, pll_hw) - -/* - * HDMI PLL: - * - * To get the parent clock setup properly, we need to plug in hdmi pll - * configuration into common-clock-framework. - */ - -struct pll_rate { - unsigned long rate; - struct { - uint32_t val; - uint32_t reg; - } conf[32]; -}; - -/* NOTE: keep sorted highest freq to lowest: */ -static const struct pll_rate freqtbl[] = { - { 154000000, { - { 0x08, REG_HDMI_8960_PHY_PLL_REFCLK_CFG }, - { 0x20, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 }, - { 0xf9, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 }, - { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 }, - { 0x03, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 }, - { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 }, - { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 }, - { 0x0d, REG_HDMI_8960_PHY_PLL_SDM_CFG0 }, - { 0x4d, REG_HDMI_8960_PHY_PLL_SDM_CFG1 }, - { 0x5e, REG_HDMI_8960_PHY_PLL_SDM_CFG2 }, - { 0x42, REG_HDMI_8960_PHY_PLL_SDM_CFG3 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 }, - { 0, 0 } } - }, - /* 1080p60/1080p50 case */ - { 148500000, { - { 0x02, REG_HDMI_8960_PHY_PLL_REFCLK_CFG }, - { 0x02, REG_HDMI_8960_PHY_PLL_CHRG_PUMP_CFG }, - { 0x01, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 }, - { 0x33, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 }, - { 0x2c, REG_HDMI_8960_PHY_PLL_IDAC_ADJ_CFG }, - { 0x06, REG_HDMI_8960_PHY_PLL_I_VI_KVCO_CFG }, - { 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B }, - { 0x76, REG_HDMI_8960_PHY_PLL_SDM_CFG0 }, - { 0x01, REG_HDMI_8960_PHY_PLL_SDM_CFG1 }, - { 0x4c, REG_HDMI_8960_PHY_PLL_SDM_CFG2 }, - { 0xc0, REG_HDMI_8960_PHY_PLL_SDM_CFG3 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 }, - { 0x9a, REG_HDMI_8960_PHY_PLL_SSC_CFG0 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG1 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG2 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG3 }, - { 0x10, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0 }, - { 0x1a, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1 }, - { 0x0d, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2 }, - { 0xe6, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 }, - { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 }, - { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 }, - { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 }, - { 0x33, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG6 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG7 }, - { 0, 0 } } - }, - { 108000000, { - { 0x08, REG_HDMI_8960_PHY_PLL_REFCLK_CFG }, - { 0x21, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 }, - { 0xf9, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 }, - { 0x1c, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 }, - { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 }, - { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 }, - { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 }, - { 0x49, REG_HDMI_8960_PHY_PLL_SDM_CFG0 }, - { 0x49, REG_HDMI_8960_PHY_PLL_SDM_CFG1 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG2 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG3 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 }, - { 0, 0 } } - }, - /* 720p60/720p50/1080i60/1080i50/1080p24/1080p30/1080p25 */ - { 74250000, { - { 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B }, - { 0x12, REG_HDMI_8960_PHY_PLL_REFCLK_CFG }, - { 0x01, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 }, - { 0x33, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 }, - { 0x76, REG_HDMI_8960_PHY_PLL_SDM_CFG0 }, - { 0xe6, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 }, - { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 }, - { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 }, - { 0, 0 } } - }, - { 74176000, { - { 0x18, REG_HDMI_8960_PHY_PLL_REFCLK_CFG }, - { 0x20, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 }, - { 0xf9, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 }, - { 0xe5, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 }, - { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 }, - { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 }, - { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 }, - { 0x0c, REG_HDMI_8960_PHY_PLL_SDM_CFG0 }, - { 0x4c, REG_HDMI_8960_PHY_PLL_SDM_CFG1 }, - { 0x7d, REG_HDMI_8960_PHY_PLL_SDM_CFG2 }, - { 0xbc, REG_HDMI_8960_PHY_PLL_SDM_CFG3 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 }, - { 0, 0 } } - }, - { 65000000, { - { 0x18, REG_HDMI_8960_PHY_PLL_REFCLK_CFG }, - { 0x20, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 }, - { 0xf9, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 }, - { 0x8a, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 }, - { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 }, - { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 }, - { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 }, - { 0x0b, REG_HDMI_8960_PHY_PLL_SDM_CFG0 }, - { 0x4b, REG_HDMI_8960_PHY_PLL_SDM_CFG1 }, - { 0x7b, REG_HDMI_8960_PHY_PLL_SDM_CFG2 }, - { 0x09, REG_HDMI_8960_PHY_PLL_SDM_CFG3 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 }, - { 0, 0 } } - }, - /* 480p60/480i60 */ - { 27030000, { - { 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B }, - { 0x38, REG_HDMI_8960_PHY_PLL_REFCLK_CFG }, - { 0x02, REG_HDMI_8960_PHY_PLL_CHRG_PUMP_CFG }, - { 0x20, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 }, - { 0xff, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG0 }, - { 0x4e, REG_HDMI_8960_PHY_PLL_SDM_CFG1 }, - { 0xd7, REG_HDMI_8960_PHY_PLL_SDM_CFG2 }, - { 0x03, REG_HDMI_8960_PHY_PLL_SDM_CFG3 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 }, - { 0x2a, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 }, - { 0x03, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 }, - { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 }, - { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 }, - { 0x33, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG6 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG7 }, - { 0, 0 } } - }, - /* 576p50/576i50 */ - { 27000000, { - { 0x32, REG_HDMI_8960_PHY_PLL_REFCLK_CFG }, - { 0x02, REG_HDMI_8960_PHY_PLL_CHRG_PUMP_CFG }, - { 0x01, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 }, - { 0x33, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 }, - { 0x2c, REG_HDMI_8960_PHY_PLL_IDAC_ADJ_CFG }, - { 0x06, REG_HDMI_8960_PHY_PLL_I_VI_KVCO_CFG }, - { 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B }, - { 0x7b, REG_HDMI_8960_PHY_PLL_SDM_CFG0 }, - { 0x01, REG_HDMI_8960_PHY_PLL_SDM_CFG1 }, - { 0x4c, REG_HDMI_8960_PHY_PLL_SDM_CFG2 }, - { 0xc0, REG_HDMI_8960_PHY_PLL_SDM_CFG3 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 }, - { 0x9a, REG_HDMI_8960_PHY_PLL_SSC_CFG0 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG1 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG2 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG3 }, - { 0x10, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0 }, - { 0x1a, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1 }, - { 0x0d, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2 }, - { 0x2a, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 }, - { 0x03, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 }, - { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 }, - { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 }, - { 0x33, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG6 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG7 }, - { 0, 0 } } - }, - /* 640x480p60 */ - { 25200000, { - { 0x32, REG_HDMI_8960_PHY_PLL_REFCLK_CFG }, - { 0x02, REG_HDMI_8960_PHY_PLL_CHRG_PUMP_CFG }, - { 0x01, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 }, - { 0x33, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 }, - { 0x2c, REG_HDMI_8960_PHY_PLL_IDAC_ADJ_CFG }, - { 0x06, REG_HDMI_8960_PHY_PLL_I_VI_KVCO_CFG }, - { 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B }, - { 0x77, REG_HDMI_8960_PHY_PLL_SDM_CFG0 }, - { 0x4c, REG_HDMI_8960_PHY_PLL_SDM_CFG1 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG2 }, - { 0xc0, REG_HDMI_8960_PHY_PLL_SDM_CFG3 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 }, - { 0x9a, REG_HDMI_8960_PHY_PLL_SSC_CFG0 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG1 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG2 }, - { 0x20, REG_HDMI_8960_PHY_PLL_SSC_CFG3 }, - { 0x10, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0 }, - { 0x1a, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1 }, - { 0x0d, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2 }, - { 0xf4, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 }, - { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 }, - { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 }, - { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 }, - { 0x33, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG6 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG7 }, - { 0, 0 } } - }, -}; - -static int hdmi_pll_enable(struct clk_hw *hw) -{ - struct hdmi_phy_8960 *phy_8960 = clk_to_phy(hw); - struct hdmi *hdmi = phy_8960->hdmi; - int timeout_count, pll_lock_retry = 10; - unsigned int val; - - DBG(""); - - /* Assert PLL S/W reset */ - hdmi_write(hdmi, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2, 0x8d); - hdmi_write(hdmi, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0, 0x10); - hdmi_write(hdmi, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1, 0x1a); - - /* Wait for a short time before de-asserting - * to allow the hardware to complete its job. - * This much of delay should be fine for hardware - * to assert and de-assert. - */ - udelay(10); - - /* De-assert PLL S/W reset */ - hdmi_write(hdmi, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2, 0x0d); - - val = hdmi_read(hdmi, REG_HDMI_8960_PHY_REG12); - val |= HDMI_8960_PHY_REG12_SW_RESET; - /* Assert PHY S/W reset */ - hdmi_write(hdmi, REG_HDMI_8960_PHY_REG12, val); - val &= ~HDMI_8960_PHY_REG12_SW_RESET; - /* Wait for a short time before de-asserting - to allow the hardware to complete its job. - This much of delay should be fine for hardware - to assert and de-assert. */ - udelay(10); - /* De-assert PHY S/W reset */ - hdmi_write(hdmi, REG_HDMI_8960_PHY_REG12, val); - hdmi_write(hdmi, REG_HDMI_8960_PHY_REG2, 0x3f); - - val = hdmi_read(hdmi, REG_HDMI_8960_PHY_REG12); - val |= HDMI_8960_PHY_REG12_PWRDN_B; - hdmi_write(hdmi, REG_HDMI_8960_PHY_REG12, val); - /* Wait 10 us for enabling global power for PHY */ - mb(); - udelay(10); - - val = hdmi_read(hdmi, REG_HDMI_8960_PHY_PLL_PWRDN_B); - val |= HDMI_8960_PHY_PLL_PWRDN_B_PLL_PWRDN_B; - val &= ~HDMI_8960_PHY_PLL_PWRDN_B_PD_PLL; - hdmi_write(hdmi, REG_HDMI_8960_PHY_PLL_PWRDN_B, val); - hdmi_write(hdmi, REG_HDMI_8960_PHY_REG2, 0x80); - - timeout_count = 1000; - while (--pll_lock_retry > 0) { - - /* are we there yet? */ - val = hdmi_read(hdmi, REG_HDMI_8960_PHY_PLL_STATUS0); - if (val & HDMI_8960_PHY_PLL_STATUS0_PLL_LOCK) - break; - - udelay(1); - - if (--timeout_count > 0) - continue; - - /* - * PLL has still not locked. - * Do a software reset and try again - * Assert PLL S/W reset first - */ - hdmi_write(hdmi, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2, 0x8d); - udelay(10); - hdmi_write(hdmi, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2, 0x0d); - - /* - * Wait for a short duration for the PLL calibration - * before checking if the PLL gets locked - */ - udelay(350); - - timeout_count = 1000; - } - - return 0; -} - -static void hdmi_pll_disable(struct clk_hw *hw) -{ - struct hdmi_phy_8960 *phy_8960 = clk_to_phy(hw); - struct hdmi *hdmi = phy_8960->hdmi; - unsigned int val; - - DBG(""); - - val = hdmi_read(hdmi, REG_HDMI_8960_PHY_REG12); - val &= ~HDMI_8960_PHY_REG12_PWRDN_B; - hdmi_write(hdmi, REG_HDMI_8960_PHY_REG12, val); - - val = hdmi_read(hdmi, REG_HDMI_8960_PHY_PLL_PWRDN_B); - val |= HDMI_8960_PHY_REG12_SW_RESET; - val &= ~HDMI_8960_PHY_REG12_PWRDN_B; - hdmi_write(hdmi, REG_HDMI_8960_PHY_PLL_PWRDN_B, val); - /* Make sure HDMI PHY/PLL are powered down */ - mb(); -} - -static const struct pll_rate *find_rate(unsigned long rate) -{ - int i; - for (i = 1; i < ARRAY_SIZE(freqtbl); i++) - if (rate > freqtbl[i].rate) - return &freqtbl[i-1]; - return &freqtbl[i-1]; -} - -static unsigned long hdmi_pll_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct hdmi_phy_8960 *phy_8960 = clk_to_phy(hw); - return phy_8960->pixclk; -} - -static long hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) -{ - const struct pll_rate *pll_rate = find_rate(rate); - return pll_rate->rate; -} - -static int hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct hdmi_phy_8960 *phy_8960 = clk_to_phy(hw); - struct hdmi *hdmi = phy_8960->hdmi; - const struct pll_rate *pll_rate = find_rate(rate); - int i; - - DBG("rate=%lu", rate); - - for (i = 0; pll_rate->conf[i].reg; i++) - hdmi_write(hdmi, pll_rate->conf[i].reg, pll_rate->conf[i].val); - - phy_8960->pixclk = rate; - - return 0; -} - - -static const struct clk_ops hdmi_pll_ops = { - .enable = hdmi_pll_enable, - .disable = hdmi_pll_disable, - .recalc_rate = hdmi_pll_recalc_rate, - .round_rate = hdmi_pll_round_rate, - .set_rate = hdmi_pll_set_rate, -}; - -static const char *hdmi_pll_parents[] = { - "pxo", -}; - -static struct clk_init_data pll_init = { - .name = "hdmi_pll", - .ops = &hdmi_pll_ops, - .parent_names = hdmi_pll_parents, - .num_parents = ARRAY_SIZE(hdmi_pll_parents), -}; -#endif - -/* - * HDMI Phy: - */ - -static void hdmi_phy_8960_destroy(struct hdmi_phy *phy) -{ - struct hdmi_phy_8960 *phy_8960 = to_hdmi_phy_8960(phy); - kfree(phy_8960); -} - static void hdmi_phy_8960_powerup(struct hdmi_phy *phy, - unsigned long int pixclock) + unsigned long int pixclock) { - struct hdmi_phy_8960 *phy_8960 = to_hdmi_phy_8960(phy); - struct hdmi *hdmi = phy_8960->hdmi; - DBG("pixclock: %lu", pixclock); - hdmi_write(hdmi, REG_HDMI_8960_PHY_REG2, 0x00); - hdmi_write(hdmi, REG_HDMI_8960_PHY_REG0, 0x1b); - hdmi_write(hdmi, REG_HDMI_8960_PHY_REG1, 0xf2); - hdmi_write(hdmi, REG_HDMI_8960_PHY_REG4, 0x00); - hdmi_write(hdmi, REG_HDMI_8960_PHY_REG5, 0x00); - hdmi_write(hdmi, REG_HDMI_8960_PHY_REG6, 0x00); - hdmi_write(hdmi, REG_HDMI_8960_PHY_REG7, 0x00); - hdmi_write(hdmi, REG_HDMI_8960_PHY_REG8, 0x00); - hdmi_write(hdmi, REG_HDMI_8960_PHY_REG9, 0x00); - hdmi_write(hdmi, REG_HDMI_8960_PHY_REG10, 0x00); - hdmi_write(hdmi, REG_HDMI_8960_PHY_REG11, 0x00); - hdmi_write(hdmi, REG_HDMI_8960_PHY_REG3, 0x20); + hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG2, 0x00); + hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG0, 0x1b); + hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG1, 0xf2); + hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG4, 0x00); + hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG5, 0x00); + hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG6, 0x00); + hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG7, 0x00); + hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG8, 0x00); + hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG9, 0x00); + hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG10, 0x00); + hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG11, 0x00); + hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG3, 0x20); } static void hdmi_phy_8960_powerdown(struct hdmi_phy *phy) { - struct hdmi_phy_8960 *phy_8960 = to_hdmi_phy_8960(phy); - struct hdmi *hdmi = phy_8960->hdmi; - DBG(""); - hdmi_write(hdmi, REG_HDMI_8960_PHY_REG2, 0x7f); + hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG2, 0x7f); } -static const struct hdmi_phy_funcs hdmi_phy_8960_funcs = { - .destroy = hdmi_phy_8960_destroy, - .powerup = hdmi_phy_8960_powerup, - .powerdown = hdmi_phy_8960_powerdown, +static const char * const hdmi_phy_8960_reg_names[] = { + "core-vdda", }; -struct hdmi_phy *hdmi_phy_8960_init(struct hdmi *hdmi) -{ - struct hdmi_phy_8960 *phy_8960; - struct hdmi_phy *phy = NULL; - int ret; -#ifdef CONFIG_COMMON_CLK - int i; - - /* sanity check: */ - for (i = 0; i < (ARRAY_SIZE(freqtbl) - 1); i++) - if (WARN_ON(freqtbl[i].rate < freqtbl[i+1].rate)) - return ERR_PTR(-EINVAL); -#endif - - phy_8960 = kzalloc(sizeof(*phy_8960), GFP_KERNEL); - if (!phy_8960) { - ret = -ENOMEM; - goto fail; - } - - phy = &phy_8960->base; - - phy->funcs = &hdmi_phy_8960_funcs; - - phy_8960->hdmi = hdmi; - -#ifdef CONFIG_COMMON_CLK - phy_8960->pll_hw.init = &pll_init; - phy_8960->pll = devm_clk_register(&hdmi->pdev->dev, &phy_8960->pll_hw); - if (IS_ERR(phy_8960->pll)) { - ret = PTR_ERR(phy_8960->pll); - phy_8960->pll = NULL; - goto fail; - } -#endif - - return phy; +static const char * const hdmi_phy_8960_clk_names[] = { + "slave_iface_clk", +}; -fail: - if (phy) - hdmi_phy_8960_destroy(phy); - return ERR_PTR(ret); -} +const struct hdmi_phy_cfg msm_hdmi_phy_8960_cfg = { + .type = MSM_HDMI_PHY_8960, + .powerup = hdmi_phy_8960_powerup, + .powerdown = hdmi_phy_8960_powerdown, + .reg_names = hdmi_phy_8960_reg_names, + .num_regs = ARRAY_SIZE(hdmi_phy_8960_reg_names), + .clk_names = hdmi_phy_8960_clk_names, + .num_clks = ARRAY_SIZE(hdmi_phy_8960_clk_names), +}; diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c new file mode 100644 index 000000000..aa94a5537 --- /dev/null +++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c @@ -0,0 +1,766 @@ +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +#include "hdmi.h" + +#define HDMI_VCO_MAX_FREQ 12000000000UL +#define HDMI_VCO_MIN_FREQ 8000000000UL + +#define HDMI_PCLK_MAX_FREQ 600000000 +#define HDMI_PCLK_MIN_FREQ 25000000 + +#define HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD 3400000000UL +#define HDMI_DIG_FREQ_BIT_CLK_THRESHOLD 1500000000UL +#define HDMI_MID_FREQ_BIT_CLK_THRESHOLD 750000000UL +#define HDMI_CORECLK_DIV 5 +#define HDMI_DEFAULT_REF_CLOCK 19200000 +#define HDMI_PLL_CMP_CNT 1024 + +#define HDMI_PLL_POLL_MAX_READS 100 +#define HDMI_PLL_POLL_TIMEOUT_US 150 + +#define HDMI_NUM_TX_CHANNEL 4 + +struct hdmi_pll_8996 { + struct platform_device *pdev; + struct clk_hw clk_hw; + + /* pll mmio base */ + void __iomem *mmio_qserdes_com; + /* tx channel base */ + void __iomem *mmio_qserdes_tx[HDMI_NUM_TX_CHANNEL]; +}; + +#define hw_clk_to_pll(x) container_of(x, struct hdmi_pll_8996, clk_hw) + +struct hdmi_8996_phy_pll_reg_cfg { + u32 tx_lx_lane_mode[HDMI_NUM_TX_CHANNEL]; + u32 tx_lx_tx_band[HDMI_NUM_TX_CHANNEL]; + u32 com_svs_mode_clk_sel; + u32 com_hsclk_sel; + u32 com_pll_cctrl_mode0; + u32 com_pll_rctrl_mode0; + u32 com_cp_ctrl_mode0; + u32 com_dec_start_mode0; + u32 com_div_frac_start1_mode0; + u32 com_div_frac_start2_mode0; + u32 com_div_frac_start3_mode0; + u32 com_integloop_gain0_mode0; + u32 com_integloop_gain1_mode0; + u32 com_lock_cmp_en; + u32 com_lock_cmp1_mode0; + u32 com_lock_cmp2_mode0; + u32 com_lock_cmp3_mode0; + u32 com_core_clk_en; + u32 com_coreclk_div; + u32 com_vco_tune_ctrl; + + u32 tx_lx_tx_drv_lvl[HDMI_NUM_TX_CHANNEL]; + u32 tx_lx_tx_emp_post1_lvl[HDMI_NUM_TX_CHANNEL]; + u32 tx_lx_vmode_ctrl1[HDMI_NUM_TX_CHANNEL]; + u32 tx_lx_vmode_ctrl2[HDMI_NUM_TX_CHANNEL]; + u32 tx_lx_res_code_lane_tx[HDMI_NUM_TX_CHANNEL]; + u32 tx_lx_hp_pd_enables[HDMI_NUM_TX_CHANNEL]; + + u32 phy_mode; +}; + +struct hdmi_8996_post_divider { + u64 vco_freq; + int hsclk_divsel; + int vco_ratio; + int tx_band_sel; + int half_rate_mode; +}; + +static inline struct hdmi_phy *pll_get_phy(struct hdmi_pll_8996 *pll) +{ + return platform_get_drvdata(pll->pdev); +} + +static inline void hdmi_pll_write(struct hdmi_pll_8996 *pll, int offset, + u32 data) +{ + msm_writel(data, pll->mmio_qserdes_com + offset); +} + +static inline u32 hdmi_pll_read(struct hdmi_pll_8996 *pll, int offset) +{ + return msm_readl(pll->mmio_qserdes_com + offset); +} + +static inline void hdmi_tx_chan_write(struct hdmi_pll_8996 *pll, int channel, + int offset, int data) +{ + msm_writel(data, pll->mmio_qserdes_tx[channel] + offset); +} + +static inline u32 pll_get_cpctrl(u64 frac_start, unsigned long ref_clk, + bool gen_ssc) +{ + if ((frac_start != 0) || gen_ssc) + return (11000000 / (ref_clk / 20)); + + return 0x23; +} + +static inline u32 pll_get_rctrl(u64 frac_start, bool gen_ssc) +{ + if ((frac_start != 0) || gen_ssc) + return 0x16; + + return 0x10; +} + +static inline u32 pll_get_cctrl(u64 frac_start, bool gen_ssc) +{ + if ((frac_start != 0) || gen_ssc) + return 0x28; + + return 0x1; +} + +static inline u32 pll_get_integloop_gain(u64 frac_start, u64 bclk, u32 ref_clk, + bool gen_ssc) +{ + int digclk_divsel = bclk >= HDMI_DIG_FREQ_BIT_CLK_THRESHOLD ? 1 : 2; + u64 base; + + if ((frac_start != 0) || gen_ssc) + base = (64 * ref_clk) / HDMI_DEFAULT_REF_CLOCK; + else + base = (1022 * ref_clk) / 100; + + base <<= digclk_divsel; + + return (base <= 2046 ? base : 2046); +} + +static inline u32 pll_get_pll_cmp(u64 fdata, unsigned long ref_clk) +{ + u64 dividend = HDMI_PLL_CMP_CNT * fdata; + u32 divisor = ref_clk * 10; + u32 rem; + + rem = do_div(dividend, divisor); + if (rem > (divisor >> 1)) + dividend++; + + return dividend - 1; +} + +static inline u64 pll_cmp_to_fdata(u32 pll_cmp, unsigned long ref_clk) +{ + u64 fdata = ((u64)pll_cmp) * ref_clk * 10; + + do_div(fdata, HDMI_PLL_CMP_CNT); + + return fdata; +} + +static int pll_get_post_div(struct hdmi_8996_post_divider *pd, u64 bclk) +{ + int ratio[] = { 2, 3, 4, 5, 6, 9, 10, 12, 14, 15, 20, 21, 25, 28, 35 }; + int hs_divsel[] = { 0, 4, 8, 12, 1, 5, 2, 9, 3, 13, 10, 7, 14, 11, 15 }; + int tx_band_sel[] = { 0, 1, 2, 3 }; + u64 vco_freq[60]; + u64 vco, vco_optimal; + int half_rate_mode = 0; + int vco_optimal_index, vco_freq_index; + int i, j; + +retry: + vco_optimal = HDMI_VCO_MAX_FREQ; + vco_optimal_index = -1; + vco_freq_index = 0; + for (i = 0; i < 15; i++) { + for (j = 0; j < 4; j++) { + u32 ratio_mult = ratio[i] << tx_band_sel[j]; + + vco = bclk >> half_rate_mode; + vco *= ratio_mult; + vco_freq[vco_freq_index++] = vco; + } + } + + for (i = 0; i < 60; i++) { + u64 vco_tmp = vco_freq[i]; + + if ((vco_tmp >= HDMI_VCO_MIN_FREQ) && + (vco_tmp <= vco_optimal)) { + vco_optimal = vco_tmp; + vco_optimal_index = i; + } + } + + if (vco_optimal_index == -1) { + if (!half_rate_mode) { + half_rate_mode = 1; + goto retry; + } + } else { + pd->vco_freq = vco_optimal; + pd->tx_band_sel = tx_band_sel[vco_optimal_index % 4]; + pd->vco_ratio = ratio[vco_optimal_index / 4]; + pd->hsclk_divsel = hs_divsel[vco_optimal_index / 4]; + + return 0; + } + + return -EINVAL; +} + +static int pll_calculate(unsigned long pix_clk, unsigned long ref_clk, + struct hdmi_8996_phy_pll_reg_cfg *cfg) +{ + struct hdmi_8996_post_divider pd; + u64 bclk; + u64 tmds_clk; + u64 dec_start; + u64 frac_start; + u64 fdata; + u32 pll_divisor; + u32 rem; + u32 cpctrl; + u32 rctrl; + u32 cctrl; + u32 integloop_gain; + u32 pll_cmp; + int i, ret; + + /* bit clk = 10 * pix_clk */ + bclk = ((u64)pix_clk) * 10; + + if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) + tmds_clk = pix_clk >> 2; + else + tmds_clk = pix_clk; + + ret = pll_get_post_div(&pd, bclk); + if (ret) + return ret; + + dec_start = pd.vco_freq; + pll_divisor = 4 * ref_clk; + do_div(dec_start, pll_divisor); + + frac_start = pd.vco_freq * (1 << 20); + + rem = do_div(frac_start, pll_divisor); + frac_start -= dec_start * (1 << 20); + if (rem > (pll_divisor >> 1)) + frac_start++; + + cpctrl = pll_get_cpctrl(frac_start, ref_clk, false); + rctrl = pll_get_rctrl(frac_start, false); + cctrl = pll_get_cctrl(frac_start, false); + integloop_gain = pll_get_integloop_gain(frac_start, bclk, + ref_clk, false); + + fdata = pd.vco_freq; + do_div(fdata, pd.vco_ratio); + + pll_cmp = pll_get_pll_cmp(fdata, ref_clk); + + DBG("VCO freq: %llu", pd.vco_freq); + DBG("fdata: %llu", fdata); + DBG("pix_clk: %lu", pix_clk); + DBG("tmds clk: %llu", tmds_clk); + DBG("HSCLK_SEL: %d", pd.hsclk_divsel); + DBG("DEC_START: %llu", dec_start); + DBG("DIV_FRAC_START: %llu", frac_start); + DBG("PLL_CPCTRL: %u", cpctrl); + DBG("PLL_RCTRL: %u", rctrl); + DBG("PLL_CCTRL: %u", cctrl); + DBG("INTEGLOOP_GAIN: %u", integloop_gain); + DBG("TX_BAND: %d", pd.tx_band_sel); + DBG("PLL_CMP: %u", pll_cmp); + + /* Convert these values to register specific values */ + if (bclk > HDMI_DIG_FREQ_BIT_CLK_THRESHOLD) + cfg->com_svs_mode_clk_sel = 1; + else + cfg->com_svs_mode_clk_sel = 2; + + cfg->com_hsclk_sel = (0x20 | pd.hsclk_divsel); + cfg->com_pll_cctrl_mode0 = cctrl; + cfg->com_pll_rctrl_mode0 = rctrl; + cfg->com_cp_ctrl_mode0 = cpctrl; + cfg->com_dec_start_mode0 = dec_start; + cfg->com_div_frac_start1_mode0 = (frac_start & 0xff); + cfg->com_div_frac_start2_mode0 = ((frac_start & 0xff00) >> 8); + cfg->com_div_frac_start3_mode0 = ((frac_start & 0xf0000) >> 16); + cfg->com_integloop_gain0_mode0 = (integloop_gain & 0xff); + cfg->com_integloop_gain1_mode0 = ((integloop_gain & 0xf00) >> 8); + cfg->com_lock_cmp1_mode0 = (pll_cmp & 0xff); + cfg->com_lock_cmp2_mode0 = ((pll_cmp & 0xff00) >> 8); + cfg->com_lock_cmp3_mode0 = ((pll_cmp & 0x30000) >> 16); + cfg->com_lock_cmp_en = 0x0; + cfg->com_core_clk_en = 0x2c; + cfg->com_coreclk_div = HDMI_CORECLK_DIV; + cfg->phy_mode = (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) ? 0x10 : 0x0; + cfg->com_vco_tune_ctrl = 0x0; + + cfg->tx_lx_lane_mode[0] = + cfg->tx_lx_lane_mode[2] = 0x43; + + cfg->tx_lx_hp_pd_enables[0] = + cfg->tx_lx_hp_pd_enables[1] = + cfg->tx_lx_hp_pd_enables[2] = 0x0c; + cfg->tx_lx_hp_pd_enables[3] = 0x3; + + for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) + cfg->tx_lx_tx_band[i] = pd.tx_band_sel + 4; + + if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) { + cfg->tx_lx_tx_drv_lvl[0] = + cfg->tx_lx_tx_drv_lvl[1] = + cfg->tx_lx_tx_drv_lvl[2] = 0x25; + cfg->tx_lx_tx_drv_lvl[3] = 0x22; + + cfg->tx_lx_tx_emp_post1_lvl[0] = + cfg->tx_lx_tx_emp_post1_lvl[1] = + cfg->tx_lx_tx_emp_post1_lvl[2] = 0x23; + cfg->tx_lx_tx_emp_post1_lvl[3] = 0x27; + + cfg->tx_lx_vmode_ctrl1[0] = + cfg->tx_lx_vmode_ctrl1[1] = + cfg->tx_lx_vmode_ctrl1[2] = + cfg->tx_lx_vmode_ctrl1[3] = 0x00; + + cfg->tx_lx_vmode_ctrl2[0] = + cfg->tx_lx_vmode_ctrl2[1] = + cfg->tx_lx_vmode_ctrl2[2] = 0x0D; + + cfg->tx_lx_vmode_ctrl2[3] = 0x00; + } else if (bclk > HDMI_MID_FREQ_BIT_CLK_THRESHOLD) { + for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { + cfg->tx_lx_tx_drv_lvl[i] = 0x25; + cfg->tx_lx_tx_emp_post1_lvl[i] = 0x23; + cfg->tx_lx_vmode_ctrl1[i] = 0x00; + } + + cfg->tx_lx_vmode_ctrl2[0] = + cfg->tx_lx_vmode_ctrl2[1] = + cfg->tx_lx_vmode_ctrl2[2] = 0x0D; + cfg->tx_lx_vmode_ctrl2[3] = 0x00; + } else { + for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { + cfg->tx_lx_tx_drv_lvl[i] = 0x20; + cfg->tx_lx_tx_emp_post1_lvl[i] = 0x20; + cfg->tx_lx_vmode_ctrl1[i] = 0x00; + cfg->tx_lx_vmode_ctrl2[i] = 0x0E; + } + } + + DBG("com_svs_mode_clk_sel = 0x%x", cfg->com_svs_mode_clk_sel); + DBG("com_hsclk_sel = 0x%x", cfg->com_hsclk_sel); + DBG("com_lock_cmp_en = 0x%x", cfg->com_lock_cmp_en); + DBG("com_pll_cctrl_mode0 = 0x%x", cfg->com_pll_cctrl_mode0); + DBG("com_pll_rctrl_mode0 = 0x%x", cfg->com_pll_rctrl_mode0); + DBG("com_cp_ctrl_mode0 = 0x%x", cfg->com_cp_ctrl_mode0); + DBG("com_dec_start_mode0 = 0x%x", cfg->com_dec_start_mode0); + DBG("com_div_frac_start1_mode0 = 0x%x", cfg->com_div_frac_start1_mode0); + DBG("com_div_frac_start2_mode0 = 0x%x", cfg->com_div_frac_start2_mode0); + DBG("com_div_frac_start3_mode0 = 0x%x", cfg->com_div_frac_start3_mode0); + DBG("com_integloop_gain0_mode0 = 0x%x", cfg->com_integloop_gain0_mode0); + DBG("com_integloop_gain1_mode0 = 0x%x", cfg->com_integloop_gain1_mode0); + DBG("com_lock_cmp1_mode0 = 0x%x", cfg->com_lock_cmp1_mode0); + DBG("com_lock_cmp2_mode0 = 0x%x", cfg->com_lock_cmp2_mode0); + DBG("com_lock_cmp3_mode0 = 0x%x", cfg->com_lock_cmp3_mode0); + DBG("com_core_clk_en = 0x%x", cfg->com_core_clk_en); + DBG("com_coreclk_div = 0x%x", cfg->com_coreclk_div); + DBG("phy_mode = 0x%x", cfg->phy_mode); + + DBG("tx_l0_lane_mode = 0x%x", cfg->tx_lx_lane_mode[0]); + DBG("tx_l2_lane_mode = 0x%x", cfg->tx_lx_lane_mode[2]); + + for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { + DBG("tx_l%d_tx_band = 0x%x", i, cfg->tx_lx_tx_band[i]); + DBG("tx_l%d_tx_drv_lvl = 0x%x", i, cfg->tx_lx_tx_drv_lvl[i]); + DBG("tx_l%d_tx_emp_post1_lvl = 0x%x", i, + cfg->tx_lx_tx_emp_post1_lvl[i]); + DBG("tx_l%d_vmode_ctrl1 = 0x%x", i, cfg->tx_lx_vmode_ctrl1[i]); + DBG("tx_l%d_vmode_ctrl2 = 0x%x", i, cfg->tx_lx_vmode_ctrl2[i]); + } + + return 0; +} + +static int hdmi_8996_pll_set_clk_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw); + struct hdmi_phy *phy = pll_get_phy(pll); + struct hdmi_8996_phy_pll_reg_cfg cfg; + int i, ret; + + memset(&cfg, 0x00, sizeof(cfg)); + + ret = pll_calculate(rate, parent_rate, &cfg); + if (ret) { + DRM_ERROR("PLL calculation failed\n"); + return ret; + } + + /* Initially shut down PHY */ + DBG("Disabling PHY"); + hdmi_phy_write(phy, REG_HDMI_8996_PHY_PD_CTL, 0x0); + udelay(500); + + /* Power up sequence */ + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_BG_CTRL, 0x04); + + hdmi_phy_write(phy, REG_HDMI_8996_PHY_PD_CTL, 0x1); + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_RESETSM_CNTRL, 0x20); + hdmi_phy_write(phy, REG_HDMI_8996_PHY_TX0_TX1_LANE_CTL, 0x0F); + hdmi_phy_write(phy, REG_HDMI_8996_PHY_TX2_TX3_LANE_CTL, 0x0F); + + for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { + hdmi_tx_chan_write(pll, i, + REG_HDMI_PHY_QSERDES_TX_LX_CLKBUF_ENABLE, + 0x03); + hdmi_tx_chan_write(pll, i, + REG_HDMI_PHY_QSERDES_TX_LX_TX_BAND, + cfg.tx_lx_tx_band[i]); + hdmi_tx_chan_write(pll, i, + REG_HDMI_PHY_QSERDES_TX_LX_RESET_TSYNC_EN, + 0x03); + } + + hdmi_tx_chan_write(pll, 0, REG_HDMI_PHY_QSERDES_TX_LX_LANE_MODE, + cfg.tx_lx_lane_mode[0]); + hdmi_tx_chan_write(pll, 2, REG_HDMI_PHY_QSERDES_TX_LX_LANE_MODE, + cfg.tx_lx_lane_mode[2]); + + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SYSCLK_BUF_ENABLE, 0x1E); + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x07); + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SYSCLK_EN_SEL, 0x37); + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SYS_CLK_CTRL, 0x02); + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CLK_ENABLE1, 0x0E); + + /* Bypass VCO calibration */ + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SVS_MODE_CLK_SEL, + cfg.com_svs_mode_clk_sel); + + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_BG_TRIM, 0x0F); + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_PLL_IVCO, 0x0F); + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_VCO_TUNE_CTRL, + cfg.com_vco_tune_ctrl); + + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_BG_CTRL, 0x06); + + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CLK_SELECT, 0x30); + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_HSCLK_SEL, + cfg.com_hsclk_sel); + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP_EN, + cfg.com_lock_cmp_en); + + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_PLL_CCTRL_MODE0, + cfg.com_pll_cctrl_mode0); + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_PLL_RCTRL_MODE0, + cfg.com_pll_rctrl_mode0); + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CP_CTRL_MODE0, + cfg.com_cp_ctrl_mode0); + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_DEC_START_MODE0, + cfg.com_dec_start_mode0); + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_DIV_FRAC_START1_MODE0, + cfg.com_div_frac_start1_mode0); + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_DIV_FRAC_START2_MODE0, + cfg.com_div_frac_start2_mode0); + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_DIV_FRAC_START3_MODE0, + cfg.com_div_frac_start3_mode0); + + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_INTEGLOOP_GAIN0_MODE0, + cfg.com_integloop_gain0_mode0); + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_INTEGLOOP_GAIN1_MODE0, + cfg.com_integloop_gain1_mode0); + + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP1_MODE0, + cfg.com_lock_cmp1_mode0); + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP2_MODE0, + cfg.com_lock_cmp2_mode0); + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP3_MODE0, + cfg.com_lock_cmp3_mode0); + + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_VCO_TUNE_MAP, 0x00); + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CORE_CLK_EN, + cfg.com_core_clk_en); + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CORECLK_DIV, + cfg.com_coreclk_div); + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CMN_CONFIG, 0x02); + + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_RESCODE_DIV_NUM, 0x15); + + /* TX lanes setup (TX 0/1/2/3) */ + for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { + hdmi_tx_chan_write(pll, i, + REG_HDMI_PHY_QSERDES_TX_LX_TX_DRV_LVL, + cfg.tx_lx_tx_drv_lvl[i]); + hdmi_tx_chan_write(pll, i, + REG_HDMI_PHY_QSERDES_TX_LX_TX_EMP_POST1_LVL, + cfg.tx_lx_tx_emp_post1_lvl[i]); + hdmi_tx_chan_write(pll, i, + REG_HDMI_PHY_QSERDES_TX_LX_VMODE_CTRL1, + cfg.tx_lx_vmode_ctrl1[i]); + hdmi_tx_chan_write(pll, i, + REG_HDMI_PHY_QSERDES_TX_LX_VMODE_CTRL2, + cfg.tx_lx_vmode_ctrl2[i]); + hdmi_tx_chan_write(pll, i, + REG_HDMI_PHY_QSERDES_TX_LX_TX_DRV_LVL_OFFSET, + 0x00); + hdmi_tx_chan_write(pll, i, + REG_HDMI_PHY_QSERDES_TX_LX_RES_CODE_LANE_OFFSET, + 0x00); + hdmi_tx_chan_write(pll, i, + REG_HDMI_PHY_QSERDES_TX_LX_TRAN_DRVR_EMP_EN, + 0x03); + hdmi_tx_chan_write(pll, i, + REG_HDMI_PHY_QSERDES_TX_LX_PARRATE_REC_DETECT_IDLE_EN, + 0x40); + hdmi_tx_chan_write(pll, i, + REG_HDMI_PHY_QSERDES_TX_LX_HP_PD_ENABLES, + cfg.tx_lx_hp_pd_enables[i]); + } + + hdmi_phy_write(phy, REG_HDMI_8996_PHY_MODE, cfg.phy_mode); + hdmi_phy_write(phy, REG_HDMI_8996_PHY_PD_CTL, 0x1F); + + /* + * Ensure that vco configuration gets flushed to hardware before + * enabling the PLL + */ + wmb(); + + return 0; +} + +static int hdmi_8996_phy_ready_status(struct hdmi_phy *phy) +{ + u32 nb_tries = HDMI_PLL_POLL_MAX_READS; + unsigned long timeout = HDMI_PLL_POLL_TIMEOUT_US; + u32 status; + int phy_ready = 0; + + DBG("Waiting for PHY ready"); + + while (nb_tries--) { + status = hdmi_phy_read(phy, REG_HDMI_8996_PHY_STATUS); + phy_ready = status & BIT(0); + + if (phy_ready) + break; + + udelay(timeout); + } + + DBG("PHY is %sready", phy_ready ? "" : "*not* "); + + return phy_ready; +} + +static int hdmi_8996_pll_lock_status(struct hdmi_pll_8996 *pll) +{ + u32 status; + int nb_tries = HDMI_PLL_POLL_MAX_READS; + unsigned long timeout = HDMI_PLL_POLL_TIMEOUT_US; + int pll_locked = 0; + + DBG("Waiting for PLL lock"); + + while (nb_tries--) { + status = hdmi_pll_read(pll, + REG_HDMI_PHY_QSERDES_COM_C_READY_STATUS); + pll_locked = status & BIT(0); + + if (pll_locked) + break; + + udelay(timeout); + } + + DBG("HDMI PLL is %slocked", pll_locked ? "" : "*not* "); + + return pll_locked; +} + +static int hdmi_8996_pll_prepare(struct clk_hw *hw) +{ + struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw); + struct hdmi_phy *phy = pll_get_phy(pll); + int i, ret = 0; + + hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x1); + udelay(100); + + hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x19); + udelay(100); + + ret = hdmi_8996_pll_lock_status(pll); + if (!ret) + return ret; + + for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) + hdmi_tx_chan_write(pll, i, + REG_HDMI_PHY_QSERDES_TX_LX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, + 0x6F); + + /* Disable SSC */ + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_PER1, 0x0); + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_PER2, 0x0); + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_STEP_SIZE1, 0x0); + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_STEP_SIZE2, 0x0); + hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_EN_CENTER, 0x2); + + ret = hdmi_8996_phy_ready_status(phy); + if (!ret) + return ret; + + /* Restart the retiming buffer */ + hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x18); + udelay(1); + hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x19); + + return 0; +} + +static long hdmi_8996_pll_round_rate(struct clk_hw *hw, + unsigned long rate, + unsigned long *parent_rate) +{ + if (rate < HDMI_PCLK_MIN_FREQ) + return HDMI_PCLK_MIN_FREQ; + else if (rate > HDMI_PCLK_MAX_FREQ) + return HDMI_PCLK_MAX_FREQ; + else + return rate; +} + +static unsigned long hdmi_8996_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw); + u64 fdata; + u32 cmp1, cmp2, cmp3, pll_cmp; + + cmp1 = hdmi_pll_read(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP1_MODE0); + cmp2 = hdmi_pll_read(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP2_MODE0); + cmp3 = hdmi_pll_read(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP3_MODE0); + + pll_cmp = cmp1 | (cmp2 << 8) | (cmp3 << 16); + + fdata = pll_cmp_to_fdata(pll_cmp + 1, parent_rate); + + do_div(fdata, 10); + + return fdata; +} + +static void hdmi_8996_pll_unprepare(struct clk_hw *hw) +{ +} + +static int hdmi_8996_pll_is_enabled(struct clk_hw *hw) +{ + struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw); + u32 status; + int pll_locked; + + status = hdmi_pll_read(pll, REG_HDMI_PHY_QSERDES_COM_C_READY_STATUS); + pll_locked = status & BIT(0); + + return pll_locked; +} + +static struct clk_ops hdmi_8996_pll_ops = { + .set_rate = hdmi_8996_pll_set_clk_rate, + .round_rate = hdmi_8996_pll_round_rate, + .recalc_rate = hdmi_8996_pll_recalc_rate, + .prepare = hdmi_8996_pll_prepare, + .unprepare = hdmi_8996_pll_unprepare, + .is_enabled = hdmi_8996_pll_is_enabled, +}; + +static const char * const hdmi_pll_parents[] = { + "xo", +}; + +static struct clk_init_data pll_init = { + .name = "hdmipll", + .ops = &hdmi_8996_pll_ops, + .parent_names = hdmi_pll_parents, + .num_parents = ARRAY_SIZE(hdmi_pll_parents), +}; + +int msm_hdmi_pll_8996_init(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct hdmi_pll_8996 *pll; + struct clk *clk; + int i; + + pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL); + if (!pll) + return -ENOMEM; + + pll->pdev = pdev; + + pll->mmio_qserdes_com = msm_ioremap(pdev, "hdmi_pll", "HDMI_PLL"); + if (IS_ERR(pll->mmio_qserdes_com)) { + dev_err(dev, "failed to map pll base\n"); + return -ENOMEM; + } + + for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { + char name[32], label[32]; + + snprintf(name, sizeof(name), "hdmi_tx_l%d", i); + snprintf(label, sizeof(label), "HDMI_TX_L%d", i); + + pll->mmio_qserdes_tx[i] = msm_ioremap(pdev, name, label); + if (IS_ERR(pll->mmio_qserdes_tx[i])) { + dev_err(dev, "failed to map pll base\n"); + return -ENOMEM; + } + } + pll->clk_hw.init = &pll_init; + + clk = devm_clk_register(dev, &pll->clk_hw); + if (IS_ERR(clk)) { + dev_err(dev, "failed to register pll clock\n"); + return -EINVAL; + } + + return 0; +} + +static const char * const hdmi_phy_8996_reg_names[] = { + "vddio", + "vcca", +}; + +static const char * const hdmi_phy_8996_clk_names[] = { + "mmagic_iface_clk", + "iface_clk", + "ref_clk", +}; + +const struct hdmi_phy_cfg msm_hdmi_phy_8996_cfg = { + .type = MSM_HDMI_PHY_8996, + .reg_names = hdmi_phy_8996_reg_names, + .num_regs = ARRAY_SIZE(hdmi_phy_8996_reg_names), + .clk_names = hdmi_phy_8996_clk_names, + .num_clks = ARRAY_SIZE(hdmi_phy_8996_clk_names), +}; diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8x60.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8x60.c index cb01421ae..a68eea415 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8x60.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8x60.c @@ -17,166 +17,122 @@ #include "hdmi.h" -struct hdmi_phy_8x60 { - struct hdmi_phy base; - struct hdmi *hdmi; -}; -#define to_hdmi_phy_8x60(x) container_of(x, struct hdmi_phy_8x60, base) - -static void hdmi_phy_8x60_destroy(struct hdmi_phy *phy) -{ - struct hdmi_phy_8x60 *phy_8x60 = to_hdmi_phy_8x60(phy); - kfree(phy_8x60); -} - static void hdmi_phy_8x60_powerup(struct hdmi_phy *phy, unsigned long int pixclock) { - struct hdmi_phy_8x60 *phy_8x60 = to_hdmi_phy_8x60(phy); - struct hdmi *hdmi = phy_8x60->hdmi; - /* De-serializer delay D/C for non-lbk mode: */ - hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG0, - HDMI_8x60_PHY_REG0_DESER_DEL_CTRL(3)); + hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG0, + HDMI_8x60_PHY_REG0_DESER_DEL_CTRL(3)); if (pixclock == 27000000) { /* video_format == HDMI_VFRMT_720x480p60_16_9 */ - hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG1, - HDMI_8x60_PHY_REG1_DTEST_MUX_SEL(5) | - HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL(3)); + hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG1, + HDMI_8x60_PHY_REG1_DTEST_MUX_SEL(5) | + HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL(3)); } else { - hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG1, - HDMI_8x60_PHY_REG1_DTEST_MUX_SEL(5) | - HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL(4)); + hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG1, + HDMI_8x60_PHY_REG1_DTEST_MUX_SEL(5) | + HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL(4)); } /* No matter what, start from the power down mode: */ - hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG2, - HDMI_8x60_PHY_REG2_PD_PWRGEN | - HDMI_8x60_PHY_REG2_PD_PLL | - HDMI_8x60_PHY_REG2_PD_DRIVE_4 | - HDMI_8x60_PHY_REG2_PD_DRIVE_3 | - HDMI_8x60_PHY_REG2_PD_DRIVE_2 | - HDMI_8x60_PHY_REG2_PD_DRIVE_1 | - HDMI_8x60_PHY_REG2_PD_DESER); + hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2, + HDMI_8x60_PHY_REG2_PD_PWRGEN | + HDMI_8x60_PHY_REG2_PD_PLL | + HDMI_8x60_PHY_REG2_PD_DRIVE_4 | + HDMI_8x60_PHY_REG2_PD_DRIVE_3 | + HDMI_8x60_PHY_REG2_PD_DRIVE_2 | + HDMI_8x60_PHY_REG2_PD_DRIVE_1 | + HDMI_8x60_PHY_REG2_PD_DESER); /* Turn PowerGen on: */ - hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG2, - HDMI_8x60_PHY_REG2_PD_PLL | - HDMI_8x60_PHY_REG2_PD_DRIVE_4 | - HDMI_8x60_PHY_REG2_PD_DRIVE_3 | - HDMI_8x60_PHY_REG2_PD_DRIVE_2 | - HDMI_8x60_PHY_REG2_PD_DRIVE_1 | - HDMI_8x60_PHY_REG2_PD_DESER); + hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2, + HDMI_8x60_PHY_REG2_PD_PLL | + HDMI_8x60_PHY_REG2_PD_DRIVE_4 | + HDMI_8x60_PHY_REG2_PD_DRIVE_3 | + HDMI_8x60_PHY_REG2_PD_DRIVE_2 | + HDMI_8x60_PHY_REG2_PD_DRIVE_1 | + HDMI_8x60_PHY_REG2_PD_DESER); /* Turn PLL power on: */ - hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG2, - HDMI_8x60_PHY_REG2_PD_DRIVE_4 | - HDMI_8x60_PHY_REG2_PD_DRIVE_3 | - HDMI_8x60_PHY_REG2_PD_DRIVE_2 | - HDMI_8x60_PHY_REG2_PD_DRIVE_1 | - HDMI_8x60_PHY_REG2_PD_DESER); + hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2, + HDMI_8x60_PHY_REG2_PD_DRIVE_4 | + HDMI_8x60_PHY_REG2_PD_DRIVE_3 | + HDMI_8x60_PHY_REG2_PD_DRIVE_2 | + HDMI_8x60_PHY_REG2_PD_DRIVE_1 | + HDMI_8x60_PHY_REG2_PD_DESER); /* Write to HIGH after PLL power down de-assert: */ - hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG3, - HDMI_8x60_PHY_REG3_PLL_ENABLE); + hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG3, + HDMI_8x60_PHY_REG3_PLL_ENABLE); /* ASIC power on; PHY REG9 = 0 */ - hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG9, 0); + hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG9, 0); /* Enable PLL lock detect, PLL lock det will go high after lock * Enable the re-time logic */ - hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG12, - HDMI_8x60_PHY_REG12_RETIMING_EN | - HDMI_8x60_PHY_REG12_PLL_LOCK_DETECT_EN); + hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG12, + HDMI_8x60_PHY_REG12_RETIMING_EN | + HDMI_8x60_PHY_REG12_PLL_LOCK_DETECT_EN); /* Drivers are on: */ - hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG2, - HDMI_8x60_PHY_REG2_PD_DESER); + hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2, + HDMI_8x60_PHY_REG2_PD_DESER); /* If the RX detector is needed: */ - hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG2, - HDMI_8x60_PHY_REG2_RCV_SENSE_EN | - HDMI_8x60_PHY_REG2_PD_DESER); - - hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG4, 0); - hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG5, 0); - hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG6, 0); - hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG7, 0); - hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG8, 0); - hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG9, 0); - hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG10, 0); - hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG11, 0); + hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2, + HDMI_8x60_PHY_REG2_RCV_SENSE_EN | + HDMI_8x60_PHY_REG2_PD_DESER); + + hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG4, 0); + hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG5, 0); + hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG6, 0); + hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG7, 0); + hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG8, 0); + hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG9, 0); + hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG10, 0); + hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG11, 0); /* If we want to use lock enable based on counting: */ - hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG12, - HDMI_8x60_PHY_REG12_RETIMING_EN | - HDMI_8x60_PHY_REG12_PLL_LOCK_DETECT_EN | - HDMI_8x60_PHY_REG12_FORCE_LOCK); + hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG12, + HDMI_8x60_PHY_REG12_RETIMING_EN | + HDMI_8x60_PHY_REG12_PLL_LOCK_DETECT_EN | + HDMI_8x60_PHY_REG12_FORCE_LOCK); } static void hdmi_phy_8x60_powerdown(struct hdmi_phy *phy) { - struct hdmi_phy_8x60 *phy_8x60 = to_hdmi_phy_8x60(phy); - struct hdmi *hdmi = phy_8x60->hdmi; - /* Assert RESET PHY from controller */ - hdmi_write(hdmi, REG_HDMI_PHY_CTRL, - HDMI_PHY_CTRL_SW_RESET); + hdmi_phy_write(phy, REG_HDMI_PHY_CTRL, + HDMI_PHY_CTRL_SW_RESET); udelay(10); /* De-assert RESET PHY from controller */ - hdmi_write(hdmi, REG_HDMI_PHY_CTRL, 0); + hdmi_phy_write(phy, REG_HDMI_PHY_CTRL, 0); /* Turn off Driver */ - hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG2, - HDMI_8x60_PHY_REG2_PD_DRIVE_4 | - HDMI_8x60_PHY_REG2_PD_DRIVE_3 | - HDMI_8x60_PHY_REG2_PD_DRIVE_2 | - HDMI_8x60_PHY_REG2_PD_DRIVE_1 | - HDMI_8x60_PHY_REG2_PD_DESER); + hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2, + HDMI_8x60_PHY_REG2_PD_DRIVE_4 | + HDMI_8x60_PHY_REG2_PD_DRIVE_3 | + HDMI_8x60_PHY_REG2_PD_DRIVE_2 | + HDMI_8x60_PHY_REG2_PD_DRIVE_1 | + HDMI_8x60_PHY_REG2_PD_DESER); udelay(10); /* Disable PLL */ - hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG3, 0); + hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG3, 0); /* Power down PHY, but keep RX-sense: */ - hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG2, - HDMI_8x60_PHY_REG2_RCV_SENSE_EN | - HDMI_8x60_PHY_REG2_PD_PWRGEN | - HDMI_8x60_PHY_REG2_PD_PLL | - HDMI_8x60_PHY_REG2_PD_DRIVE_4 | - HDMI_8x60_PHY_REG2_PD_DRIVE_3 | - HDMI_8x60_PHY_REG2_PD_DRIVE_2 | - HDMI_8x60_PHY_REG2_PD_DRIVE_1 | - HDMI_8x60_PHY_REG2_PD_DESER); + hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2, + HDMI_8x60_PHY_REG2_RCV_SENSE_EN | + HDMI_8x60_PHY_REG2_PD_PWRGEN | + HDMI_8x60_PHY_REG2_PD_PLL | + HDMI_8x60_PHY_REG2_PD_DRIVE_4 | + HDMI_8x60_PHY_REG2_PD_DRIVE_3 | + HDMI_8x60_PHY_REG2_PD_DRIVE_2 | + HDMI_8x60_PHY_REG2_PD_DRIVE_1 | + HDMI_8x60_PHY_REG2_PD_DESER); } -static const struct hdmi_phy_funcs hdmi_phy_8x60_funcs = { - .destroy = hdmi_phy_8x60_destroy, - .powerup = hdmi_phy_8x60_powerup, - .powerdown = hdmi_phy_8x60_powerdown, +const struct hdmi_phy_cfg msm_hdmi_phy_8x60_cfg = { + .type = MSM_HDMI_PHY_8x60, + .powerup = hdmi_phy_8x60_powerup, + .powerdown = hdmi_phy_8x60_powerdown, }; - -struct hdmi_phy *hdmi_phy_8x60_init(struct hdmi *hdmi) -{ - struct hdmi_phy_8x60 *phy_8x60; - struct hdmi_phy *phy = NULL; - int ret; - - phy_8x60 = kzalloc(sizeof(*phy_8x60), GFP_KERNEL); - if (!phy_8x60) { - ret = -ENOMEM; - goto fail; - } - - phy = &phy_8x60->base; - - phy->funcs = &hdmi_phy_8x60_funcs; - - phy_8x60->hdmi = hdmi; - - return phy; - -fail: - if (phy) - hdmi_phy_8x60_destroy(phy); - return ERR_PTR(ret); -} diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8x74.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8x74.c index 56ab8917e..c4a61e537 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8x74.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8x74.c @@ -17,84 +17,40 @@ #include "hdmi.h" -struct hdmi_phy_8x74 { - struct hdmi_phy base; - void __iomem *mmio; -}; -#define to_hdmi_phy_8x74(x) container_of(x, struct hdmi_phy_8x74, base) - - -static void phy_write(struct hdmi_phy_8x74 *phy, u32 reg, u32 data) -{ - msm_writel(data, phy->mmio + reg); -} - -//static u32 phy_read(struct hdmi_phy_8x74 *phy, u32 reg) -//{ -// return msm_readl(phy->mmio + reg); -//} - -static void hdmi_phy_8x74_destroy(struct hdmi_phy *phy) -{ - struct hdmi_phy_8x74 *phy_8x74 = to_hdmi_phy_8x74(phy); - kfree(phy_8x74); -} - static void hdmi_phy_8x74_powerup(struct hdmi_phy *phy, unsigned long int pixclock) { - struct hdmi_phy_8x74 *phy_8x74 = to_hdmi_phy_8x74(phy); - - phy_write(phy_8x74, REG_HDMI_8x74_ANA_CFG0, 0x1b); - phy_write(phy_8x74, REG_HDMI_8x74_ANA_CFG1, 0xf2); - phy_write(phy_8x74, REG_HDMI_8x74_BIST_CFG0, 0x0); - phy_write(phy_8x74, REG_HDMI_8x74_BIST_PATN0, 0x0); - phy_write(phy_8x74, REG_HDMI_8x74_BIST_PATN1, 0x0); - phy_write(phy_8x74, REG_HDMI_8x74_BIST_PATN2, 0x0); - phy_write(phy_8x74, REG_HDMI_8x74_BIST_PATN3, 0x0); - phy_write(phy_8x74, REG_HDMI_8x74_PD_CTRL1, 0x20); + hdmi_phy_write(phy, REG_HDMI_8x74_ANA_CFG0, 0x1b); + hdmi_phy_write(phy, REG_HDMI_8x74_ANA_CFG1, 0xf2); + hdmi_phy_write(phy, REG_HDMI_8x74_BIST_CFG0, 0x0); + hdmi_phy_write(phy, REG_HDMI_8x74_BIST_PATN0, 0x0); + hdmi_phy_write(phy, REG_HDMI_8x74_BIST_PATN1, 0x0); + hdmi_phy_write(phy, REG_HDMI_8x74_BIST_PATN2, 0x0); + hdmi_phy_write(phy, REG_HDMI_8x74_BIST_PATN3, 0x0); + hdmi_phy_write(phy, REG_HDMI_8x74_PD_CTRL1, 0x20); } static void hdmi_phy_8x74_powerdown(struct hdmi_phy *phy) { - struct hdmi_phy_8x74 *phy_8x74 = to_hdmi_phy_8x74(phy); - phy_write(phy_8x74, REG_HDMI_8x74_PD_CTRL0, 0x7f); + hdmi_phy_write(phy, REG_HDMI_8x74_PD_CTRL0, 0x7f); } -static const struct hdmi_phy_funcs hdmi_phy_8x74_funcs = { - .destroy = hdmi_phy_8x74_destroy, - .powerup = hdmi_phy_8x74_powerup, - .powerdown = hdmi_phy_8x74_powerdown, +static const char * const hdmi_phy_8x74_reg_names[] = { + "core-vdda", + "vddio", }; -struct hdmi_phy *hdmi_phy_8x74_init(struct hdmi *hdmi) -{ - struct hdmi_phy_8x74 *phy_8x74; - struct hdmi_phy *phy = NULL; - int ret; - - phy_8x74 = kzalloc(sizeof(*phy_8x74), GFP_KERNEL); - if (!phy_8x74) { - ret = -ENOMEM; - goto fail; - } - - phy = &phy_8x74->base; - - phy->funcs = &hdmi_phy_8x74_funcs; - - /* for 8x74, the phy mmio is mapped separately: */ - phy_8x74->mmio = msm_ioremap(hdmi->pdev, - "phy_physical", "HDMI_8x74"); - if (IS_ERR(phy_8x74->mmio)) { - ret = PTR_ERR(phy_8x74->mmio); - goto fail; - } - - return phy; +static const char * const hdmi_phy_8x74_clk_names[] = { + "iface_clk", + "alt_iface_clk" +}; -fail: - if (phy) - hdmi_phy_8x74_destroy(phy); - return ERR_PTR(ret); -} +const struct hdmi_phy_cfg msm_hdmi_phy_8x74_cfg = { + .type = MSM_HDMI_PHY_8x74, + .powerup = hdmi_phy_8x74_powerup, + .powerdown = hdmi_phy_8x74_powerdown, + .reg_names = hdmi_phy_8x74_reg_names, + .num_regs = ARRAY_SIZE(hdmi_phy_8x74_reg_names), + .clk_names = hdmi_phy_8x74_clk_names, + .num_clks = ARRAY_SIZE(hdmi_phy_8x74_clk_names), +}; diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_pll_8960.c b/drivers/gpu/drm/msm/hdmi/hdmi_pll_8960.c new file mode 100644 index 000000000..92da69aa6 --- /dev/null +++ b/drivers/gpu/drm/msm/hdmi/hdmi_pll_8960.c @@ -0,0 +1,461 @@ +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * Copyright (C) 2013 Red Hat + * Author: Rob Clark + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include +#include "hdmi.h" + +struct hdmi_pll_8960 { + struct platform_device *pdev; + struct clk_hw clk_hw; + void __iomem *mmio; + + unsigned long pixclk; +}; + +#define hw_clk_to_pll(x) container_of(x, struct hdmi_pll_8960, clk_hw) + +/* + * HDMI PLL: + * + * To get the parent clock setup properly, we need to plug in hdmi pll + * configuration into common-clock-framework. + */ + +struct pll_rate { + unsigned long rate; + int num_reg; + struct { + u32 val; + u32 reg; + } conf[32]; +}; + +/* NOTE: keep sorted highest freq to lowest: */ +static const struct pll_rate freqtbl[] = { + { 154000000, 14, { + { 0x08, REG_HDMI_8960_PHY_PLL_REFCLK_CFG }, + { 0x20, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 }, + { 0xf9, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 }, + { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 }, + { 0x03, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 }, + { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 }, + { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 }, + { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 }, + { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 }, + { 0x0d, REG_HDMI_8960_PHY_PLL_SDM_CFG0 }, + { 0x4d, REG_HDMI_8960_PHY_PLL_SDM_CFG1 }, + { 0x5e, REG_HDMI_8960_PHY_PLL_SDM_CFG2 }, + { 0x42, REG_HDMI_8960_PHY_PLL_SDM_CFG3 }, + { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 }, + } + }, + /* 1080p60/1080p50 case */ + { 148500000, 27, { + { 0x02, REG_HDMI_8960_PHY_PLL_REFCLK_CFG }, + { 0x02, REG_HDMI_8960_PHY_PLL_CHRG_PUMP_CFG }, + { 0x01, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 }, + { 0x33, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 }, + { 0x2c, REG_HDMI_8960_PHY_PLL_IDAC_ADJ_CFG }, + { 0x06, REG_HDMI_8960_PHY_PLL_I_VI_KVCO_CFG }, + { 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B }, + { 0x76, REG_HDMI_8960_PHY_PLL_SDM_CFG0 }, + { 0x01, REG_HDMI_8960_PHY_PLL_SDM_CFG1 }, + { 0x4c, REG_HDMI_8960_PHY_PLL_SDM_CFG2 }, + { 0xc0, REG_HDMI_8960_PHY_PLL_SDM_CFG3 }, + { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 }, + { 0x9a, REG_HDMI_8960_PHY_PLL_SSC_CFG0 }, + { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG1 }, + { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG2 }, + { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG3 }, + { 0x10, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0 }, + { 0x1a, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1 }, + { 0x0d, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2 }, + { 0xe6, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 }, + { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 }, + { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 }, + { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 }, + { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 }, + { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 }, + { 0x33, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG6 }, + { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG7 }, + } + }, + { 108000000, 13, { + { 0x08, REG_HDMI_8960_PHY_PLL_REFCLK_CFG }, + { 0x21, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 }, + { 0xf9, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 }, + { 0x1c, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 }, + { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 }, + { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 }, + { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 }, + { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 }, + { 0x49, REG_HDMI_8960_PHY_PLL_SDM_CFG0 }, + { 0x49, REG_HDMI_8960_PHY_PLL_SDM_CFG1 }, + { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG2 }, + { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG3 }, + { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 }, + } + }, + /* 720p60/720p50/1080i60/1080i50/1080p24/1080p30/1080p25 */ + { 74250000, 8, { + { 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B }, + { 0x12, REG_HDMI_8960_PHY_PLL_REFCLK_CFG }, + { 0x01, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 }, + { 0x33, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 }, + { 0x76, REG_HDMI_8960_PHY_PLL_SDM_CFG0 }, + { 0xe6, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 }, + { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 }, + { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 }, + } + }, + { 74176000, 14, { + { 0x18, REG_HDMI_8960_PHY_PLL_REFCLK_CFG }, + { 0x20, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 }, + { 0xf9, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 }, + { 0xe5, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 }, + { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 }, + { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 }, + { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 }, + { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 }, + { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 }, + { 0x0c, REG_HDMI_8960_PHY_PLL_SDM_CFG0 }, + { 0x4c, REG_HDMI_8960_PHY_PLL_SDM_CFG1 }, + { 0x7d, REG_HDMI_8960_PHY_PLL_SDM_CFG2 }, + { 0xbc, REG_HDMI_8960_PHY_PLL_SDM_CFG3 }, + { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 }, + } + }, + { 65000000, 14, { + { 0x18, REG_HDMI_8960_PHY_PLL_REFCLK_CFG }, + { 0x20, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 }, + { 0xf9, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 }, + { 0x8a, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 }, + { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 }, + { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 }, + { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 }, + { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 }, + { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 }, + { 0x0b, REG_HDMI_8960_PHY_PLL_SDM_CFG0 }, + { 0x4b, REG_HDMI_8960_PHY_PLL_SDM_CFG1 }, + { 0x7b, REG_HDMI_8960_PHY_PLL_SDM_CFG2 }, + { 0x09, REG_HDMI_8960_PHY_PLL_SDM_CFG3 }, + { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 }, + } + }, + /* 480p60/480i60 */ + { 27030000, 18, { + { 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B }, + { 0x38, REG_HDMI_8960_PHY_PLL_REFCLK_CFG }, + { 0x02, REG_HDMI_8960_PHY_PLL_CHRG_PUMP_CFG }, + { 0x20, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 }, + { 0xff, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 }, + { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG0 }, + { 0x4e, REG_HDMI_8960_PHY_PLL_SDM_CFG1 }, + { 0xd7, REG_HDMI_8960_PHY_PLL_SDM_CFG2 }, + { 0x03, REG_HDMI_8960_PHY_PLL_SDM_CFG3 }, + { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 }, + { 0x2a, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 }, + { 0x03, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 }, + { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 }, + { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 }, + { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 }, + { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 }, + { 0x33, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG6 }, + { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG7 }, + } + }, + /* 576p50/576i50 */ + { 27000000, 27, { + { 0x32, REG_HDMI_8960_PHY_PLL_REFCLK_CFG }, + { 0x02, REG_HDMI_8960_PHY_PLL_CHRG_PUMP_CFG }, + { 0x01, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 }, + { 0x33, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 }, + { 0x2c, REG_HDMI_8960_PHY_PLL_IDAC_ADJ_CFG }, + { 0x06, REG_HDMI_8960_PHY_PLL_I_VI_KVCO_CFG }, + { 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B }, + { 0x7b, REG_HDMI_8960_PHY_PLL_SDM_CFG0 }, + { 0x01, REG_HDMI_8960_PHY_PLL_SDM_CFG1 }, + { 0x4c, REG_HDMI_8960_PHY_PLL_SDM_CFG2 }, + { 0xc0, REG_HDMI_8960_PHY_PLL_SDM_CFG3 }, + { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 }, + { 0x9a, REG_HDMI_8960_PHY_PLL_SSC_CFG0 }, + { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG1 }, + { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG2 }, + { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG3 }, + { 0x10, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0 }, + { 0x1a, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1 }, + { 0x0d, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2 }, + { 0x2a, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 }, + { 0x03, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 }, + { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 }, + { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 }, + { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 }, + { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 }, + { 0x33, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG6 }, + { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG7 }, + } + }, + /* 640x480p60 */ + { 25200000, 27, { + { 0x32, REG_HDMI_8960_PHY_PLL_REFCLK_CFG }, + { 0x02, REG_HDMI_8960_PHY_PLL_CHRG_PUMP_CFG }, + { 0x01, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 }, + { 0x33, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 }, + { 0x2c, REG_HDMI_8960_PHY_PLL_IDAC_ADJ_CFG }, + { 0x06, REG_HDMI_8960_PHY_PLL_I_VI_KVCO_CFG }, + { 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B }, + { 0x77, REG_HDMI_8960_PHY_PLL_SDM_CFG0 }, + { 0x4c, REG_HDMI_8960_PHY_PLL_SDM_CFG1 }, + { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG2 }, + { 0xc0, REG_HDMI_8960_PHY_PLL_SDM_CFG3 }, + { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 }, + { 0x9a, REG_HDMI_8960_PHY_PLL_SSC_CFG0 }, + { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG1 }, + { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG2 }, + { 0x20, REG_HDMI_8960_PHY_PLL_SSC_CFG3 }, + { 0x10, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0 }, + { 0x1a, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1 }, + { 0x0d, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2 }, + { 0xf4, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 }, + { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 }, + { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 }, + { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 }, + { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 }, + { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 }, + { 0x33, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG6 }, + { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG7 }, + } + }, +}; + +static inline void pll_write(struct hdmi_pll_8960 *pll, u32 reg, u32 data) +{ + msm_writel(data, pll->mmio + reg); +} + +static inline u32 pll_read(struct hdmi_pll_8960 *pll, u32 reg) +{ + return msm_readl(pll->mmio + reg); +} + +static inline struct hdmi_phy *pll_get_phy(struct hdmi_pll_8960 *pll) +{ + return platform_get_drvdata(pll->pdev); +} + +static int hdmi_pll_enable(struct clk_hw *hw) +{ + struct hdmi_pll_8960 *pll = hw_clk_to_pll(hw); + struct hdmi_phy *phy = pll_get_phy(pll); + int timeout_count, pll_lock_retry = 10; + unsigned int val; + + DBG(""); + + /* Assert PLL S/W reset */ + pll_write(pll, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2, 0x8d); + pll_write(pll, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0, 0x10); + pll_write(pll, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1, 0x1a); + + /* Wait for a short time before de-asserting + * to allow the hardware to complete its job. + * This much of delay should be fine for hardware + * to assert and de-assert. + */ + udelay(10); + + /* De-assert PLL S/W reset */ + pll_write(pll, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2, 0x0d); + + val = hdmi_phy_read(phy, REG_HDMI_8960_PHY_REG12); + val |= HDMI_8960_PHY_REG12_SW_RESET; + /* Assert PHY S/W reset */ + hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG12, val); + val &= ~HDMI_8960_PHY_REG12_SW_RESET; + /* + * Wait for a short time before de-asserting to allow the hardware to + * complete its job. This much of delay should be fine for hardware to + * assert and de-assert. + */ + udelay(10); + /* De-assert PHY S/W reset */ + hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG12, val); + hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG2, 0x3f); + + val = hdmi_phy_read(phy, REG_HDMI_8960_PHY_REG12); + val |= HDMI_8960_PHY_REG12_PWRDN_B; + hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG12, val); + /* Wait 10 us for enabling global power for PHY */ + mb(); + udelay(10); + + val = pll_read(pll, REG_HDMI_8960_PHY_PLL_PWRDN_B); + val |= HDMI_8960_PHY_PLL_PWRDN_B_PLL_PWRDN_B; + val &= ~HDMI_8960_PHY_PLL_PWRDN_B_PD_PLL; + pll_write(pll, REG_HDMI_8960_PHY_PLL_PWRDN_B, val); + hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG2, 0x80); + + timeout_count = 1000; + while (--pll_lock_retry > 0) { + /* are we there yet? */ + val = pll_read(pll, REG_HDMI_8960_PHY_PLL_STATUS0); + if (val & HDMI_8960_PHY_PLL_STATUS0_PLL_LOCK) + break; + + udelay(1); + + if (--timeout_count > 0) + continue; + + /* + * PLL has still not locked. + * Do a software reset and try again + * Assert PLL S/W reset first + */ + pll_write(pll, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2, 0x8d); + udelay(10); + pll_write(pll, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2, 0x0d); + + /* + * Wait for a short duration for the PLL calibration + * before checking if the PLL gets locked + */ + udelay(350); + + timeout_count = 1000; + } + + return 0; +} + +static void hdmi_pll_disable(struct clk_hw *hw) +{ + struct hdmi_pll_8960 *pll = hw_clk_to_pll(hw); + struct hdmi_phy *phy = pll_get_phy(pll); + unsigned int val; + + DBG(""); + + val = hdmi_phy_read(phy, REG_HDMI_8960_PHY_REG12); + val &= ~HDMI_8960_PHY_REG12_PWRDN_B; + hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG12, val); + + val = pll_read(pll, REG_HDMI_8960_PHY_PLL_PWRDN_B); + val |= HDMI_8960_PHY_REG12_SW_RESET; + val &= ~HDMI_8960_PHY_REG12_PWRDN_B; + pll_write(pll, REG_HDMI_8960_PHY_PLL_PWRDN_B, val); + /* Make sure HDMI PHY/PLL are powered down */ + mb(); +} + +static const struct pll_rate *find_rate(unsigned long rate) +{ + int i; + + for (i = 1; i < ARRAY_SIZE(freqtbl); i++) + if (rate > freqtbl[i].rate) + return &freqtbl[i - 1]; + + return &freqtbl[i - 1]; +} + +static unsigned long hdmi_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct hdmi_pll_8960 *pll = hw_clk_to_pll(hw); + + return pll->pixclk; +} + +static long hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + const struct pll_rate *pll_rate = find_rate(rate); + + return pll_rate->rate; +} + +static int hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct hdmi_pll_8960 *pll = hw_clk_to_pll(hw); + const struct pll_rate *pll_rate = find_rate(rate); + int i; + + DBG("rate=%lu", rate); + + for (i = 0; i < pll_rate->num_reg; i++) + pll_write(pll, pll_rate->conf[i].reg, pll_rate->conf[i].val); + + pll->pixclk = rate; + + return 0; +} + +static const struct clk_ops hdmi_pll_ops = { + .enable = hdmi_pll_enable, + .disable = hdmi_pll_disable, + .recalc_rate = hdmi_pll_recalc_rate, + .round_rate = hdmi_pll_round_rate, + .set_rate = hdmi_pll_set_rate, +}; + +static const char * const hdmi_pll_parents[] = { + "pxo", +}; + +static struct clk_init_data pll_init = { + .name = "hdmi_pll", + .ops = &hdmi_pll_ops, + .parent_names = hdmi_pll_parents, + .num_parents = ARRAY_SIZE(hdmi_pll_parents), +}; + +int msm_hdmi_pll_8960_init(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct hdmi_pll_8960 *pll; + struct clk *clk; + int i; + + /* sanity check: */ + for (i = 0; i < (ARRAY_SIZE(freqtbl) - 1); i++) + if (WARN_ON(freqtbl[i].rate < freqtbl[i + 1].rate)) + return -EINVAL; + + pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL); + if (!pll) + return -ENOMEM; + + pll->mmio = msm_ioremap(pdev, "hdmi_pll", "HDMI_PLL"); + if (IS_ERR(pll->mmio)) { + dev_err(dev, "failed to map pll base\n"); + return -ENOMEM; + } + + pll->pdev = pdev; + pll->clk_hw.init = &pll_init; + + clk = devm_clk_register(dev, &pll->clk_hw); + if (IS_ERR(clk)) { + dev_err(dev, "failed to register pll clock\n"); + return -EINVAL; + } + + return 0; +} diff --git a/drivers/gpu/drm/msm/hdmi/qfprom.xml.h b/drivers/gpu/drm/msm/hdmi/qfprom.xml.h index dbd9cc4da..6eab7d0cf 100644 --- a/drivers/gpu/drm/msm/hdmi/qfprom.xml.h +++ b/drivers/gpu/drm/msm/hdmi/qfprom.xml.h @@ -9,7 +9,7 @@ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2015-05-20 20:03:07) +- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2016-02-10 17:07:21) - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2015-05-20 20:03:14) - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2015-09-18 12:07:28) - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 37194 bytes, from 2015-09-18 12:07:28) @@ -17,11 +17,12 @@ The rules-ng-ng source files this header was generated from are: - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 602 bytes, from 2015-10-22 16:35:02) - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2015-05-20 20:03:14) - /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2015-05-20 20:03:07) -- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 29154 bytes, from 2015-08-10 21:25:43) +- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 41472 bytes, from 2016-01-22 18:18:18) - /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 10416 bytes, from 2015-05-20 20:03:14) Copyright (C) 2013-2015 by the following authors: - Rob Clark (robclark) +- Ilia Mirkin (imirkin) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the -- cgit v1.2.3-54-g00ecf