aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/exynos/exynos_drm_gsc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_drm_gsc.c')
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gsc.c35
1 files changed, 28 insertions, 7 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
index 11b87d2a7913..7aecd23cfa11 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
@@ -15,7 +15,8 @@
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/pm_runtime.h>
-#include <plat/map-base.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
#include <drm/drmP.h>
#include <drm/exynos_drm.h>
@@ -126,6 +127,7 @@ struct gsc_capability {
* @ippdrv: prepare initialization using ippdrv.
* @regs_res: register resources.
* @regs: memory mapped io registers.
+ * @sysreg: handle to SYSREG block regmap.
* @lock: locking of operations.
* @gsc_clk: gsc gate clock.
* @sc: scaler infomations.
@@ -138,6 +140,7 @@ struct gsc_context {
struct exynos_drm_ippdrv ippdrv;
struct resource *regs_res;
void __iomem *regs;
+ struct regmap *sysreg;
struct mutex lock;
struct clk *gsc_clk;
struct gsc_scaler sc;
@@ -437,9 +440,12 @@ static int gsc_sw_reset(struct gsc_context *ctx)
static void gsc_set_gscblk_fimd_wb(struct gsc_context *ctx, bool enable)
{
- u32 gscblk_cfg;
+ unsigned int gscblk_cfg;
- gscblk_cfg = readl(SYSREG_GSCBLK_CFG1);
+ if (!ctx->sysreg)
+ return;
+
+ regmap_read(ctx->sysreg, SYSREG_GSCBLK_CFG1, &gscblk_cfg);
if (enable)
gscblk_cfg |= GSC_BLK_DISP1WB_DEST(ctx->id) |
@@ -448,7 +454,7 @@ static void gsc_set_gscblk_fimd_wb(struct gsc_context *ctx, bool enable)
else
gscblk_cfg |= GSC_BLK_PXLASYNC_LO_MASK_WB(ctx->id);
- writel(gscblk_cfg, SYSREG_GSCBLK_CFG1);
+ regmap_write(ctx->sysreg, SYSREG_GSCBLK_CFG1, gscblk_cfg);
}
static void gsc_handle_irq(struct gsc_context *ctx, bool enable,
@@ -1215,10 +1221,10 @@ static int gsc_clk_ctrl(struct gsc_context *ctx, bool enable)
DRM_DEBUG_KMS("enable[%d]\n", enable);
if (enable) {
- clk_enable(ctx->gsc_clk);
+ clk_prepare_enable(ctx->gsc_clk);
ctx->suspended = false;
} else {
- clk_disable(ctx->gsc_clk);
+ clk_disable_unprepare(ctx->gsc_clk);
ctx->suspended = true;
}
@@ -1663,6 +1669,15 @@ static int gsc_probe(struct platform_device *pdev)
if (!ctx)
return -ENOMEM;
+ if (dev->of_node) {
+ ctx->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
+ "samsung,sysreg");
+ if (IS_ERR(ctx->sysreg)) {
+ dev_warn(dev, "failed to get system register.\n");
+ ctx->sysreg = NULL;
+ }
+ }
+
/* clock control */
ctx->gsc_clk = devm_clk_get(dev, "gscl");
if (IS_ERR(ctx->gsc_clk)) {
@@ -1713,7 +1728,6 @@ static int gsc_probe(struct platform_device *pdev)
mutex_init(&ctx->lock);
platform_set_drvdata(pdev, ctx);
- pm_runtime_set_active(dev);
pm_runtime_enable(dev);
ret = exynos_drm_ippdrv_register(ippdrv);
@@ -1797,6 +1811,12 @@ static const struct dev_pm_ops gsc_pm_ops = {
SET_RUNTIME_PM_OPS(gsc_runtime_suspend, gsc_runtime_resume, NULL)
};
+static const struct of_device_id exynos_drm_gsc_of_match[] = {
+ { .compatible = "samsung,exynos5-gsc" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, exynos_drm_gsc_of_match);
+
struct platform_driver gsc_driver = {
.probe = gsc_probe,
.remove = gsc_remove,
@@ -1804,6 +1824,7 @@ struct platform_driver gsc_driver = {
.name = "exynos-drm-gsc",
.owner = THIS_MODULE,
.pm = &gsc_pm_ops,
+ .of_match_table = of_match_ptr(exynos_drm_gsc_of_match),
},
};