From patchwork Fri Aug 10 06:06:20 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jagan Teki X-Patchwork-Id: 955944 X-Patchwork-Delegate: jagannadh.teki@gmail.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=amarulasolutions.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=amarulasolutions.com header.i=@amarulasolutions.com header.b="BOz24HgV"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41mvqp09Rxz9s7Q for ; Fri, 10 Aug 2018 16:10:29 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id A496BC21E77; Fri, 10 Aug 2018 06:08:34 +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 0570DC21DD9; Fri, 10 Aug 2018 06:08:03 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 679A3C21DA1; Fri, 10 Aug 2018 06:07:53 +0000 (UTC) Received: from mail-pg1-f194.google.com (mail-pg1-f194.google.com [209.85.215.194]) by lists.denx.de (Postfix) with ESMTPS id 1BABCC21DA2 for ; Fri, 10 Aug 2018 06:07:47 +0000 (UTC) Received: by mail-pg1-f194.google.com with SMTP id r5-v6so3901036pgv.0 for ; Thu, 09 Aug 2018 23:07:47 -0700 (PDT) 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; bh=SGyNxDetIZvbUTo+YJrjobOhGBOIt7xakYNQh+kl1uw=; b=BOz24HgVIk/WGI5DbFZRUfvV+PInSUr6NIu6rMkCN2c4JltQPR3pvP97H3lZbTkdkA 340ftNQ5F7uf1kFcPp36osJHAHMne+YNoh+uF+VVNNDGS79c14u8YbuQrpPJCw8KDWqA O4JyCF3qwkmd6u1Tma5IYXbd05VJhH9dOPhWg= 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; bh=SGyNxDetIZvbUTo+YJrjobOhGBOIt7xakYNQh+kl1uw=; b=JbbWig3+PjNTtm404jQoTwRhV8liWbK+y6R4nwQuAKxYQgzRr/c5E1c2AyF7ugujvc EQCDJazaU3W5kvPyn4WgHpsm3imk15RicsUq40fWsru+0IMKtIEq+UyB3oMTrLercpeu vNLv9BnTgQn1/js6BSXlw2A0AEndey/K63EU2gkhwF5GFjE6vZHJFb30JU/2VOSnXyCm OLqfyv2zpO+aTPFf+AkIikhYKYydMr2t3Hj+QGro8o5i+naB4JfMTORh06GjyLWnLbaF oMfnM/pK0FP1//+GSqFVu/DFHL7C5P48qHc2RI8QZN3hbSHzN87CDTQcZ9SitGdRSvGq OHiQ== X-Gm-Message-State: AOUpUlGdHFH5oAzDKuLrFtBBHvdaXmgRWPCyYk0N1ufSADLqx86j9tnU nOowVsWEMsJJvWGQBn7Ua5yTyA== X-Google-Smtp-Source: AA+uWPxForjVKbEwTCV6m00eHIs9JGuwAVld4D+Zbs910X18VtXDgYYrpWZWvhQSC4StoWgOv2LfKA== X-Received: by 2002:a63:f751:: with SMTP id f17-v6mr5133975pgk.410.1533881265458; Thu, 09 Aug 2018 23:07:45 -0700 (PDT) Received: from localhost.localdomain ([183.82.228.250]) by smtp.gmail.com with ESMTPSA id r23-v6sm16880975pfj.5.2018.08.09.23.07.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 09 Aug 2018 23:07:44 -0700 (PDT) From: Jagan Teki To: Maxime Ripard , Andre Przywara , Chen-Yu Tsai , Icenowy Zheng Date: Fri, 10 Aug 2018 11:36:20 +0530 Message-Id: <20180810060711.6547-3-jagan@amarulasolutions.com> X-Mailer: git-send-email 2.18.0.321.gffc6fa0e3 In-Reply-To: <20180810060711.6547-1-jagan@amarulasolutions.com> References: <20180810060711.6547-1-jagan@amarulasolutions.com> MIME-Version: 1.0 Cc: Tom Rini , u-boot@lists.denx.de Subject: [U-Boot] [PATCH v2 02/53] clk: Add Allwinner A64 CLK 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: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Add initial clock driver for Allwinner A64. Implement USB clock enable and disable functions for OHCI, EHCI, OTG and USBPHY gate and clock registers. Signed-off-by: Jagan Teki --- arch/arm/include/asm/arch-sunxi/ccu.h | 47 ++++++++++++++++++++ drivers/clk/Kconfig | 1 + drivers/clk/Makefile | 1 + drivers/clk/sunxi/Kconfig | 18 ++++++++ drivers/clk/sunxi/Makefile | 9 ++++ drivers/clk/sunxi/clk_a64.c | 62 +++++++++++++++++++++++++++ drivers/clk/sunxi/clk_sunxi.c | 58 +++++++++++++++++++++++++ 7 files changed, 196 insertions(+) create mode 100644 arch/arm/include/asm/arch-sunxi/ccu.h create mode 100644 drivers/clk/sunxi/Kconfig create mode 100644 drivers/clk/sunxi/Makefile create mode 100644 drivers/clk/sunxi/clk_a64.c create mode 100644 drivers/clk/sunxi/clk_sunxi.c diff --git a/arch/arm/include/asm/arch-sunxi/ccu.h b/arch/arm/include/asm/arch-sunxi/ccu.h new file mode 100644 index 0000000000..f628c893de --- /dev/null +++ b/arch/arm/include/asm/arch-sunxi/ccu.h @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2018 Amarula Solutions. + * Author: Jagan Teki + */ + +#ifndef _ASM_ARCH_CCU_H +#define _ASM_ARCH_CCU_H + +/** + * ccu_clk_map - common clock unit clock map + * + * @off: ccu clock offset + * @bit: ccu clock bit value + * @ccu_clk_set_rate: ccu clock set rate func + */ +struct ccu_clk_map { + u16 off; + u32 bit; + int (*ccu_clk_set_rate)(void *base, u32 bit, ulong rate); +}; + +/** + * struct ccu_desc - common clock unit descriptor + * + * @clks: mapping clocks descriptor + * @num_clks: number of mapped clocks + */ +struct ccu_desc { + struct ccu_clk_map *clks; + unsigned long num_clks; +}; + +/** + * struct sunxi_clk_priv - sunxi clock private structure + * + * @base: base address + * @desc: ccu descriptor + */ +struct sunxi_clk_priv { + void *base; + const struct ccu_desc *desc; +}; + +extern struct clk_ops sunxi_clk_ops; + +#endif /* _ASM_ARCH_CCU_H */ diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index a99abed9e9..b4992e9ff1 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -88,6 +88,7 @@ source "drivers/clk/exynos/Kconfig" source "drivers/clk/mvebu/Kconfig" source "drivers/clk/owl/Kconfig" source "drivers/clk/renesas/Kconfig" +source "drivers/clk/sunxi/Kconfig" source "drivers/clk/tegra/Kconfig" source "drivers/clk/uniphier/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 146283c723..7cefcd99a0 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -11,6 +11,7 @@ obj-y += tegra/ obj-$(CONFIG_ARCH_ASPEED) += aspeed/ obj-$(CONFIG_ARCH_MESON) += clk_meson.o obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ +obj-$(CONFIG_ARCH_SUNXI) += sunxi/ obj-$(CONFIG_CLK_AT91) += at91/ obj-$(CONFIG_CLK_MVEBU) += mvebu/ obj-$(CONFIG_CLK_BCM6345) += clk_bcm6345.o diff --git a/drivers/clk/sunxi/Kconfig b/drivers/clk/sunxi/Kconfig new file mode 100644 index 0000000000..bf5ecb3801 --- /dev/null +++ b/drivers/clk/sunxi/Kconfig @@ -0,0 +1,18 @@ +config CLK_SUNXI + bool "Clock support for Allwinner SoCs" + depends on CLK && ARCH_SUNXI + default y + help + This enables support for common clock driver API on Allwinner + SoCs. + +if CLK_SUNXI + +config CLK_SUN50I_A64 + bool "Clock driver for Allwinner A64" + default MACH_SUN50I + help + This enables common clock driver support for platforms based + on Allwinner A64 SoC. + +endif # CLK_SUNXI diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile new file mode 100644 index 0000000000..fb20d28333 --- /dev/null +++ b/drivers/clk/sunxi/Makefile @@ -0,0 +1,9 @@ +# +# Copyright (C) 2018 Amarula Solutions. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-$(CONFIG_CLK_SUNXI) += clk_sunxi.o + +obj-$(CONFIG_CLK_SUN50I_A64) += clk_a64.o diff --git a/drivers/clk/sunxi/clk_a64.c b/drivers/clk/sunxi/clk_a64.c new file mode 100644 index 0000000000..9393a01ccf --- /dev/null +++ b/drivers/clk/sunxi/clk_a64.c @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2018 Amarula Solutions. + * Author: Jagan Teki + */ + +#include +#include +#include +#include +#include +#include + +static struct ccu_clk_map a64_clks[] = { + [CLK_BUS_OTG] = { 0x060, BIT(23), NULL }, + [CLK_BUS_EHCI0] = { 0x060, BIT(24), NULL }, + [CLK_BUS_EHCI1] = { 0x060, BIT(25), NULL }, + [CLK_BUS_OHCI0] = { 0x060, BIT(28), NULL }, + [CLK_BUS_OHCI1] = { 0x060, BIT(29), NULL }, + + [CLK_USB_PHY0] = { 0x0cc, BIT(8), NULL }, + [CLK_USB_PHY1] = { 0x0cc, BIT(9), NULL }, + [CLK_USB_HSIC] = { 0x0cc, BIT(10), NULL }, + [CLK_USB_HSIC_12M] = { 0x0cc, BIT(11), NULL }, + [CLK_USB_OHCI0] = { 0x0cc, BIT(16), NULL }, + [CLK_USB_OHCI1] = { 0x0cc, BIT(17), NULL }, +}; + +static const struct ccu_desc sun50i_a64_ccu_desc = { + .clks = a64_clks, + .num_clks = ARRAY_SIZE(a64_clks), +}; + +static int a64_clk_probe(struct udevice *dev) +{ + struct sunxi_clk_priv *priv = dev_get_priv(dev); + + priv->base = dev_read_addr_ptr(dev); + if (!priv->base) + return -ENOMEM; + + priv->desc = (const struct ccu_desc *)dev_get_driver_data(dev); + if (!priv->desc) + return -EINVAL; + + return 0; +} + +static const struct udevice_id a64_clk_ids[] = { + { .compatible = "allwinner,sun50i-a64-ccu", + .data = (ulong)&sun50i_a64_ccu_desc }, + { } +}; + +U_BOOT_DRIVER(clk_sun50i_a64) = { + .name = "sun50i_a64_ccu", + .id = UCLASS_CLK, + .of_match = a64_clk_ids, + .priv_auto_alloc_size = sizeof(struct sunxi_clk_priv), + .ops = &sunxi_clk_ops, + .probe = a64_clk_probe, +}; diff --git a/drivers/clk/sunxi/clk_sunxi.c b/drivers/clk/sunxi/clk_sunxi.c new file mode 100644 index 0000000000..791b1ac7f2 --- /dev/null +++ b/drivers/clk/sunxi/clk_sunxi.c @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2018 Amarula Solutions. + * Author: Jagan Teki + */ + +#include +#include +#include +#include +#include +#include +#include + +static int sunxi_clk_enable(struct clk *clk) +{ + struct sunxi_clk_priv *priv = dev_get_priv(clk->dev); + struct ccu_clk_map *map = &priv->desc->clks[clk->id]; + u32 reg; + + if (!map->off || !map->bit) { + debug("%s (CLK#%ld) unhandled\n", __func__, clk->id); + return 0; + } + + debug("%s(#%ld) off#0x%x, BIT(%d)\n", __func__, + clk->id, map->off, ilog2(map->bit)); + + reg = readl(priv->base + map->off); + writel(reg | map->bit, priv->base + map->off); + + return 0; +} + +static int sunxi_clk_disable(struct clk *clk) +{ + struct sunxi_clk_priv *priv = dev_get_priv(clk->dev); + struct ccu_clk_map *map = &priv->desc->clks[clk->id]; + u32 reg; + + if (!map->off || !map->bit) { + debug("%s (CLK#%ld) unhandled\n", __func__, clk->id); + return 0; + } + + debug("%s(#%ld) off#0x%x, BIT(%d)\n", __func__, + clk->id, map->off, ilog2(map->bit)); + + reg = readl(priv->base + map->off); + writel(reg & ~map->bit, priv->base + map->off); + + return 0; +} + +struct clk_ops sunxi_clk_ops = { + .enable = sunxi_clk_enable, + .disable = sunxi_clk_disable, +};