mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-16 15:34:48 +08:00
drm/msm: Add support for msm8x94
This change adds the MDP and HDMI support for msm8x94. Note that HDMI PHY registers are not being accessed anymore from the driver. Signed-off-by: Stephane Viau <sviau@codeaurora.org> [rename compatible s/8x94/8994/ since preference is to not trust the marketing folks who invent chip #'s but instead name things after the lead chip.. we should rename some 80XY to 89XY to standardize on the lead chip but leave that for another patch. Also, update dt bindings doc] Signed-off-by: Rob Clark <robdclark@gmail.com>
This commit is contained in:
parent
da32855219
commit
3a84f8469e
@ -2,6 +2,7 @@ Qualcomm adreno/snapdragon hdmi output
|
||||
|
||||
Required properties:
|
||||
- compatible: one of the following
|
||||
* "qcom,hdmi-tx-8994"
|
||||
* "qcom,hdmi-tx-8084"
|
||||
* "qcom,hdmi-tx-8074"
|
||||
* "qcom,hdmi-tx-8660"
|
||||
|
@ -107,16 +107,15 @@ static struct hdmi *hdmi_init(struct platform_device *pdev)
|
||||
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");
|
||||
@ -368,7 +367,19 @@ static struct hdmi_platform_config hdmi_tx_8084_config = {
|
||||
.hpd_freq = hpd_clk_freq_8x74,
|
||||
};
|
||||
|
||||
static const char *hpd_reg_names_8x94[] = {};
|
||||
|
||||
static struct hdmi_platform_config hdmi_tx_8x94_config = {
|
||||
.phy_init = NULL, /* nothing to do for this HDMI PHY 20nm */
|
||||
HDMI_CFG(pwr_reg, 8x74),
|
||||
HDMI_CFG(hpd_reg, 8x94),
|
||||
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-8994", .data = &hdmi_tx_8x94_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-8960", .data = &hdmi_tx_8960_config },
|
||||
@ -385,8 +396,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;
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +100,9 @@ static void hdmi_bridge_pre_enable(struct drm_bridge *bridge)
|
||||
hdmi_audio_update(hdmi);
|
||||
}
|
||||
|
||||
phy->funcs->powerup(phy, hdmi->pixclock);
|
||||
if (phy)
|
||||
phy->funcs->powerup(phy, hdmi->pixclock);
|
||||
|
||||
hdmi_set_mode(hdmi, true);
|
||||
|
||||
if (hdmi->hdcp_ctrl)
|
||||
@ -126,7 +128,9 @@ static void hdmi_bridge_post_disable(struct drm_bridge *bridge)
|
||||
|
||||
DBG("power down");
|
||||
hdmi_set_mode(hdmi, false);
|
||||
phy->funcs->powerdown(phy);
|
||||
|
||||
if (phy)
|
||||
phy->funcs->powerdown(phy);
|
||||
|
||||
if (hdmi->power_on) {
|
||||
power_off(bridge);
|
||||
|
@ -84,21 +84,25 @@ static int gpio_config(struct hdmi *hdmi, bool on)
|
||||
int ret;
|
||||
|
||||
if (on) {
|
||||
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;
|
||||
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);
|
||||
}
|
||||
gpio_set_value_cansleep(config->ddc_clk_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;
|
||||
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);
|
||||
}
|
||||
gpio_set_value_cansleep(config->ddc_data_gpio, 1);
|
||||
|
||||
ret = gpio_request(config->hpd_gpio, "HDMI_HPD");
|
||||
if (ret) {
|
||||
@ -143,8 +147,12 @@ static int gpio_config(struct hdmi *hdmi, bool on)
|
||||
}
|
||||
DBG("gpio on");
|
||||
} else {
|
||||
gpio_free(config->ddc_clk_gpio);
|
||||
gpio_free(config->ddc_data_gpio);
|
||||
if (config->ddc_clk_gpio != -1)
|
||||
gpio_free(config->ddc_clk_gpio);
|
||||
|
||||
if (config->ddc_data_gpio != -1)
|
||||
gpio_free(config->ddc_data_gpio);
|
||||
|
||||
gpio_free(config->hpd_gpio);
|
||||
|
||||
if (config->mux_en_gpio != -1) {
|
||||
@ -175,9 +183,11 @@ error5:
|
||||
error4:
|
||||
gpio_free(config->hpd_gpio);
|
||||
error3:
|
||||
gpio_free(config->ddc_data_gpio);
|
||||
if (config->ddc_data_gpio != -1)
|
||||
gpio_free(config->ddc_data_gpio);
|
||||
error2:
|
||||
gpio_free(config->ddc_clk_gpio);
|
||||
if (config->ddc_clk_gpio != -1)
|
||||
gpio_free(config->ddc_clk_gpio);
|
||||
error1:
|
||||
return ret;
|
||||
}
|
||||
|
@ -203,14 +203,85 @@ const struct mdp5_cfg_hw msm8x16_config = {
|
||||
.max_clk = 320000000,
|
||||
};
|
||||
|
||||
const struct mdp5_cfg_hw msm8x94_config = {
|
||||
.name = "msm8x94",
|
||||
.mdp = {
|
||||
.count = 1,
|
||||
.base = { 0x01000 },
|
||||
},
|
||||
.smp = {
|
||||
.mmb_count = 44,
|
||||
.mmb_size = 8192,
|
||||
.clients = {
|
||||
[SSPP_VIG0] = 1, [SSPP_VIG1] = 4,
|
||||
[SSPP_VIG2] = 7, [SSPP_VIG3] = 19,
|
||||
[SSPP_DMA0] = 10, [SSPP_DMA1] = 13,
|
||||
[SSPP_RGB0] = 16, [SSPP_RGB1] = 17,
|
||||
[SSPP_RGB2] = 18, [SSPP_RGB3] = 22,
|
||||
},
|
||||
.reserved_state[0] = GENMASK(23, 0), /* first 24 MMBs */
|
||||
.reserved = {
|
||||
[1] = 1, [4] = 1, [7] = 1, [19] = 1,
|
||||
[16] = 5, [17] = 5, [18] = 5, [22] = 5,
|
||||
},
|
||||
},
|
||||
.ctl = {
|
||||
.count = 5,
|
||||
.base = { 0x02000, 0x02200, 0x02400, 0x02600, 0x02800 },
|
||||
.flush_hw_mask = 0xf0ffffff,
|
||||
},
|
||||
.pipe_vig = {
|
||||
.count = 4,
|
||||
.base = { 0x05000, 0x07000, 0x09000, 0x0b000 },
|
||||
/* TODO: add decimation bit */
|
||||
},
|
||||
.pipe_rgb = {
|
||||
.count = 4,
|
||||
.base = { 0x15000, 0x17000, 0x19000, 0x1b000 },
|
||||
/* TODO: add decimation bit */
|
||||
},
|
||||
.pipe_dma = {
|
||||
.count = 2,
|
||||
.base = { 0x25000, 0x27000 },
|
||||
},
|
||||
.lm = {
|
||||
.count = 6,
|
||||
.base = { 0x45000, 0x46000, 0x47000, 0x48000, 0x49000, 0x4a000 },
|
||||
.nb_stages = 8,
|
||||
},
|
||||
.dspp = {
|
||||
.count = 4,
|
||||
.base = { 0x55000, 0x57000, 0x59000, 0x5b000 },
|
||||
|
||||
},
|
||||
.ad = {
|
||||
.count = 3,
|
||||
.base = { 0x79000, 0x79800, 0x7a000 },
|
||||
},
|
||||
.pp = {
|
||||
.count = 4,
|
||||
.base = { 0x71000, 0x71800, 0x72000, 0x72800 },
|
||||
},
|
||||
.intf = {
|
||||
.base = { 0x6b000, 0x6b800, 0x6c000, 0x6c800, 0x6d000 },
|
||||
.connect = {
|
||||
[0] = INTF_DISABLED,
|
||||
[1] = INTF_DSI,
|
||||
[2] = INTF_DSI,
|
||||
[3] = INTF_HDMI,
|
||||
},
|
||||
},
|
||||
.max_clk = 320000000,
|
||||
};
|
||||
|
||||
static const struct mdp5_cfg_handler cfg_handlers[] = {
|
||||
{ .revision = 0, .config = { .hw = &msm8x74_config } },
|
||||
{ .revision = 2, .config = { .hw = &msm8x74_config } },
|
||||
{ .revision = 3, .config = { .hw = &apq8084_config } },
|
||||
{ .revision = 6, .config = { .hw = &msm8x16_config } },
|
||||
{ .revision = 9, .config = { .hw = &msm8x94_config } },
|
||||
};
|
||||
|
||||
|
||||
static struct mdp5_cfg_platform *mdp5_get_config(struct platform_device *dev);
|
||||
|
||||
const struct mdp5_cfg_hw *mdp5_cfg_get_hw_config(struct mdp5_cfg_handler *cfg_handler)
|
||||
|
@ -177,7 +177,8 @@ int mdp5_disable(struct mdp5_kms *mdp5_kms)
|
||||
clk_disable_unprepare(mdp5_kms->ahb_clk);
|
||||
clk_disable_unprepare(mdp5_kms->axi_clk);
|
||||
clk_disable_unprepare(mdp5_kms->core_clk);
|
||||
clk_disable_unprepare(mdp5_kms->lut_clk);
|
||||
if (mdp5_kms->lut_clk)
|
||||
clk_disable_unprepare(mdp5_kms->lut_clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -189,7 +190,8 @@ int mdp5_enable(struct mdp5_kms *mdp5_kms)
|
||||
clk_prepare_enable(mdp5_kms->ahb_clk);
|
||||
clk_prepare_enable(mdp5_kms->axi_clk);
|
||||
clk_prepare_enable(mdp5_kms->core_clk);
|
||||
clk_prepare_enable(mdp5_kms->lut_clk);
|
||||
if (mdp5_kms->lut_clk)
|
||||
clk_prepare_enable(mdp5_kms->lut_clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -489,7 +491,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
|
||||
goto fail;
|
||||
ret = get_clk(pdev, &mdp5_kms->lut_clk, "lut_clk");
|
||||
if (ret)
|
||||
goto fail;
|
||||
DBG("failed to get (optional) lut_clk clock");
|
||||
ret = get_clk(pdev, &mdp5_kms->vsync_clk, "vsync_clk");
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
Loading…
Reference in New Issue
Block a user