From patchwork Sat Oct 28 16:40:16 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neil Armstrong X-Patchwork-Id: 10031051 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 1D6636032C for ; Sat, 28 Oct 2017 16:41:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0D205286BD for ; Sat, 28 Oct 2017 16:41:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F2D1E288EB; Sat, 28 Oct 2017 16:41:32 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 74B70286BD for ; Sat, 28 Oct 2017 16:41:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=Ad+Ju5eAKEJihbLUEImPJ/Qu+M7SPFqen/w8oNd/qX4=; b=s0v6uUfUlAYUbszdy82KzPpfaY 7PBAbk/UKCs9lzVEPyPvX3EZtgFYrFygUKEqkdTJfF4yLTRZNgNurRamNHxGlEQ6gIwYDUK/q0bFe 9wv0VeDakwTNNjG2Ch6KN0yIgkzcAhqbgNCPzTJtuawrQZrp7m7C4Rphm0qxV7bCLXq1TaHyy8NUC yuYuNRtT5mDHr2zgdOhB4sajuTyseoUFJFEoycS+c+LpUHyW90YcSpqu4Tay5BY9+fYiz76MekS0+ AjU3Qm+wy6bdjqlg/wiSMeUnOEj7UoUikx1OHF7iW2cddMwRP1Phq57F8HWwCLH95Jabn6ad8G2is N/i9iurg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1e8UAt-0008Fa-GG; Sat, 28 Oct 2017 16:41:31 +0000 Received: from mail-wr0-x241.google.com ([2a00:1450:400c:c0c::241]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1e8UA8-0007gm-Rd for linux-arm-kernel@lists.infradead.org; Sat, 28 Oct 2017 16:40:48 +0000 Received: by mail-wr0-x241.google.com with SMTP id y9so8661361wrb.2 for ; Sat, 28 Oct 2017 09:40:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=9uQPKw7Wr/aAtPUNJv6OlJwqW/598BHoDyed+Qp/s/c=; b=OACh81U2vpJhM4+48VxTFNyu5LnDmYNOf+E23MNgaDOgt/hXSH745ZvI2YZXmY6x9z oQSSf/wU2WDYb1qRYdczgf4tvLs7iFeTLx4r8ZIUguCp/zBRLNvwnhPPb2kSBVNJGz71 KWAkU9aRoUrx0MCf8raznUhUudpYhWPqzSMyqk0z34Lsjg/Fu3z/MNNtdadaTl01d+VF J/P2DA16JmdLFeLDhIc7ype4SRhvUkWxdaR9REoFVp7fI672JJH0NlUyTMndHIHcpoHA Cex4RU1v9/9xuLZoyB4XOoo846QrLBXE/2zj9NgORBL0KPJwad9An8n2TYEGdNuySQfP 7t8g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=9uQPKw7Wr/aAtPUNJv6OlJwqW/598BHoDyed+Qp/s/c=; b=LujPq4oLILimgpAuYV8V3Axg61t2KQvi/J2gCjC6b9BaiNLBthgnRmwio+JGKIJANb vy/NvFxwGMsqe3fqtnmf/K0ydRkeIoOvFHlpADAFR9KHxugpJkoqp5gf759gNKBtcXJ2 O92hJZSWuoc3Bk/BCEt0+gCnSJaRqYvemqND/vQTIQbPrHdbhdck3yoNSJWojnIgjZH6 A4g3qqfPZbTgEdHGTdcPeinsevgbsImaldguy0rZDm6paY3uH8w0V8k0BYAEnmJWfIsP VyhQQ2UMK2k+RooA+0hpNAyLshF2EgMxwqEZysfUGIPyeO1UG9ou0CjYJG27u4wF8Elf xzag== X-Gm-Message-State: AMCzsaUyepdvkeoughPYKlYtT3Tr+AVSGpcYCXqyFsQ8aw7eReqVxHEb KJDJuWeJkwTN7tIAYJ4K8dLYaQ== X-Google-Smtp-Source: ABhQp+Q7ENdifxKWqe4gSd/zd12a5kfUMth+Ut2JM5lWHT0bKWHrnlqjkVt78BcDDHjyhn0n2rpkQA== X-Received: by 10.223.191.10 with SMTP id p10mr3593426wrh.127.1509208822846; Sat, 28 Oct 2017 09:40:22 -0700 (PDT) Received: from localhost.localdomain ([2a01:e34:ec4e:2270:f137:26ec:d606:4dd]) by smtp.gmail.com with ESMTPSA id b11sm9543540wrd.91.2017.10.28.09.40.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 28 Oct 2017 09:40:22 -0700 (PDT) From: Neil Armstrong To: khilman@baylibre.com, carlo@caione.org Subject: [RESEND PATCH v2 1/2] soc: amlogic: add Meson GX VPU Domains driver Date: Sat, 28 Oct 2017 18:40:16 +0200 Message-Id: <1509208817-30632-2-git-send-email-narmstrong@baylibre.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1509208817-30632-1-git-send-email-narmstrong@baylibre.com> References: <1509208817-30632-1-git-send-email-narmstrong@baylibre.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20171028_094045_244756_49F62421 X-CRM114-Status: GOOD ( 18.48 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-amlogic@lists.infradead.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Neil Armstrong MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP The Video Processing Unit needs a specific Power Domain powering scheme this driver handles this as a PM Power Domain driver. Signed-off-by: Neil Armstrong --- drivers/soc/amlogic/Kconfig | 10 ++ drivers/soc/amlogic/Makefile | 1 + drivers/soc/amlogic/meson-gx-pwrc-vpu.c | 234 ++++++++++++++++++++++++++++++++ 3 files changed, 245 insertions(+) create mode 100644 drivers/soc/amlogic/meson-gx-pwrc-vpu.c diff --git a/drivers/soc/amlogic/Kconfig b/drivers/soc/amlogic/Kconfig index ef0b8f6..1621bb2 100644 --- a/drivers/soc/amlogic/Kconfig +++ b/drivers/soc/amlogic/Kconfig @@ -9,6 +9,16 @@ config MESON_GX_SOCINFO Say yes to support decoding of Amlogic Meson GX SoC family information about the type, package and version. +config MESON_GX_PM_DOMAINS + bool "Amlogic Meson GX Power Domains driver" + depends on ARCH_MESON || COMPILE_TEST + default ARCH_MESON + select PM_GENERIC_DOMAINS + select PM_GENERIC_DOMAINS_OF + help + Say yes to expose Amlogic Meson GX Power Domains as + Generic Power Domains. + config MESON_MX_SOCINFO bool "Amlogic Meson MX SoC Information driver" depends on ARCH_MESON || COMPILE_TEST diff --git a/drivers/soc/amlogic/Makefile b/drivers/soc/amlogic/Makefile index 1f5df50..8fa3218 100644 --- a/drivers/soc/amlogic/Makefile +++ b/drivers/soc/amlogic/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_MESON_GX_SOCINFO) += meson-gx-socinfo.o +obj-$(CONFIG_MESON_GX_PM_DOMAINS) += meson-gx-pwrc-vpu.o obj-$(CONFIG_MESON_MX_SOCINFO) += meson-mx-socinfo.o diff --git a/drivers/soc/amlogic/meson-gx-pwrc-vpu.c b/drivers/soc/amlogic/meson-gx-pwrc-vpu.c new file mode 100644 index 0000000..bf5190b --- /dev/null +++ b/drivers/soc/amlogic/meson-gx-pwrc-vpu.c @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2017 BayLibre, SAS + * Author: Neil Armstrong + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* AO Offsets */ + +#define AO_RTI_GEN_PWR_SLEEP0 (0x3a << 2) + +#define GEN_PWR_VPU_HDMI BIT(8) +#define GEN_PWR_VPU_HDMI_ISO BIT(9) + +/* HHI Offsets */ + +#define HHI_MEM_PD_REG0 (0x40 << 2) +#define HHI_VPU_MEM_PD_REG0 (0x41 << 2) +#define HHI_VPU_MEM_PD_REG1 (0x42 << 2) + +struct meson_gx_pwrc_vpu { + struct generic_pm_domain genpd; + struct regmap *regmap_ao; + struct regmap *regmap_hhi; + struct reset_control *rstc; + struct clk *vpu_clk; + struct clk *vapb_clk; + bool powered; +}; + +static inline +struct meson_gx_pwrc_vpu *genpd_to_pd(struct generic_pm_domain *d) +{ + return container_of(d, struct meson_gx_pwrc_vpu, genpd); +} + +static int meson_gx_pwrc_vpu_power_off(struct generic_pm_domain *genpd) +{ + struct meson_gx_pwrc_vpu *pd = genpd_to_pd(genpd); + int i; + + regmap_update_bits(pd->regmap_ao, AO_RTI_GEN_PWR_SLEEP0, + GEN_PWR_VPU_HDMI_ISO, GEN_PWR_VPU_HDMI_ISO); + udelay(20); + + /* Power Down Memories */ + for (i = 0; i < 32; i += 2) { + regmap_update_bits(pd->regmap_hhi, HHI_VPU_MEM_PD_REG0, + 0x2 << i, 0x3 << i); + udelay(5); + } + for (i = 0; i < 32; i += 2) { + regmap_update_bits(pd->regmap_hhi, HHI_VPU_MEM_PD_REG1, + 0x2 << i, 0x3 << i); + udelay(5); + } + for (i = 8; i < 16; i++) { + regmap_update_bits(pd->regmap_hhi, HHI_MEM_PD_REG0, + BIT(i), BIT(i)); + udelay(5); + } + udelay(20); + + regmap_update_bits(pd->regmap_ao, AO_RTI_GEN_PWR_SLEEP0, + GEN_PWR_VPU_HDMI, GEN_PWR_VPU_HDMI); + + msleep(20); + + clk_disable_unprepare(pd->vpu_clk); + clk_disable_unprepare(pd->vapb_clk); + + pd->powered = false; + + return 0; +} + +static int meson_gx_pwrc_vpu_setup_clk(struct meson_gx_pwrc_vpu *pd) +{ + int ret; + + ret = clk_prepare_enable(pd->vpu_clk); + if (ret) + return ret; + + return clk_prepare_enable(pd->vapb_clk); +} + +static int meson_gx_pwrc_vpu_power_on(struct generic_pm_domain *genpd) +{ + struct meson_gx_pwrc_vpu *pd = genpd_to_pd(genpd); + int ret; + int i; + + regmap_update_bits(pd->regmap_ao, AO_RTI_GEN_PWR_SLEEP0, + GEN_PWR_VPU_HDMI, 0); + udelay(20); + + /* Power Up Memories */ + for (i = 0; i < 32; i += 2) { + regmap_update_bits(pd->regmap_hhi, HHI_VPU_MEM_PD_REG0, + 0x2 << i, 0); + udelay(5); + } + + for (i = 0; i < 32; i += 2) { + regmap_update_bits(pd->regmap_hhi, HHI_VPU_MEM_PD_REG1, + 0x2 << i, 0); + udelay(5); + } + + for (i = 8; i < 16; i++) { + regmap_update_bits(pd->regmap_hhi, HHI_MEM_PD_REG0, + BIT(i), 0); + udelay(5); + } + udelay(20); + + ret = reset_control_assert(pd->rstc); + if (ret) + return ret; + + regmap_update_bits(pd->regmap_ao, AO_RTI_GEN_PWR_SLEEP0, + GEN_PWR_VPU_HDMI_ISO, 0); + + ret = reset_control_deassert(pd->rstc); + if (ret) + return ret; + + ret = meson_gx_pwrc_vpu_setup_clk(pd); + if (ret) + return ret; + + pd->powered = true; + + return 0; +} + +static bool meson_gx_pwrc_vpu_get_power(struct meson_gx_pwrc_vpu *pd) +{ + u32 reg; + + regmap_read(pd->regmap_ao, AO_RTI_GEN_PWR_SLEEP0, ®); + + return (reg & GEN_PWR_VPU_HDMI); +} + +static struct meson_gx_pwrc_vpu vpu_hdmi_pd = { + .genpd = { + .name = "vpu_hdmi", + .power_off = meson_gx_pwrc_vpu_power_off, + .power_on = meson_gx_pwrc_vpu_power_on, + }, +}; + +static int meson_gx_pwrc_vpu_probe(struct platform_device *pdev) +{ + struct regmap *regmap_ao, *regmap_hhi; + struct reset_control *rstc; + struct clk *vpu_clk; + struct clk *vapb_clk; + + regmap_ao = syscon_node_to_regmap(of_get_parent(pdev->dev.of_node)); + if (IS_ERR(regmap_ao)) { + dev_err(&pdev->dev, "failed to get regmap\n"); + return PTR_ERR(regmap_ao); + } + + regmap_hhi = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, + "amlogic,hhi-sysctrl"); + if (IS_ERR(regmap_hhi)) { + dev_err(&pdev->dev, "failed to get HHI regmap\n"); + return PTR_ERR(regmap_hhi); + } + + rstc = devm_reset_control_array_get(&pdev->dev, false, false); + if (IS_ERR(rstc)) { + dev_err(&pdev->dev, "failed to get reset lines\n"); + return PTR_ERR(rstc); + } + + vpu_clk = devm_clk_get(&pdev->dev, "vpu"); + if (IS_ERR(vpu_clk)) { + dev_err(&pdev->dev, "vpu clock request failed\n"); + return PTR_ERR(vpu_clk); + } + + vapb_clk = devm_clk_get(&pdev->dev, "vapb"); + if (IS_ERR(vapb_clk)) { + dev_err(&pdev->dev, "vapb clock request failed\n"); + return PTR_ERR(vapb_clk); + } + + vpu_hdmi_pd.regmap_ao = regmap_ao; + vpu_hdmi_pd.regmap_hhi = regmap_hhi; + vpu_hdmi_pd.rstc = rstc; + vpu_hdmi_pd.vpu_clk = vpu_clk; + vpu_hdmi_pd.vapb_clk = vapb_clk; + + pm_genpd_init(&vpu_hdmi_pd.genpd, &simple_qos_governor, + meson_gx_pwrc_vpu_get_power(&vpu_hdmi_pd)); + + return of_genpd_add_provider_simple(pdev->dev.of_node, + &vpu_hdmi_pd.genpd); +} + +static void meson_gx_pwrc_vpu_shutdown(struct platform_device *pdev) +{ + if (vpu_hdmi_pd.powered) + meson_gx_pwrc_vpu_power_off(&vpu_hdmi_pd.genpd); +} + +static const struct of_device_id meson_gx_pwrc_vpu_match_table[] = { + { .compatible = "amlogic,meson-gx-pwrc-vpu" }, + { /* sentinel */ } +}; + +static struct platform_driver meson_gx_pwrc_vpu_driver = { + .probe = meson_gx_pwrc_vpu_probe, + .shutdown = meson_gx_pwrc_vpu_shutdown, + .driver = { + .name = "meson_gx_pwrc_vpu", + .of_match_table = meson_gx_pwrc_vpu_match_table, + }, +}; +builtin_platform_driver(meson_gx_pwrc_vpu_driver);