diff options
author | José Pekkarinen <jose.pekkarinen@nokia.com> | 2016-04-11 10:41:07 +0300 |
---|---|---|
committer | José Pekkarinen <jose.pekkarinen@nokia.com> | 2016-04-13 08:17:18 +0300 |
commit | e09b41010ba33a20a87472ee821fa407a5b8da36 (patch) | |
tree | d10dc367189862e7ca5c592f033dc3726e1df4e3 /kernel/drivers/gpu/drm/msm/hdmi | |
parent | f93b97fd65072de626c074dbe099a1fff05ce060 (diff) |
These changes are the raw update to linux-4.4.6-rt14. Kernel sources
are taken from kernel.org, and rt patch from the rt wiki download page.
During the rebasing, the following patch collided:
Force tick interrupt and get rid of softirq magic(I70131fb85).
Collisions have been removed because its logic was found on the
source already.
Change-Id: I7f57a4081d9deaa0d9ccfc41a6c8daccdee3b769
Signed-off-by: José Pekkarinen <jose.pekkarinen@nokia.com>
Diffstat (limited to 'kernel/drivers/gpu/drm/msm/hdmi')
-rw-r--r-- | kernel/drivers/gpu/drm/msm/hdmi/hdmi.c | 90 | ||||
-rw-r--r-- | kernel/drivers/gpu/drm/msm/hdmi/hdmi.h | 32 | ||||
-rw-r--r-- | kernel/drivers/gpu/drm/msm/hdmi/hdmi.xml.h | 115 | ||||
-rw-r--r-- | kernel/drivers/gpu/drm/msm/hdmi/hdmi_audio.c | 1 | ||||
-rw-r--r-- | kernel/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 16 | ||||
-rw-r--r-- | kernel/drivers/gpu/drm/msm/hdmi/hdmi_connector.c | 140 | ||||
-rw-r--r-- | kernel/drivers/gpu/drm/msm/hdmi/hdmi_hdcp.c | 1437 | ||||
-rw-r--r-- | kernel/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c | 52 | ||||
-rw-r--r-- | kernel/drivers/gpu/drm/msm/hdmi/hdmi_phy_8x60.c | 32 | ||||
-rw-r--r-- | kernel/drivers/gpu/drm/msm/hdmi/hdmi_phy_8x74.c | 57 | ||||
-rw-r--r-- | kernel/drivers/gpu/drm/msm/hdmi/qfprom.xml.h | 26 |
11 files changed, 1778 insertions, 220 deletions
diff --git a/kernel/drivers/gpu/drm/msm/hdmi/hdmi.c b/kernel/drivers/gpu/drm/msm/hdmi/hdmi.c index 814536202..1f4a95eeb 100644 --- a/kernel/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/kernel/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -22,7 +22,9 @@ void hdmi_set_mode(struct hdmi *hdmi, bool power_on) { uint32_t ctrl = 0; + unsigned long flags; + spin_lock_irqsave(&hdmi->reg_lock, flags); if (power_on) { ctrl |= HDMI_CTRL_ENABLE; if (!hdmi->hdmi_mode) { @@ -37,6 +39,7 @@ void hdmi_set_mode(struct hdmi *hdmi, bool power_on) } hdmi_write(hdmi, REG_HDMI_CTRL, ctrl); + spin_unlock_irqrestore(&hdmi->reg_lock, flags); DBG("HDMI Core: %s, HDMI_CTRL=0x%08x", power_on ? "Enable" : "Disable", ctrl); } @@ -51,6 +54,10 @@ static irqreturn_t hdmi_irq(int irq, void *dev_id) /* Process DDC: */ hdmi_i2c_irq(hdmi->i2c); + /* Process HDCP: */ + if (hdmi->hdcp_ctrl) + hdmi_hdcp_irq(hdmi->hdcp_ctrl); + /* TODO audio.. */ return IRQ_HANDLED; @@ -60,6 +67,15 @@ static void 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 + */ + if (hdmi->workq) { + flush_workqueue(hdmi->workq); + destroy_workqueue(hdmi->workq); + } + hdmi_hdcp_destroy(hdmi); if (phy) phy->funcs->destroy(phy); @@ -77,6 +93,7 @@ static struct hdmi *hdmi_init(struct platform_device *pdev) { struct hdmi_platform_config *config = pdev->dev.platform_data; struct hdmi *hdmi = NULL; + struct resource *res; int i, ret; hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL); @@ -87,18 +104,18 @@ static struct hdmi *hdmi_init(struct platform_device *pdev) hdmi->pdev = 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) + if (config->phy_init) { hdmi->phy = config->phy_init(hdmi); - else - hdmi->phy = ERR_PTR(-ENXIO); - 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; + 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"); @@ -107,6 +124,18 @@ static struct hdmi *hdmi_init(struct platform_device *pdev) goto fail; } + /* HDCP needs physical address of hdmi register */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + config->mmio_name); + hdmi->mmio_phy_addr = res->start; + + hdmi->qfprom_mmio = msm_ioremap(pdev, + config->qfprom_mmio_name, "HDMI_QFPROM"); + if (IS_ERR(hdmi->qfprom_mmio)) { + dev_info(&pdev->dev, "can't find qfprom resource\n"); + hdmi->qfprom_mmio = NULL; + } + hdmi->hpd_regs = devm_kzalloc(&pdev->dev, sizeof(hdmi->hpd_regs[0]) * config->hpd_reg_cnt, GFP_KERNEL); if (!hdmi->hpd_regs) { @@ -189,6 +218,8 @@ static struct hdmi *hdmi_init(struct platform_device *pdev) hdmi->pwr_clks[i] = clk; } + hdmi->workq = alloc_ordered_workqueue("msm_hdmi", 0); + hdmi->i2c = hdmi_i2c_init(hdmi); if (IS_ERR(hdmi->i2c)) { ret = PTR_ERR(hdmi->i2c); @@ -197,6 +228,12 @@ static struct hdmi *hdmi_init(struct platform_device *pdev) goto fail; } + hdmi->hdcp_ctrl = hdmi_hdcp_init(hdmi); + if (IS_ERR(hdmi->hdcp_ctrl)) { + dev_warn(&pdev->dev, "failed to init hdcp: disabled\n"); + hdmi->hdcp_ctrl = NULL; + } + return hdmi; fail: @@ -291,6 +328,9 @@ fail: .item ## _names = item ##_names_ ## entry, \ .item ## _cnt = ARRAY_SIZE(item ## _names_ ## entry) +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, }; @@ -310,7 +350,7 @@ static const char *pwr_clk_names_8x74[] = {"extp_clk", "alt_iface_clk"}; static const char *hpd_clk_names_8x74[] = {"iface_clk", "core_clk", "mdp_core_clk"}; static unsigned long hpd_clk_freq_8x74[] = {0, 19200000, 0}; -static struct hdmi_platform_config hdmi_tx_8074_config = { +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), @@ -330,9 +370,29 @@ static struct hdmi_platform_config hdmi_tx_8084_config = { .hpd_freq = hpd_clk_freq_8x74, }; +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), + HDMI_CFG(hpd_clk, 8x74), + .hpd_freq = hpd_clk_freq_8x74, +}; + +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), + HDMI_CFG(hpd_clk, 8x74), + .hpd_freq = hpd_clk_freq_8x74, +}; + static const struct of_device_id 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 }, - { .compatible = "qcom,hdmi-tx-8074", .data = &hdmi_tx_8074_config }, + { .compatible = "qcom,hdmi-tx-8974", .data = &hdmi_tx_8974_config }, { .compatible = "qcom,hdmi-tx-8960", .data = &hdmi_tx_8960_config }, { .compatible = "qcom,hdmi-tx-8660", .data = &hdmi_tx_8660_config }, {} @@ -347,8 +407,7 @@ static int get_gpio(struct device *dev, struct device_node *of_node, const char snprintf(name2, sizeof(name2), "%s-gpio", name); gpio = of_get_named_gpio(of_node, name2, 0); if (gpio < 0) { - dev_err(dev, "failed to get gpio: %s (%d)\n", - name, gpio); + DBG("failed to get gpio: %s (%d)", name, gpio); gpio = -1; } } @@ -376,6 +435,7 @@ 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"); @@ -391,7 +451,6 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) if (cpu_is_apq8064()) { static const char *hpd_reg_names[] = {"8921_hdmi_mvs"}; config.phy_init = hdmi_phy_8960_init; - config.mmio_name = "hdmi_msm_hdmi_addr"; config.hpd_reg_names = hpd_reg_names; config.hpd_reg_cnt = ARRAY_SIZE(hpd_reg_names); config.hpd_clk_names = hpd_clk_names; @@ -404,7 +463,6 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) } else if (cpu_is_msm8960() || cpu_is_msm8960ab()) { static const char *hpd_reg_names[] = {"8921_hdmi_mvs"}; config.phy_init = hdmi_phy_8960_init; - config.mmio_name = "hdmi_msm_hdmi_addr"; config.hpd_reg_names = hpd_reg_names; config.hpd_reg_cnt = ARRAY_SIZE(hpd_reg_names); config.hpd_clk_names = hpd_clk_names; @@ -419,7 +477,6 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) "8901_hdmi_mvs", "8901_mpp0" }; config.phy_init = hdmi_phy_8x60_init; - config.mmio_name = "hdmi_msm_hdmi_addr"; config.hpd_reg_names = hpd_reg_names; config.hpd_reg_cnt = ARRAY_SIZE(hpd_reg_names); config.hpd_clk_names = hpd_clk_names; @@ -430,6 +487,9 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) config.mux_en_gpio = -1; config.mux_sel_gpio = -1; } + config.mmio_name = "hdmi_msm_hdmi_addr"; + config.qfprom_mmio_name = "hdmi_msm_qfprom_addr"; + hdmi_cfg = &config; #endif dev->platform_data = hdmi_cfg; diff --git a/kernel/drivers/gpu/drm/msm/hdmi/hdmi.h b/kernel/drivers/gpu/drm/msm/hdmi/hdmi.h index 68fdfb362..d0e663192 100644 --- a/kernel/drivers/gpu/drm/msm/hdmi/hdmi.h +++ b/kernel/drivers/gpu/drm/msm/hdmi/hdmi.h @@ -37,6 +37,8 @@ struct hdmi_audio { int rate; }; +struct hdmi_hdcp_ctrl; + struct hdmi { struct drm_device *dev; struct platform_device *pdev; @@ -51,6 +53,8 @@ struct hdmi { unsigned long int pixclock; void __iomem *mmio; + void __iomem *qfprom_mmio; + phys_addr_t mmio_phy_addr; struct regulator **hpd_regs; struct regulator **pwr_regs; @@ -68,12 +72,25 @@ struct hdmi { bool hdmi_mode; /* are we in hdmi mode? */ int irq; + struct workqueue_struct *workq; + + struct hdmi_hdcp_ctrl *hdcp_ctrl; + + /* + * spinlock to protect registers shared by different execution + * REG_HDMI_CTRL + * REG_HDMI_DDC_ARBITRATION + * REG_HDMI_HDCP_INT_CTRL + * REG_HDMI_HPD_CTRL + */ + spinlock_t reg_lock; }; /* 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; /* regulators that need to be on for hpd: */ const char **hpd_reg_names; @@ -109,6 +126,11 @@ static inline u32 hdmi_read(struct hdmi *hdmi, u32 reg) return msm_readl(hdmi->mmio + reg); } +static inline u32 hdmi_qfprom_read(struct hdmi *hdmi, u32 reg) +{ + return msm_readl(hdmi->qfprom_mmio + 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 @@ -117,7 +139,6 @@ static inline u32 hdmi_read(struct hdmi *hdmi, u32 reg) struct hdmi_phy_funcs { void (*destroy)(struct hdmi_phy *phy); - void (*reset)(struct hdmi_phy *phy); void (*powerup)(struct hdmi_phy *phy, unsigned long int pixclock); void (*powerdown)(struct hdmi_phy *phy); }; @@ -163,4 +184,13 @@ 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); +/* + * 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); + #endif /* __HDMI_CONNECTOR_H__ */ diff --git a/kernel/drivers/gpu/drm/msm/hdmi/hdmi.xml.h b/kernel/drivers/gpu/drm/msm/hdmi/hdmi.xml.h index 350988740..10c45700a 100644 --- a/kernel/drivers/gpu/drm/msm/hdmi/hdmi.xml.h +++ b/kernel/drivers/gpu/drm/msm/hdmi/hdmi.xml.h @@ -8,17 +8,17 @@ http://github.com/freedreno/envytools/ 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 2014-12-05 15:34:49) -- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20908 bytes, from 2014-12-08 16:13:00) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2357 bytes, from 2014-12-08 16:13:00) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 27208 bytes, from 2015-01-13 23:56:11) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57) -- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12) -- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 26848 bytes, from 2015-01-13 23:55:57) -- /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 8253 bytes, from 2014-12-08 16:13:00) +- /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/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) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 27887 bytes, from 2015-10-22 16:34:52) +- /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/edp/edp.xml ( 10416 bytes, from 2015-05-20 20:03:14) Copyright (C) 2013-2015 by the following authors: - Rob Clark <robdclark@gmail.com> (robclark) @@ -441,6 +441,12 @@ static inline uint32_t HDMI_DDC_REF_REFTIMER(uint32_t val) #define REG_HDMI_HDCP_SW_LOWER_AKSV 0x00000288 +#define REG_HDMI_CEC_CTRL 0x0000028c + +#define REG_HDMI_CEC_WR_DATA 0x00000290 + +#define REG_HDMI_CEC_CEC_RETRANSMIT 0x00000294 + #define REG_HDMI_CEC_STATUS 0x00000298 #define REG_HDMI_CEC_INT 0x0000029c @@ -750,5 +756,92 @@ static inline uint32_t HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL(uint32_t val) #define REG_HDMI_8x74_BIST_PATN3 0x00000048 +#define REG_HDMI_28nm_PHY_PLL_REFCLK_CFG 0x00000000 + +#define REG_HDMI_28nm_PHY_PLL_POSTDIV1_CFG 0x00000004 + +#define REG_HDMI_28nm_PHY_PLL_CHGPUMP_CFG 0x00000008 + +#define REG_HDMI_28nm_PHY_PLL_VCOLPF_CFG 0x0000000c + +#define REG_HDMI_28nm_PHY_PLL_VREG_CFG 0x00000010 + +#define REG_HDMI_28nm_PHY_PLL_PWRGEN_CFG 0x00000014 + +#define REG_HDMI_28nm_PHY_PLL_DMUX_CFG 0x00000018 + +#define REG_HDMI_28nm_PHY_PLL_AMUX_CFG 0x0000001c + +#define REG_HDMI_28nm_PHY_PLL_GLB_CFG 0x00000020 +#define HDMI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B 0x00000001 +#define HDMI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B 0x00000002 +#define HDMI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B 0x00000004 +#define HDMI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE 0x00000008 + +#define REG_HDMI_28nm_PHY_PLL_POSTDIV2_CFG 0x00000024 + +#define REG_HDMI_28nm_PHY_PLL_POSTDIV3_CFG 0x00000028 + +#define REG_HDMI_28nm_PHY_PLL_LPFR_CFG 0x0000002c + +#define REG_HDMI_28nm_PHY_PLL_LPFC1_CFG 0x00000030 + +#define REG_HDMI_28nm_PHY_PLL_LPFC2_CFG 0x00000034 + +#define REG_HDMI_28nm_PHY_PLL_SDM_CFG0 0x00000038 + +#define REG_HDMI_28nm_PHY_PLL_SDM_CFG1 0x0000003c + +#define REG_HDMI_28nm_PHY_PLL_SDM_CFG2 0x00000040 + +#define REG_HDMI_28nm_PHY_PLL_SDM_CFG3 0x00000044 + +#define REG_HDMI_28nm_PHY_PLL_SDM_CFG4 0x00000048 + +#define REG_HDMI_28nm_PHY_PLL_SSC_CFG0 0x0000004c + +#define REG_HDMI_28nm_PHY_PLL_SSC_CFG1 0x00000050 + +#define REG_HDMI_28nm_PHY_PLL_SSC_CFG2 0x00000054 + +#define REG_HDMI_28nm_PHY_PLL_SSC_CFG3 0x00000058 + +#define REG_HDMI_28nm_PHY_PLL_LKDET_CFG0 0x0000005c + +#define REG_HDMI_28nm_PHY_PLL_LKDET_CFG1 0x00000060 + +#define REG_HDMI_28nm_PHY_PLL_LKDET_CFG2 0x00000064 + |