From patchwork Mon Dec 31 16:59:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jagan Teki X-Patchwork-Id: 117 Return-Path: X-Original-To: linux-amarula@patchwork.amarulasolutions.com Delivered-To: linux-amarula@patchwork.amarulasolutions.com Received: from mail-pg1-f197.google.com (cartago.priv [10.11.12.1]) by cassiopea.amarulasolutions.com (Postfix) with ESMTPS id 8E6312E0C47 for ; Mon, 31 Dec 2018 18:00:33 +0100 (CET) Received: by mail-pg1-f197.google.com with SMTP id v72sf24521835pgb.10 for ; Mon, 31 Dec 2018 09:00:33 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1546275632; cv=pass; d=google.com; s=arc-20160816; b=HaQY5wlJzU4UDRUNj+JfDlq1iUN9LQ4TnS0dDDwKAX7uyKY1AoXeLP+Tv5Da2CrZ77 N9aEBUpAceDoxy2dnJo2fZQAjyuWiNvo07i7Pf00KU7NGdt2hS5OGmajD0Rxsh7m408j 4AmduZzIB8rx/sv+fYfu2tXj2mE1MZq8DRft4u40ULcpM6qKDUS3h1CUdzJfHS5ocQvo 0lc9kph7dWIHoUgGcNZufbTxjqgjBUP1LWvGl0iX/zftywsSf/UfHqFSNXXnLfEuf+xD lAxWLECTn86/Rj5h9S0oWbjIM6N0h6jHT/IzG5hiD7QbnpM91PuverorbMifCBjm9UAP bE7A== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-archive:list-help:list-post:list-id :mailing-list:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=W9gFfRiETUWR19dw2hfjUwVCGMjKrLos7vSptn2uaM0=; b=EMqkQm0L++1zom0ksn0P5Q3h0IHTPutfqF+pAxAk2S2N79zMH15E63sXwS2drGwv3a M6dKwe1/1z+jhrkN3DvELst/dJydhRwzEcDx7Grs1ewLfUxI2Vb3cuIQwv788nJM2QYe qjfxUEzf8dITdtdxQ9otFUNt8HpiYfphVDJvNFQTQp6jFNZ9/VLil/dAsn4PQZDiJDVQ mj50Thoi5uhIz7Y7DbVkpBfLkTqJQ0XnPIna0WymGJe/gh+MzExb8BiheuCxDyKOnpLA ndBQv9DpnvE+IpckxD0E3mSxd6b2o2dVfHoDsiLT6yGDLE7MmtkWuA2zIA34P0huf2nz U/+g== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=WVqumsyl; spf=pass (google.com: domain of jagan@amarulasolutions.com designates 209.85.220.65 as permitted sender) smtp.mailfrom=jagan@amarulasolutions.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amarulasolutions.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=W9gFfRiETUWR19dw2hfjUwVCGMjKrLos7vSptn2uaM0=; b=bEdsDtXc1rfUXvv1I2RRAPpLGvxJP9AoywpCEfYo6ujfkaA8tqHyb2tbBgj7vgcWli nZV4H9sDmA589NSWxxFUW/yhdf4a+7n9tTMXRMaf0SYFDCmvmIBRdhqIkZ4apgPe1btw 2x0j7bT0nkMIevmNEQuGXvTT4kU3Ju0ffjEbU= 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:mime-version:content-transfer-encoding:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :x-spam-checked-in-group:list-post:list-help:list-archive :list-unsubscribe; bh=W9gFfRiETUWR19dw2hfjUwVCGMjKrLos7vSptn2uaM0=; b=DrU4RaMGWDCAQLgNL9cZD00KcO6VESIa9omvlNPysH6Lg2hSBlQ1bY1Nax96LeO/Fe 03tzYBfGo0gG5uedxawBk/Hrn02ElXkixp7PNjIH9IGWJuWdg4C0QpnJF3i11jRiRIMX lWlHDEuN9tLMu2gHsDJ+lQjsuJR7XzFuWKuNk1Q7zGqGvJPA4vKBZGa5pL4h97iuPc0N pru12x8TVg7jPKGRxl/UT1P9VqEsAZ9SJJE2hISMTLL1u5OZCmOPGVmtNQTJseSRT7na nnG29HC7Bnz8tsv3VcCGWamXuTyWySSzYfN7xp8hHFGXkrhCHMPtdI3Wh4/inUV7fCVC Wvdg== X-Gm-Message-State: AA+aEWacES+T1lG1dLMdCEpcOCaszmRkoVCg2XpmwuE1yD70K38OUwVm usOB4CTADU3fY/e0iblbGrNUnvYh X-Google-Smtp-Source: AFSGD/VDh+Fsuch+vhfY7ObnoLu3yytFxJ200yG1Pmf5q9PIwcb/TLifFfgNz7ZcHVUV4s+BhnmNhw== X-Received: by 2002:a62:ca16:: with SMTP id n22mr17081807pfg.142.1546275632163; Mon, 31 Dec 2018 09:00:32 -0800 (PST) X-BeenThere: linux-amarula@amarulasolutions.com Received: by 2002:a63:151d:: with SMTP id v29ls6485668pgl.2.gmail; Mon, 31 Dec 2018 09:00:31 -0800 (PST) X-Received: by 2002:a63:2586:: with SMTP id l128mr8236911pgl.104.1546275631762; Mon, 31 Dec 2018 09:00:31 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1546275631; cv=none; d=google.com; s=arc-20160816; b=QV2okAusy6qs/jK+F1nmIST79KgrMmeKu+ZGb5RnlGmq+UJEf9EuLu9FK7WGWDiCwg KINs4G3rbAIQugs/K26pmccuvTJ9rMgpQmxJzkx6QjJOJvpgl9QqnZDXeEZeJILamSFX tpCQenui5GWR6eSR7DxpPF/5Zdfl7r5UGqb6qjCB3xkcMvS3BOkdRrEpbCku5edS64zG sews5DmFvDvOyI+P7VQwnIWprGBXQVBk8IeUXoQZoYxwOlqArOIv8uYWC/5TP0fAKdcR 3rHBFjrue24CbJQQz+adj0eV4SMBbGyV2SWT600pQAh7o8lYHo3R8K5wBT2wX7+PVjMt Ig2g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=W9gFfRiETUWR19dw2hfjUwVCGMjKrLos7vSptn2uaM0=; b=U4x6Wi180pk6x90i5Hf51sdq9bFYyVmO+DFw1tUdlYkoWjNxwdCCGPMkXsgGye/UHx MubrL+Wu+bPf0CEM99mV3q2aKLKsDc9/ZD2IEXOAyhPfEBwJWf7LpxyeLcEf281uIM9O vMCBsY/NLW5vVbVme2bR4B7Z8636YqdPeW7k8jJ6Jqrpi//RX98hyUO6kM/SaCvltYDk ru2NwRdkRGQINToVMFbzc+8OzShqulV4EZsR9ALbX+7+twm7mgboO+fYoM1vcXUODg5V CJ5yAU7Ge+IU+Z3T59Dsu4Lwfb4EHfxigr8cxOF3rfeXRHoNbS+3YpjeT5h0X8OuFrCi Ek1w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=WVqumsyl; spf=pass (google.com: domain of jagan@amarulasolutions.com designates 209.85.220.65 as permitted sender) smtp.mailfrom=jagan@amarulasolutions.com Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id d184sor13802848pgc.58.2018.12.31.09.00.31 for (Google Transport Security); Mon, 31 Dec 2018 09:00:31 -0800 (PST) Received-SPF: pass (google.com: domain of jagan@amarulasolutions.com designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; X-Received: by 2002:a63:5964:: with SMTP id j36mr755965pgm.210.1546275631310; Mon, 31 Dec 2018 09:00:31 -0800 (PST) Received: from localhost.localdomain ([115.97.184.237]) by smtp.gmail.com with ESMTPSA id p7sm90692925pfj.72.2018.12.31.09.00.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 31 Dec 2018 09:00:30 -0800 (PST) From: Jagan Teki To: Maxime Ripard , Andre Przywara Cc: Chen-Yu Tsai , Simon Glass , Tom Rini , u-boot@lists.denx.de, linux-sunxi@googlegroups.com, Michael Trimarchi , linux-amarula@amarulasolutions.com, Jagan Teki Subject: [PATCH v5 02/26] reset: Add Allwinner RESET driver Date: Mon, 31 Dec 2018 22:29:03 +0530 Message-Id: <20181231165927.13803-3-jagan@amarulasolutions.com> X-Mailer: git-send-email 2.18.0.321.gffc6fa0e3 In-Reply-To: <20181231165927.13803-1-jagan@amarulasolutions.com> References: <20181231165927.13803-1-jagan@amarulasolutions.com> MIME-Version: 1.0 X-Original-Sender: jagan@amarulasolutions.com X-Original-Authentication-Results: mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=WVqumsyl; spf=pass (google.com: domain of jagan@amarulasolutions.com designates 209.85.220.65 as permitted sender) smtp.mailfrom=jagan@amarulasolutions.com Precedence: list Mailing-list: list linux-amarula@amarulasolutions.com; contact linux-amarula+owners@amarulasolutions.com List-ID: X-Spam-Checked-In-Group: linux-amarula@amarulasolutions.com X-Google-Group-Id: 476853432473 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Add common reset driver for all Allwinner SoC's. Since CLK and RESET share common DT compatible, it is CLK driver job is to bind the reset driver. So add CLK bind call on respective SoC driver by passing ccu map descriptor so-that reset deassert, deassert operations held based on ccu reset table defined from CLK driver. Select DM_RESET via CLK_SUNXI, this make hidden section of RESET since CLK and RESET share common DT compatible and code. Signed-off-by: Jagan Teki Acked-by: Maxime Ripard --- arch/arm/include/asm/arch-sunxi/ccu.h | 29 ++++++ drivers/clk/sunxi/Kconfig | 1 + drivers/clk/sunxi/clk_a64.c | 20 +++++ drivers/reset/Kconfig | 8 ++ drivers/reset/Makefile | 1 + drivers/reset/reset-sunxi.c | 125 ++++++++++++++++++++++++++ 6 files changed, 184 insertions(+) create mode 100644 drivers/reset/reset-sunxi.c diff --git a/arch/arm/include/asm/arch-sunxi/ccu.h b/arch/arm/include/asm/arch-sunxi/ccu.h index db69c8f0d5..3fdc26978d 100644 --- a/arch/arm/include/asm/arch-sunxi/ccu.h +++ b/arch/arm/include/asm/arch-sunxi/ccu.h @@ -34,13 +34,33 @@ struct ccu_clk_gate { .flags = CCU_CLK_F_INIT_DONE, \ } +/** + * struct ccu_reset - ccu reset + * @off: reset offset + * @bit: reset bit + * @flags: reset flags + */ +struct ccu_reset { + u16 off; + u32 bit; + enum ccu_clk_flags flags; +}; + +#define RESET(_off, _bit) { \ + .off = _off, \ + .bit = _bit, \ + .flags = CCU_CLK_F_INIT_DONE, \ +} + /** * struct ccu_desc - clock control unit descriptor * * @gates: clock gates + * @resets: reset unit */ struct ccu_desc { const struct ccu_clk_gate *gates; + const struct ccu_reset *resets; }; /** @@ -62,4 +82,13 @@ int sunxi_clk_probe(struct udevice *dev); extern struct clk_ops sunxi_clk_ops; +/** + * sunxi_reset_bind() - reset binding + * + * @dev: reset device + * @count: reset count + * @return 0 success, or error value + */ +int sunxi_reset_bind(struct udevice *dev, ulong count); + #endif /* _ASM_ARCH_CCU_H */ diff --git a/drivers/clk/sunxi/Kconfig b/drivers/clk/sunxi/Kconfig index bf5ecb3801..041d711e58 100644 --- a/drivers/clk/sunxi/Kconfig +++ b/drivers/clk/sunxi/Kconfig @@ -1,6 +1,7 @@ config CLK_SUNXI bool "Clock support for Allwinner SoCs" depends on CLK && ARCH_SUNXI + select DM_RESET default y help This enables support for common clock driver API on Allwinner diff --git a/drivers/clk/sunxi/clk_a64.c b/drivers/clk/sunxi/clk_a64.c index 803a2f711d..28bda1f497 100644 --- a/drivers/clk/sunxi/clk_a64.c +++ b/drivers/clk/sunxi/clk_a64.c @@ -10,6 +10,7 @@ #include #include #include +#include static const struct ccu_clk_gate a64_gates[] = { [CLK_BUS_OTG] = GATE(0x060, BIT(23)), @@ -26,10 +27,28 @@ static const struct ccu_clk_gate a64_gates[] = { [CLK_USB_OHCI1] = GATE(0x0cc, BIT(17)), }; +static const struct ccu_reset a64_resets[] = { + [RST_USB_PHY0] = RESET(0x0cc, BIT(0)), + [RST_USB_PHY1] = RESET(0x0cc, BIT(1)), + [RST_USB_HSIC] = RESET(0x0cc, BIT(2)), + + [RST_BUS_OTG] = RESET(0x2c0, BIT(23)), + [RST_BUS_EHCI0] = RESET(0x2c0, BIT(24)), + [RST_BUS_EHCI1] = RESET(0x2c0, BIT(25)), + [RST_BUS_OHCI0] = RESET(0x2c0, BIT(28)), + [RST_BUS_OHCI1] = RESET(0x2c0, BIT(29)), +}; + static const struct ccu_desc a64_ccu_desc = { .gates = a64_gates, + .resets = a64_resets, }; +static int a64_clk_bind(struct udevice *dev) +{ + return sunxi_reset_bind(dev, 50); +} + static const struct udevice_id a64_ccu_ids[] = { { .compatible = "allwinner,sun50i-a64-ccu", .data = (ulong)&a64_ccu_desc }, @@ -43,4 +62,5 @@ U_BOOT_DRIVER(clk_sun50i_a64) = { .priv_auto_alloc_size = sizeof(struct ccu_priv), .ops = &sunxi_clk_ops, .probe = sunxi_clk_probe, + .bind = a64_clk_bind, }; diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 9c5208b7da..b6b40b6ce9 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -106,4 +106,12 @@ config RESET_SOCFPGA help Support for reset controller on SoCFPGA platform. +config RESET_SUNXI + bool "RESET support for Allwinner SoCs" + depends on DM_RESET && ARCH_SUNXI + default y + help + This enables support for common reset driver for + Allwinner SoCs. + endmenu diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index f4520878b7..377c038163 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -17,3 +17,4 @@ obj-$(CONFIG_AST2500_RESET) += ast2500-reset.o obj-$(CONFIG_RESET_ROCKCHIP) += reset-rockchip.o obj-$(CONFIG_RESET_MESON) += reset-meson.o obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o +obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o diff --git a/drivers/reset/reset-sunxi.c b/drivers/reset/reset-sunxi.c new file mode 100644 index 0000000000..af63cac64e --- /dev/null +++ b/drivers/reset/reset-sunxi.c @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2018 Amarula Solutions. + * Author: Jagan Teki + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct sunxi_reset_priv { + void *base; + ulong count; + const struct ccu_desc *desc; +}; + +static const struct ccu_reset *priv_to_reset(struct sunxi_reset_priv *priv, + unsigned long id) +{ + return &priv->desc->resets[id]; +} + +static int sunxi_reset_request(struct reset_ctl *reset_ctl) +{ + struct sunxi_reset_priv *priv = dev_get_priv(reset_ctl->dev); + + debug("%s: (RST#%ld)\n", __func__, reset_ctl->id); + + /* check dt-bindings/reset/sun8i-h3-ccu.h for max id */ + if (reset_ctl->id >= priv->count) + return -EINVAL; + + return 0; +} + +static int sunxi_reset_free(struct reset_ctl *reset_ctl) +{ + debug("%s: (RST#%ld)\n", __func__, reset_ctl->id); + + return 0; +} + +static int sunxi_set_reset(struct reset_ctl *reset_ctl, bool on) +{ + struct sunxi_reset_priv *priv = dev_get_priv(reset_ctl->dev); + const struct ccu_reset *reset = priv_to_reset(priv, reset_ctl->id); + u32 reg; + + if (!(reset->flags & CCU_CLK_F_INIT_DONE)) { + printf("%s: (RST#%ld) unhandled\n", __func__, reset_ctl->id); + return 0; + } + + debug("%s: (RST#%ld) off#0x%x, BIT(%d)\n", __func__, + reset_ctl->id, reset->off, ilog2(reset->bit)); + + reg = readl(priv->base + reset->off); + if (on) + reg |= reset->bit; + else + reg &= ~reset->bit; + + writel(reg, priv->base + reset->off); + + return 0; +} + +static int sunxi_reset_assert(struct reset_ctl *reset_ctl) +{ + return sunxi_set_reset(reset_ctl, false); +} + +static int sunxi_reset_deassert(struct reset_ctl *reset_ctl) +{ + return sunxi_set_reset(reset_ctl, true); +} + +struct reset_ops sunxi_reset_ops = { + .request = sunxi_reset_request, + .free = sunxi_reset_free, + .rst_assert = sunxi_reset_assert, + .rst_deassert = sunxi_reset_deassert, +}; + +static int sunxi_reset_probe(struct udevice *dev) +{ + struct sunxi_reset_priv *priv = dev_get_priv(dev); + + priv->base = dev_read_addr_ptr(dev); + + return 0; +} + +int sunxi_reset_bind(struct udevice *dev, ulong count) +{ + struct udevice *rst_dev; + struct sunxi_reset_priv *priv; + int ret; + + ret = device_bind_driver_to_node(dev, "sunxi_reset", "reset", + dev_ofnode(dev), &rst_dev); + if (ret) { + debug("failed to bind sunxi_reset driver (ret=%d)\n", ret); + return ret; + } + priv = malloc(sizeof(struct sunxi_reset_priv)); + priv->count = count; + priv->desc = (const struct ccu_desc *)dev_get_driver_data(dev); + rst_dev->priv = priv; + + return 0; +} + +U_BOOT_DRIVER(sunxi_reset) = { + .name = "sunxi_reset", + .id = UCLASS_RESET, + .ops = &sunxi_reset_ops, + .probe = sunxi_reset_probe, + .priv_auto_alloc_size = sizeof(struct sunxi_reset_priv), +};