From patchwork Thu Jul 26 13:54:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neil Armstrong X-Patchwork-Id: 949683 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=baylibre-com.20150623.gappssmtp.com header.i=@baylibre-com.20150623.gappssmtp.com header.b="SZcPnm6t"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41btqz3Kr2z9rxx for ; Thu, 26 Jul 2018 23:54:22 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 8FAC0C21DE8; Thu, 26 Jul 2018 13:54:14 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id B2599C21C3F; Thu, 26 Jul 2018 13:54:10 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 8406DC21C3F; Thu, 26 Jul 2018 13:54:09 +0000 (UTC) Received: from mail-wm0-f67.google.com (mail-wm0-f67.google.com [74.125.82.67]) by lists.denx.de (Postfix) with ESMTPS id 65586C21BE5 for ; Thu, 26 Jul 2018 13:54:08 +0000 (UTC) Received: by mail-wm0-f67.google.com with SMTP id y2-v6so2078491wma.1 for ; Thu, 26 Jul 2018 06:54:08 -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=M+ISBo30pHOoiwwfzQbPN4v0yPDboqIWeMQbHLhARVA=; b=SZcPnm6tV+WNiRu7VRp8zx/kVIzOY2ESXPrwkNbD7GpZVKMl9dQFOpof1pKcGh5KOs XVpx0aI0RR9cqefUWCpagsuPp+puMmif+DkP2snjslmLrKlR5io8Z4ZJytaEu+GlYwHY areNi3KQkCrLfrd0iy7ZKrdK0vkBHSeOUA1rKprLrh4uYh+scIWwmUivg9FINns7tGo4 4r/1ozSaBv2nI5MYD2oatowV06njoIra9ns2O0FqzgZAe8mh6848GAH9XTAfO5UtR97s c91SwPagwGA14bcZtlhOU718JZlkn0cR66drbrCVvOC66Uqjq5Lnz6oOViOY8MRD+zPV GsZQ== 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=M+ISBo30pHOoiwwfzQbPN4v0yPDboqIWeMQbHLhARVA=; b=uMjIMYHIjgMRBuAPuLWGVfUzHQ2mbFVdpcyzS7Bmo+0hwLRMVf6xLuixPJKavbvW9u cO/m61vUvzfqlFS9gmge5wBqhkIdcfXmlYKoTXhvf3xJKIksUkfsyTVPet/zlV6IKUN0 nOv2F7rjfxSVaNjKIHbAx3oKyqx5h+9Ds/sEyo3rPex+778KB3AjzjSbTt9abxb03uEK /h8CPCHO9WHXNkxv0/X2iCp9wYqB/cFeeSo2bMCWzqZB2bz5WwtW0kgKAR0/gmFWi05N Tkm0YvZnbxAzMg43d/8oEZL+7sO/nTj6DE0qcdJg6NTRxX9R/6gTBLyx9SWVqKNTz6uo ODew== X-Gm-Message-State: AOUpUlGaiwcvb7L6aJoLbqUUs8pyL6FU00oFaq2JucBDECIU9WXykGtS 9WocBYKTprp3RN7yywabGHKp+w== X-Google-Smtp-Source: AAOMgpdHWBexDHA/QXRAQ1+AgFVbt0qz1ugn+IidR/gcQV/ZJLbaWZt48hzyMh2W0TJ+6e7rxRSCUA== X-Received: by 2002:a1c:c912:: with SMTP id f18-v6mr1735772wmb.73.1532613247976; Thu, 26 Jul 2018 06:54:07 -0700 (PDT) Received: from bender.baylibre.local ([90.63.244.31]) by smtp.gmail.com with ESMTPSA id z14-v6sm2237131wrr.71.2018.07.26.06.54.06 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 26 Jul 2018 06:54:07 -0700 (PDT) From: Neil Armstrong To: jh80.chung@samsung.com, sjg@chromium.org Date: Thu, 26 Jul 2018 15:54:03 +0200 Message-Id: <1532613244-4585-2-git-send-email-narmstrong@baylibre.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1532613244-4585-1-git-send-email-narmstrong@baylibre.com> References: <1532613244-4585-1-git-send-email-narmstrong@baylibre.com> Cc: u-boot@lists.denx.de, linux-amlogic@lists.infradead.org Subject: [U-Boot] [PATCH u-boot 1/2] power: domain: Add the VPU Power Domain driver X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" The Amlogic Meson SoCs embeds a specific Power Domain dedicated to the Video Processing Unit. This patch implements support for this power domain in preparation of the future support for the Video display support in U-Boot. This driver will depend on changes in the clock driver to handle the setup of the VPU and VAPB clocks configured from DT using assigned-clocks entries. Signed-off-by: Neil Armstrong Reviewed-by: Simon Glass --- drivers/power/domain/Kconfig | 7 ++ drivers/power/domain/Makefile | 1 + drivers/power/domain/meson-gx-pwrc-vpu.c | 198 +++++++++++++++++++++++++++++++ 3 files changed, 206 insertions(+) create mode 100644 drivers/power/domain/meson-gx-pwrc-vpu.c diff --git a/drivers/power/domain/Kconfig b/drivers/power/domain/Kconfig index 7cfa761..4618847 100644 --- a/drivers/power/domain/Kconfig +++ b/drivers/power/domain/Kconfig @@ -16,6 +16,13 @@ config BCM6328_POWER_DOMAIN Enable support for manipulating BCM6345 power domains via MMIO mapped registers. +config MESON_GX_VPU_POWER_DOMAIN + bool "Enable Amlogic Meson GX VPU power domain driver" + depends on ARCH_MESON + help + Enable support for manipulating Amlogic Meson GX Video Processing + Unit power domain. + config SANDBOX_POWER_DOMAIN bool "Enable the sandbox power domain test driver" depends on POWER_DOMAIN && SANDBOX diff --git a/drivers/power/domain/Makefile b/drivers/power/domain/Makefile index c7d7644..4a3282b 100644 --- a/drivers/power/domain/Makefile +++ b/drivers/power/domain/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_POWER_DOMAIN) += power-domain-uclass.o obj-$(CONFIG_BCM6328_POWER_DOMAIN) += bcm6328-power-domain.o +obj-$(CONFIG_MESON_GX_VPU_POWER_DOMAIN) += meson-gx-pwrc-vpu.o obj-$(CONFIG_SANDBOX_POWER_DOMAIN) += sandbox-power-domain.o obj-$(CONFIG_SANDBOX_POWER_DOMAIN) += sandbox-power-domain-test.o obj-$(CONFIG_TEGRA186_POWER_DOMAIN) += tegra186-power-domain.o diff --git a/drivers/power/domain/meson-gx-pwrc-vpu.c b/drivers/power/domain/meson-gx-pwrc-vpu.c new file mode 100644 index 0000000..d631d3e --- /dev/null +++ b/drivers/power/domain/meson-gx-pwrc-vpu.c @@ -0,0 +1,198 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Amlogic Meson VPU Power Domain Controller driver + * + * Copyright (c) 2018 BayLibre, SAS. + * Author: Neil Armstrong + */ + +#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_priv { + struct regmap *regmap_ao; + struct regmap *regmap_hhi; + struct reset_ctl_bulk resets; + struct clk_bulk clks; +}; + +static int meson_gx_pwrc_vpu_request(struct power_domain *power_domain) +{ + return 0; +} + +static int meson_gx_pwrc_vpu_free(struct power_domain *power_domain) +{ + return 0; +} + +static int meson_gx_pwrc_vpu_on(struct power_domain *power_domain) +{ + struct meson_gx_pwrc_vpu_priv *priv = dev_get_priv(power_domain->dev); + int i, ret; + + regmap_update_bits(priv->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(priv->regmap_hhi, HHI_VPU_MEM_PD_REG0, + 0x3 << i, 0); + udelay(5); + } + + for (i = 0; i < 32; i += 2) { + regmap_update_bits(priv->regmap_hhi, HHI_VPU_MEM_PD_REG1, + 0x3 << i, 0); + udelay(5); + } + + for (i = 8; i < 16; i++) { + regmap_update_bits(priv->regmap_hhi, HHI_MEM_PD_REG0, + BIT(i), 0); + udelay(5); + } + udelay(20); + + ret = reset_assert_bulk(&priv->resets); + if (ret) + return ret; + + regmap_update_bits(priv->regmap_ao, AO_RTI_GEN_PWR_SLEEP0, + GEN_PWR_VPU_HDMI_ISO, 0); + + ret = reset_deassert_bulk(&priv->resets); + if (ret) + return ret; + + ret = clk_enable_bulk(&priv->clks); + if (ret) + return ret; + + return 0; +} + +static int meson_gx_pwrc_vpu_off(struct power_domain *power_domain) +{ + struct meson_gx_pwrc_vpu_priv *priv = dev_get_priv(power_domain->dev); + int i; + + regmap_update_bits(priv->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(priv->regmap_hhi, HHI_VPU_MEM_PD_REG0, + 0x3 << i, 0x3 << i); + udelay(5); + } + for (i = 0; i < 32; i += 2) { + regmap_update_bits(priv->regmap_hhi, HHI_VPU_MEM_PD_REG1, + 0x3 << i, 0x3 << i); + udelay(5); + } + for (i = 8; i < 16; i++) { + regmap_update_bits(priv->regmap_hhi, HHI_MEM_PD_REG0, + BIT(i), BIT(i)); + udelay(5); + } + udelay(20); + + regmap_update_bits(priv->regmap_ao, AO_RTI_GEN_PWR_SLEEP0, + GEN_PWR_VPU_HDMI, GEN_PWR_VPU_HDMI); + mdelay(20); + + clk_disable_bulk(&priv->clks); + + return 0; +} + +static int meson_gx_pwrc_vpu_of_xlate(struct power_domain *power_domain, + struct ofnode_phandle_args *args) +{ + /* #power-domain-cells is 0 */ + + if (args->args_count != 0) { + debug("Invalid args_count: %d\n", args->args_count); + return -EINVAL; + } + + return 0; +} + +struct power_domain_ops meson_gx_pwrc_vpu_ops = { + .free = meson_gx_pwrc_vpu_free, + .off = meson_gx_pwrc_vpu_off, + .on = meson_gx_pwrc_vpu_on, + .request = meson_gx_pwrc_vpu_request, + .of_xlate = meson_gx_pwrc_vpu_of_xlate, +}; + +static const struct udevice_id meson_gx_pwrc_vpu_ids[] = { + { .compatible = "amlogic,meson-gx-pwrc-vpu" }, + { } +}; + +static int meson_gx_pwrc_vpu_probe(struct udevice *dev) +{ + struct meson_gx_pwrc_vpu_priv *priv = dev_get_priv(dev); + u32 hhi_phandle; + ofnode hhi_node; + int ret; + + priv->regmap_ao = syscon_node_to_regmap(dev_get_parent(dev)->node); + if (IS_ERR(priv->regmap_ao)) + return PTR_ERR(priv->regmap_ao); + + ret = ofnode_read_u32(dev->node, "amlogic,hhi-sysctrl", + &hhi_phandle); + if (ret) + return ret; + + hhi_node = ofnode_get_by_phandle(hhi_phandle); + if (!ofnode_valid(hhi_node)) + return -EINVAL; + + priv->regmap_hhi = syscon_node_to_regmap(hhi_node); + if (IS_ERR(priv->regmap_hhi)) + return PTR_ERR(priv->regmap_hhi); + + ret = reset_get_bulk(dev, &priv->resets); + if (ret) + return ret; + + ret = clk_get_bulk(dev, &priv->clks); + if (ret) + return ret; + + return 0; +} + +U_BOOT_DRIVER(meson_gx_pwrc_vpu) = { + .name = "meson_gx_pwrc_vpu", + .id = UCLASS_POWER_DOMAIN, + .of_match = meson_gx_pwrc_vpu_ids, + .probe = meson_gx_pwrc_vpu_probe, + .ops = &meson_gx_pwrc_vpu_ops, + .priv_auto_alloc_size = sizeof(struct meson_gx_pwrc_vpu_priv), +};