Merge branch 'nuvoton/newsoc' into arm/newsoc

Merge the new SoC support from Tomer Maimon:
 "This patchset  adds initial support for the Nuvoton
  Arbel NPCM8XX Board Management controller (BMC) SoC family.

  The Nuvoton Arbel NPCM8XX SoC is a fourth-generation BMC.
  The NPCM8XX computing subsystem comprises a quadcore ARM
  Cortex A35 ARM-V8 architecture.

  This patchset adds minimal architecture and drivers such as:
  Clocksource, Clock, Reset, and WD.

  Some of the Arbel NPCM8XX peripherals are based on Poleg NPCM7XX.

  This patchset was tested on the Arbel NPCM8XX evaluation board."

I'm leaving out the clk controller driver, which is still under
review.

* nuvoton/newsoc:
  arm64: defconfig: Add Nuvoton NPCM family support
  arm64: dts: nuvoton: Add initial NPCM845 EVB device tree
  arm64: dts: nuvoton: Add initial NPCM8XX device tree
  arm64: npcm: Add support for Nuvoton NPCM8XX BMC SoC
  dt-bindings: arm: npcm: Add nuvoton,npcm845 GCR compatible string
  dt-bindings: arm: npcm: Add nuvoton,npcm845 compatible string
  dt-bindings: arm: npcm: Add maintainer
  reset: npcm: Add NPCM8XX support
  dt-bindings: reset: npcm: Add support for NPCM8XX
  reset: npcm: using syscon instead of device data
  ARM: dts: nuvoton: add reset syscon property
  dt-bindings: reset: npcm: add GCR syscon property
  dt-binding: clk: npcm845: Add binding for Nuvoton NPCM8XX Clock
  dt-bindings: watchdog: npcm: Add npcm845 compatible string
  dt-bindings: timer: npcm: Add npcm845 compatible string
This commit is contained in:
Arnd Bergmann 2022-07-19 15:42:00 +02:00
commit 2d0f3f13a9
17 changed files with 589 additions and 36 deletions

View File

@ -8,6 +8,7 @@ title: NPCM Platforms Device Tree Bindings
maintainers:
- Jonathan Neuschäfer <j.neuschaefer@gmx.net>
- Tomer Maimon <tmaimon77@gmail.com>
properties:
$nodename:
@ -26,4 +27,10 @@ properties:
- nuvoton,npcm750-evb # NPCM750 evaluation board
- const: nuvoton,npcm750
- description: NPCM845 based boards
items:
- enum:
- nuvoton,npcm845-evb # NPCM845 evaluation board
- const: nuvoton,npcm845
additionalProperties: true

View File

@ -8,6 +8,7 @@ title: Global Control Registers block in Nuvoton SoCs
maintainers:
- Jonathan Neuschäfer <j.neuschaefer@gmx.net>
- Tomer Maimon <tmaimon77@gmail.com>
description:
The Global Control Registers (GCR) are a block of registers in Nuvoton SoCs
@ -20,6 +21,7 @@ properties:
- enum:
- nuvoton,wpcm450-gcr
- nuvoton,npcm750-gcr
- nuvoton,npcm845-gcr
- const: syscon
- const: simple-mfd

View File

@ -0,0 +1,49 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/nuvoton,npcm845-clk.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Nuvoton NPCM8XX Clock Controller Binding
maintainers:
- Tomer Maimon <tmaimon77@gmail.com>
description: |
Nuvoton Arbel BMC NPCM8XX contains an integrated clock controller, which
generates and supplies clocks to all modules within the BMC.
properties:
compatible:
enum:
- nuvoton,npcm845-clk
reg:
maxItems: 1
'#clock-cells':
const: 1
description:
See include/dt-bindings/clock/nuvoton,npcm8xx-clock.h for the full
list of NPCM8XX clock IDs.
required:
- compatible
- reg
- '#clock-cells'
additionalProperties: false
examples:
- |
ahb {
#address-cells = <2>;
#size-cells = <2>;
clock-controller@f0801000 {
compatible = "nuvoton,npcm845-clk";
reg = <0x0 0xf0801000 0x0 0x1000>;
#clock-cells = <1>;
};
};
...

View File

@ -11,7 +11,9 @@ maintainers:
properties:
compatible:
const: nuvoton,npcm750-reset
enum:
- nuvoton,npcm750-reset # Poleg NPCM7XX SoC
- nuvoton,npcm845-reset # Arbel NPCM8XX SoC
reg:
maxItems: 1
@ -19,6 +21,10 @@ properties:
'#reset-cells':
const: 2
nuvoton,sysgcr:
$ref: /schemas/types.yaml#/definitions/phandle
description: a phandle to access GCR registers.
nuvoton,sw-reset-number:
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 1
@ -31,6 +37,7 @@ required:
- compatible
- reg
- '#reset-cells'
- nuvoton,sysgcr
additionalProperties: false
@ -41,6 +48,7 @@ examples:
compatible = "nuvoton,npcm750-reset";
reg = <0xf0801000 0x70>;
#reset-cells = <2>;
nuvoton,sysgcr = <&gcr>;
nuvoton,sw-reset-number = <2>;
};

View File

@ -8,12 +8,14 @@ title: Nuvoton NPCM7xx timer
maintainers:
- Jonathan Neuschäfer <j.neuschaefer@gmx.net>
- Tomer Maimon <tmaimon77@gmail.com>
properties:
compatible:
enum:
- nuvoton,wpcm450-timer # for Hermon WPCM450
- nuvoton,npcm750-timer # for Poleg NPCM750
- nuvoton,npcm845-timer # for Arbel NPCM845
reg:
maxItems: 1

View File

@ -6,7 +6,8 @@ expiry.
Required properties:
- compatible : "nuvoton,npcm750-wdt" for NPCM750 (Poleg), or
"nuvoton,wpcm450-wdt" for WPCM450 (Hermon).
"nuvoton,wpcm450-wdt" for WPCM450 (Hermon), or
"nuvoton,npcm845-wdt" for NPCM845 (Arbel).
- reg : Offset and length of the register set for the device.
- interrupts : Contain the timer interrupt with flags for
falling edge.

View File

@ -2450,9 +2450,11 @@ F: Documentation/devicetree/bindings/*/*npcm*
F: Documentation/devicetree/bindings/arm/npcm/*
F: arch/arm/boot/dts/nuvoton-npcm*
F: arch/arm/mach-npcm/
F: arch/arm64/boot/dts/nuvoton/
F: drivers/*/*npcm*
F: drivers/*/*/*npcm*
F: include/dt-bindings/clock/nuvoton,npcm7xx-clock.h
F: include/dt-bindings/clock/nuvoton,npcm8xx-clock.h
ARM/NUVOTON WPCM450 ARCHITECTURE
M: Jonathan Neuschäfer <j.neuschaefer@gmx.net>

View File

@ -110,6 +110,7 @@
compatible = "nuvoton,npcm750-reset";
reg = <0xf0801000 0x70>;
#reset-cells = <2>;
nuvoton,sysgcr = <&gcr>;
};
clk: clock-controller@f0801000 {

View File

@ -202,6 +202,17 @@ config ARCH_MXC
This enables support for the ARMv8 based SoCs in the
NXP i.MX family.
config ARCH_NPCM
bool "Nuvoton NPCM Architecture"
select PINCTRL
select GPIOLIB
select NPCM7XX_TIMER
select RESET_CONTROLLER
select MFD_SYSCON
help
General support for NPCM8xx BMC (Arbel).
Nuvoton NPCM8xx BMC based on the Cortex A35.
config ARCH_QCOM
bool "Qualcomm Platforms"
select GPIOLIB

View File

@ -19,6 +19,7 @@ subdir-y += lg
subdir-y += marvell
subdir-y += mediatek
subdir-y += microchip
subdir-y += nuvoton
subdir-y += nvidia
subdir-y += qcom
subdir-y += realtek

View File

@ -0,0 +1,2 @@
# SPDX-License-Identifier: GPL-2.0
dtb-$(CONFIG_ARCH_NPCM) += nuvoton-npcm845-evb.dtb

View File

@ -0,0 +1,170 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2021 Nuvoton Technology tomer.maimon@nuvoton.com
#include <dt-bindings/clock/nuvoton,npcm845-clk.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
/ {
#address-cells = <2>;
#size-cells = <2>;
interrupt-parent = <&gic>;
soc {
#address-cells = <2>;
#size-cells = <2>;
compatible = "simple-bus";
interrupt-parent = <&gic>;
ranges;
gcr: system-controller@f0800000 {
compatible = "nuvoton,npcm845-gcr", "syscon";
reg = <0x0 0xf0800000 0x0 0x1000>;
};
gic: interrupt-controller@dfff9000 {
compatible = "arm,gic-400";
reg = <0x0 0xdfff9000 0x0 0x1000>,
<0x0 0xdfffa000 0x0 0x2000>,
<0x0 0xdfffc000 0x0 0x2000>,
<0x0 0xdfffe000 0x0 0x2000>;
interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
#interrupt-cells = <3>;
interrupt-controller;
#address-cells = <0>;
ppi-partitions {
ppi_cluster0: interrupt-partition-0 {
affinity = <&cpu0 &cpu1 &cpu2 &cpu3>;
};
};
};
};
ahb {
#address-cells = <2>;
#size-cells = <2>;
compatible = "simple-bus";
interrupt-parent = <&gic>;
ranges;
rstc: reset-controller@f0801000 {
compatible = "nuvoton,npcm845-reset";
reg = <0x0 0xf0801000 0x0 0x78>;
#reset-cells = <2>;
nuvoton,sysgcr = <&gcr>;
};
clk: clock-controller@f0801000 {
compatible = "nuvoton,npcm845-clk";
#clock-cells = <1>;
reg = <0x0 0xf0801000 0x0 0x1000>;
};
apb {
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
interrupt-parent = <&gic>;
ranges = <0x0 0x0 0xf0000000 0x00300000>,
<0xfff00000 0x0 0xfff00000 0x00016000>;
timer0: timer@8000 {
compatible = "nuvoton,npcm845-timer";
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x8000 0x1C>;
clocks = <&clk NPCM8XX_CLK_REFCLK>;
clock-names = "refclk";
};
serial0: serial@0 {
compatible = "nuvoton,npcm845-uart", "nuvoton,npcm750-uart";
reg = <0x0 0x1000>;
clocks = <&clk NPCM8XX_CLK_UART>;
interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
status = "disabled";
};
serial1: serial@1000 {
compatible = "nuvoton,npcm845-uart", "nuvoton,npcm750-uart";
reg = <0x1000 0x1000>;
clocks = <&clk NPCM8XX_CLK_UART>;
interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
status = "disabled";
};
serial2: serial@2000 {
compatible = "nuvoton,npcm845-uart", "nuvoton,npcm750-uart";
reg = <0x2000 0x1000>;
clocks = <&clk NPCM8XX_CLK_UART>;
interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
status = "disabled";
};
serial3: serial@3000 {
compatible = "nuvoton,npcm845-uart", "nuvoton,npcm750-uart";
reg = <0x3000 0x1000>;
clocks = <&clk NPCM8XX_CLK_UART>;
interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
status = "disabled";
};
serial4: serial@4000 {
compatible = "nuvoton,npcm845-uart", "nuvoton,npcm750-uart";
reg = <0x4000 0x1000>;
clocks = <&clk NPCM8XX_CLK_UART>;
interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
status = "disabled";
};
serial5: serial@5000 {
compatible = "nuvoton,npcm845-uart", "nuvoton,npcm750-uart";
reg = <0x5000 0x1000>;
clocks = <&clk NPCM8XX_CLK_UART>;
interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
status = "disabled";
};
serial6: serial@6000 {
compatible = "nuvoton,npcm845-uart", "nuvoton,npcm750-uart";
reg = <0x6000 0x1000>;
clocks = <&clk NPCM8XX_CLK_UART>;
interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
status = "disabled";
};
watchdog0: watchdog@801c {
compatible = "nuvoton,npcm845-wdt", "nuvoton,npcm750-wdt";
interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x801c 0x4>;
status = "disabled";
clocks = <&clk NPCM8XX_CLK_REFCLK>;
syscon = <&gcr>;
};
watchdog1: watchdog@901c {
compatible = "nuvoton,npcm845-wdt", "nuvoton,npcm750-wdt";
interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x901c 0x4>;
status = "disabled";
clocks = <&clk NPCM8XX_CLK_REFCLK>;
syscon = <&gcr>;
};
watchdog2: watchdog@a01c {
compatible = "nuvoton,npcm845-wdt", "nuvoton,npcm750-wdt";
interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
reg = <0xa01c 0x4>;
status = "disabled";
clocks = <&clk NPCM8XX_CLK_REFCLK>;
syscon = <&gcr>;
};
};
};
};

View File

@ -0,0 +1,30 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2021 Nuvoton Technology tomer.maimon@nuvoton.com
/dts-v1/;
#include "nuvoton-npcm845.dtsi"
/ {
model = "Nuvoton npcm845 Development Board (Device Tree)";
compatible = "nuvoton,npcm845-evb", "nuvoton,npcm845";
aliases {
serial0 = &serial0;
};
chosen {
stdout-path = &serial0;
};
memory {
reg = <0x0 0x0 0x0 0x40000000>;
};
};
&serial0 {
status = "okay";
};
&watchdog1 {
status = "okay";
};

View File

@ -0,0 +1,76 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2021 Nuvoton Technology tomer.maimon@nuvoton.com
#include "nuvoton-common-npcm8xx.dtsi"
/ {
#address-cells = <2>;
#size-cells = <2>;
cpus {
#address-cells = <2>;
#size-cells = <0>;
cpu0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a35";
clocks = <&clk NPCM8XX_CLK_CPU>;
reg = <0x0 0x0>;
next-level-cache = <&l2>;
enable-method = "psci";
};
cpu1: cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a35";
clocks = <&clk NPCM8XX_CLK_CPU>;
reg = <0x0 0x1>;
next-level-cache = <&l2>;
enable-method = "psci";
};
cpu2: cpu@2 {
device_type = "cpu";
compatible = "arm,cortex-a35";
clocks = <&clk NPCM8XX_CLK_CPU>;
reg = <0x0 0x2>;
next-level-cache = <&l2>;
enable-method = "psci";
};
cpu3: cpu@3 {
device_type = "cpu";
compatible = "arm,cortex-a35";
clocks = <&clk NPCM8XX_CLK_CPU>;
reg = <0x0 0x3>;
next-level-cache = <&l2>;
enable-method = "psci";
};
l2: l2-cache {
compatible = "cache";
};
};
arm-pmu {
compatible = "arm,cortex-a35-pmu";
interrupts = <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>;
interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
};
psci {
compatible = "arm,psci-1.0";
method = "smc";
};
timer {
compatible = "arm,armv8-timer";
interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
<GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
<GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
<GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
};
};

View File

@ -49,6 +49,7 @@ CONFIG_ARCH_MEDIATEK=y
CONFIG_ARCH_MESON=y
CONFIG_ARCH_MVEBU=y
CONFIG_ARCH_MXC=y
CONFIG_ARCH_NPCM=y
CONFIG_ARCH_QCOM=y
CONFIG_ARCH_RENESAS=y
CONFIG_ARCH_ROCKCHIP=y
@ -627,6 +628,7 @@ CONFIG_RENESAS_RZG2LWDT=y
CONFIG_UNIPHIER_WATCHDOG=y
CONFIG_PM8916_WATCHDOG=m
CONFIG_BCM2835_WDT=y
CONFIG_NPCM7XX_WATCHDOG=y
CONFIG_MFD_ALTERA_SYSMGR=y
CONFIG_MFD_BD9571MWV=y
CONFIG_MFD_AXP20X_I2C=y
@ -1021,6 +1023,7 @@ CONFIG_COMMON_CLK_FSL_SAI=y
CONFIG_COMMON_CLK_S2MPS11=y
CONFIG_COMMON_CLK_PWM=y
CONFIG_COMMON_CLK_VC5=y
CONFIG_COMMON_CLK_NPCM8XX=y
CONFIG_COMMON_CLK_BD718XX=m
CONFIG_CLK_RASPBERRYPI=m
CONFIG_CLK_IMX8MM=y

View File

@ -17,13 +17,20 @@
/* NPCM7xx GCR registers */
#define NPCM_MDLR_OFFSET 0x7C
#define NPCM_MDLR_USBD0 BIT(9)
#define NPCM_MDLR_USBD1 BIT(8)
#define NPCM_MDLR_USBD2_4 BIT(21)
#define NPCM_MDLR_USBD5_9 BIT(22)
#define NPCM7XX_MDLR_USBD0 BIT(9)
#define NPCM7XX_MDLR_USBD1 BIT(8)
#define NPCM7XX_MDLR_USBD2_4 BIT(21)
#define NPCM7XX_MDLR_USBD5_9 BIT(22)
/* NPCM8xx MDLR bits */
#define NPCM8XX_MDLR_USBD0_3 BIT(9)
#define NPCM8XX_MDLR_USBD4_7 BIT(22)
#define NPCM8XX_MDLR_USBD8 BIT(24)
#define NPCM8XX_MDLR_USBD9 BIT(21)
#define NPCM_USB1PHYCTL_OFFSET 0x140
#define NPCM_USB2PHYCTL_OFFSET 0x144
#define NPCM_USB3PHYCTL_OFFSET 0x148
#define NPCM_USBXPHYCTL_RS BIT(28)
/* NPCM7xx Reset registers */
@ -49,12 +56,38 @@
#define NPCM_IPSRST3_USBPHY1 BIT(24)
#define NPCM_IPSRST3_USBPHY2 BIT(25)
#define NPCM_IPSRST4 0x74
#define NPCM_IPSRST4_USBPHY3 BIT(25)
#define NPCM_IPSRST4_USB_HOST2 BIT(31)
#define NPCM_RC_RESETS_PER_REG 32
#define NPCM_MASK_RESETS GENMASK(4, 0)
enum {
BMC_NPCM7XX = 0,
BMC_NPCM8XX,
};
static const u32 npxm7xx_ipsrst[] = {NPCM_IPSRST1, NPCM_IPSRST2, NPCM_IPSRST3};
static const u32 npxm8xx_ipsrst[] = {NPCM_IPSRST1, NPCM_IPSRST2, NPCM_IPSRST3,
NPCM_IPSRST4};
struct npcm_reset_info {
u32 bmc_id;
u32 num_ipsrst;
const u32 *ipsrst;
};
static const struct npcm_reset_info npxm7xx_reset_info[] = {
{.bmc_id = BMC_NPCM7XX, .num_ipsrst = 3, .ipsrst = npxm7xx_ipsrst}};
static const struct npcm_reset_info npxm8xx_reset_info[] = {
{.bmc_id = BMC_NPCM8XX, .num_ipsrst = 4, .ipsrst = npxm8xx_ipsrst}};
struct npcm_rc_data {
struct reset_controller_dev rcdev;
struct notifier_block restart_nb;
const struct npcm_reset_info *info;
struct regmap *gcr_regmap;
u32 sw_reset_number;
void __iomem *base;
spinlock_t lock;
@ -120,14 +153,24 @@ static int npcm_rc_status(struct reset_controller_dev *rcdev,
static int npcm_reset_xlate(struct reset_controller_dev *rcdev,
const struct of_phandle_args *reset_spec)
{
struct npcm_rc_data *rc = to_rc_data(rcdev);
unsigned int offset, bit;
bool offset_found = false;
int off_num;
offset = reset_spec->args[0];
if (offset != NPCM_IPSRST1 && offset != NPCM_IPSRST2 &&
offset != NPCM_IPSRST3) {
for (off_num = 0 ; off_num < rc->info->num_ipsrst ; off_num++) {
if (offset == rc->info->ipsrst[off_num]) {
offset_found = true;
break;
}
}
if (!offset_found) {
dev_err(rcdev->dev, "Error reset register (0x%x)\n", offset);
return -EINVAL;
}
bit = reset_spec->args[1];
if (bit >= NPCM_RC_RESETS_PER_REG) {
dev_err(rcdev->dev, "Error reset number (%d)\n", bit);
@ -138,45 +181,29 @@ static int npcm_reset_xlate(struct reset_controller_dev *rcdev,
}
static const struct of_device_id npcm_rc_match[] = {
{ .compatible = "nuvoton,npcm750-reset",
.data = (void *)"nuvoton,npcm750-gcr" },
{ .compatible = "nuvoton,npcm750-reset", .data = &npxm7xx_reset_info},
{ .compatible = "nuvoton,npcm845-reset", .data = &npxm8xx_reset_info},
{ }
};
/*
* The following procedure should be observed in USB PHY, USB device and
* USB host initialization at BMC boot
*/
static int npcm_usb_reset(struct platform_device *pdev, struct npcm_rc_data *rc)
static void npcm_usb_reset_npcm7xx(struct npcm_rc_data *rc)
{
u32 mdlr, iprst1, iprst2, iprst3;
struct device *dev = &pdev->dev;
struct regmap *gcr_regmap;
u32 ipsrst1_bits = 0;
u32 ipsrst2_bits = NPCM_IPSRST2_USB_HOST;
u32 ipsrst3_bits = 0;
const char *gcr_dt;
gcr_dt = (const char *)
of_match_device(dev->driver->of_match_table, dev)->data;
gcr_regmap = syscon_regmap_lookup_by_compatible(gcr_dt);
if (IS_ERR(gcr_regmap)) {
dev_err(&pdev->dev, "Failed to find %s\n", gcr_dt);
return PTR_ERR(gcr_regmap);
}
/* checking which USB device is enabled */
regmap_read(gcr_regmap, NPCM_MDLR_OFFSET, &mdlr);
if (!(mdlr & NPCM_MDLR_USBD0))
regmap_read(rc->gcr_regmap, NPCM_MDLR_OFFSET, &mdlr);
if (!(mdlr & NPCM7XX_MDLR_USBD0))
ipsrst3_bits |= NPCM_IPSRST3_USBD0;
if (!(mdlr & NPCM_MDLR_USBD1))
if (!(mdlr & NPCM7XX_MDLR_USBD1))
ipsrst1_bits |= NPCM_IPSRST1_USBD1;
if (!(mdlr & NPCM_MDLR_USBD2_4))
if (!(mdlr & NPCM7XX_MDLR_USBD2_4))
ipsrst1_bits |= (NPCM_IPSRST1_USBD2 |
NPCM_IPSRST1_USBD3 |
NPCM_IPSRST1_USBD4);
if (!(mdlr & NPCM_MDLR_USBD0)) {
if (!(mdlr & NPCM7XX_MDLR_USBD0)) {
ipsrst1_bits |= (NPCM_IPSRST1_USBD5 |
NPCM_IPSRST1_USBD6);
ipsrst3_bits |= (NPCM_IPSRST3_USBD7 |
@ -199,9 +226,9 @@ static int npcm_usb_reset(struct platform_device *pdev, struct npcm_rc_data *rc)
writel(iprst3, rc->base + NPCM_IPSRST3);
/* clear USB PHY RS bit */
regmap_update_bits(gcr_regmap, NPCM_USB1PHYCTL_OFFSET,
regmap_update_bits(rc->gcr_regmap, NPCM_USB1PHYCTL_OFFSET,
NPCM_USBXPHYCTL_RS, 0);
regmap_update_bits(gcr_regmap, NPCM_USB2PHYCTL_OFFSET,
regmap_update_bits(rc->gcr_regmap, NPCM_USB2PHYCTL_OFFSET,
NPCM_USBXPHYCTL_RS, 0);
/* deassert reset USB PHY */
@ -211,9 +238,9 @@ static int npcm_usb_reset(struct platform_device *pdev, struct npcm_rc_data *rc)
udelay(50);
/* set USB PHY RS bit */
regmap_update_bits(gcr_regmap, NPCM_USB1PHYCTL_OFFSET,
regmap_update_bits(rc->gcr_regmap, NPCM_USB1PHYCTL_OFFSET,
NPCM_USBXPHYCTL_RS, NPCM_USBXPHYCTL_RS);
regmap_update_bits(gcr_regmap, NPCM_USB2PHYCTL_OFFSET,
regmap_update_bits(rc->gcr_regmap, NPCM_USB2PHYCTL_OFFSET,
NPCM_USBXPHYCTL_RS, NPCM_USBXPHYCTL_RS);
/* deassert reset USB devices*/
@ -224,6 +251,118 @@ static int npcm_usb_reset(struct platform_device *pdev, struct npcm_rc_data *rc)
writel(iprst1, rc->base + NPCM_IPSRST1);
writel(iprst2, rc->base + NPCM_IPSRST2);
writel(iprst3, rc->base + NPCM_IPSRST3);
}
static void npcm_usb_reset_npcm8xx(struct npcm_rc_data *rc)
{
u32 mdlr, iprst1, iprst2, iprst3, iprst4;
u32 ipsrst1_bits = 0;
u32 ipsrst2_bits = NPCM_IPSRST2_USB_HOST;
u32 ipsrst3_bits = 0;
u32 ipsrst4_bits = NPCM_IPSRST4_USB_HOST2 | NPCM_IPSRST4_USBPHY3;
/* checking which USB device is enabled */
regmap_read(rc->gcr_regmap, NPCM_MDLR_OFFSET, &mdlr);
if (!(mdlr & NPCM8XX_MDLR_USBD0_3)) {
ipsrst3_bits |= NPCM_IPSRST3_USBD0;
ipsrst1_bits |= (NPCM_IPSRST1_USBD1 |
NPCM_IPSRST1_USBD2 |
NPCM_IPSRST1_USBD3);
}
if (!(mdlr & NPCM8XX_MDLR_USBD4_7)) {
ipsrst1_bits |= (NPCM_IPSRST1_USBD4 |
NPCM_IPSRST1_USBD5 |
NPCM_IPSRST1_USBD6);
ipsrst3_bits |= NPCM_IPSRST3_USBD7;
}
if (!(mdlr & NPCM8XX_MDLR_USBD8))
ipsrst3_bits |= NPCM_IPSRST3_USBD8;
if (!(mdlr & NPCM8XX_MDLR_USBD9))
ipsrst3_bits |= NPCM_IPSRST3_USBD9;
/* assert reset USB PHY and USB devices */
iprst1 = readl(rc->base + NPCM_IPSRST1);
iprst2 = readl(rc->base + NPCM_IPSRST2);
iprst3 = readl(rc->base + NPCM_IPSRST3);
iprst4 = readl(rc->base + NPCM_IPSRST4);
iprst1 |= ipsrst1_bits;
iprst2 |= ipsrst2_bits;
iprst3 |= (ipsrst3_bits | NPCM_IPSRST3_USBPHY1 |
NPCM_IPSRST3_USBPHY2);
iprst2 |= ipsrst4_bits;
writel(iprst1, rc->base + NPCM_IPSRST1);
writel(iprst2, rc->base + NPCM_IPSRST2);
writel(iprst3, rc->base + NPCM_IPSRST3);
writel(iprst4, rc->base + NPCM_IPSRST4);
/* clear USB PHY RS bit */
regmap_update_bits(rc->gcr_regmap, NPCM_USB1PHYCTL_OFFSET,
NPCM_USBXPHYCTL_RS, 0);
regmap_update_bits(rc->gcr_regmap, NPCM_USB2PHYCTL_OFFSET,
NPCM_USBXPHYCTL_RS, 0);
regmap_update_bits(rc->gcr_regmap, NPCM_USB3PHYCTL_OFFSET,
NPCM_USBXPHYCTL_RS, 0);
/* deassert reset USB PHY */
iprst3 &= ~(NPCM_IPSRST3_USBPHY1 | NPCM_IPSRST3_USBPHY2);
writel(iprst3, rc->base + NPCM_IPSRST3);
iprst4 &= ~NPCM_IPSRST4_USBPHY3;
writel(iprst4, rc->base + NPCM_IPSRST4);
/* set USB PHY RS bit */
regmap_update_bits(rc->gcr_regmap, NPCM_USB1PHYCTL_OFFSET,
NPCM_USBXPHYCTL_RS, NPCM_USBXPHYCTL_RS);
regmap_update_bits(rc->gcr_regmap, NPCM_USB2PHYCTL_OFFSET,
NPCM_USBXPHYCTL_RS, NPCM_USBXPHYCTL_RS);
regmap_update_bits(rc->gcr_regmap, NPCM_USB3PHYCTL_OFFSET,
NPCM_USBXPHYCTL_RS, NPCM_USBXPHYCTL_RS);
/* deassert reset USB devices*/
iprst1 &= ~ipsrst1_bits;
iprst2 &= ~ipsrst2_bits;
iprst3 &= ~ipsrst3_bits;
iprst4 &= ~ipsrst4_bits;
writel(iprst1, rc->base + NPCM_IPSRST1);
writel(iprst2, rc->base + NPCM_IPSRST2);
writel(iprst3, rc->base + NPCM_IPSRST3);
writel(iprst4, rc->base + NPCM_IPSRST4);
}
/*
* The following procedure should be observed in USB PHY, USB device and
* USB host initialization at BMC boot
*/
static int npcm_usb_reset(struct platform_device *pdev, struct npcm_rc_data *rc)
{
struct device *dev = &pdev->dev;
rc->gcr_regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "nuvoton,sysgcr");
if (IS_ERR(rc->gcr_regmap)) {
dev_warn(&pdev->dev, "Failed to find nuvoton,sysgcr property, please update the device tree\n");
dev_info(&pdev->dev, "Using nuvoton,npcm750-gcr for Poleg backward compatibility\n");
rc->gcr_regmap = syscon_regmap_lookup_by_compatible("nuvoton,npcm750-gcr");
if (IS_ERR(rc->gcr_regmap)) {
dev_err(&pdev->dev, "Failed to find nuvoton,npcm750-gcr");
return PTR_ERR(rc->gcr_regmap);
}
}
rc->info = (const struct npcm_reset_info *)
of_match_device(dev->driver->of_match_table, dev)->data;
switch (rc->info->bmc_id) {
case BMC_NPCM7XX:
npcm_usb_reset_npcm7xx(rc);
break;
case BMC_NPCM8XX:
npcm_usb_reset_npcm8xx(rc);
break;
default:
return -ENODEV;
}
return 0;
}

View File

@ -0,0 +1,49 @@
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
/*
* Copyright (C) 2021 Nuvoton Technologies.
* Author: Tomer Maimon <tomer.maimon@nuvoton.com>
*
* Device Tree binding constants for NPCM8XX clock controller.
*/
#ifndef __DT_BINDINGS_CLOCK_NPCM8XX_H
#define __DT_BINDINGS_CLOCK_NPCM8XX_H
#define NPCM8XX_CLK_CPU 0
#define NPCM8XX_CLK_GFX_PIXEL 1
#define NPCM8XX_CLK_MC 2
#define NPCM8XX_CLK_ADC 3
#define NPCM8XX_CLK_AHB 4
#define NPCM8XX_CLK_TIMER 5
#define NPCM8XX_CLK_UART 6
#define NPCM8XX_CLK_UART2 7
#define NPCM8XX_CLK_MMC 8
#define NPCM8XX_CLK_SPI3 9
#define NPCM8XX_CLK_PCI 10
#define NPCM8XX_CLK_AXI 11
#define NPCM8XX_CLK_APB4 12
#define NPCM8XX_CLK_APB3 13
#define NPCM8XX_CLK_APB2 14
#define NPCM8XX_CLK_APB1 15
#define NPCM8XX_CLK_APB5 16
#define NPCM8XX_CLK_CLKOUT 17
#define NPCM8XX_CLK_GFX 18
#define NPCM8XX_CLK_SU 19
#define NPCM8XX_CLK_SU48 20
#define NPCM8XX_CLK_SDHC 21
#define NPCM8XX_CLK_SPI0 22
#define NPCM8XX_CLK_SPI1 23
#define NPCM8XX_CLK_SPIX 24
#define NPCM8XX_CLK_RG 25
#define NPCM8XX_CLK_RCP 26
#define NPCM8XX_CLK_PRE_ADC 27
#define NPCM8XX_CLK_ATB 28
#define NPCM8XX_CLK_PRE_CLK 29
#define NPCM8XX_CLK_TH 30
#define NPCM8XX_CLK_REFCLK 31
#define NPCM8XX_CLK_SYSBYPCK 32
#define NPCM8XX_CLK_MCBYPCK 33
#define NPCM8XX_NUM_CLOCKS (NPCM8XX_CLK_MCBYPCK + 1)
#endif