From patchwork Fri Dec 3 07:34:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qin Jian X-Patchwork-Id: 12654443 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 29512C433EF for ; Fri, 3 Dec 2021 07:43:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243412AbhLCHqx (ORCPT ); Fri, 3 Dec 2021 02:46:53 -0500 Received: from [113.204.237.245] ([113.204.237.245]:44242 "EHLO test.cqplus1.com" rhost-flags-FAIL-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1379086AbhLCHqO (ORCPT ); Fri, 3 Dec 2021 02:46:14 -0500 X-MailGates: (flag:4,DYNAMIC,BADHELO,RELAY,NOHOST:PASS)(compute_score:DE LIVER,40,3) Received: from 172.28.114.216 by cqmailgates with MailGates ESMTP Server V5.0(21484:0:AUTH_RELAY) (envelope-from ); Fri, 03 Dec 2021 15:35:50 +0800 (CST) From: Qin Jian To: robh+dt@kernel.org Cc: mturquette@baylibre.com, sboyd@kernel.org, tglx@linutronix.de, maz@kernel.org, p.zabel@pengutronix.de, linux@armlinux.org.uk, broonie@kernel.org, arnd@arndb.de, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, wells.lu@sunplus.com, Qin Jian , Rob Herring Subject: [PATCH v5 01/10] dt-bindings: vendor-prefixes: Add Sunplus Date: Fri, 3 Dec 2021 15:34:18 +0800 Message-Id: <2e74a1339a5ea54d92fdc4d1998a2b169e23b82b.1638515726.git.qinjian@cqplus1.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org Add vendor prefix for Sunplus Technology Co., Ltd. (http://www.sunplus.com) Acked-by: Rob Herring Signed-off-by: Qin Jian --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index a867f7102..50d4ee5ac 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -1131,6 +1131,8 @@ patternProperties: description: Summit microelectronics "^sunchip,.*": description: Shenzhen Sunchip Technology Co., Ltd + "^sunplus,.*": + description: Sunplus Technology Co., Ltd. "^SUNW,.*": description: Sun Microsystems, Inc "^supermicro,.*": From patchwork Fri Dec 3 07:34:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qin Jian X-Patchwork-Id: 12654449 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AD2D3C433FE for ; Fri, 3 Dec 2021 07:43:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350629AbhLCHq6 (ORCPT ); Fri, 3 Dec 2021 02:46:58 -0500 Received: from [113.204.237.245] ([113.204.237.245]:44244 "EHLO test.cqplus1.com" rhost-flags-FAIL-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1379090AbhLCHqO (ORCPT ); Fri, 3 Dec 2021 02:46:14 -0500 X-MailGates: (flag:4,DYNAMIC,BADHELO,RELAY,NOHOST:PASS)(compute_score:DE LIVER,40,3) Received: from 172.28.114.216 by cqmailgates with MailGates ESMTP Server V5.0(21484:0:AUTH_RELAY) (envelope-from ); Fri, 03 Dec 2021 15:35:50 +0800 (CST) From: Qin Jian To: robh+dt@kernel.org Cc: mturquette@baylibre.com, sboyd@kernel.org, tglx@linutronix.de, maz@kernel.org, p.zabel@pengutronix.de, linux@armlinux.org.uk, broonie@kernel.org, arnd@arndb.de, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, wells.lu@sunplus.com, Qin Jian , Rob Herring Subject: [PATCH v5 02/10] dt-bindings: arm: sunplus: Add bindings for Sunplus SP7021 SoC boards Date: Fri, 3 Dec 2021 15:34:19 +0800 Message-Id: <87cc20bb3ef747c4da89f9e60c0847532bb0a679.1638515726.git.qinjian@cqplus1.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org This introduces bindings for boards based Sunplus SP7021 SoC. Reviewed-by: Rob Herring Signed-off-by: Qin Jian --- .../bindings/arm/sunplus,sp7021.yaml | 27 +++++++++++++++++++ MAINTAINERS | 7 +++++ 2 files changed, 34 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml diff --git a/Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml b/Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml new file mode 100644 index 000000000..5b9985b73 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (C) Sunplus Co., Ltd. 2021 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/arm/sunplus,sp7021.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Sunplus SP7021 Boards Device Tree Bindings + +maintainers: + - qinjian + +description: | + ARM platforms using Sunplus SP7021, an ARM Cortex A7 (4-cores) based SoC. + Wiki: https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview + +properties: + $nodename: + const: '/' + compatible: + oneOf: + - items: + - const: sunplus,sp7021-achip + +additionalProperties: true + +... diff --git a/MAINTAINERS b/MAINTAINERS index e0bca0de0..6a5422f10 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2655,6 +2655,13 @@ F: drivers/clocksource/armv7m_systick.c N: stm32 N: stm +ARM/SUNPLUS SP7021 SOC SUPPORT +M: Qin Jian +L: linux-arm-kernel@lists.infradead.org (moderated for mon-subscribers) +S: Maintained +W: https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview +F: Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml + ARM/Synaptics SoC support M: Jisheng Zhang M: Sebastian Hesselbarth From patchwork Fri Dec 3 07:34:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qin Jian X-Patchwork-Id: 12654457 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 08815C433EF for ; Fri, 3 Dec 2021 07:44:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350283AbhLCHrX (ORCPT ); Fri, 3 Dec 2021 02:47:23 -0500 Received: from [113.204.237.245] ([113.204.237.245]:44264 "EHLO test.cqplus1.com" rhost-flags-FAIL-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1379114AbhLCHqV (ORCPT ); Fri, 3 Dec 2021 02:46:21 -0500 X-MailGates: (flag:4,DYNAMIC,BADHELO,RELAY,NOHOST:PASS)(compute_score:DE LIVER,40,3) Received: from 172.28.114.216 by cqmailgates with MailGates ESMTP Server V5.0(21484:0:AUTH_RELAY) (envelope-from ); Fri, 03 Dec 2021 15:35:50 +0800 (CST) From: Qin Jian To: robh+dt@kernel.org Cc: mturquette@baylibre.com, sboyd@kernel.org, tglx@linutronix.de, maz@kernel.org, p.zabel@pengutronix.de, linux@armlinux.org.uk, broonie@kernel.org, arnd@arndb.de, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, wells.lu@sunplus.com, Qin Jian , Rob Herring Subject: [PATCH v5 03/10] dt-bindings: reset: Add bindings for SP7021 reset driver Date: Fri, 3 Dec 2021 15:34:20 +0800 Message-Id: <773564b54d9e76daea54e6f2fb1373abc059eed3.1638515726.git.qinjian@cqplus1.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org Add documentation to describe Sunplus SP7021 reset driver bindings. Reviewed-by: Rob Herring Signed-off-by: Qin Jian --- .../bindings/reset/sunplus,reset.yaml | 38 ++++++++ MAINTAINERS | 2 + include/dt-bindings/reset/sp-sp7021.h | 97 +++++++++++++++++++ 3 files changed, 137 insertions(+) create mode 100644 Documentation/devicetree/bindings/reset/sunplus,reset.yaml create mode 100644 include/dt-bindings/reset/sp-sp7021.h diff --git a/Documentation/devicetree/bindings/reset/sunplus,reset.yaml b/Documentation/devicetree/bindings/reset/sunplus,reset.yaml new file mode 100644 index 000000000..c083c821f --- /dev/null +++ b/Documentation/devicetree/bindings/reset/sunplus,reset.yaml @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (C) Sunplus Co., Ltd. 2021 +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/reset/sunplus,reset.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Sunplus SoC Reset Controller + +maintainers: + - Qin Jian + +properties: + compatible: + const: sunplus,sp7021-reset + + "#reset-cells": + const: 1 + + reg: + maxItems: 1 + +required: + - compatible + - "#reset-cells" + - reg + +additionalProperties: false + +examples: + - | + rstc: reset@9c000054 { + compatible = "sunplus,sp7021-reset"; + #reset-cells = <1>; + reg = <0x9c000054 0x28>; + }; + +... diff --git a/MAINTAINERS b/MAINTAINERS index 6a5422f10..652f42cab 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2661,6 +2661,8 @@ L: linux-arm-kernel@lists.infradead.org (moderated for mon-subscribers) S: Maintained W: https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview F: Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml +F: Documentation/devicetree/bindings/reset/sunplus,reset.yaml +F: include/dt-bindings/reset/sp-sp7021.h ARM/Synaptics SoC support M: Jisheng Zhang diff --git a/include/dt-bindings/reset/sp-sp7021.h b/include/dt-bindings/reset/sp-sp7021.h new file mode 100644 index 000000000..c0224a960 --- /dev/null +++ b/include/dt-bindings/reset/sp-sp7021.h @@ -0,0 +1,97 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (C) Sunplus Technology Co., Ltd. + * All rights reserved. + */ +#ifndef _DT_BINDINGS_RST_SUNPLUS_SP7021_H +#define _DT_BINDINGS_RST_SUNPLUS_SP7021_H + +/* mo_reset0 ~ mo_reset9 */ +#define RST_SYSTEM 0x00 +#define RST_RTC 0x02 +#define RST_IOCTL 0x03 +#define RST_IOP 0x04 +#define RST_OTPRX 0x05 +#define RST_NOC 0x06 +#define RST_BR 0x07 +#define RST_RBUS_L00 0x08 +#define RST_SPIFL 0x09 +#define RST_SDCTRL0 0x0a +#define RST_PERI0 0x0b +#define RST_A926 0x0d +#define RST_UMCTL2 0x0e +#define RST_PERI1 0x0f + +#define RST_DDR_PHY0 0x10 +#define RST_ACHIP 0x12 +#define RST_STC0 0x14 +#define RST_STC_AV0 0x15 +#define RST_STC_AV1 0x16 +#define RST_STC_AV2 0x17 +#define RST_UA0 0x18 +#define RST_UA1 0x19 +#define RST_UA2 0x1a +#define RST_UA3 0x1b +#define RST_UA4 0x1c +#define RST_HWUA 0x1d +#define RST_DDC0 0x1e +#define RST_UADMA 0x1f + +#define RST_CBDMA0 0x20 +#define RST_CBDMA1 0x21 +#define RST_SPI_COMBO_0 0x22 +#define RST_SPI_COMBO_1 0x23 +#define RST_SPI_COMBO_2 0x24 +#define RST_SPI_COMBO_3 0x25 +#define RST_AUD 0x26 +#define RST_USBC0 0x2a +#define RST_USBC1 0x2b +#define RST_UPHY0 0x2d +#define RST_UPHY1 0x2e + +#define RST_I2CM0 0x30 +#define RST_I2CM1 0x31 +#define RST_I2CM2 0x32 +#define RST_I2CM3 0x33 +#define RST_PMC 0x3d +#define RST_CARD_CTL0 0x3e +#define RST_CARD_CTL1 0x3f + +#define RST_CARD_CTL4 0x42 +#define RST_BCH 0x44 +#define RST_DDFCH 0x4b +#define RST_CSIIW0 0x4c +#define RST_CSIIW1 0x4d +#define RST_MIPICSI0 0x4e +#define RST_MIPICSI1 0x4f + +#define RST_HDMI_TX 0x50 +#define RST_VPOST 0x55 + +#define RST_TGEN 0x60 +#define RST_DMIX 0x61 +#define RST_TCON 0x6a +#define RST_INTERRUPT 0x6f + +#define RST_RGST 0x70 +#define RST_GPIO 0x73 +#define RST_RBUS_TOP 0x74 + +#define RST_MAILBOX 0x86 +#define RST_SPIND 0x8a +#define RST_I2C2CBUS 0x8b +#define RST_SEC 0x8d +#define RST_DVE 0x8e +#define RST_GPOST0 0x8f + +#define RST_OSD0 0x90 +#define RST_DISP_PWM 0x92 +#define RST_UADBG 0x93 +#define RST_DUMMY_MASTER 0x94 +#define RST_FIO_CTL 0x95 +#define RST_FPGA 0x96 +#define RST_L2SW 0x97 +#define RST_ICM 0x98 +#define RST_AXI_GLOBAL 0x99 + +#endif From patchwork Fri Dec 3 07:34:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qin Jian X-Patchwork-Id: 12654453 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6EDE6C433F5 for ; Fri, 3 Dec 2021 07:43:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1351012AbhLCHrQ (ORCPT ); Fri, 3 Dec 2021 02:47:16 -0500 Received: from [113.204.237.245] ([113.204.237.245]:44256 "EHLO test.cqplus1.com" rhost-flags-FAIL-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1379106AbhLCHqU (ORCPT ); Fri, 3 Dec 2021 02:46:20 -0500 X-MailGates: (flag:4,DYNAMIC,BADHELO,RELAY,NOHOST:PASS)(compute_score:DE LIVER,40,3) Received: from 172.28.114.216 by cqmailgates with MailGates ESMTP Server V5.0(21484:0:AUTH_RELAY) (envelope-from ); Fri, 03 Dec 2021 15:35:51 +0800 (CST) From: Qin Jian To: robh+dt@kernel.org Cc: mturquette@baylibre.com, sboyd@kernel.org, tglx@linutronix.de, maz@kernel.org, p.zabel@pengutronix.de, linux@armlinux.org.uk, broonie@kernel.org, arnd@arndb.de, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, wells.lu@sunplus.com, Qin Jian Subject: [PATCH v5 04/10] reset: Add Sunplus SP7021 reset driver Date: Fri, 3 Dec 2021 15:34:21 +0800 Message-Id: <5b847375ae9591dfd0551c86141102e02b450479.1638515726.git.qinjian@cqplus1.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org Add reset driver for Sunplus SP7021 SoC. Signed-off-by: Qin Jian --- MAINTAINERS | 1 + drivers/reset/Kconfig | 9 +++ drivers/reset/Makefile | 1 + drivers/reset/reset-sunplus.c | 132 ++++++++++++++++++++++++++++++++++ 4 files changed, 143 insertions(+) create mode 100644 drivers/reset/reset-sunplus.c diff --git a/MAINTAINERS b/MAINTAINERS index 652f42cab..6caffd6d0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2662,6 +2662,7 @@ S: Maintained W: https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview F: Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml F: Documentation/devicetree/bindings/reset/sunplus,reset.yaml +F: drivers/reset/reset-sunplus.c F: include/dt-bindings/reset/sp-sp7021.h ARM/Synaptics SoC support diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index be799a5ab..5cdd022ad 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -224,6 +224,15 @@ config RESET_SOCFPGA This enables the reset driver for the SoCFPGA ARMv7 platforms. This driver gets initialized early during platform init calls. +config RESET_SUNPLUS + bool "Sunplus SoCs Reset Driver" + depends on ARCH_SUNPLUS || COMPILE_TEST + help + This enables the reset driver support for Sunplus SP7021 SoC family. + Say Y if you want to control reset signals by the reset controller. + Otherwise, say N. + This driver is selected automatically by arm/mach-sunplus platform config. + config RESET_SUNXI bool "Allwinner SoCs Reset Driver" if COMPILE_TEST && !ARCH_SUNXI default ARCH_SUNXI diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 21d46d886..f03403e97 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -29,6 +29,7 @@ obj-$(CONFIG_RESET_RZG2L_USBPHY_CTRL) += reset-rzg2l-usbphy-ctrl.o obj-$(CONFIG_RESET_SCMI) += reset-scmi.o obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o +obj-$(CONFIG_RESET_SUNPLUS) += reset-sunplus.o obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o obj-$(CONFIG_RESET_TI_SYSCON) += reset-ti-syscon.o diff --git a/drivers/reset/reset-sunplus.c b/drivers/reset/reset-sunplus.c new file mode 100644 index 000000000..a1d88dbaf --- /dev/null +++ b/drivers/reset/reset-sunplus.c @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * SP7021 reset driver + * + * Copyright (C) Sunplus Technology Co., Ltd. + * All rights reserved. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* HIWORD_MASK_REG BITS */ +#define BITS_PER_HWM_REG 16 + +struct sp_reset_data { + struct reset_controller_dev rcdev; + void __iomem *membase; +} *sp_reset; + +static inline struct sp_reset_data *to_sp_reset_data(struct reset_controller_dev + *rcdev) +{ + return container_of(rcdev, struct sp_reset_data, rcdev); +} + +static int sp_reset_update(struct reset_controller_dev *rcdev, + unsigned long id, bool assert) +{ + struct sp_reset_data *data = to_sp_reset_data(rcdev); + int index = id / BITS_PER_HWM_REG; + int shift = id % BITS_PER_HWM_REG; + void __iomem *addr = data->membase + (index * 4); + u32 value; + + value = (1 << (16 + shift)) | (assert << shift); + writel(value, addr); + + return 0; +} + +static int sp_reset_assert(struct reset_controller_dev *rcdev, unsigned long id) +{ + return sp_reset_update(rcdev, id, true); +} + +static int sp_reset_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + return sp_reset_update(rcdev, id, false); +} + +static int sp_reset_status(struct reset_controller_dev *rcdev, unsigned long id) +{ + struct sp_reset_data *data = to_sp_reset_data(rcdev); + int index = id / BITS_PER_HWM_REG; + int shift = id % BITS_PER_HWM_REG; + u32 reg; + + reg = readl(data->membase + (index * 4)); + + return !!(reg & BIT(shift)); +} + +static int sp_restart(struct notifier_block *this, unsigned long mode, + void *cmd) +{ + sp_reset_assert(&sp_reset->rcdev, 0); + sp_reset_deassert(&sp_reset->rcdev, 0); + + return NOTIFY_DONE; +} + +static struct notifier_block sp_restart_nb = { + .notifier_call = sp_restart, + .priority = 192, +}; + +static const struct reset_control_ops sp_reset_ops = { + .assert = sp_reset_assert, + .deassert = sp_reset_deassert, + .status = sp_reset_status, +}; + +static const struct of_device_id sp_reset_dt_ids[] = { + {.compatible = "sunplus,sp7021-reset",}, + { /* sentinel */ }, +}; + +static int sp_reset_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + void __iomem *membase; + struct resource *res; + + sp_reset = devm_kzalloc(&pdev->dev, sizeof(*sp_reset), GFP_KERNEL); + if (!sp_reset) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + membase = devm_ioremap_resource(dev, res); + if (IS_ERR(membase)) + return PTR_ERR(membase); + + sp_reset->membase = membase; + sp_reset->rcdev.owner = THIS_MODULE; + sp_reset->rcdev.nr_resets = resource_size(res) / 4 * 16; /* HIWORD_MASK */ + sp_reset->rcdev.ops = &sp_reset_ops; + sp_reset->rcdev.of_node = dev->of_node; + register_restart_handler(&sp_restart_nb); + + return devm_reset_controller_register(dev, &sp_reset->rcdev); +} + +static struct platform_driver sp_reset_driver = { + .probe = sp_reset_probe, + .driver = { + .name = "sunplus-reset", + .of_match_table = sp_reset_dt_ids, + }, +}; + +module_platform_driver(sp_reset_driver); + +MODULE_AUTHOR("Edwin Chiu "); +MODULE_DESCRIPTION("Sunplus Reset Driver"); +MODULE_LICENSE("GPL v2"); From patchwork Fri Dec 3 07:34:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qin Jian X-Patchwork-Id: 12654445 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4DB91C433FE for ; Fri, 3 Dec 2021 07:43:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350935AbhLCHqy (ORCPT ); Fri, 3 Dec 2021 02:46:54 -0500 Received: from [113.204.237.245] ([113.204.237.245]:44246 "EHLO test.cqplus1.com" rhost-flags-FAIL-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1379089AbhLCHqO (ORCPT ); Fri, 3 Dec 2021 02:46:14 -0500 X-MailGates: (flag:4,DYNAMIC,BADHELO,RELAY,NOHOST:PASS)(compute_score:DE LIVER,40,3) Received: from 172.28.114.216 by cqmailgates with MailGates ESMTP Server V5.0(21484:0:AUTH_RELAY) (envelope-from ); Fri, 03 Dec 2021 15:35:51 +0800 (CST) From: Qin Jian To: robh+dt@kernel.org Cc: mturquette@baylibre.com, sboyd@kernel.org, tglx@linutronix.de, maz@kernel.org, p.zabel@pengutronix.de, linux@armlinux.org.uk, broonie@kernel.org, arnd@arndb.de, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, wells.lu@sunplus.com, Qin Jian , Rob Herring Subject: [PATCH v5 05/10] dt-bindings: clock: Add bindings for SP7021 clock driver Date: Fri, 3 Dec 2021 15:34:22 +0800 Message-Id: X-Mailer: git-send-email 2.33.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org Add documentation to describe Sunplus SP7021 clock driver bindings. Reviewed-by: Rob Herring Signed-off-by: Qin Jian --- .../bindings/clock/sunplus,sp7021-clkc.yaml | 38 ++++++ MAINTAINERS | 2 + include/dt-bindings/clock/sp-sp7021.h | 112 ++++++++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml create mode 100644 include/dt-bindings/clock/sp-sp7021.h diff --git a/Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml b/Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml new file mode 100644 index 000000000..1ce7e41d8 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (C) Sunplus Co., Ltd. 2021 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/sunplus,sp7021-clkc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Sunplus SP7021 SoC Clock Controller Binding + +maintainers: + - Qin Jian + +properties: + compatible: + const: sunplus,sp7021-clkc + + "#clock-cells": + const: 1 + + reg: + maxItems: 1 + +required: + - compatible + - "#clock-cells" + - reg + +additionalProperties: false + +examples: + - | + clkc: clkc@9c000000 { + compatible = "sunplus,sp7021-clkc"; + #clock-cells = <1>; + reg = <0x9c000000 0x280>; + }; + +... diff --git a/MAINTAINERS b/MAINTAINERS index 6caffd6d0..90ebb823f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2661,8 +2661,10 @@ L: linux-arm-kernel@lists.infradead.org (moderated for mon-subscribers) S: Maintained W: https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview F: Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml +F: Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml F: Documentation/devicetree/bindings/reset/sunplus,reset.yaml F: drivers/reset/reset-sunplus.c +F: include/dt-bindings/clock/sp-sp7021.h F: include/dt-bindings/reset/sp-sp7021.h ARM/Synaptics SoC support diff --git a/include/dt-bindings/clock/sp-sp7021.h b/include/dt-bindings/clock/sp-sp7021.h new file mode 100644 index 000000000..778a1df1c --- /dev/null +++ b/include/dt-bindings/clock/sp-sp7021.h @@ -0,0 +1,112 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (C) Sunplus Technology Co., Ltd. + * All rights reserved. + */ +#ifndef _DT_BINDINGS_CLOCK_SUNPLUS_SP7021_H +#define _DT_BINDINGS_CLOCK_SUNPLUS_SP7021_H + +#define XTAL 27000000 + +/* plls */ +#define PLL_A 0 +#define PLL_E 1 +#define PLL_E_2P5 2 +#define PLL_E_25 3 +#define PLL_E_112P5 4 +#define PLL_F 5 +#define PLL_TV 6 +#define PLL_TV_A 7 +#define PLL_SYS 8 + +/* gates: mo_clken0 ~ mo_clken9 */ +#define CLK_SYSTEM 0x10 +#define CLK_RTC 0x12 +#define CLK_IOCTL 0x13 +#define CLK_IOP 0x14 +#define CLK_OTPRX 0x15 +#define CLK_NOC 0x16 +#define CLK_BR 0x17 +#define CLK_RBUS_L00 0x18 +#define CLK_SPIFL 0x19 +#define CLK_SDCTRL0 0x1a +#define CLK_PERI0 0x1b +#define CLK_A926 0x1d +#define CLK_UMCTL2 0x1e +#define CLK_PERI1 0x1f + +#define CLK_DDR_PHY0 0x20 +#define CLK_ACHIP 0x22 +#define CLK_STC0 0x24 +#define CLK_STC_AV0 0x25 +#define CLK_STC_AV1 0x26 +#define CLK_STC_AV2 0x27 +#define CLK_UA0 0x28 +#define CLK_UA1 0x29 +#define CLK_UA2 0x2a +#define CLK_UA3 0x2b +#define CLK_UA4 0x2c +#define CLK_HWUA 0x2d +#define CLK_DDC0 0x2e +#define CLK_UADMA 0x2f + +#define CLK_CBDMA0 0x30 +#define CLK_CBDMA1 0x31 +#define CLK_SPI_COMBO_0 0x32 +#define CLK_SPI_COMBO_1 0x33 +#define CLK_SPI_COMBO_2 0x34 +#define CLK_SPI_COMBO_3 0x35 +#define CLK_AUD 0x36 +#define CLK_USBC0 0x3a +#define CLK_USBC1 0x3b +#define CLK_UPHY0 0x3d +#define CLK_UPHY1 0x3e + +#define CLK_I2CM0 0x40 +#define CLK_I2CM1 0x41 +#define CLK_I2CM2 0x42 +#define CLK_I2CM3 0x43 +#define CLK_PMC 0x4d +#define CLK_CARD_CTL0 0x4e +#define CLK_CARD_CTL1 0x4f + +#define CLK_CARD_CTL4 0x52 +#define CLK_BCH 0x54 +#define CLK_DDFCH 0x5b +#define CLK_CSIIW0 0x5c +#define CLK_CSIIW1 0x5d +#define CLK_MIPICSI0 0x5e +#define CLK_MIPICSI1 0x5f + +#define CLK_HDMI_TX 0x60 +#define CLK_VPOST 0x65 + +#define CLK_TGEN 0x70 +#define CLK_DMIX 0x71 +#define CLK_TCON 0x7a +#define CLK_INTERRUPT 0x7f + +#define CLK_RGST 0x80 +#define CLK_GPIO 0x83 +#define CLK_RBUS_TOP 0x84 + +#define CLK_MAILBOX 0x96 +#define CLK_SPIND 0x9a +#define CLK_I2C2CBUS 0x9b +#define CLK_SEC 0x9d +#define CLK_DVE 0x9e +#define CLK_GPOST0 0x9f + +#define CLK_OSD0 0xa0 +#define CLK_DISP_PWM 0xa2 +#define CLK_UADBG 0xa3 +#define CLK_DUMMY_MASTER 0xa4 +#define CLK_FIO_CTL 0xa5 +#define CLK_FPGA 0xa6 +#define CLK_L2SW 0xa7 +#define CLK_ICM 0xa8 +#define CLK_AXI_GLOBAL 0xa9 + +#define CLK_MAX 0xb0 + +#endif From patchwork Fri Dec 3 07:34:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qin Jian X-Patchwork-Id: 12654463 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3F36CC433FE for ; Fri, 3 Dec 2021 07:44:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350979AbhLCHr3 (ORCPT ); Fri, 3 Dec 2021 02:47:29 -0500 Received: from [113.204.237.245] ([113.204.237.245]:44276 "EHLO test.cqplus1.com" rhost-flags-FAIL-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1379127AbhLCHqW (ORCPT ); Fri, 3 Dec 2021 02:46:22 -0500 X-MailGates: (flag:4,DYNAMIC,BADHELO,RELAY,NOHOST:PASS)(compute_score:DE LIVER,40,3) Received: from 172.28.114.216 by cqmailgates with MailGates ESMTP Server V5.0(21484:0:AUTH_RELAY) (envelope-from ); Fri, 03 Dec 2021 15:35:51 +0800 (CST) From: Qin Jian To: robh+dt@kernel.org Cc: mturquette@baylibre.com, sboyd@kernel.org, tglx@linutronix.de, maz@kernel.org, p.zabel@pengutronix.de, linux@armlinux.org.uk, broonie@kernel.org, arnd@arndb.de, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, wells.lu@sunplus.com, Qin Jian Subject: [PATCH v5 06/10] clk: Add Sunplus SP7021 clock driver Date: Fri, 3 Dec 2021 15:34:23 +0800 Message-Id: <8d23a5e00d870173993032c6a68fb5f48182691d.1638515726.git.qinjian@cqplus1.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org Add clock driver for Sunplus SP7021 SoC. Signed-off-by: Qin Jian --- MAINTAINERS | 1 + drivers/clk/Kconfig | 9 + drivers/clk/Makefile | 1 + drivers/clk/clk-sp7021.c | 738 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 749 insertions(+) create mode 100644 drivers/clk/clk-sp7021.c diff --git a/MAINTAINERS b/MAINTAINERS index 90ebb823f..5069f552f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2663,6 +2663,7 @@ W: https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview F: Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml F: Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml F: Documentation/devicetree/bindings/reset/sunplus,reset.yaml +F: drivers/clk/clk-sp7021.c F: drivers/reset/reset-sunplus.c F: include/dt-bindings/clock/sp-sp7021.h F: include/dt-bindings/reset/sp-sp7021.h diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index c5b3dc973..b92a176c7 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -334,6 +334,15 @@ config COMMON_CLK_VC5 This driver supports the IDT VersaClock 5 and VersaClock 6 programmable clock generators. +config COMMON_CLK_SP7021 + bool "Clock driver for Sunplus SP7021 SoC" + help + This driver supports the Sunplus SP7021 SoC clocks. + It implements SP7021 PLLs/gate. + Not all features of the PLL are currently supported + by the driver. + This driver is selected automatically by platform config. + config COMMON_CLK_STM32MP157 def_bool COMMON_CLK && MACH_STM32MP157 help diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index e42312121..f15bb5070 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -60,6 +60,7 @@ obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o obj-$(CONFIG_COMMON_CLK_SI514) += clk-si514.o obj-$(CONFIG_COMMON_CLK_SI544) += clk-si544.o obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o +obj-$(CONFIG_COMMON_CLK_SP7021) += clk-sp7021.o obj-$(CONFIG_COMMON_CLK_STM32F) += clk-stm32f4.o obj-$(CONFIG_COMMON_CLK_STM32H7) += clk-stm32h7.o obj-$(CONFIG_COMMON_CLK_STM32MP157) += clk-stm32mp1.o diff --git a/drivers/clk/clk-sp7021.c b/drivers/clk/clk-sp7021.c new file mode 100644 index 000000000..040578e82 --- /dev/null +++ b/drivers/clk/clk-sp7021.c @@ -0,0 +1,738 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Copyright (C) Sunplus Technology Co., Ltd. + * All rights reserved. + */ +//#define DEBUG +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef clk_readl +#define clk_readl readl +#define clk_writel writel +#endif + +#define REG(i) (pll_regs + (i) * 4) + +#define PLLA_CTL REG(7) +#define PLLE_CTL REG(12) +#define PLLF_CTL REG(13) +#define PLLTV_CTL REG(14) +#define PLLSYS_CTL REG(26) + +#define EXTCLK "extclk" + +/* speical div_width values for PLLTV/PLLA */ +#define DIV_TV 33 +#define DIV_A 34 + +/* PLLTV parameters */ +enum { + SEL_FRA, + SDM_MOD, + PH_SEL, + NFRA, + DIVR, + DIVN, + DIVM, + P_MAX +}; + +#define MASK_SEL_FRA GENMASK(1, 1) +#define MASK_SDM_MOD GENMASK(2, 2) +#define MASK_PH_SEL GENMASK(4, 4) +#define MASK_NFRA GENMASK(12, 6) +#define MASK_DIVR GENMASK(8, 7) +#define MASK_DIVN GENMASK(7, 0) +#define MASK_DIVM GENMASK(14, 8) + +/* HIWORD_MASK FIELD_PREP */ +#define HWM_FIELD_PREP(mask, value) \ +({\ + u32 m = mask; \ + (m << 16) | FIELD_PREP(m, value); \ +}) + +struct sp_pll { + struct clk_hw hw; + void __iomem *reg; + spinlock_t *lock; /* lock for reg */ + int div_shift; + int div_width; + int pd_bit; /* power down bit idx */ + int bp_bit; /* bypass bit idx */ + unsigned long brate; /* base rate, TODO: replace brate with muldiv */ + u32 p[P_MAX]; /* for hold PLLTV/PLLA parameters */ +}; + +#define to_sp_pll(_hw) container_of(_hw, struct sp_pll, hw) + +#define clk_regs (moon_regs + 0x000) /* G0 ~ CLKEN */ +#define pll_regs (moon_regs + 0x200) /* G4 ~ PLL */ +static void __iomem *moon_regs; + +#define P_EXTCLK BIT(16) +static const char * const parents[] = { + "pllsys", + "extclk", +}; + +static const u32 gates[] = { + CLK_SYSTEM, + CLK_RTC, + CLK_IOCTL, + CLK_IOP, + CLK_OTPRX, + CLK_NOC, + CLK_BR, + CLK_RBUS_L00, + CLK_SPIFL, + CLK_SDCTRL0, + CLK_PERI0 | P_EXTCLK, + CLK_A926, + CLK_UMCTL2, + CLK_PERI1 | P_EXTCLK, + + CLK_DDR_PHY0, + CLK_ACHIP, + CLK_STC0, + CLK_STC_AV0, + CLK_STC_AV1, + CLK_STC_AV2, + CLK_UA0 | P_EXTCLK, + CLK_UA1 | P_EXTCLK, + CLK_UA2 | P_EXTCLK, + CLK_UA3 | P_EXTCLK, + CLK_UA4 | P_EXTCLK, + CLK_HWUA | P_EXTCLK, + CLK_DDC0, + CLK_UADMA | P_EXTCLK, + + CLK_CBDMA0, + CLK_CBDMA1, + CLK_SPI_COMBO_0, + CLK_SPI_COMBO_1, + CLK_SPI_COMBO_2, + CLK_SPI_COMBO_3, + CLK_AUD, + CLK_USBC0, + CLK_USBC1, + CLK_UPHY0, + CLK_UPHY1, + + CLK_I2CM0, + CLK_I2CM1, + CLK_I2CM2, + CLK_I2CM3, + CLK_PMC, + CLK_CARD_CTL0, + CLK_CARD_CTL1, + + CLK_CARD_CTL4, + CLK_BCH, + CLK_DDFCH, + CLK_CSIIW0, + CLK_CSIIW1, + CLK_MIPICSI0, + CLK_MIPICSI1, + + CLK_HDMI_TX, + CLK_VPOST, + + CLK_TGEN, + CLK_DMIX, + CLK_TCON, + CLK_INTERRUPT, + + CLK_RGST, + CLK_GPIO, + CLK_RBUS_TOP, + + CLK_MAILBOX, + CLK_SPIND, + CLK_I2C2CBUS, + CLK_SEC, + CLK_GPOST0, + CLK_DVE, + + CLK_OSD0, + CLK_DISP_PWM, + CLK_UADBG, + CLK_DUMMY_MASTER, + CLK_FIO_CTL, + CLK_FPGA, + CLK_L2SW, + CLK_ICM, + CLK_AXI_GLOBAL, +}; + +static struct clk *clks[CLK_MAX]; +static struct clk_onecell_data clk_data; + +static DEFINE_SPINLOCK(plla_lock); +static DEFINE_SPINLOCK(plle_lock); +static DEFINE_SPINLOCK(pllf_lock); +static DEFINE_SPINLOCK(pllsys_lock); +static DEFINE_SPINLOCK(plltv_lock); + +#define _M 1000000UL +#define F_27M (27 * _M) + +/******************************************** PLL_TV *******************************************/ + +//#define PLLTV_STEP_DIR (?) /* Unit: HZ */ + +/* TODO: set proper FVCO range */ +#define FVCO_MIN (100 * _M) +#define FVCO_MAX (200 * _M) + +#define F_MIN (FVCO_MIN / 8) +#define F_MAX (FVCO_MAX) + +static long plltv_integer_div(struct sp_pll *clk, unsigned long freq) +{ + /* valid m values: 27M must be divisible by m, 0 means end */ + static const u32 m_table[] = { + 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, 0 + }; + u32 m, n, r; +#ifdef PLLTV_STEP_DIR + u32 step = (PLLTV_STEP_DIR > 0) ? PLLTV_STEP_DIR : -PLLTV_STEP_DIR; + int calc_times = 1000000 / step; +#endif + unsigned long fvco, nf; + + /* check freq */ + if (freq < F_MIN) { + pr_warn("%s: %s freq:%lu < F_MIN:%lu, round up\n", + __func__, clk_hw_get_name(&clk->hw), freq, F_MIN); + freq = F_MIN; + } else if (freq > F_MAX) { + pr_warn("%s: %s freq:%lu > F_MAX:%lu, round down\n", + __func__, clk_hw_get_name(&clk->hw), freq, F_MAX); + freq = F_MAX; + } + +#ifdef PLLTV_STEP_DIR + if ((freq % step) != 0) + freq += step - (freq % step) + ((PLLTV_STEP_DIR > 0) ? 0 : PLLTV_STEP_DIR); +#endif + +#ifdef PLLTV_STEP_DIR +CALC: + if (!calc_times) { + pr_err("%s: %s freq:%lu out of recalc times\n", + __func__, clk_hw_get_name(&clk->hw), freq); + return -ETIMEOUT; + } +#endif + + /* DIVR 0~3 */ + for (r = 0; r <= 3; r++) { + fvco = freq << r; + if (fvco <= FVCO_MAX) + break; + } + + /* DIVM */ + for (m = 0; m_table[m]; m++) { + nf = fvco * m_table[m]; + n = nf / F_27M; + if ((n * F_27M) == nf) + break; + } + m = m_table[m]; + + if (!m) { +#ifdef PLLTV_STEP_DIR + freq += PLLTV_STEP_DIR; + calc_times--; + goto CALC; +#else + pr_err("%s: %s freq:%lu not found a valid setting\n", + __func__, clk_hw_get_name(&clk->hw), freq); + return -EINVAL; +#endif + } + + /* save parameters */ + clk->p[SEL_FRA] = 0; + clk->p[DIVR] = r; + clk->p[DIVN] = n; + clk->p[DIVM] = m; + + return freq; +} + +/* parameters for PLLTV fractional divider */ +static const u32 pt[][5] = { + /* conventional fractional */ + { + 1, // factor + 5, // 5 * p0 (nint) + 1, // 1 * p0 + F_27M, // F_27M / p0 + 1, // p0 / p2 + }, + /* phase rotation */ + { + 10, // factor + 54, // 5.4 * p0 (nint) + 2, // 0.2 * p0 + F_27M / 10, // F_27M / p0 + 5, // p0 / p2 + }, +}; + +static const u32 mods[] = { 91, 55 }; /* SDM_MOD mod values */ + +static long plltv_fractional_div(struct sp_pll *clk, unsigned long freq) +{ + u32 m, r; + u32 nint, nfra; + u32 diff_min_quotient = 210000000, diff_min_remainder = 0; + u32 diff_min_sign = 0; + unsigned long fvco, nf, f, fout = 0; + int sdm, ph; + + /* check freq */ + if (freq < F_MIN) { + pr_warn("%s: %s freq:%lu < F_MIN:%lu, round up\n", + __func__, clk_hw_get_name(&clk->hw), freq, F_MIN); + freq = F_MIN; + } else if (freq > F_MAX) { + pr_warn("%s: %s freq:%lu > F_MAX:%lu, round down\n", + __func__, clk_hw_get_name(&clk->hw), freq, F_MAX); + freq = F_MAX; + } + + /* DIVR 0~3 */ + for (r = 0; r <= 3; r++) { + fvco = freq << r; + if (fvco <= FVCO_MAX) + break; + } + f = F_27M >> r; + + /* PH_SEL 1/0 */ + for (ph = 1; ph >= 0; ph--) { + const u32 *pp = pt[ph]; + u32 ms = 1; + + /* SDM_MOD 0/1 */ + for (sdm = 0; sdm <= 1; sdm++) { + u32 mod = mods[sdm]; + + /* DIVM 1~32 */ + for (m = ms; m <= 32; m++) { + u32 diff_freq; + u32 diff_freq_quotient = 0, diff_freq_remainder = 0; + u32 diff_freq_sign = 0; /* 0:Positive number, 1:Negative number */ + + nf = fvco * m; + nint = nf / pp[3]; + + if (nint < pp[1]) + continue; + if (nint > pp[1]) + break; + + nfra = (((nf % pp[3]) * mod * pp[4]) + (F_27M / 2)) / F_27M; + if (nfra) + diff_freq = (f * (nint + pp[2]) / pp[0]) - + (f * (mod - nfra) / mod / pp[4]); + else + diff_freq = (f * (nint) / pp[0]); + + diff_freq_quotient = diff_freq / m; + diff_freq_remainder = ((diff_freq % m) * 1000) / m; + + if (freq > diff_freq_quotient) { + diff_freq_quotient = freq - diff_freq_quotient - 1; + diff_freq_remainder = 1000 - diff_freq_remainder; + diff_freq_sign = 1; + } else { + diff_freq_quotient = diff_freq_quotient - freq; + diff_freq_sign = 0; + } + + if (diff_min_quotient > diff_freq_quotient || + (diff_min_quotient == diff_freq_quotient && + diff_min_remainder > diff_freq_remainder)) { + /* found a closer freq, save parameters */ + clk->p[SEL_FRA] = 1; + clk->p[SDM_MOD] = sdm; + clk->p[PH_SEL] = ph; + clk->p[NFRA] = nfra; + clk->p[DIVR] = r; + clk->p[DIVM] = m; + + fout = diff_freq / m; + diff_min_quotient = diff_freq_quotient; + diff_min_remainder = diff_freq_remainder; + diff_min_sign = diff_freq_sign; + } + } + } + } + + if (!fout) { + pr_err("%s: %s freq:%lu not found a valid setting\n", + __func__, clk_hw_get_name(&clk->hw), freq); + return -EINVAL; + } + + return fout; +} + +static long plltv_div(struct sp_pll *clk, unsigned long freq) +{ + if (freq % 100) + return plltv_fractional_div(clk, freq); + else + return plltv_integer_div(clk, freq); +} + +static void plltv_set_rate(struct sp_pll *clk) +{ + u32 reg; + + reg = HWM_FIELD_PREP(MASK_SEL_FRA, clk->p[SEL_FRA]); + reg |= HWM_FIELD_PREP(MASK_SDM_MOD, clk->p[SDM_MOD]); + reg |= HWM_FIELD_PREP(MASK_PH_SEL, clk->p[PH_SEL]); + reg |= HWM_FIELD_PREP(MASK_NFRA, clk->p[NFRA]); + clk_writel(reg, clk->reg); + + reg = HWM_FIELD_PREP(MASK_DIVR, clk->p[DIVR]); + clk_writel(reg, clk->reg + 4); + + reg = HWM_FIELD_PREP(MASK_DIVN, clk->p[DIVN] - 1); + reg |= HWM_FIELD_PREP(MASK_DIVM, clk->p[DIVM] - 1); + clk_writel(reg, clk->reg + 8); +} + +/******************************************** PLL_A ********************************************/ + +/* from Q628_PLLs_REG_setting.xlsx */ +struct { + u32 rate; + u32 regs[5]; +} pa[] = { + { + .rate = 135475200, + .regs = { + 0x4801, + 0x02df, + 0x248f, + 0x0211, + 0x33e9 + } + }, + { + .rate = 147456000, + .regs = { + 0x4801, + 0x1adf, + 0x2490, + 0x0349, + 0x33e9 + } + }, + { + .rate = 196608000, + .regs = { + 0x4801, + 0x42ef, + 0x2495, + 0x01c6, + 0x33e9 + } + }, +}; + +static void plla_set_rate(struct sp_pll *clk) +{ + const u32 *pp = pa[clk->p[0]].regs; + int i; + + for (i = 0; i < ARRAY_SIZE(pa->regs); i++) + clk_writel(0xffff0000 | pp[i], clk->reg + (i * 4)); +} + +static long plla_round_rate(struct sp_pll *clk, unsigned long rate) +{ + int i = ARRAY_SIZE(pa); + + while (--i) { + if (rate >= pa[i].rate) + break; + } + clk->p[0] = i; + return pa[i].rate; +} + +/******************************************* SP_PLL ********************************************/ + +static long sp_pll_calc_div(struct sp_pll *clk, unsigned long rate) +{ + u32 fbdiv; + u32 max = 1 << clk->div_width; + + fbdiv = DIV_ROUND_CLOSEST(rate, clk->brate); + if (fbdiv > max) + fbdiv = max; + return fbdiv; +} + +static long sp_pll_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + struct sp_pll *clk = to_sp_pll(hw); + long ret; + + if (rate == *prate) + ret = *prate; /* bypass */ + else if (clk->div_width == DIV_A) { + ret = plla_round_rate(clk, rate); + } else if (clk->div_width == DIV_TV) { + ret = plltv_div(clk, rate); + if (ret < 0) + ret = *prate; + } else { + ret = sp_pll_calc_div(clk, rate) * clk->brate; + } + + return ret; +} + +static unsigned long sp_pll_recalc_rate(struct clk_hw *hw, + unsigned long prate) +{ + struct sp_pll *clk = to_sp_pll(hw); + u32 reg = clk_readl(clk->reg); + unsigned long ret; + + if (reg & BIT(clk->bp_bit)) { + ret = prate; /* bypass */ + } else if (clk->div_width == DIV_A) { + ret = pa[clk->p[0]].rate; + } else if (clk->div_width == DIV_TV) { + u32 m, r, reg2; + + r = FIELD_GET(MASK_DIVR, clk_readl(clk->reg + 4)); + reg2 = clk_readl(clk->reg + 8); + m = FIELD_GET(MASK_DIVM, reg2) + 1; + + if (reg & BIT(1)) { /* SEL_FRA */ + /* fractional divider */ + u32 sdm = FIELD_GET(MASK_SDM_MOD, reg); + u32 ph = FIELD_GET(MASK_PH_SEL, reg); + u32 nfra = FIELD_GET(MASK_NFRA, reg); + const u32 *pp = pt[ph]; + + ret = prate >> r; + ret = (ret * (pp[1] + pp[2]) / pp[0]) - + (ret * (mods[sdm] - nfra) / mods[sdm] / pp[4]); + ret /= m; + } else { + /* integer divider */ + u32 n = FIELD_GET(MASK_DIVN, reg2) + 1; + + ret = (prate / m * n) >> r; + } + } else { + u32 fbdiv = (reg >> clk->div_shift) & ((1 << clk->div_width) - 1); + + ret = clk->brate * fbdiv; + } + + return ret; +} + +static int sp_pll_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long prate) +{ + struct sp_pll *clk = to_sp_pll(hw); + unsigned long flags; + u32 reg; + + spin_lock_irqsave(clk->lock, flags); + + reg = BIT(clk->bp_bit + 16); /* HIWORD_MASK */ + + if (rate == prate) + reg |= BIT(clk->bp_bit); /* bypass */ + else if (clk->div_width == DIV_A) + plla_set_rate(clk); + else if (clk->div_width == DIV_TV) + plltv_set_rate(clk); + else if (clk->div_width) { + u32 fbdiv = sp_pll_calc_div(clk, rate); + u32 mask = GENMASK(clk->div_shift + clk->div_width - 1, clk->div_shift); + + reg |= (mask << 16) | (((fbdiv - 1) << clk->div_shift) & mask); + } + + clk_writel(reg, clk->reg); + + spin_unlock_irqrestore(clk->lock, flags); + + return 0; +} + +static int sp_pll_enable(struct clk_hw *hw) +{ + struct sp_pll *clk = to_sp_pll(hw); + unsigned long flags; + + spin_lock_irqsave(clk->lock, flags); + clk_writel(BIT(clk->pd_bit + 16) | BIT(clk->pd_bit), clk->reg); /* power up */ + spin_unlock_irqrestore(clk->lock, flags); + + return 0; +} + +static void sp_pll_disable(struct clk_hw *hw) +{ + struct sp_pll *clk = to_sp_pll(hw); + unsigned long flags; + + spin_lock_irqsave(clk->lock, flags); + clk_writel(BIT(clk->pd_bit + 16), clk->reg); /* power down */ + spin_unlock_irqrestore(clk->lock, flags); +} + +static int sp_pll_is_enabled(struct clk_hw *hw) +{ + struct sp_pll *clk = to_sp_pll(hw); + + return clk_readl(clk->reg) & BIT(clk->pd_bit); +} + +static const struct clk_ops sp_pll_ops = { + .enable = sp_pll_enable, + .disable = sp_pll_disable, + .is_enabled = sp_pll_is_enabled, + .round_rate = sp_pll_round_rate, + .recalc_rate = sp_pll_recalc_rate, + .set_rate = sp_pll_set_rate +}; + +static const struct clk_ops sp_pll_sub_ops = { + .enable = sp_pll_enable, + .disable = sp_pll_disable, + .is_enabled = sp_pll_is_enabled, + .recalc_rate = sp_pll_recalc_rate, +}; + +struct clk *clk_register_sp_pll(const char *name, const char *parent, + void __iomem *reg, int pd_bit, int bp_bit, + unsigned long brate, int shift, int width, + spinlock_t *lock) +{ + struct sp_pll *pll; + struct clk *clk; + struct clk_init_data initd = { + .name = name, + .parent_names = &parent, + .ops = (bp_bit >= 0) ? &sp_pll_ops : &sp_pll_sub_ops, + .num_parents = 1, + .flags = CLK_IGNORE_UNUSED + }; + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) + return ERR_PTR(-ENOMEM); + + if (reg == PLLSYS_CTL) + initd.flags |= CLK_IS_CRITICAL; + + pll->hw.init = &initd; + pll->reg = reg; + pll->pd_bit = pd_bit; + pll->bp_bit = bp_bit; + pll->brate = brate; + pll->div_shift = shift; + pll->div_width = width; + pll->lock = lock; + + clk = clk_register(NULL, &pll->hw); + if (WARN_ON(IS_ERR(clk))) { + kfree(pll); + } else { + pr_info("%-20s%lu\n", name, clk_get_rate(clk)); + clk_register_clkdev(clk, NULL, name); + } + + return clk; +} + +static void __init sp_clk_setup(struct device_node *np) +{ + int i, j; + + moon_regs = of_iomap(np, 0); + if (WARN_ON(!moon_regs)) + return; /* -ENXIO */ + + /* PLL_A */ + clks[PLL_A] = clk_register_sp_pll("plla", EXTCLK, + PLLA_CTL, 11, 12, 27000000, 0, DIV_A, &plla_lock); + + /* PLL_E */ + clks[PLL_E] = clk_register_sp_pll("plle", EXTCLK, + PLLE_CTL, 6, 2, 50000000, 0, 0, &plle_lock); + clks[PLL_E_2P5] = clk_register_sp_pll("plle_2p5", "plle", + PLLE_CTL, 13, -1, 2500000, 0, 0, &plle_lock); + clks[PLL_E_25] = clk_register_sp_pll("plle_25", "plle", + PLLE_CTL, 12, -1, 25000000, 0, 0, &plle_lock); + clks[PLL_E_112P5] = clk_register_sp_pll("plle_112p5", "plle", + PLLE_CTL, 11, -1, 112500000, 0, 0, &plle_lock); + + /* PLL_F */ + clks[PLL_F] = clk_register_sp_pll("pllf", EXTCLK, + PLLF_CTL, 0, 10, 13500000, 1, 4, &pllf_lock); + + /* PLL_TV */ + clks[PLL_TV] = clk_register_sp_pll("plltv", EXTCLK, + PLLTV_CTL, 0, 15, 27000000, 0, DIV_TV, &plltv_lock); + clks[PLL_TV_A] = clk_register_divider(NULL, "plltv_a", "plltv", 0, + PLLTV_CTL + 4, 5, 1, + CLK_DIVIDER_POWER_OF_TWO, &plltv_lock); + clk_register_clkdev(clks[PLL_TV_A], NULL, "plltv_a"); + + /* PLL_SYS */ + clks[PLL_SYS] = clk_register_sp_pll("pllsys", EXTCLK, + PLLSYS_CTL, 10, 9, 13500000, 0, 4, &pllsys_lock); + + /* gates */ + for (i = 0; i < ARRAY_SIZE(gates); i++) { + char s[10]; + + j = gates[i] & 0xffff; + sprintf(s, "clken%02x", j); + clks[j] = clk_register_gate(NULL, s, parents[gates[i] >> 16], CLK_IGNORE_UNUSED, + clk_regs + (j >> 4) * 4, j & 0x0f, + CLK_GATE_HIWORD_MASK, NULL); + } + + clk_data.clks = clks; + clk_data.clk_num = ARRAY_SIZE(clks); + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); +} + +CLK_OF_DECLARE(sp_clkc, "sunplus,sp7021-clkc", sp_clk_setup); + +MODULE_AUTHOR("Qin Jian "); +MODULE_DESCRIPTION("Sunplus SP7021 Clock Driver"); +MODULE_LICENSE("GPL v2"); From patchwork Fri Dec 3 07:34:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qin Jian X-Patchwork-Id: 12654455 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A3583C433F5 for ; Fri, 3 Dec 2021 07:44:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350954AbhLCHrW (ORCPT ); Fri, 3 Dec 2021 02:47:22 -0500 Received: from [113.204.237.245] ([113.204.237.245]:44262 "EHLO test.cqplus1.com" rhost-flags-FAIL-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1379030AbhLCHqV (ORCPT ); Fri, 3 Dec 2021 02:46:21 -0500 X-MailGates: (flag:4,DYNAMIC,BADHELO,RELAY,NOHOST:PASS)(compute_score:DE LIVER,40,3) Received: from 172.28.114.216 by cqmailgates with MailGates ESMTP Server V5.0(21484:0:AUTH_RELAY) (envelope-from ); Fri, 03 Dec 2021 15:35:52 +0800 (CST) From: Qin Jian To: robh+dt@kernel.org Cc: mturquette@baylibre.com, sboyd@kernel.org, tglx@linutronix.de, maz@kernel.org, p.zabel@pengutronix.de, linux@armlinux.org.uk, broonie@kernel.org, arnd@arndb.de, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, wells.lu@sunplus.com, Qin Jian , Rob Herring Subject: [PATCH v5 07/10] dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt controller Date: Fri, 3 Dec 2021 15:34:24 +0800 Message-Id: X-Mailer: git-send-email 2.33.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org Add documentation to describe Sunplus SP7021 interrupt controller bindings. Reviewed-by: Rob Herring Signed-off-by: Qin Jian --- .../sunplus,sp7021-intc.yaml | 62 +++++++++++++++++++ MAINTAINERS | 1 + 2 files changed, 63 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml diff --git a/Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml new file mode 100644 index 000000000..5daeab63c --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (C) Sunplus Co., Ltd. 2021 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interrupt-controller/sunplus,sp7021-intc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Sunplus SP7021 SoC Interrupt Controller Device Tree Bindings + +maintainers: + - Qin Jian + +properties: + compatible: + items: + - const: sunplus,sp7021-intc + + interrupt-controller: true + + "#interrupt-cells": + const: 2 + description: + The first cell is the IRQ number, the second cell is the trigger + type as defined in interrupt.txt in this directory. + + reg: + maxItems: 2 + description: + Specifies base physical address(s) and size of the controller regs. + The 1st region include type/polarity/priority/mask regs. + The 2nd region include clear/masked_ext0/masked_ext1/group regs. + + interrupts: + maxItems: 2 + description: + EXT_INT0 & EXT_INT1, 2 interrupts references to primary interrupt + controller. + +required: + - compatible + - interrupt-controller + - "#interrupt-cells" + - reg + - interrupts + +additionalProperties: false + +examples: + - | + #include + + intc: interrupt-controller@9c000780 { + compatible = "sunplus,sp7021-intc"; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x9c000780 0x80>, <0x9c000a80 0x80>; + interrupt-parent = <&gic>; + interrupts = , /* EXT_INT0 */ + ; /* EXT_INT1 */ + }; + +... diff --git a/MAINTAINERS b/MAINTAINERS index 5069f552f..6b3bbe021 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2662,6 +2662,7 @@ S: Maintained W: https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview F: Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml F: Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml +F: Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml F: Documentation/devicetree/bindings/reset/sunplus,reset.yaml F: drivers/clk/clk-sp7021.c F: drivers/reset/reset-sunplus.c From patchwork Fri Dec 3 07:34:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qin Jian X-Patchwork-Id: 12654461 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4EDD6C433F5 for ; Fri, 3 Dec 2021 07:44:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1378990AbhLCHr0 (ORCPT ); Fri, 3 Dec 2021 02:47:26 -0500 Received: from [113.204.237.245] ([113.204.237.245]:44268 "EHLO test.cqplus1.com" rhost-flags-FAIL-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1379034AbhLCHqV (ORCPT ); Fri, 3 Dec 2021 02:46:21 -0500 X-MailGates: (flag:4,DYNAMIC,BADHELO,RELAY,NOHOST:PASS)(compute_score:DE LIVER,40,3) Received: from 172.28.114.216 by cqmailgates with MailGates ESMTP Server V5.0(21484:0:AUTH_RELAY) (envelope-from ); Fri, 03 Dec 2021 15:35:52 +0800 (CST) From: Qin Jian To: robh+dt@kernel.org Cc: mturquette@baylibre.com, sboyd@kernel.org, tglx@linutronix.de, maz@kernel.org, p.zabel@pengutronix.de, linux@armlinux.org.uk, broonie@kernel.org, arnd@arndb.de, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, wells.lu@sunplus.com, Qin Jian Subject: [PATCH v5 08/10] irqchip: Add Sunplus SP7021 interrupt controller driver Date: Fri, 3 Dec 2021 15:34:25 +0800 Message-Id: X-Mailer: git-send-email 2.33.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org Add interrupt controller driver for Sunplus SP7021 SoC. This is the interrupt controller in P-chip which collects all interrupt sources in P-chip and routes them to parent interrupt controller in C-chip. Signed-off-by: Qin Jian --- MAINTAINERS | 1 + drivers/irqchip/Kconfig | 9 + drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-sp7021-intc.c | 284 ++++++++++++++++++++++++++++++ 4 files changed, 295 insertions(+) create mode 100644 drivers/irqchip/irq-sp7021-intc.c diff --git a/MAINTAINERS b/MAINTAINERS index 6b3bbe021..febbd97bf 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2665,6 +2665,7 @@ F: Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml F: Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml F: Documentation/devicetree/bindings/reset/sunplus,reset.yaml F: drivers/clk/clk-sp7021.c +F: drivers/irqchip/irq-sp7021-intc.c F: drivers/reset/reset-sunplus.c F: include/dt-bindings/clock/sp-sp7021.h F: include/dt-bindings/reset/sp-sp7021.h diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index aca7b595c..b9429b8d0 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -602,4 +602,13 @@ config APPLE_AIC Support for the Apple Interrupt Controller found on Apple Silicon SoCs, such as the M1. +config SUNPLUS_SP7021_INTC + bool "Sunplus SP7021 interrupt controller" + help + Support for the Sunplus SP7021 Interrupt Controller IP core. + SP7021 SoC has 2 Chips: C-Chip & P-Chip. This is used as a + chained controller, routing all interrupt source in P-Chip to + the primary controller on C-Chip. + This is selected automatically by platform config. + endmenu diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index f88cbf36a..75411f654 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -116,3 +116,4 @@ obj-$(CONFIG_MACH_REALTEK_RTL) += irq-realtek-rtl.o obj-$(CONFIG_WPCM450_AIC) += irq-wpcm450-aic.o obj-$(CONFIG_IRQ_IDT3243X) += irq-idt3243x.o obj-$(CONFIG_APPLE_AIC) += irq-apple-aic.o +obj-$(CONFIG_SUNPLUS_SP7021_INTC) += irq-sp7021-intc.o diff --git a/drivers/irqchip/irq-sp7021-intc.c b/drivers/irqchip/irq-sp7021-intc.c new file mode 100644 index 000000000..beabc64d5 --- /dev/null +++ b/drivers/irqchip/irq-sp7021-intc.c @@ -0,0 +1,284 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Copyright (C) Sunplus Technology Co., Ltd. + * All rights reserved. + */ +#include +#include +#include +#include +#include +#include +#include + +#define SP_INTC_HWIRQ_MIN 0 +#define SP_INTC_HWIRQ_MAX 223 + +#define SP_INTC_NR_IRQS (SP_INTC_HWIRQ_MAX - SP_INTC_HWIRQ_MIN + 1) +#define SP_INTC_NR_GROUPS DIV_ROUND_UP(SP_INTC_NR_IRQS, 32) +#define SP_INTC_REG_SIZE (SP_INTC_NR_GROUPS * 4) + +/* REG_GROUP_0 regs */ +#define REG_INTR_TYPE (sp_intc.g0) +#define REG_INTR_POLARITY (REG_INTR_TYPE + SP_INTC_REG_SIZE) +#define REG_INTR_PRIORITY (REG_INTR_POLARITY + SP_INTC_REG_SIZE) +#define REG_INTR_MASK (REG_INTR_PRIORITY + SP_INTC_REG_SIZE) + +/* REG_GROUP_1 regs */ +#define REG_INTR_CLEAR (sp_intc.g1) +#define REG_MASKED_EXT1 (REG_INTR_CLEAR + SP_INTC_REG_SIZE) +#define REG_MASKED_EXT0 (REG_MASKED_EXT1 + SP_INTC_REG_SIZE) +#define REG_INTR_GROUP (REG_INTR_CLEAR + 31 * 4) + +#define GROUP_MASK (BIT(SP_INTC_NR_GROUPS) - 1) +#define GROUP_SHIFT_EXT1 (0) +#define GROUP_SHIFT_EXT0 (8) + +/* + * When GPIO_INT0~7 set to edge trigger, doesn't work properly. + * WORKAROUND: change it to level trigger, and toggle the polarity + * at ACK/Handler to make the HW work. + */ +#define GPIO_INT0_HWIRQ 120 +#define GPIO_INT7_HWIRQ 127 +#define IS_GPIO_INT(irq) \ +({ \ + u32 i = irq; \ + (i >= GPIO_INT0_HWIRQ) && (i <= GPIO_INT7_HWIRQ); \ +}) + +/* index of states */ +enum { + _IS_EDGE = 0, + _IS_LOW, + _IS_ACTIVE +}; + +#define STATE_BIT(irq, idx) (((irq) - GPIO_INT0_HWIRQ) * 3 + (idx)) +#define ASSIGN_STATE(irq, idx, v) assign_bit(STATE_BIT(irq, idx), sp_intc.states, v) +#define TEST_STATE(irq, idx) test_bit(STATE_BIT(irq, idx), sp_intc.states) + +static struct sp_intctl { + /* + * REG_GROUP_0: include type/polarity/priority/mask regs. + * REG_GROUP_1: include clear/masked_ext0/masked_ext1/group regs. + */ + void __iomem *g0; // REG_GROUP_0 base + void __iomem *g1; // REG_GROUP_1 base + + struct irq_domain *domain; + raw_spinlock_t lock; + + /* + * store GPIO_INT states + * each interrupt has 3 states: is_edge, is_low, is_active + */ + DECLARE_BITMAP(states, (GPIO_INT7_HWIRQ - GPIO_INT0_HWIRQ + 1) * 3); +} sp_intc; + +static struct irq_chip sp_intc_chip; + +static void sp_intc_assign_bit(u32 hwirq, void __iomem *base, bool value) +{ + unsigned long flags; + + raw_spin_lock_irqsave(&sp_intc.lock, flags); + __assign_bit(hwirq, base, value); + raw_spin_unlock_irqrestore(&sp_intc.lock, flags); +} + +static void sp_intc_ack_irq(struct irq_data *d) +{ + u32 hwirq = d->hwirq; + + if (unlikely(IS_GPIO_INT(hwirq) && TEST_STATE(hwirq, _IS_EDGE))) { // WORKAROUND + sp_intc_assign_bit(hwirq, REG_INTR_POLARITY, !TEST_STATE(hwirq, _IS_LOW)); + ASSIGN_STATE(hwirq, _IS_ACTIVE, true); + } + + sp_intc_assign_bit(hwirq, REG_INTR_CLEAR, 1); +} + +static void sp_intc_mask_irq(struct irq_data *d) +{ + sp_intc_assign_bit(d->hwirq, REG_INTR_MASK, 0); +} + +static void sp_intc_unmask_irq(struct irq_data *d) +{ + sp_intc_assign_bit(d->hwirq, REG_INTR_MASK, 1); +} + +static int sp_intc_set_type(struct irq_data *d, unsigned int type) +{ + u32 hwirq = d->hwirq; + bool is_edge = !(type & IRQ_TYPE_LEVEL_MASK); + bool is_low = (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_EDGE_FALLING); + + irq_set_handler_locked(d, is_edge ? handle_edge_irq : handle_level_irq); + + if (unlikely(IS_GPIO_INT(hwirq) && is_edge)) { // WORKAROUND + /* store states */ + ASSIGN_STATE(hwirq, _IS_EDGE, is_edge); + ASSIGN_STATE(hwirq, _IS_LOW, is_low); + ASSIGN_STATE(hwirq, _IS_ACTIVE, false); + /* change to level */ + is_edge = false; + } + + sp_intc_assign_bit(hwirq, REG_INTR_TYPE, is_edge); + sp_intc_assign_bit(hwirq, REG_INTR_POLARITY, is_low); + + return 0; +} + +static int sp_intc_get_ext_irq(int ext_num) +{ + void __iomem *base = ext_num ? REG_MASKED_EXT1 : REG_MASKED_EXT0; + u32 shift = ext_num ? GROUP_SHIFT_EXT1 : GROUP_SHIFT_EXT0; + u32 groups; + u32 pending_group; + u32 group; + u32 pending_irq; + + groups = readl_relaxed(REG_INTR_GROUP); + pending_group = (groups >> shift) & GROUP_MASK; + if (!pending_group) + return -1; + + group = fls(pending_group) - 1; + pending_irq = readl_relaxed(base + group * 4); + if (!pending_irq) + return -1; + + return (group * 32) + fls(pending_irq) - 1; +} + +static void sp_intc_handle_ext_cascaded(struct irq_desc *desc) +{ + struct irq_chip *chip = irq_desc_get_chip(desc); + int ext_num = (int)irq_desc_get_handler_data(desc); + int hwirq; + + chained_irq_enter(chip, desc); + + while ((hwirq = sp_intc_get_ext_irq(ext_num)) >= 0) { + if (unlikely(IS_GPIO_INT(hwirq) && TEST_STATE(hwirq, _IS_ACTIVE))) { // WORKAROUND + ASSIGN_STATE(hwirq, _IS_ACTIVE, false); + sp_intc_assign_bit(hwirq, REG_INTR_POLARITY, TEST_STATE(hwirq, _IS_LOW)); + } else { + generic_handle_domain_irq(sp_intc.domain, hwirq); + } + } + + chained_irq_exit(chip, desc); +} + +#ifdef CONFIG_SMP +static int sp_intc_set_affinity(struct irq_data *d, const struct cpumask *mask, bool force) +{ + return -EINVAL; +} +#endif + +static struct irq_chip sp_intc_chip = { + .name = "sp_intc", + .irq_ack = sp_intc_ack_irq, + .irq_mask = sp_intc_mask_irq, + .irq_unmask = sp_intc_unmask_irq, + .irq_set_type = sp_intc_set_type, +#ifdef CONFIG_SMP + .irq_set_affinity = sp_intc_set_affinity, +#endif +}; + +static int sp_intc_irq_domain_map(struct irq_domain *domain, + unsigned int irq, irq_hw_number_t hwirq) +{ + irq_set_chip_and_handler(irq, &sp_intc_chip, handle_level_irq); + irq_set_chip_data(irq, &sp_intc_chip); + irq_set_noprobe(irq); + + return 0; +} + +static const struct irq_domain_ops sp_intc_dm_ops = { + .xlate = irq_domain_xlate_twocell, + .map = sp_intc_irq_domain_map, +}; + +static int sp_intc_irq_map(struct device_node *node, int i) +{ + unsigned int irq; + + irq = irq_of_parse_and_map(node, i); + if (!irq) + return -ENOENT; + + irq_set_chained_handler_and_data(irq, sp_intc_handle_ext_cascaded, (void *)i); + + return 0; +} + +void sp_intc_set_ext(u32 hwirq, int ext_num) +{ + sp_intc_assign_bit(hwirq, REG_INTR_PRIORITY, !ext_num); +} +EXPORT_SYMBOL_GPL(sp_intc_set_ext); + +int __init sp_intc_init_dt(struct device_node *node, struct device_node *parent) +{ + int i, ret; + + sp_intc.g0 = of_iomap(node, 0); + if (!sp_intc.g0) + return -ENXIO; + + sp_intc.g1 = of_iomap(node, 1); + if (!sp_intc.g1) { + ret = -ENXIO; + goto out_unmap0; + } + + ret = sp_intc_irq_map(node, 0); // EXT_INT0 + if (ret) + goto out_unmap1; + + ret = sp_intc_irq_map(node, 1); // EXT_INT1 + if (ret) + goto out_unmap1; + + /* initial regs */ + for (i = 0; i < SP_INTC_NR_GROUPS; i++) { + /* all mask */ + writel_relaxed(0, REG_INTR_MASK + i * 4); + /* all edge */ + writel_relaxed(~0, REG_INTR_TYPE + i * 4); + /* all high-active */ + writel_relaxed(0, REG_INTR_POLARITY + i * 4); + /* all EXT_INT0 */ + writel_relaxed(~0, REG_INTR_PRIORITY + i * 4); + /* all clear */ + writel_relaxed(~0, REG_INTR_CLEAR + i * 4); + } + + sp_intc.domain = irq_domain_add_linear(node, SP_INTC_NR_IRQS, + &sp_intc_dm_ops, &sp_intc); + if (!sp_intc.domain) { + ret = -ENOMEM; + goto out_unmap1; + } + + raw_spin_lock_init(&sp_intc.lock); + + return 0; + +out_unmap1: + iounmap(sp_intc.g1); +out_unmap0: + iounmap(sp_intc.g0); + + return ret; +} + +IRQCHIP_DECLARE(sp_intc, "sunplus,sp7021-intc", sp_intc_init_dt); From patchwork Fri Dec 3 07:34:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qin Jian X-Patchwork-Id: 12654459 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7E10FC433FE for ; Fri, 3 Dec 2021 07:44:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1378942AbhLCHr0 (ORCPT ); Fri, 3 Dec 2021 02:47:26 -0500 Received: from [113.204.237.245] ([113.204.237.245]:44274 "EHLO test.cqplus1.com" rhost-flags-FAIL-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1379033AbhLCHqV (ORCPT ); Fri, 3 Dec 2021 02:46:21 -0500 X-MailGates: (flag:4,DYNAMIC,BADHELO,RELAY,NOHOST:PASS)(compute_score:DE LIVER,40,3) Received: from 172.28.114.216 by cqmailgates with MailGates ESMTP Server V5.0(21484:0:AUTH_RELAY) (envelope-from ); Fri, 03 Dec 2021 15:35:52 +0800 (CST) From: Qin Jian To: robh+dt@kernel.org Cc: mturquette@baylibre.com, sboyd@kernel.org, tglx@linutronix.de, maz@kernel.org, p.zabel@pengutronix.de, linux@armlinux.org.uk, broonie@kernel.org, arnd@arndb.de, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, wells.lu@sunplus.com, Qin Jian Subject: [PATCH v5 09/10] ARM: sunplus: Add initial support for Sunplus SP7021 SoC Date: Fri, 3 Dec 2021 15:34:26 +0800 Message-Id: X-Mailer: git-send-email 2.33.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org This patch aims to add an initial support for Sunplus SP7021 SoC. Signed-off-by: Qin Jian --- MAINTAINERS | 1 + arch/arm/Kconfig | 18 ++++++++++++++++++ arch/arm/Makefile | 2 ++ arch/arm/mach-sunplus/Kconfig | 20 ++++++++++++++++++++ arch/arm/mach-sunplus/Makefile | 9 +++++++++ arch/arm/mach-sunplus/Makefile.boot | 3 +++ arch/arm/mach-sunplus/sp7021.c | 16 ++++++++++++++++ 7 files changed, 69 insertions(+) create mode 100644 arch/arm/mach-sunplus/Kconfig create mode 100644 arch/arm/mach-sunplus/Makefile create mode 100644 arch/arm/mach-sunplus/Makefile.boot create mode 100644 arch/arm/mach-sunplus/sp7021.c diff --git a/MAINTAINERS b/MAINTAINERS index febbd97bf..0ae537a41 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2664,6 +2664,7 @@ F: Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml F: Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml F: Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml F: Documentation/devicetree/bindings/reset/sunplus,reset.yaml +F: arch/arm/mach-sunplus/ F: drivers/clk/clk-sp7021.c F: drivers/irqchip/irq-sp7021-intc.c F: drivers/reset/reset-sunplus.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 59baf6c13..b128ef4ee 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -487,6 +487,22 @@ config ARCH_S3C24XX (), the IPAQ 1940 or the Samsung SMDK2410 development board (and derivatives). +config ARCH_SUNPLUS + bool "Sunplus SoCs" + select CLKSRC_OF + select COMMON_CLK + select GENERIC_CLOCKEVENTS + select GENERIC_IRQ_CHIP + select GENERIC_IRQ_MULTI_HANDLER + select USE_OF + select RTC_CLASS + select RESET_SUNPLUS + help + Support for Sunplus SoC family: SP7021 and succeeding SoC-based systems, + such as the Banana Pi BPI-F2S development board (and derivatives). + () + () + config ARCH_OMAP1 bool "TI OMAP1" depends on MMU @@ -689,6 +705,8 @@ source "arch/arm/mach-sti/Kconfig" source "arch/arm/mach-stm32/Kconfig" +source "arch/arm/mach-sunplus/Kconfig" + source "arch/arm/mach-sunxi/Kconfig" source "arch/arm/mach-tegra/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 847c31e7c..cac95a950 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -152,6 +152,7 @@ textofs-$(CONFIG_ARCH_MSM8X60) := 0x00208000 textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000 textofs-$(CONFIG_ARCH_MESON) := 0x00208000 textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000 +textofs-$(CONFIG_ARCH_SUNPLUS) := 0x00308000 # Machine directory name. This list is sorted alphanumerically # by CONFIG_* macro name. @@ -212,6 +213,7 @@ machine-$(CONFIG_ARCH_RENESAS) += shmobile machine-$(CONFIG_ARCH_INTEL_SOCFPGA) += socfpga machine-$(CONFIG_ARCH_STI) += sti machine-$(CONFIG_ARCH_STM32) += stm32 +machine-$(CONFIG_ARCH_SUNPLUS) += sunplus machine-$(CONFIG_ARCH_SUNXI) += sunxi machine-$(CONFIG_ARCH_TEGRA) += tegra machine-$(CONFIG_ARCH_U8500) += ux500 diff --git a/arch/arm/mach-sunplus/Kconfig b/arch/arm/mach-sunplus/Kconfig new file mode 100644 index 000000000..81ef4d026 --- /dev/null +++ b/arch/arm/mach-sunplus/Kconfig @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) + +config SOC_SP7021 + bool "Sunplus SP7021 SoC support" + default y + select CPU_V7 + select ARM_GIC + select SUNPLUS_SP7021_INTC + select HAVE_SMP + select ARM_PSCI + select COMMON_CLK_SP7021 + select PINCTRL + select PINCTRL_SPPCTL + select OF_OVERLAY + select GPIOLIB + help + Support for Sunplus SP7021 SoC. It is based on ARM 4-core + Cortex-A7 with various peripherals (ex: I2C, SPI, SDIO, + Ethernet and etc.), FPGA interface, chip-to-chip bus. + It is designed for industrial control. diff --git a/arch/arm/mach-sunplus/Makefile b/arch/arm/mach-sunplus/Makefile new file mode 100644 index 000000000..c902580a7 --- /dev/null +++ b/arch/arm/mach-sunplus/Makefile @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Makefile for the linux kernel. +# + +# Object file lists. + +obj-$(CONFIG_SOC_SP7021) += sp7021.o + diff --git a/arch/arm/mach-sunplus/Makefile.boot b/arch/arm/mach-sunplus/Makefile.boot new file mode 100644 index 000000000..401c30840 --- /dev/null +++ b/arch/arm/mach-sunplus/Makefile.boot @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +zreladdr-$(CONFIG_ARCH_SUNPLUS) := 0x00308000 diff --git a/arch/arm/mach-sunplus/sp7021.c b/arch/arm/mach-sunplus/sp7021.c new file mode 100644 index 000000000..774d0a5bd --- /dev/null +++ b/arch/arm/mach-sunplus/sp7021.c @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Copyright (C) Sunplus Technology Co., Ltd. + * All rights reserved. + */ +#include +#include + +static const char *sp7021_compat[] __initconst = { + "sunplus,sp7021", + NULL +}; + +DT_MACHINE_START(SP7021_DT, "SP7021") + .dt_compat = sp7021_compat, +MACHINE_END From patchwork Fri Dec 3 07:34:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qin Jian X-Patchwork-Id: 12654451 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9E64BC433EF for ; Fri, 3 Dec 2021 07:43:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350994AbhLCHrP (ORCPT ); Fri, 3 Dec 2021 02:47:15 -0500 Received: from [113.204.237.245] ([113.204.237.245]:44252 "EHLO test.cqplus1.com" rhost-flags-FAIL-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1379003AbhLCHqU (ORCPT ); Fri, 3 Dec 2021 02:46:20 -0500 X-MailGates: (flag:4,DYNAMIC,BADHELO,RELAY,NOHOST:PASS)(compute_score:DE LIVER,40,3) Received: from 172.28.114.216 by cqmailgates with MailGates ESMTP Server V5.0(21484:0:AUTH_RELAY) (envelope-from ); Fri, 03 Dec 2021 15:35:52 +0800 (CST) From: Qin Jian To: robh+dt@kernel.org Cc: mturquette@baylibre.com, sboyd@kernel.org, tglx@linutronix.de, maz@kernel.org, p.zabel@pengutronix.de, linux@armlinux.org.uk, broonie@kernel.org, arnd@arndb.de, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, wells.lu@sunplus.com, Qin Jian Subject: [PATCH v5 10/10] ARM: sp7021_defconfig: Add Sunplus SP7021 defconfig Date: Fri, 3 Dec 2021 15:34:27 +0800 Message-Id: X-Mailer: git-send-email 2.33.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org Add generic Sunplus SP7021 based board defconfig Signed-off-by: Qin Jian --- MAINTAINERS | 1 + arch/arm/configs/sp7021_defconfig | 178 ++++++++++++++++++++++++++++++ 2 files changed, 179 insertions(+) create mode 100644 arch/arm/configs/sp7021_defconfig diff --git a/MAINTAINERS b/MAINTAINERS index 0ae537a41..9340f8760 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2664,6 +2664,7 @@ F: Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml F: Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml F: Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml F: Documentation/devicetree/bindings/reset/sunplus,reset.yaml +F: arch/arm/configs/sp7021_*defconfig F: arch/arm/mach-sunplus/ F: drivers/clk/clk-sp7021.c F: drivers/irqchip/irq-sp7021-intc.c diff --git a/arch/arm/configs/sp7021_defconfig b/arch/arm/configs/sp7021_defconfig new file mode 100644 index 000000000..249fe779e --- /dev/null +++ b/arch/arm/configs/sp7021_defconfig @@ -0,0 +1,178 @@ +CONFIG_DEFAULT_HOSTNAME="SP7021-Ev" +CONFIG_SYSVIPC=y +CONFIG_USELIB=y +CONFIG_NO_HZ_IDLE=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_PREEMPT=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="../rootfs/initramfs/disk/ ../rootfs/initramfs/initramfs.devnodes" +CONFIG_INITRAMFS_ROOT_UID=-1 +CONFIG_INITRAMFS_ROOT_GID=-1 +# CONFIG_RD_GZIP is not set +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +# CONFIG_RD_LZ4 is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +# CONFIG_FHANDLE is not set +CONFIG_KALLSYMS_ALL=y +CONFIG_EMBEDDED=y +CONFIG_PERF_EVENTS=y +CONFIG_SLAB=y +CONFIG_ARCH_SUNPLUS=y +# CONFIG_VDSO is not set +CONFIG_SMP=y +CONFIG_HAVE_ARM_ARCH_TIMER=y +CONFIG_THUMB2_KERNEL=y +CONFIG_HIGHMEM=y +# CONFIG_HIGHPTE is not set +CONFIG_FORCE_MAX_ZONEORDER=12 +CONFIG_ZBOOT_ROM_TEXT=0x98307000 +CONFIG_ZBOOT_ROM_BSS=0x03400000 +CONFIG_CMDLINE="root=/dev/ram rw init=/init console=ttyS0,115200 earlyprintk mem=512M@0x0" +CONFIG_AUTO_ZRELADDR=y +CONFIG_VFP=y +CONFIG_NEON=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_PACKET_DIAG=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=m +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +CONFIG_NETLINK_DIAG=y +CONFIG_CAN=y +CONFIG_CFG80211=m +CONFIG_CFG80211_WEXT=y +CONFIG_MAC80211=m +CONFIG_CAIF=y +CONFIG_CEPH_LIB=y +CONFIG_CEPH_LIB_USE_DNS_RESOLVER=y +CONFIG_UEVENT_HELPER=y +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_NETDEVICES=y +# CONFIG_NET_VENDOR_ALACRITECH is not set +# CONFIG_NET_VENDOR_AMAZON is not set +# CONFIG_NET_VENDOR_AQUANTIA is not set +# CONFIG_NET_VENDOR_ARC is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_CADENCE is not set +# CONFIG_NET_VENDOR_CAVIUM is not set +# CONFIG_NET_VENDOR_CIRRUS is not set +# CONFIG_NET_VENDOR_CORTINA is not set +# CONFIG_NET_VENDOR_EZCHIP is not set +# CONFIG_NET_VENDOR_FARADAY is not set +# CONFIG_NET_VENDOR_GOOGLE is not set +# CONFIG_NET_VENDOR_HISILICON is not set +# CONFIG_NET_VENDOR_HUAWEI is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set +# CONFIG_NET_VENDOR_MICROSEMI is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_NETRONOME is not set +# CONFIG_NET_VENDOR_NI is not set +# CONFIG_NET_VENDOR_PENSANDO is not set +# CONFIG_NET_VENDOR_QUALCOMM is not set +# CONFIG_NET_VENDOR_RENESAS is not set +# CONFIG_NET_VENDOR_ROCKER is not set +# CONFIG_NET_VENDOR_SAMSUNG is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SOLARFLARE is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_SOCIONEXT is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_SYNOPSYS is not set +# CONFIG_NET_VENDOR_VIA is not set +# CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_NET_VENDOR_XILINX is not set +CONFIG_NET_VENDOR_SUNPLUS=y +CONFIG_INPUT_POLLDEV=y +CONFIG_INPUT_SPARSEKMAP=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_MISC=y +CONFIG_INPUT_UINPUT=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_LEGACY_PTYS is not set +CONFIG_SERIAL_SUNPLUS=y +CONFIG_SERIAL_SUNPLUS_CONSOLE=y +# CONFIG_HW_RANDOM is not set +# CONFIG_HWMON is not set +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_SUPPORT_FILTER=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_PLATFORM_SUPPORT=y +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_USB_VIDEO_CLASS=y +CONFIG_FB=y +CONFIG_FB_SP7021=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER=y +CONFIG_HIDRAW=y +CONFIG_GEMINI_USB=y +CONFIG_USB_USE_PLATFORM_RESOURCE=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_SUNPLUS_USB_PHY=y +CONFIG_USB_SUNPLUS_OTG=y +CONFIG_USB_GADGET=y +CONFIG_USB_DEVICE_LOSE_PACKET_AFTER_SET_INTERFACE_WORKAROUND=y +CONFIG_USB_DEVICE_EP11_NOT_AUTO_SWITCH_WORKAROUND=y +CONFIG_USB_GADGET_SUNPLUS=y +CONFIG_USB_ZERO=y +CONFIG_MMC=y +CONFIG_SP_EMMC=m +CONFIG_STAGING=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_PWM=y +CONFIG_PWM_SP7021=y +CONFIG_RESET_CONTROLLER=y +CONFIG_EXT2_FS=y +# CONFIG_DNOTIFY is not set +CONFIG_FANOTIFY=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_IOCHARSET="utf8" +CONFIG_EXFAT_FS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +# CONFIG_MISC_FILESYSTEMS is not set +CONFIG_NFS_FS=y +CONFIG_NFS_V4=y +CONFIG_ROOT_NFS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_UTF8=y +CONFIG_CRC16=y +CONFIG_PRINTK_TIME=y +CONFIG_DYNAMIC_DEBUG=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_FS=y +# CONFIG_SCHED_DEBUG is not set +CONFIG_SCHEDSTATS=y +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_FTRACE is not set +CONFIG_DEBUG_USER=y