summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c')
-rw-r--r--drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c118
1 files changed, 56 insertions, 62 deletions
diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
index 700df4040e9a..4ba1cb74ad76 100644
--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
+++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
@@ -135,8 +135,6 @@ static void mdp4_destroy(struct msm_kms *kms)
pm_runtime_disable(dev);
mdp_kms_destroy(&mdp4_kms->base);
-
- kfree(mdp4_kms);
}
static const struct mdp_kms_funcs kms_funcs = {
@@ -380,56 +378,27 @@ static int mdp4_kms_init(struct drm_device *dev)
{
struct platform_device *pdev = to_platform_device(dev->dev);
struct msm_drm_private *priv = dev->dev_private;
- struct mdp4_kms *mdp4_kms;
+ struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(priv->kms));
struct msm_kms *kms = NULL;
struct msm_mmu *mmu;
struct msm_gem_address_space *aspace;
- int irq, ret;
+ int ret;
u32 major, minor;
unsigned long max_clk;
/* TODO: Chips that aren't apq8064 have a 200 Mhz max_clk */
max_clk = 266667000;
- mdp4_kms = kzalloc(sizeof(*mdp4_kms), GFP_KERNEL);
- if (!mdp4_kms) {
- DRM_DEV_ERROR(dev->dev, "failed to allocate kms\n");
- return -ENOMEM;
- }
-
ret = mdp_kms_init(&mdp4_kms->base, &kms_funcs);
if (ret) {
DRM_DEV_ERROR(dev->dev, "failed to init kms\n");
goto fail;
}
- priv->kms = &mdp4_kms->base.base;
kms = priv->kms;
mdp4_kms->dev = dev;
- mdp4_kms->mmio = msm_ioremap(pdev, NULL);
- if (IS_ERR(mdp4_kms->mmio)) {
- ret = PTR_ERR(mdp4_kms->mmio);
- goto fail;
- }
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- ret = irq;
- goto fail;
- }
-
- kms->irq = irq;
-
- /* NOTE: driver for this regulator still missing upstream.. use
- * _get_exclusive() and ignore the error if it does not exist
- * (and hope that the bootloader left it on for us)
- */
- mdp4_kms->vdd = devm_regulator_get_exclusive(&pdev->dev, "vdd");
- if (IS_ERR(mdp4_kms->vdd))
- mdp4_kms->vdd = NULL;
-
if (mdp4_kms->vdd) {
ret = regulator_enable(mdp4_kms->vdd);
if (ret) {
@@ -438,24 +407,6 @@ static int mdp4_kms_init(struct drm_device *dev)
}
}
- mdp4_kms->clk = devm_clk_get(&pdev->dev, "core_clk");
- if (IS_ERR(mdp4_kms->clk)) {
- DRM_DEV_ERROR(dev->dev, "failed to get core_clk\n");
- ret = PTR_ERR(mdp4_kms->clk);
- goto fail;
- }
-
- mdp4_kms->pclk = devm_clk_get(&pdev->dev, "iface_clk");
- if (IS_ERR(mdp4_kms->pclk))
- mdp4_kms->pclk = NULL;
-
- mdp4_kms->axi_clk = devm_clk_get(&pdev->dev, "bus_clk");
- if (IS_ERR(mdp4_kms->axi_clk)) {
- DRM_DEV_ERROR(dev->dev, "failed to get axi_clk\n");
- ret = PTR_ERR(mdp4_kms->axi_clk);
- goto fail;
- }
-
clk_set_rate(mdp4_kms->clk, max_clk);
read_mdp_hw_revision(mdp4_kms, &major, &minor);
@@ -470,10 +421,9 @@ static int mdp4_kms_init(struct drm_device *dev)
mdp4_kms->rev = minor;
if (mdp4_kms->rev >= 2) {
- mdp4_kms->lut_clk = devm_clk_get(&pdev->dev, "lut_clk");
- if (IS_ERR(mdp4_kms->lut_clk)) {
+ if (!mdp4_kms->lut_clk) {
DRM_DEV_ERROR(dev->dev, "failed to get lut_clk\n");
- ret = PTR_ERR(mdp4_kms->lut_clk);
+ ret = -ENODEV;
goto fail;
}
clk_set_rate(mdp4_kms->lut_clk, max_clk);
@@ -551,20 +501,64 @@ fail:
}
static const struct dev_pm_ops mdp4_pm_ops = {
- .prepare = msm_pm_prepare,
- .complete = msm_pm_complete,
+ .prepare = msm_kms_pm_prepare,
+ .complete = msm_kms_pm_complete,
};
static int mdp4_probe(struct platform_device *pdev)
{
- return msm_drv_probe(&pdev->dev, mdp4_kms_init);
+ struct device *dev = &pdev->dev;
+ struct mdp4_kms *mdp4_kms;
+ int irq;
+
+ mdp4_kms = devm_kzalloc(dev, sizeof(*mdp4_kms), GFP_KERNEL);
+ if (!mdp4_kms)
+ return dev_err_probe(dev, -ENOMEM, "failed to allocate kms\n");
+
+ mdp4_kms->mmio = msm_ioremap(pdev, NULL);
+ if (IS_ERR(mdp4_kms->mmio))
+ return PTR_ERR(mdp4_kms->mmio);
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return dev_err_probe(dev, irq, "failed to get irq\n");
+
+ mdp4_kms->base.base.irq = irq;
+
+ /* NOTE: driver for this regulator still missing upstream.. use
+ * _get_exclusive() and ignore the error if it does not exist
+ * (and hope that the bootloader left it on for us)
+ */
+ mdp4_kms->vdd = devm_regulator_get_exclusive(&pdev->dev, "vdd");
+ if (IS_ERR(mdp4_kms->vdd))
+ mdp4_kms->vdd = NULL;
+
+ mdp4_kms->clk = devm_clk_get(&pdev->dev, "core_clk");
+ if (IS_ERR(mdp4_kms->clk))
+ return dev_err_probe(dev, PTR_ERR(mdp4_kms->clk), "failed to get core_clk\n");
+
+ mdp4_kms->pclk = devm_clk_get(&pdev->dev, "iface_clk");
+ if (IS_ERR(mdp4_kms->pclk))
+ mdp4_kms->pclk = NULL;
+
+ mdp4_kms->axi_clk = devm_clk_get(&pdev->dev, "bus_clk");
+ if (IS_ERR(mdp4_kms->axi_clk))
+ return dev_err_probe(dev, PTR_ERR(mdp4_kms->axi_clk), "failed to get axi_clk\n");
+
+ /*
+ * This is required for revn >= 2. Handle errors here and let the kms
+ * init bail out if the clock is not provided.
+ */
+ mdp4_kms->lut_clk = devm_clk_get_optional(&pdev->dev, "lut_clk");
+ if (IS_ERR(mdp4_kms->lut_clk))
+ return dev_err_probe(dev, PTR_ERR(mdp4_kms->lut_clk), "failed to get lut_clk\n");
+
+ return msm_drv_probe(&pdev->dev, mdp4_kms_init, &mdp4_kms->base.base);
}
-static int mdp4_remove(struct platform_device *pdev)
+static void mdp4_remove(struct platform_device *pdev)
{
component_master_del(&pdev->dev, &msm_drm_ops);
-
- return 0;
}
static const struct of_device_id mdp4_dt_match[] = {
@@ -575,8 +569,8 @@ MODULE_DEVICE_TABLE(of, mdp4_dt_match);
static struct platform_driver mdp4_platform_driver = {
.probe = mdp4_probe,
- .remove = mdp4_remove,
- .shutdown = msm_drv_shutdown,
+ .remove_new = mdp4_remove,
+ .shutdown = msm_kms_shutdown,
.driver = {
.name = "mdp4",
.of_match_table = mdp4_dt_match,