Merge branches 'clk-rockchip', 'clk-renesas', 'clk-microchip', 'clk-allwinner' and 'clk-imx' into clk-next

* clk-rockchip:
  dt-bindings: clock: rockchip: change SPDX-License-Identifier
  dt-bindings: clock: convert rockchip,rk3128-cru.txt to YAML
  clk: rockchip: Add clock controller support for RV1126 SoC
  dt-bindings: clock: rockchip: Document RV1126 CRU
  clk: rockchip: Add dt-binding header for RV1126
  clk: rockchip: Add MUXTBL variant

* clk-renesas:
  clk: renesas: r8a779g0: Add EtherAVB clocks
  clk: renesas: r8a779g0: Add PFC/GPIO clocks
  clk: renesas: r8a779g0: Add I2C clocks
  clk: renesas: r8a779g0: Add watchdog clock
  dt-bindings: clock: renesas,rzg2l: Document RZ/Five SoC
  clk: renesas: r8a779f0: Add MSIOF clocks
  clk: renesas: r9a09g011: Add IIC clock and reset entries
  clk: renesas: r9a07g044: Add conditional compilation for r9a07g044_cpg_info
  clk: renesas: r8a779f0: Add TMU and parent SASYNC clocks
  clk: renesas: r8a779f0: Add CMT clocks
  clk: renesas: r8a779f0: Add SDH0 clock

* clk-microchip:
  clk: at91: sama5d2: Add Generic Clocks for UART/USART
  clk: microchip: add PolarFire SoC fabric clock support
  dt-bindings: clk: add PolarFire SoC fabric clock ids
  dt-bindings: clk: document PolarFire SoC fabric clocks
  dt-bindings: clk: rename mpfs-clkcfg binding
  clk: microchip: mpfs: update module authorship & licencing
  clk: microchip: mpfs: convert periph_clk to clk_gate
  clk: microchip: mpfs: convert cfg_clk to clk_divider
  clk: microchip: mpfs: delete 2 line mpfs_clk_register_foo()
  clk: microchip: mpfs: simplify control reg access
  clk: microchip: mpfs: move id & offset out of clock structs
  clk: microchip: mpfs: add MSS pll's set & round rate
  MAINTAINERS: add polarfire soc reset controller
  reset: add polarfire soc reset support
  clk: microchip: mpfs: add reset controller
  dt-bindings: clk: microchip: mpfs: add reset controller support
  clk: microchip: mpfs: make the rtc's ahb clock critical
  clk: microchip: mpfs: fix clk_cfg array bounds violation

* clk-allwinner:
  clk: sunxi-ng: ccu-sun9i-a80-usb: Use dev_err_probe() helper
  clk: sunxi-ng: ccu-sun9i-a80-de: Use dev_err_probe() helper
  clk: sunxi-ng: sun8i-de2: Use dev_err_probe() helper
  clk: sunxi-ng: d1: Limit PLL rates to stable ranges

* clk-imx:
  clk: imx: scu: fix memleak on platform_device_add() fails
  clk: imx93: add SAI IPG clk
  clk: imx93: add MU1/2 clock
  clk: imx93: switch to use new clk gate API
  clk: imx: add i.MX93 clk gate
  clk: imx: clk-composite-93: check white_list
  clk: imx: clk-composite-93: check slice busy
  dt-bindings: clock: imx93-clock: add more MU/SAI clocks
  dt-bindings: clock: imx8mm: don't use multiple blank lines
  clk: imx8mp: tune the order of enet_qos_root_clk
This commit is contained in:
Stephen Boyd 2022-10-04 10:54:02 -07:00
48 changed files with 3244 additions and 329 deletions

View File

@ -0,0 +1,80 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/microchip,mpfs-ccc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Microchip PolarFire SoC Fabric Clock Conditioning Circuitry
maintainers:
- Conor Dooley <conor.dooley@microchip.com>
description: |
Microchip PolarFire SoC has 4 Clock Conditioning Circuitry blocks. Each of
these blocks contains two PLLs and 2 DLLs & are located in the four corners of
the FPGA. For more information see "PolarFire SoC FPGA Clocking Resources" at:
https://onlinedocs.microchip.com/pr/GUID-8F0CC4C0-0317-4262-89CA-CE7773ED1931-en-US-1/index.html
properties:
compatible:
const: microchip,mpfs-ccc
reg:
items:
- description: PLL0's control registers
- description: PLL1's control registers
- description: DLL0's control registers
- description: DLL1's control registers
clocks:
description:
The CCC PLL's have two input clocks. It is required that even if the input
clocks are identical that both are provided.
minItems: 2
items:
- description: PLL0's refclk0
- description: PLL0's refclk1
- description: PLL1's refclk0
- description: PLL1's refclk1
- description: DLL0's refclk
- description: DLL1's refclk
clock-names:
minItems: 2
items:
- const: pll0_ref0
- const: pll0_ref1
- const: pll1_ref0
- const: pll1_ref1
- const: dll0_ref
- const: dll1_ref
'#clock-cells':
const: 1
description: |
The clock consumer should specify the desired clock by having the clock
ID in its "clocks" phandle cell.
See include/dt-bindings/clock/microchip,mpfs-clock.h for the full list of
PolarFire clock IDs.
required:
- compatible
- reg
- clocks
- clock-names
- '#clock-cells'
additionalProperties: false
examples:
- |
clock-controller@38100000 {
compatible = "microchip,mpfs-ccc";
reg = <0x38010000 0x1000>, <0x38020000 0x1000>,
<0x39010000 0x1000>, <0x39020000 0x1000>;
#clock-cells = <1>;
clocks = <&refclk_ccc>, <&refclk_ccc>, <&refclk_ccc>, <&refclk_ccc>,
<&refclk_ccc>, <&refclk_ccc>;
clock-names = "pll0_ref0", "pll0_ref1", "pll1_ref0", "pll1_ref1",
"dll0_ref", "dll1_ref";
};

View File

@ -1,7 +1,7 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/microchip,mpfs.yaml#
$id: http://devicetree.org/schemas/clock/microchip,mpfs-clkcfg.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Microchip PolarFire Clock Control Module Binding
@ -40,8 +40,21 @@ properties:
const: 1
description: |
The clock consumer should specify the desired clock by having the clock
ID in its "clocks" phandle cell. See include/dt-bindings/clock/microchip,mpfs-clock.h
for the full list of PolarFire clock IDs.
ID in its "clocks" phandle cell.
See include/dt-bindings/clock/microchip,mpfs-clock.h for the full list of
PolarFire clock IDs.
resets:
maxItems: 1
'#reset-cells':
description:
The AHB/AXI peripherals on the PolarFire SoC have reset support, so from
CLK_ENVM to CLK_CFM. The reset consumer should specify the desired
peripheral via the clock ID in its "resets" phandle cell.
See include/dt-bindings/clock/microchip,mpfs-clock.h for the full list of
PolarFire clock IDs.
const: 1
required:
- compatible

View File

@ -24,7 +24,7 @@ description: |
properties:
compatible:
enum:
- renesas,r9a07g043-cpg # RZ/G2UL{Type-1,Type-2}
- renesas,r9a07g043-cpg # RZ/G2UL{Type-1,Type-2} and RZ/Five
- renesas,r9a07g044-cpg # RZ/G2{L,LC}
- renesas,r9a07g054-cpg # RZ/V2L
- renesas,r9a09g011-cpg # RZ/V2M

View File

@ -1,4 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/rockchip,px30-cru.yaml#

View File

@ -1,4 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/rockchip,rk3036-cru.yaml#

View File

@ -1,58 +0,0 @@
* Rockchip RK3126/RK3128 Clock and Reset Unit
The RK3126/RK3128 clock controller generates and supplies clock to various
controllers within the SoC and also implements a reset controller for SoC
peripherals.
Required Properties:
- compatible: should be "rockchip,rk3126-cru" or "rockchip,rk3128-cru"
"rockchip,rk3126-cru" - controller compatible with RK3126 SoC.
"rockchip,rk3128-cru" - controller compatible with RK3128 SoC.
- reg: physical base address of the controller and length of memory mapped
region.
- #clock-cells: should be 1.
- #reset-cells: should be 1.
Optional Properties:
- rockchip,grf: phandle to the syscon managing the "general register files"
If missing pll rates are not changeable, due to the missing pll lock status.
Each clock is assigned an identifier and client nodes can use this identifier
to specify the clock which they consume. All available clocks are defined as
preprocessor macros in the dt-bindings/clock/rk3128-cru.h headers and can be
used in device tree sources. Similar macros exist for the reset sources in
these files.
External clocks:
There are several clocks that are generated outside the SoC. It is expected
that they are defined using standard clock bindings with following
clock-output-names:
- "xin24m" - crystal input - required,
- "ext_i2s" - external I2S clock - optional,
- "gmac_clkin" - external GMAC clock - optional
Example: Clock controller node:
cru: cru@20000000 {
compatible = "rockchip,rk3128-cru";
reg = <0x20000000 0x1000>;
rockchip,grf = <&grf>;
#clock-cells = <1>;
#reset-cells = <1>;
};
Example: UART controller node that consumes the clock generated by the clock
controller:
uart2: serial@20068000 {
compatible = "rockchip,serial";
reg = <0x20068000 0x100>;
interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
clock-frequency = <24000000>;
clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
clock-names = "sclk_uart", "pclk_uart";
};

View File

@ -0,0 +1,76 @@
# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/rockchip,rk3128-cru.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Rockchip RK3126/RK3128 Clock and Reset Unit (CRU)
maintainers:
- Elaine Zhang <zhangqing@rock-chips.com>
- Heiko Stuebner <heiko@sntech.de>
description: |
The RK3126/RK3128 clock controller generates and supplies clock to various
controllers within the SoC and also implements a reset controller for SoC
peripherals.
Each clock is assigned an identifier and client nodes can use this identifier
to specify the clock which they consume. All available clocks are defined as
preprocessor macros in the dt-bindings/clock/rk3128-cru.h headers and can be
used in device tree sources. Similar macros exist for the reset sources in
these files.
properties:
compatible:
enum:
- rockchip,rk3126-cru
- rockchip,rk3128-cru
reg:
maxItems: 1
"#clock-cells":
const: 1
"#reset-cells":
const: 1
clocks:
minItems: 1
maxItems: 3
clock-names:
minItems: 1
items:
- const: xin24m
- enum:
- ext_i2s
- gmac_clkin
- enum:
- ext_i2s
- gmac_clkin
rockchip,grf:
$ref: /schemas/types.yaml#/definitions/phandle
description:
Phandle to the syscon managing the "general register files" (GRF),
if missing pll rates are not changeable, due to the missing pll
lock status.
required:
- compatible
- reg
- "#clock-cells"
- "#reset-cells"
additionalProperties: false
examples:
- |
cru: clock-controller@20000000 {
compatible = "rockchip,rk3128-cru";
reg = <0x20000000 0x1000>;
rockchip,grf = <&grf>;
#clock-cells = <1>;
#reset-cells = <1>;
};

View File

@ -1,4 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/rockchip,rk3228-cru.yaml#

View File

@ -1,4 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/rockchip,rk3288-cru.yaml#

View File

@ -1,4 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/rockchip,rk3308-cru.yaml#

View File

@ -1,4 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/rockchip,rk3368-cru.yaml#

View File

@ -1,4 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/rockchip,rk3399-cru.yaml#

View File

@ -1,4 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/rockchip,rv1108-cru.yaml#

View File

@ -0,0 +1,62 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/rockchip,rv1126-cru.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Rockchip RV1126 Clock and Reset Unit
maintainers:
- Jagan Teki <jagan@edgeble.ai>
- Finley Xiao <finley.xiao@rock-chips.com>
- Heiko Stuebner <heiko@sntech.de>
description:
The RV1126 clock controller generates the clock and also implements a
reset controller for SoC peripherals.
properties:
compatible:
enum:
- rockchip,rv1126-cru
- rockchip,rv1126-pmucru
reg:
maxItems: 1
"#clock-cells":
const: 1
"#reset-cells":
const: 1
clocks:
maxItems: 1
clock-names:
const: xin24m
rockchip,grf:
$ref: /schemas/types.yaml#/definitions/phandle
description:
Phandle to the syscon managing the "general register files" (GRF),
if missing pll rates are not changeable, due to the missing pll
lock status.
required:
- compatible
- reg
- "#clock-cells"
- "#reset-cells"
additionalProperties: false
examples:
- |
cru: clock-controller@ff490000 {
compatible = "rockchip,rv1126-cru";
reg = <0xff490000 0x1000>;
rockchip,grf = <&grf>;
#clock-cells = <1>;
#reset-cells = <1>;
};

View File

@ -17533,6 +17533,7 @@ F: drivers/char/hw_random/mpfs-rng.c
F: drivers/clk/microchip/clk-mpfs.c
F: drivers/mailbox/mailbox-mpfs.c
F: drivers/pci/controller/pcie-microchip-host.c
F: drivers/reset/reset-mpfs.c
F: drivers/rtc/rtc-mpfs.c
F: drivers/soc/microchip/
F: drivers/spi/spi-microchip-core.c

View File

@ -120,6 +120,16 @@ static const struct {
struct clk_range r;
int chg_pid;
} sama5d2_gck[] = {
{ .n = "flx0_gclk", .id = 19, .chg_pid = INT_MIN, .r = { .min = 0, .max = 27666666 }, },
{ .n = "flx1_gclk", .id = 20, .chg_pid = INT_MIN, .r = { .min = 0, .max = 27666666 }, },
{ .n = "flx2_gclk", .id = 21, .chg_pid = INT_MIN, .r = { .min = 0, .max = 27666666 }, },
{ .n = "flx3_gclk", .id = 22, .chg_pid = INT_MIN, .r = { .min = 0, .max = 27666666 }, },
{ .n = "flx4_gclk", .id = 23, .chg_pid = INT_MIN, .r = { .min = 0, .max = 27666666 }, },
{ .n = "uart0_gclk", .id = 24, .chg_pid = INT_MIN, .r = { .min = 0, .max = 27666666 }, },
{ .n = "uart1_gclk", .id = 25, .chg_pid = INT_MIN, .r = { .min = 0, .max = 27666666 }, },
{ .n = "uart2_gclk", .id = 26, .chg_pid = INT_MIN, .r = { .min = 0, .max = 27666666 }, },
{ .n = "uart3_gclk", .id = 27, .chg_pid = INT_MIN, .r = { .min = 0, .max = 27666666 }, },
{ .n = "uart4_gclk", .id = 28, .chg_pid = INT_MIN, .r = { .min = 0, .max = 27666666 }, },
{ .n = "sdmmc0_gclk", .id = 31, .chg_pid = INT_MIN, },
{ .n = "sdmmc1_gclk", .id = 32, .chg_pid = INT_MIN, },
{ .n = "tcb0_gclk", .id = 35, .chg_pid = INT_MIN, .r = { .min = 0, .max = 83000000 }, },

View File

@ -12,6 +12,7 @@ mxc-clk-objs += clk-fixup-div.o
mxc-clk-objs += clk-fixup-mux.o
mxc-clk-objs += clk-frac-pll.o
mxc-clk-objs += clk-gate2.o
mxc-clk-objs += clk-gate-93.o
mxc-clk-objs += clk-gate-exclusive.o
mxc-clk-objs += clk-pfd.o
mxc-clk-objs += clk-pfdv2.o

View File

@ -9,22 +9,180 @@
#include <linux/errno.h>
#include <linux/export.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/slab.h>
#include "clk.h"
#define TIMEOUT_US 500U
#define CCM_DIV_SHIFT 0
#define CCM_DIV_WIDTH 8
#define CCM_MUX_SHIFT 8
#define CCM_MUX_MASK 3
#define CCM_OFF_SHIFT 24
#define CCM_BUSY_SHIFT 28
#define STAT_OFFSET 0x4
#define AUTHEN_OFFSET 0x30
#define TZ_NS_SHIFT 9
#define TZ_NS_MASK BIT(9)
#define WHITE_LIST_SHIFT 16
static int imx93_clk_composite_wait_ready(struct clk_hw *hw, void __iomem *reg)
{
int ret;
u32 val;
ret = readl_poll_timeout_atomic(reg + STAT_OFFSET, val, !(val & BIT(CCM_BUSY_SHIFT)),
0, TIMEOUT_US);
if (ret)
pr_err("Slice[%s] busy timeout\n", clk_hw_get_name(hw));
return ret;
}
static void imx93_clk_composite_gate_endisable(struct clk_hw *hw, int enable)
{
struct clk_gate *gate = to_clk_gate(hw);
unsigned long flags;
u32 reg;
if (gate->lock)
spin_lock_irqsave(gate->lock, flags);
reg = readl(gate->reg);
if (enable)
reg &= ~BIT(gate->bit_idx);
else
reg |= BIT(gate->bit_idx);
writel(reg, gate->reg);
imx93_clk_composite_wait_ready(hw, gate->reg);
if (gate->lock)
spin_unlock_irqrestore(gate->lock, flags);
}
static int imx93_clk_composite_gate_enable(struct clk_hw *hw)
{
imx93_clk_composite_gate_endisable(hw, 1);
return 0;
}
static void imx93_clk_composite_gate_disable(struct clk_hw *hw)
{
imx93_clk_composite_gate_endisable(hw, 0);
}
static const struct clk_ops imx93_clk_composite_gate_ops = {
.enable = imx93_clk_composite_gate_enable,
.disable = imx93_clk_composite_gate_disable,
.is_enabled = clk_gate_is_enabled,
};
static unsigned long
imx93_clk_composite_divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
{
return clk_divider_ops.recalc_rate(hw, parent_rate);
}
static long
imx93_clk_composite_divider_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate)
{
return clk_divider_ops.round_rate(hw, rate, prate);
}
static int
imx93_clk_composite_divider_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
{
return clk_divider_ops.determine_rate(hw, req);
}
static int imx93_clk_composite_divider_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_divider *divider = to_clk_divider(hw);
int value;
unsigned long flags = 0;
u32 val;
int ret;
value = divider_get_val(rate, parent_rate, divider->table, divider->width, divider->flags);
if (value < 0)
return value;
if (divider->lock)
spin_lock_irqsave(divider->lock, flags);
val = readl(divider->reg);
val &= ~(clk_div_mask(divider->width) << divider->shift);
val |= (u32)value << divider->shift;
writel(val, divider->reg);
ret = imx93_clk_composite_wait_ready(hw, divider->reg);
if (divider->lock)
spin_unlock_irqrestore(divider->lock, flags);
return ret;
}
static const struct clk_ops imx93_clk_composite_divider_ops = {
.recalc_rate = imx93_clk_composite_divider_recalc_rate,
.round_rate = imx93_clk_composite_divider_round_rate,
.determine_rate = imx93_clk_composite_divider_determine_rate,
.set_rate = imx93_clk_composite_divider_set_rate,
};
static u8 imx93_clk_composite_mux_get_parent(struct clk_hw *hw)
{
return clk_mux_ops.get_parent(hw);
}
static int imx93_clk_composite_mux_set_parent(struct clk_hw *hw, u8 index)
{
struct clk_mux *mux = to_clk_mux(hw);
u32 val = clk_mux_index_to_val(mux->table, mux->flags, index);
unsigned long flags = 0;
u32 reg;
int ret;
if (mux->lock)
spin_lock_irqsave(mux->lock, flags);
reg = readl(mux->reg);
reg &= ~(mux->mask << mux->shift);
val = val << mux->shift;
reg |= val;
writel(reg, mux->reg);
ret = imx93_clk_composite_wait_ready(hw, mux->reg);
if (mux->lock)
spin_unlock_irqrestore(mux->lock, flags);
return ret;
}
static int
imx93_clk_composite_mux_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
{
return clk_mux_ops.determine_rate(hw, req);
}
static const struct clk_ops imx93_clk_composite_mux_ops = {
.get_parent = imx93_clk_composite_mux_get_parent,
.set_parent = imx93_clk_composite_mux_set_parent,
.determine_rate = imx93_clk_composite_mux_determine_rate,
};
struct clk_hw *imx93_clk_composite_flags(const char *name, const char * const *parent_names,
int num_parents, void __iomem *reg,
int num_parents, void __iomem *reg, u32 domain_id,
unsigned long flags)
{
struct clk_hw *hw = ERR_PTR(-ENOMEM), *mux_hw;
@ -33,6 +191,7 @@ struct clk_hw *imx93_clk_composite_flags(const char *name, const char * const *p
struct clk_gate *gate = NULL;
struct clk_mux *mux = NULL;
bool clk_ro = false;
u32 authen;
mux = kzalloc(sizeof(*mux), GFP_KERNEL);
if (!mux)
@ -55,7 +214,8 @@ struct clk_hw *imx93_clk_composite_flags(const char *name, const char * const *p
div->lock = &imx_ccm_lock;
div->flags = CLK_DIVIDER_ROUND_CLOSEST;
if (!(readl(reg + AUTHEN_OFFSET) & TZ_NS_MASK))
authen = readl(reg + AUTHEN_OFFSET);
if (!(authen & TZ_NS_MASK) || !(authen & BIT(WHITE_LIST_SHIFT + domain_id)))
clk_ro = true;
if (clk_ro) {
@ -74,9 +234,10 @@ struct clk_hw *imx93_clk_composite_flags(const char *name, const char * const *p
gate->flags = CLK_GATE_SET_TO_DISABLE;
hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
mux_hw, &clk_mux_ops, div_hw,
&clk_divider_ops, gate_hw,
&clk_gate_ops, flags | CLK_SET_RATE_NO_REPARENT);
mux_hw, &imx93_clk_composite_mux_ops, div_hw,
&imx93_clk_composite_divider_ops, gate_hw,
&imx93_clk_composite_gate_ops,
flags | CLK_SET_RATE_NO_REPARENT);
}
if (IS_ERR(hw))

View File

@ -0,0 +1,199 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2022 NXP
*
* Peng Fan <peng.fan@nxp.com>
*/
#include <linux/clk-provider.h>
#include <linux/errno.h>
#include <linux/export.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/slab.h>
#include "clk.h"
#define DIRECT_OFFSET 0x0
/*
* 0b000 - LPCG will be OFF in any CPU mode.
* 0b100 - LPCG will be ON in any CPU mode.
*/
#define LPM_SETTING_OFF 0x0
#define LPM_SETTING_ON 0x4
#define LPM_CUR_OFFSET 0x1c
#define AUTHEN_OFFSET 0x30
#define CPULPM_EN BIT(2)
#define TZ_NS_SHIFT 9
#define TZ_NS_MASK BIT(9)
#define WHITE_LIST_SHIFT 16
struct imx93_clk_gate {
struct clk_hw hw;
void __iomem *reg;
u32 bit_idx;
u32 val;
u32 mask;
spinlock_t *lock;
unsigned int *share_count;
};
#define to_imx93_clk_gate(_hw) container_of(_hw, struct imx93_clk_gate, hw)
static void imx93_clk_gate_do_hardware(struct clk_hw *hw, bool enable)
{
struct imx93_clk_gate *gate = to_imx93_clk_gate(hw);
u32 val;
val = readl(gate->reg + AUTHEN_OFFSET);
if (val & CPULPM_EN) {
val = enable ? LPM_SETTING_ON : LPM_SETTING_OFF;
writel(val, gate->reg + LPM_CUR_OFFSET);
} else {
val = readl(gate->reg + DIRECT_OFFSET);
val &= ~(gate->mask << gate->bit_idx);
if (enable)
val |= (gate->val & gate->mask) << gate->bit_idx;
writel(val, gate->reg + DIRECT_OFFSET);
}
}
static int imx93_clk_gate_enable(struct clk_hw *hw)
{
struct imx93_clk_gate *gate = to_imx93_clk_gate(hw);
unsigned long flags;
spin_lock_irqsave(gate->lock, flags);
if (gate->share_count && (*gate->share_count)++ > 0)
goto out;
imx93_clk_gate_do_hardware(hw, true);
out:
spin_unlock_irqrestore(gate->lock, flags);
return 0;
}
static void imx93_clk_gate_disable(struct clk_hw *hw)
{
struct imx93_clk_gate *gate = to_imx93_clk_gate(hw);
unsigned long flags;
spin_lock_irqsave(gate->lock, flags);
if (gate->share_count) {
if (WARN_ON(*gate->share_count == 0))
goto out;
else if (--(*gate->share_count) > 0)
goto out;
}
imx93_clk_gate_do_hardware(hw, false);
out:
spin_unlock_irqrestore(gate->lock, flags);
}
static int imx93_clk_gate_reg_is_enabled(struct imx93_clk_gate *gate)
{
u32 val = readl(gate->reg + AUTHEN_OFFSET);
if (val & CPULPM_EN) {
val = readl(gate->reg + LPM_CUR_OFFSET);
if (val == LPM_SETTING_ON)
return 1;
} else {
val = readl(gate->reg);
if (((val >> gate->bit_idx) & gate->mask) == gate->val)
return 1;
}
return 0;
}
static int imx93_clk_gate_is_enabled(struct clk_hw *hw)
{
struct imx93_clk_gate *gate = to_imx93_clk_gate(hw);
unsigned long flags;
int ret;
spin_lock_irqsave(gate->lock, flags);
ret = imx93_clk_gate_reg_is_enabled(gate);
spin_unlock_irqrestore(gate->lock, flags);
return ret;
}
static void imx93_clk_gate_disable_unused(struct clk_hw *hw)
{
struct imx93_clk_gate *gate = to_imx93_clk_gate(hw);
unsigned long flags;
spin_lock_irqsave(gate->lock, flags);
if (!gate->share_count || *gate->share_count == 0)
imx93_clk_gate_do_hardware(hw, false);
spin_unlock_irqrestore(gate->lock, flags);
}
static const struct clk_ops imx93_clk_gate_ops = {
.enable = imx93_clk_gate_enable,
.disable = imx93_clk_gate_disable,
.disable_unused = imx93_clk_gate_disable_unused,
.is_enabled = imx93_clk_gate_is_enabled,
};
static const struct clk_ops imx93_clk_gate_ro_ops = {
.is_enabled = imx93_clk_gate_is_enabled,
};
struct clk_hw *imx93_clk_gate(struct device *dev, const char *name, const char *parent_name,
unsigned long flags, void __iomem *reg, u32 bit_idx, u32 val,
u32 mask, u32 domain_id, unsigned int *share_count)
{
struct imx93_clk_gate *gate;
struct clk_hw *hw;
struct clk_init_data init;
int ret;
u32 authen;
gate = kzalloc(sizeof(struct imx93_clk_gate), GFP_KERNEL);
if (!gate)
return ERR_PTR(-ENOMEM);
gate->reg = reg;
gate->lock = &imx_ccm_lock;
gate->bit_idx = bit_idx;
gate->val = val;
gate->mask = mask;
gate->share_count = share_count;
init.name = name;
init.ops = &imx93_clk_gate_ops;
init.flags = flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE;
init.parent_names = parent_name ? &parent_name : NULL;
init.num_parents = parent_name ? 1 : 0;
gate->hw.init = &init;
hw = &gate->hw;
authen = readl(reg + AUTHEN_OFFSET);
if (!(authen & TZ_NS_MASK) || !(authen & BIT(WHITE_LIST_SHIFT + domain_id)))
init.ops = &imx93_clk_gate_ro_ops;
ret = clk_hw_register(dev, hw);
if (ret) {
kfree(gate);
return ERR_PTR(ret);
}
return hw;
}
EXPORT_SYMBOL_GPL(imx93_clk_gate);

View File

@ -665,8 +665,8 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
hws[IMX8MP_CLK_CAN1_ROOT] = imx_clk_hw_gate2("can1_root_clk", "can1", ccm_base + 0x4350, 0);
hws[IMX8MP_CLK_CAN2_ROOT] = imx_clk_hw_gate2("can2_root_clk", "can2", ccm_base + 0x4360, 0);
hws[IMX8MP_CLK_SDMA1_ROOT] = imx_clk_hw_gate4("sdma1_root_clk", "ipg_root", ccm_base + 0x43a0, 0);
hws[IMX8MP_CLK_ENET_QOS_ROOT] = imx_clk_hw_gate4("enet_qos_root_clk", "sim_enet_root_clk", ccm_base + 0x43b0, 0);
hws[IMX8MP_CLK_SIM_ENET_ROOT] = imx_clk_hw_gate4("sim_enet_root_clk", "enet_axi", ccm_base + 0x4400, 0);
hws[IMX8MP_CLK_ENET_QOS_ROOT] = imx_clk_hw_gate4("enet_qos_root_clk", "sim_enet_root_clk", ccm_base + 0x43b0, 0);
hws[IMX8MP_CLK_GPU2D_ROOT] = imx_clk_hw_gate4("gpu2d_root_clk", "gpu2d_core", ccm_base + 0x4450, 0);
hws[IMX8MP_CLK_GPU3D_ROOT] = imx_clk_hw_gate4("gpu3d_root_clk", "gpu3d_core", ccm_base + 0x4460, 0);
hws[IMX8MP_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", ccm_base + 0x4490, 0);

View File

@ -28,6 +28,11 @@ enum clk_sel {
MAX_SEL
};
static u32 share_count_sai1;
static u32 share_count_sai2;
static u32 share_count_sai3;
static u32 share_count_mub;
static const char *parent_names[MAX_SEL][4] = {
{"osc_24m", "sys_pll_pfd0_div2", "sys_pll_pfd1_div2", "video_pll"},
{"osc_24m", "sys_pll_pfd0_div2", "sys_pll_pfd1_div2", "sys_pll_pfd2_div2"},
@ -146,6 +151,7 @@ static const struct imx93_clk_ccgr {
char *parent_name;
u32 off;
unsigned long flags;
u32 *shared_count;
} ccgr_array[] = {
{ IMX93_CLK_A55_GATE, "a55", "a55_root", 0x8000, },
/* M33 critical clk for system run */
@ -158,8 +164,10 @@ static const struct imx93_clk_ccgr {
{ IMX93_CLK_WDOG5_GATE, "wdog5", "osc_24m", 0x8400, },
{ IMX93_CLK_SEMA1_GATE, "sema1", "bus_aon_root", 0x8440, },
{ IMX93_CLK_SEMA2_GATE, "sema2", "bus_wakeup_root", 0x8480, },
{ IMX93_CLK_MU_A_GATE, "mu_a", "bus_aon_root", 0x84c0, },
{ IMX93_CLK_MU_B_GATE, "mu_b", "bus_aon_root", 0x8500, },
{ IMX93_CLK_MU1_A_GATE, "mu1_a", "bus_aon_root", 0x84c0, CLK_IGNORE_UNUSED },
{ IMX93_CLK_MU2_A_GATE, "mu2_a", "bus_wakeup_root", 0x84c0, CLK_IGNORE_UNUSED },
{ IMX93_CLK_MU1_B_GATE, "mu1_b", "bus_aon_root", 0x8500, 0, &share_count_mub },
{ IMX93_CLK_MU2_B_GATE, "mu2_b", "bus_wakeup_root", 0x8500, 0, &share_count_mub },
{ IMX93_CLK_EDMA1_GATE, "edma1", "m33_root", 0x8540, },
{ IMX93_CLK_EDMA2_GATE, "edma2", "wakeup_axi_root", 0x8580, },
{ IMX93_CLK_FLEXSPI1_GATE, "flexspi", "flexspi_root", 0x8640, },
@ -210,9 +218,12 @@ static const struct imx93_clk_ccgr {
{ IMX93_CLK_USDHC1_GATE, "usdhc1", "usdhc1_root", 0x9380, },
{ IMX93_CLK_USDHC2_GATE, "usdhc2", "usdhc2_root", 0x93c0, },
{ IMX93_CLK_USDHC3_GATE, "usdhc3", "usdhc3_root", 0x9400, },
{ IMX93_CLK_SAI1_GATE, "sai1", "sai1_root", 0x9440, },
{ IMX93_CLK_SAI2_GATE, "sai2", "sai2_root", 0x9480, },
{ IMX93_CLK_SAI3_GATE, "sai3", "sai3_root", 0x94c0, },
{ IMX93_CLK_SAI1_GATE, "sai1", "sai1_root", 0x9440, 0, &share_count_sai1},
{ IMX93_CLK_SAI1_IPG, "sai1_ipg_clk", "bus_aon_root", 0x9440, 0, &share_count_sai1},
{ IMX93_CLK_SAI2_GATE, "sai2", "sai2_root", 0x9480, 0, &share_count_sai2},
{ IMX93_CLK_SAI2_IPG, "sai2_ipg_clk", "bus_wakeup_root", 0x9480, 0, &share_count_sai2},
{ IMX93_CLK_SAI3_GATE, "sai3", "sai3_root", 0x94c0, 0, &share_count_sai3},
{ IMX93_CLK_SAI3_IPG, "sai3_ipg_clk", "bus_wakeup_root", 0x94c0, 0, &share_count_sai3},
{ IMX93_CLK_MIPI_CSI_GATE, "mipi_csi", "media_apb_root", 0x9580, },
{ IMX93_CLK_MIPI_DSI_GATE, "mipi_dsi", "media_apb_root", 0x95c0, },
{ IMX93_CLK_LVDS_GATE, "lvds", "media_ldb_root", 0x9600, },
@ -293,16 +304,15 @@ static int imx93_clocks_probe(struct platform_device *pdev)
root = &root_array[i];
clks[root->clk] = imx93_clk_composite_flags(root->name,
parent_names[root->sel],
4, base + root->off,
4, base + root->off, 3,
root->flags);
}
for (i = 0; i < ARRAY_SIZE(ccgr_array); i++) {
ccgr = &ccgr_array[i];
clks[ccgr->clk] = imx_clk_hw_gate4_flags(ccgr->name,
ccgr->parent_name,
base + ccgr->off, 0,
ccgr->flags);
clks[ccgr->clk] = imx93_clk_gate(NULL, ccgr->name, ccgr->parent_name,
ccgr->flags, base + ccgr->off, 0, 1, 1, 3,
ccgr->shared_count);
}
imx_check_clk_hws(clks, IMX93_CLK_END);

View File

@ -695,7 +695,11 @@ struct clk_hw *imx_clk_scu_alloc_dev(const char *name,
pr_warn("%s: failed to attached the power domain %d\n",
name, ret);
platform_device_add(pdev);
ret = platform_device_add(pdev);
if (ret) {
platform_device_put(pdev);
return ERR_PTR(ret);
}
/* For API backwards compatiblilty, simply return NULL for success */
return NULL;

View File

@ -445,11 +445,16 @@ struct clk_hw *imx93_clk_composite_flags(const char *name,
const char * const *parent_names,
int num_parents,
void __iomem *reg,
u32 domain_id,
unsigned long flags);
#define imx93_clk_composite(name, parent_names, num_parents, reg) \
imx93_clk_composite_flags(name, parent_names, num_parents, reg, \
#define imx93_clk_composite(name, parent_names, num_parents, reg, domain_id) \
imx93_clk_composite_flags(name, parent_names, num_parents, reg, domain_id \
CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
struct clk_hw *imx93_clk_gate(struct device *dev, const char *name, const char *parent_name,
unsigned long flags, void __iomem *reg, u32 bit_idx, u32 val,
u32 mask, u32 domain_id, unsigned int *share_count);
struct clk_hw *imx_clk_hw_divider_gate(const char *name, const char *parent_name,
unsigned long flags, void __iomem *reg, u8 shift, u8 width,
u8 clk_divider_flags, const struct clk_div_table *table,

View File

@ -6,5 +6,6 @@ config COMMON_CLK_PIC32
config MCHP_CLK_MPFS
bool "Clk driver for PolarFire SoC"
depends on (RISCV && SOC_MICROCHIP_POLARFIRE) || COMPILE_TEST
select AUXILIARY_BUS
help
Supports Clock Configuration for PolarFire SoC

View File

@ -2,3 +2,4 @@
obj-$(CONFIG_COMMON_CLK_PIC32) += clk-core.o
obj-$(CONFIG_PIC32MZDA) += clk-pic32mzda.o
obj-$(CONFIG_MCHP_CLK_MPFS) += clk-mpfs.o
obj-$(CONFIG_MCHP_CLK_MPFS) += clk-mpfs-ccc.o

View File

@ -0,0 +1,290 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Author: Conor Dooley <conor.dooley@microchip.com>
*
* Copyright (C) 2022 Microchip Technology Inc. and its subsidiaries
*/
#include "asm-generic/errno-base.h"
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <dt-bindings/clock/microchip,mpfs-clock.h>
/* address offset of control registers */
#define MPFS_CCC_PLL_CR 0x04u
#define MPFS_CCC_REF_CR 0x08u
#define MPFS_CCC_SSCG_2_CR 0x2Cu
#define MPFS_CCC_POSTDIV01_CR 0x10u
#define MPFS_CCC_POSTDIV23_CR 0x14u
#define MPFS_CCC_FBDIV_SHIFT 0x00u
#define MPFS_CCC_FBDIV_WIDTH 0x0Cu
#define MPFS_CCC_POSTDIV0_SHIFT 0x08u
#define MPFS_CCC_POSTDIV1_SHIFT 0x18u
#define MPFS_CCC_POSTDIV2_SHIFT MPFS_CCC_POSTDIV0_SHIFT
#define MPFS_CCC_POSTDIV3_SHIFT MPFS_CCC_POSTDIV1_SHIFT
#define MPFS_CCC_POSTDIV_WIDTH 0x06u
#define MPFS_CCC_REFCLK_SEL BIT(6)
#define MPFS_CCC_REFDIV_SHIFT 0x08u
#define MPFS_CCC_REFDIV_WIDTH 0x06u
#define MPFS_CCC_FIXED_DIV 4
#define MPFS_CCC_OUTPUTS_PER_PLL 4
#define MPFS_CCC_REFS_PER_PLL 2
struct mpfs_ccc_data {
void __iomem **pll_base;
struct device *dev;
struct clk_hw_onecell_data hw_data;
};
struct mpfs_ccc_pll_hw_clock {
void __iomem *base;
const char *name;
const struct clk_parent_data *parents;
unsigned int id;
u32 reg_offset;
u32 shift;
u32 width;
u32 flags;
struct clk_hw hw;
struct clk_init_data init;
};
#define to_mpfs_ccc_clk(_hw) container_of(_hw, struct mpfs_ccc_pll_hw_clock, hw)
/*
* mpfs_ccc_lock prevents anything else from writing to a fabric ccc
* while a software locked register is being written.
*/
static DEFINE_SPINLOCK(mpfs_ccc_lock);
static const struct clk_parent_data mpfs_ccc_pll0_refs[] = {
{ .fw_name = "pll0_ref0" },
{ .fw_name = "pll0_ref1" },
};
static const struct clk_parent_data mpfs_ccc_pll1_refs[] = {
{ .fw_name = "pll1_ref0" },
{ .fw_name = "pll1_ref1" },
};
static unsigned long mpfs_ccc_pll_recalc_rate(struct clk_hw *hw, unsigned long prate)
{
struct mpfs_ccc_pll_hw_clock *ccc_hw = to_mpfs_ccc_clk(hw);
void __iomem *mult_addr = ccc_hw->base + ccc_hw->reg_offset;
void __iomem *ref_div_addr = ccc_hw->base + MPFS_CCC_REF_CR;
u32 mult, ref_div;
mult = readl_relaxed(mult_addr) >> MPFS_CCC_FBDIV_SHIFT;
mult &= clk_div_mask(MPFS_CCC_FBDIV_WIDTH);
ref_div = readl_relaxed(ref_div_addr) >> MPFS_CCC_REFDIV_SHIFT;
ref_div &= clk_div_mask(MPFS_CCC_REFDIV_WIDTH);
return prate * mult / (ref_div * MPFS_CCC_FIXED_DIV);
}
static u8 mpfs_ccc_pll_get_parent(struct clk_hw *hw)
{
struct mpfs_ccc_pll_hw_clock *ccc_hw = to_mpfs_ccc_clk(hw);
void __iomem *pll_cr_addr = ccc_hw->base + MPFS_CCC_PLL_CR;
return !!(readl_relaxed(pll_cr_addr) & MPFS_CCC_REFCLK_SEL);
}
static const struct clk_ops mpfs_ccc_pll_ops = {
.recalc_rate = mpfs_ccc_pll_recalc_rate,
.get_parent = mpfs_ccc_pll_get_parent,
};
#define CLK_CCC_PLL(_id, _parents, _shift, _width, _flags, _offset) { \
.id = _id, \
.shift = _shift, \
.width = _width, \
.reg_offset = _offset, \
.flags = _flags, \
.parents = _parents, \
}
static struct mpfs_ccc_pll_hw_clock mpfs_ccc_pll_clks[] = {
CLK_CCC_PLL(CLK_CCC_PLL0, mpfs_ccc_pll0_refs, MPFS_CCC_FBDIV_SHIFT,
MPFS_CCC_FBDIV_WIDTH, 0, MPFS_CCC_SSCG_2_CR),
CLK_CCC_PLL(CLK_CCC_PLL1, mpfs_ccc_pll1_refs, MPFS_CCC_FBDIV_SHIFT,
MPFS_CCC_FBDIV_WIDTH, 0, MPFS_CCC_SSCG_2_CR),
};
struct mpfs_ccc_out_hw_clock {
struct clk_divider divider;
struct clk_init_data init;
unsigned int id;
u32 reg_offset;
};
#define CLK_CCC_OUT(_id, _shift, _width, _flags, _offset) { \
.id = _id, \
.divider.shift = _shift, \
.divider.width = _width, \
.reg_offset = _offset, \
.divider.flags = _flags, \
.divider.lock = &mpfs_ccc_lock, \
}
static struct mpfs_ccc_out_hw_clock mpfs_ccc_pll0out_clks[] = {
CLK_CCC_OUT(CLK_CCC_PLL0_OUT0, MPFS_CCC_POSTDIV0_SHIFT, MPFS_CCC_POSTDIV_WIDTH,
CLK_DIVIDER_ONE_BASED, MPFS_CCC_POSTDIV01_CR),
CLK_CCC_OUT(CLK_CCC_PLL0_OUT1, MPFS_CCC_POSTDIV1_SHIFT, MPFS_CCC_POSTDIV_WIDTH,
CLK_DIVIDER_ONE_BASED, MPFS_CCC_POSTDIV01_CR),
CLK_CCC_OUT(CLK_CCC_PLL0_OUT2, MPFS_CCC_POSTDIV2_SHIFT, MPFS_CCC_POSTDIV_WIDTH,
CLK_DIVIDER_ONE_BASED, MPFS_CCC_POSTDIV23_CR),
CLK_CCC_OUT(CLK_CCC_PLL0_OUT3, MPFS_CCC_POSTDIV3_SHIFT, MPFS_CCC_POSTDIV_WIDTH,
CLK_DIVIDER_ONE_BASED, MPFS_CCC_POSTDIV23_CR),
};
static struct mpfs_ccc_out_hw_clock mpfs_ccc_pll1out_clks[] = {
CLK_CCC_OUT(CLK_CCC_PLL1_OUT0, MPFS_CCC_POSTDIV0_SHIFT, MPFS_CCC_POSTDIV_WIDTH,
CLK_DIVIDER_ONE_BASED, MPFS_CCC_POSTDIV01_CR),
CLK_CCC_OUT(CLK_CCC_PLL1_OUT1, MPFS_CCC_POSTDIV1_SHIFT, MPFS_CCC_POSTDIV_WIDTH,
CLK_DIVIDER_ONE_BASED, MPFS_CCC_POSTDIV01_CR),
CLK_CCC_OUT(CLK_CCC_PLL1_OUT2, MPFS_CCC_POSTDIV2_SHIFT, MPFS_CCC_POSTDIV_WIDTH,
CLK_DIVIDER_ONE_BASED, MPFS_CCC_POSTDIV23_CR),
CLK_CCC_OUT(CLK_CCC_PLL1_OUT3, MPFS_CCC_POSTDIV3_SHIFT, MPFS_CCC_POSTDIV_WIDTH,
CLK_DIVIDER_ONE_BASED, MPFS_CCC_POSTDIV23_CR),
};
static struct mpfs_ccc_out_hw_clock *mpfs_ccc_pllout_clks[] = {
mpfs_ccc_pll0out_clks, mpfs_ccc_pll1out_clks
};
static int mpfs_ccc_register_outputs(struct device *dev, struct mpfs_ccc_out_hw_clock *out_hws,
unsigned int num_clks, struct mpfs_ccc_data *data,
struct mpfs_ccc_pll_hw_clock *parent)
{
int ret;
for (unsigned int i = 0; i < num_clks; i++) {
struct mpfs_ccc_out_hw_clock *out_hw = &out_hws[i];
char *name = devm_kzalloc(dev, 23, GFP_KERNEL);
snprintf(name, 23, "%s_out%u", parent->name, i);
out_hw->divider.hw.init = CLK_HW_INIT_HW(name, &parent->hw, &clk_divider_ops, 0);
out_hw->divider.reg = data->pll_base[i / MPFS_CCC_OUTPUTS_PER_PLL] +
out_hw->reg_offset;
ret = devm_clk_hw_register(dev, &out_hw->divider.hw);
if (ret)
return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
out_hw->id);
data->hw_data.hws[out_hw->id] = &out_hw->divider.hw;
}
return 0;
}
#define CLK_HW_INIT_PARENTS_DATA_FIXED_SIZE(_name, _parents, _ops, _flags) \
(&(struct clk_init_data) { \
.flags = _flags, \
.name = _name, \
.parent_data = _parents, \
.num_parents = MPFS_CCC_REFS_PER_PLL, \
.ops = _ops, \
})
static int mpfs_ccc_register_plls(struct device *dev, struct mpfs_ccc_pll_hw_clock *pll_hws,
unsigned int num_clks, struct mpfs_ccc_data *data)
{
int ret;
for (unsigned int i = 0; i < num_clks; i++) {
struct mpfs_ccc_pll_hw_clock *pll_hw = &pll_hws[i];
char *name = devm_kzalloc(dev, 18, GFP_KERNEL);
pll_hw->base = data->pll_base[i];
snprintf(name, 18, "ccc%s_pll%u", strchrnul(dev->of_node->full_name, '@'), i);
pll_hw->name = (const char *)name;
pll_hw->hw.init = CLK_HW_INIT_PARENTS_DATA_FIXED_SIZE(pll_hw->name,
pll_hw->parents,
&mpfs_ccc_pll_ops, 0);
ret = devm_clk_hw_register(dev, &pll_hw->hw);
if (ret)
return dev_err_probe(dev, ret, "failed to register ccc id: %d\n",
pll_hw->id);
data->hw_data.hws[pll_hw->id] = &pll_hw->hw;
ret = mpfs_ccc_register_outputs(dev, mpfs_ccc_pllout_clks[i],
MPFS_CCC_OUTPUTS_PER_PLL, data, pll_hw);
if (ret)
return ret;
}
return 0;
}
static int mpfs_ccc_probe(struct platform_device *pdev)
{
struct mpfs_ccc_data *clk_data;
void __iomem *pll_base[ARRAY_SIZE(mpfs_ccc_pll_clks)];
unsigned int num_clks;
int ret;
num_clks = ARRAY_SIZE(mpfs_ccc_pll_clks) + ARRAY_SIZE(mpfs_ccc_pll0out_clks) +
ARRAY_SIZE(mpfs_ccc_pll1out_clks);
clk_data = devm_kzalloc(&pdev->dev, struct_size(clk_data, hw_data.hws, num_clks),
GFP_KERNEL);
if (!clk_data)
return -ENOMEM;
pll_base[0] = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pll_base[0]))
return PTR_ERR(pll_base[0]);
pll_base[1] = devm_platform_ioremap_resource(pdev, 1);
if (IS_ERR(pll_base[1]))
return PTR_ERR(pll_base[1]);
clk_data->pll_base = pll_base;
clk_data->hw_data.num = num_clks;
clk_data->dev = &pdev->dev;
ret = mpfs_ccc_register_plls(clk_data->dev, mpfs_ccc_pll_clks,
ARRAY_SIZE(mpfs_ccc_pll_clks), clk_data);
if (ret)
return ret;
return devm_of_clk_add_hw_provider(clk_data->dev, of_clk_hw_onecell_get,
&clk_data->hw_data);
}
static const struct of_device_id mpfs_ccc_of_match_table[] = {
{ .compatible = "microchip,mpfs-ccc", },
{}
};
MODULE_DEVICE_TABLE(of, mpfs_ccc_of_match_table);
static struct platform_driver mpfs_ccc_driver = {
.probe = mpfs_ccc_probe,
.driver = {
.name = "microchip-mpfs-ccc",
.of_match_table = mpfs_ccc_of_match_table,
},
};
static int __init clk_ccc_init(void)
{
return platform_driver_register(&mpfs_ccc_driver);
}
core_initcall(clk_ccc_init);
static void __exit clk_ccc_exit(void)
{
platform_driver_unregister(&mpfs_ccc_driver);
}
module_exit(clk_ccc_exit);
MODULE_DESCRIPTION("Microchip PolarFire SoC Clock Conditioning Circuitry Driver");
MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>");
MODULE_LICENSE("GPL");

View File

@ -1,14 +1,17 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Daire McNamara,<daire.mcnamara@microchip.com>
* Copyright (C) 2020 Microchip Technology Inc. All rights reserved.
* PolarFire SoC MSS/core complex clock control
*
* Copyright (C) 2020-2022 Microchip Technology Inc. All rights reserved.
*/
#include <linux/auxiliary_bus.h>
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <dt-bindings/clock/microchip,mpfs-clock.h>
#include <soc/microchip/mpfs.h>
/* address offset of control registers */
#define REG_MSSPLL_REF_CR 0x08u
@ -28,6 +31,7 @@
#define MSSPLL_FIXED_DIV 4u
struct mpfs_clock_data {
struct device *dev;
void __iomem *base;
void __iomem *msspll_base;
struct clk_hw_onecell_data hw_data;
@ -46,37 +50,18 @@ struct mpfs_msspll_hw_clock {
#define to_mpfs_msspll_clk(_hw) container_of(_hw, struct mpfs_msspll_hw_clock, hw)
struct mpfs_cfg_clock {
const struct clk_div_table *table;
struct mpfs_cfg_hw_clock {
struct clk_divider cfg;
struct clk_init_data init;
unsigned int id;
u32 reg_offset;
u8 shift;
u8 width;
u8 flags;
};
struct mpfs_cfg_hw_clock {
struct mpfs_cfg_clock cfg;
void __iomem *sys_base;
struct clk_hw hw;
struct clk_init_data init;
};
#define to_mpfs_cfg_clk(_hw) container_of(_hw, struct mpfs_cfg_hw_clock, hw)
struct mpfs_periph_clock {
unsigned int id;
u8 shift;
};
struct mpfs_periph_hw_clock {
struct mpfs_periph_clock periph;
void __iomem *sys_base;
struct clk_hw hw;
struct clk_gate periph;
unsigned int id;
};
#define to_mpfs_periph_clk(_hw) container_of(_hw, struct mpfs_periph_hw_clock, hw)
/*
* mpfs_clk_lock prevents anything else from writing to the
* mpfs clk block while a software locked register is being written.
@ -126,8 +111,62 @@ static unsigned long mpfs_clk_msspll_recalc_rate(struct clk_hw *hw, unsigned lon
return prate * mult / (ref_div * MSSPLL_FIXED_DIV * postdiv);
}
static long mpfs_clk_msspll_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate)
{
struct mpfs_msspll_hw_clock *msspll_hw = to_mpfs_msspll_clk(hw);
void __iomem *mult_addr = msspll_hw->base + msspll_hw->reg_offset;
void __iomem *ref_div_addr = msspll_hw->base + REG_MSSPLL_REF_CR;
u32 mult, ref_div;
unsigned long rate_before_ctrl;
mult = readl_relaxed(mult_addr) >> MSSPLL_FBDIV_SHIFT;
mult &= clk_div_mask(MSSPLL_FBDIV_WIDTH);
ref_div = readl_relaxed(ref_div_addr) >> MSSPLL_REFDIV_SHIFT;
ref_div &= clk_div_mask(MSSPLL_REFDIV_WIDTH);
rate_before_ctrl = rate * (ref_div * MSSPLL_FIXED_DIV) / mult;
return divider_round_rate(hw, rate_before_ctrl, prate, NULL, MSSPLL_POSTDIV_WIDTH,
msspll_hw->flags);
}
static int mpfs_clk_msspll_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long prate)
{
struct mpfs_msspll_hw_clock *msspll_hw = to_mpfs_msspll_clk(hw);
void __iomem *mult_addr = msspll_hw->base + msspll_hw->reg_offset;
void __iomem *ref_div_addr = msspll_hw->base + REG_MSSPLL_REF_CR;
void __iomem *postdiv_addr = msspll_hw->base + REG_MSSPLL_POSTDIV_CR;
u32 mult, ref_div, postdiv;
int divider_setting;
unsigned long rate_before_ctrl, flags;
mult = readl_relaxed(mult_addr) >> MSSPLL_FBDIV_SHIFT;
mult &= clk_div_mask(MSSPLL_FBDIV_WIDTH);
ref_div = readl_relaxed(ref_div_addr) >> MSSPLL_REFDIV_SHIFT;
ref_div &= clk_div_mask(MSSPLL_REFDIV_WIDTH);
rate_before_ctrl = rate * (ref_div * MSSPLL_FIXED_DIV) / mult;
divider_setting = divider_get_val(rate_before_ctrl, prate, NULL, MSSPLL_POSTDIV_WIDTH,
msspll_hw->flags);
if (divider_setting < 0)
return divider_setting;
spin_lock_irqsave(&mpfs_clk_lock, flags);
postdiv = readl_relaxed(postdiv_addr);
postdiv &= ~(clk_div_mask(MSSPLL_POSTDIV_WIDTH) << MSSPLL_POSTDIV_SHIFT);
writel_relaxed(postdiv, postdiv_addr);
spin_unlock_irqrestore(&mpfs_clk_lock, flags);
return 0;
}
static const struct clk_ops mpfs_clk_msspll_ops = {
.recalc_rate = mpfs_clk_msspll_recalc_rate,
.round_rate = mpfs_clk_msspll_round_rate,
.set_rate = mpfs_clk_msspll_set_rate,
};
#define CLK_PLL(_id, _name, _parent, _shift, _width, _flags, _offset) { \
@ -144,25 +183,17 @@ static struct mpfs_msspll_hw_clock mpfs_msspll_clks[] = {
MSSPLL_FBDIV_WIDTH, 0, REG_MSSPLL_SSCG_2_CR),
};
static int mpfs_clk_register_msspll(struct device *dev, struct mpfs_msspll_hw_clock *msspll_hw,
void __iomem *base)
{
msspll_hw->base = base;
return devm_clk_hw_register(dev, &msspll_hw->hw);
}
static int mpfs_clk_register_mssplls(struct device *dev, struct mpfs_msspll_hw_clock *msspll_hws,
unsigned int num_clks, struct mpfs_clock_data *data)
{
void __iomem *base = data->msspll_base;
unsigned int i;
int ret;
for (i = 0; i < num_clks; i++) {
struct mpfs_msspll_hw_clock *msspll_hw = &msspll_hws[i];
ret = mpfs_clk_register_msspll(dev, msspll_hw, base);
msspll_hw->base = data->msspll_base;
ret = devm_clk_hw_register(dev, &msspll_hw->hw);
if (ret)
return dev_err_probe(dev, ret, "failed to register msspll id: %d\n",
CLK_MSSPLL);
@ -177,68 +208,22 @@ static int mpfs_clk_register_mssplls(struct device *dev, struct mpfs_msspll_hw_c
* "CFG" clocks
*/
static unsigned long mpfs_cfg_clk_recalc_rate(struct clk_hw *hw, unsigned long prate)
{
struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw);
struct mpfs_cfg_clock *cfg = &cfg_hw->cfg;
void __iomem *base_addr = cfg_hw->sys_base;
u32 val;
val = readl_relaxed(base_addr + cfg->reg_offset) >> cfg->shift;
val &= clk_div_mask(cfg->width);
return divider_recalc_rate(hw, prate, val, cfg->table, cfg->flags, cfg->width);
}
static long mpfs_cfg_clk_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate)
{
struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw);
struct mpfs_cfg_clock *cfg = &cfg_hw->cfg;
return divider_round_rate(hw, rate, prate, cfg->table, cfg->width, 0);
}
static int mpfs_cfg_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long prate)
{
struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw);
struct mpfs_cfg_clock *cfg = &cfg_hw->cfg;
void __iomem *base_addr = cfg_hw->sys_base;
unsigned long flags;
u32 val;
int divider_setting;
divider_setting = divider_get_val(rate, prate, cfg->table, cfg->width, 0);
if (divider_setting < 0)
return divider_setting;
spin_lock_irqsave(&mpfs_clk_lock, flags);
val = readl_relaxed(base_addr + cfg->reg_offset);
val &= ~(clk_div_mask(cfg->width) << cfg_hw->cfg.shift);
val |= divider_setting << cfg->shift;
writel_relaxed(val, base_addr + cfg->reg_offset);
spin_unlock_irqrestore(&mpfs_clk_lock, flags);
return 0;
}
static const struct clk_ops mpfs_clk_cfg_ops = {
.recalc_rate = mpfs_cfg_clk_recalc_rate,
.round_rate = mpfs_cfg_clk_round_rate,
.set_rate = mpfs_cfg_clk_set_rate,
};
#define CLK_CFG(_id, _name, _parent, _shift, _width, _table, _flags, _offset) { \
.cfg.id = _id, \
.id = _id, \
.cfg.shift = _shift, \
.cfg.width = _width, \
.cfg.table = _table, \
.cfg.reg_offset = _offset, \
.reg_offset = _offset, \
.cfg.flags = _flags, \
.hw.init = CLK_HW_INIT(_name, _parent, &mpfs_clk_cfg_ops, 0), \
.cfg.hw.init = CLK_HW_INIT(_name, _parent, &clk_divider_ops, 0), \
.cfg.lock = &mpfs_clk_lock, \
}
#define CLK_CPU_OFFSET 0u
#define CLK_AXI_OFFSET 1u
#define CLK_AHB_OFFSET 2u
#define CLK_RTCREF_OFFSET 3u
static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] = {
CLK_CFG(CLK_CPU, "clk_cpu", "clk_msspll", 0, 2, mpfs_div_cpu_axi_table, 0,
REG_CLOCK_CONFIG_CR),
@ -247,42 +232,34 @@ static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] = {
CLK_CFG(CLK_AHB, "clk_ahb", "clk_msspll", 4, 2, mpfs_div_ahb_table, 0,
REG_CLOCK_CONFIG_CR),
{
.cfg.id = CLK_RTCREF,
.id = CLK_RTCREF,
.cfg.shift = 0,
.cfg.width = 12,
.cfg.table = mpfs_div_rtcref_table,
.cfg.reg_offset = REG_RTC_CLOCK_CR,
.reg_offset = REG_RTC_CLOCK_CR,
.cfg.flags = CLK_DIVIDER_ONE_BASED,
.hw.init =
CLK_HW_INIT_PARENTS_DATA("clk_rtcref", mpfs_ext_ref, &mpfs_clk_cfg_ops, 0),
.cfg.hw.init =
CLK_HW_INIT_PARENTS_DATA("clk_rtcref", mpfs_ext_ref, &clk_divider_ops, 0),
}
};
static int mpfs_clk_register_cfg(struct device *dev, struct mpfs_cfg_hw_clock *cfg_hw,
void __iomem *sys_base)
{
cfg_hw->sys_base = sys_base;
return devm_clk_hw_register(dev, &cfg_hw->hw);
}
static int mpfs_clk_register_cfgs(struct device *dev, struct mpfs_cfg_hw_clock *cfg_hws,
unsigned int num_clks, struct mpfs_clock_data *data)
{
void __iomem *sys_base = data->base;
unsigned int i, id;
int ret;
for (i = 0; i < num_clks; i++) {
struct mpfs_cfg_hw_clock *cfg_hw = &cfg_hws[i];
ret = mpfs_clk_register_cfg(dev, cfg_hw, sys_base);
cfg_hw->cfg.reg = data->base + cfg_hw->reg_offset;
ret = devm_clk_hw_register(dev, &cfg_hw->cfg.hw);
if (ret)
return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
cfg_hw->cfg.id);
cfg_hw->id);
id = cfg_hw->cfg.id;
data->hw_data.hws[id] = &cfg_hw->hw;
id = cfg_hw->id;
data->hw_data.hws[id] = &cfg_hw->cfg.hw;
}
return 0;
@ -292,77 +269,15 @@ static int mpfs_clk_register_cfgs(struct device *dev, struct mpfs_cfg_hw_clock *
* peripheral clocks - devices connected to axi or ahb buses.
*/
static int mpfs_periph_clk_enable(struct clk_hw *hw)
{
struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
struct mpfs_periph_clock *periph = &periph_hw->periph;
void __iomem *base_addr = periph_hw->sys_base;
u32 reg, val;
unsigned long flags;
spin_lock_irqsave(&mpfs_clk_lock, flags);
reg = readl_relaxed(base_addr + REG_SUBBLK_RESET_CR);
val = reg & ~(1u << periph->shift);
writel_relaxed(val, base_addr + REG_SUBBLK_RESET_CR);
reg = readl_relaxed(base_addr + REG_SUBBLK_CLOCK_CR);
val = reg | (1u << periph->shift);
writel_relaxed(val, base_addr + REG_SUBBLK_CLOCK_CR);
spin_unlock_irqrestore(&mpfs_clk_lock, flags);
return 0;
}
static void mpfs_periph_clk_disable(struct clk_hw *hw)
{
struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
struct mpfs_periph_clock *periph = &periph_hw->periph;
void __iomem *base_addr = periph_hw->sys_base;
u32 reg, val;
unsigned long flags;
spin_lock_irqsave(&mpfs_clk_lock, flags);
reg = readl_relaxed(base_addr + REG_SUBBLK_CLOCK_CR);
val = reg & ~(1u << periph->shift);
writel_relaxed(val, base_addr + REG_SUBBLK_CLOCK_CR);
spin_unlock_irqrestore(&mpfs_clk_lock, flags);
}
static int mpfs_periph_clk_is_enabled(struct clk_hw *hw)
{
struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
struct mpfs_periph_clock *periph = &periph_hw->periph;
void __iomem *base_addr = periph_hw->sys_base;
u32 reg;
reg = readl_relaxed(base_addr + REG_SUBBLK_RESET_CR);
if ((reg & (1u << periph->shift)) == 0u) {
reg = readl_relaxed(base_addr + REG_SUBBLK_CLOCK_CR);
if (reg & (1u << periph->shift))
return 1;
}
return 0;
}
static const struct clk_ops mpfs_periph_clk_ops = {
.enable = mpfs_periph_clk_enable,
.disable = mpfs_periph_clk_disable,
.is_enabled = mpfs_periph_clk_is_enabled,
};
#define CLK_PERIPH(_id, _name, _parent, _shift, _flags) { \
.periph.id = _id, \
.periph.shift = _shift, \
.hw.init = CLK_HW_INIT_HW(_name, _parent, &mpfs_periph_clk_ops, \
.id = _id, \
.periph.bit_idx = _shift, \
.periph.hw.init = CLK_HW_INIT_HW(_name, _parent, &clk_gate_ops, \
_flags), \
.periph.lock = &mpfs_clk_lock, \
}
#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT].hw)
#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT##_OFFSET].cfg.hw)
/*
* Critical clocks:
@ -370,6 +285,8 @@ static const struct clk_ops mpfs_periph_clk_ops = {
* trap handler
* - CLK_MMUART0: reserved by the hss
* - CLK_DDRC: provides clock to the ddr subsystem
* - CLK_RTC: the onboard RTC's AHB bus clock must be kept running as the rtc will stop
* if the AHB interface clock is disabled
* - CLK_FICx: these provide the processor side clocks to the "FIC" (Fabric InterConnect)
* clock domain crossers which provide the interface to the FPGA fabric. Disabling them
* causes the FPGA fabric to go into reset.
@ -394,7 +311,7 @@ static struct mpfs_periph_hw_clock mpfs_periph_clks[] = {
CLK_PERIPH(CLK_CAN0, "clk_periph_can0", PARENT_CLK(AHB), 14, 0),
CLK_PERIPH(CLK_CAN1, "clk_periph_can1", PARENT_CLK(AHB), 15, 0),
CLK_PERIPH(CLK_USB, "clk_periph_usb", PARENT_CLK(AHB), 16, 0),
CLK_PERIPH(CLK_RTC, "clk_periph_rtc", PARENT_CLK(AHB), 18, 0),
CLK_PERIPH(CLK_RTC, "clk_periph_rtc", PARENT_CLK(AHB), 18, CLK_IS_CRITICAL),
CLK_PERIPH(CLK_QSPI, "clk_periph_qspi", PARENT_CLK(AHB), 19, 0),
CLK_PERIPH(CLK_GPIO0, "clk_periph_gpio0", PARENT_CLK(AHB), 20, 0),
CLK_PERIPH(CLK_GPIO1, "clk_periph_gpio1", PARENT_CLK(AHB), 21, 0),
@ -408,36 +325,116 @@ static struct mpfs_periph_hw_clock mpfs_periph_clks[] = {
CLK_PERIPH(CLK_CFM, "clk_periph_cfm", PARENT_CLK(AHB), 29, 0),
};
static int mpfs_clk_register_periph(struct device *dev, struct mpfs_periph_hw_clock *periph_hw,
void __iomem *sys_base)
{
periph_hw->sys_base = sys_base;
return devm_clk_hw_register(dev, &periph_hw->hw);
}
static int mpfs_clk_register_periphs(struct device *dev, struct mpfs_periph_hw_clock *periph_hws,
int num_clks, struct mpfs_clock_data *data)
{
void __iomem *sys_base = data->base;
unsigned int i, id;
int ret;
for (i = 0; i < num_clks; i++) {
struct mpfs_periph_hw_clock *periph_hw = &periph_hws[i];
ret = mpfs_clk_register_periph(dev, periph_hw, sys_base);
periph_hw->periph.reg = data->base + REG_SUBBLK_CLOCK_CR;
ret = devm_clk_hw_register(dev, &periph_hw->periph.hw);
if (ret)
return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
periph_hw->periph.id);
periph_hw->id);
id = periph_hws[i].periph.id;
data->hw_data.hws[id] = &periph_hw->hw;
id = periph_hws[i].id;
data->hw_data.hws[id] = &periph_hw->periph.hw;
}
return 0;
}
/*
* Peripheral clock resets
*/
#if IS_ENABLED(CONFIG_RESET_CONTROLLER)
u32 mpfs_reset_read(struct device *dev)
{
struct mpfs_clock_data *clock_data = dev_get_drvdata(dev->parent);
return readl_relaxed(clock_data->base + REG_SUBBLK_RESET_CR);
}
EXPORT_SYMBOL_NS_GPL(mpfs_reset_read, MCHP_CLK_MPFS);
void mpfs_reset_write(struct device *dev, u32 val)
{
struct mpfs_clock_data *clock_data = dev_get_drvdata(dev->parent);
writel_relaxed(val, clock_data->base + REG_SUBBLK_RESET_CR);
}
EXPORT_SYMBOL_NS_GPL(mpfs_reset_write, MCHP_CLK_MPFS);
static void mpfs_reset_unregister_adev(void *_adev)
{
struct auxiliary_device *adev = _adev;
auxiliary_device_delete(adev);
}
static void mpfs_reset_adev_release(struct device *dev)
{
struct auxiliary_device *adev = to_auxiliary_dev(dev);
auxiliary_device_uninit(adev);
kfree(adev);
}
static struct auxiliary_device *mpfs_reset_adev_alloc(struct mpfs_clock_data *clk_data)
{
struct auxiliary_device *adev;
int ret;
adev = kzalloc(sizeof(*adev), GFP_KERNEL);
if (!adev)
return ERR_PTR(-ENOMEM);
adev->name = "reset-mpfs";
adev->dev.parent = clk_data->dev;
adev->dev.release = mpfs_reset_adev_release;
adev->id = 666u;
ret = auxiliary_device_init(adev);
if (ret) {
kfree(adev);
return ERR_PTR(ret);
}
return adev;
}
static int mpfs_reset_controller_register(struct mpfs_clock_data *clk_data)
{
struct auxiliary_device *adev;
int ret;
adev = mpfs_reset_adev_alloc(clk_data);
if (IS_ERR(adev))
return PTR_ERR(adev);
ret = auxiliary_device_add(adev);
if (ret) {
auxiliary_device_uninit(adev);
return ret;
}
return devm_add_action_or_reset(clk_data->dev, mpfs_reset_unregister_adev, adev);
}
#else /* !CONFIG_RESET_CONTROLLER */
static int mpfs_reset_controller_register(struct mpfs_clock_data *clk_data)
{
return 0;
}
#endif /* !CONFIG_RESET_CONTROLLER */
static int mpfs_clk_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@ -462,6 +459,8 @@ static int mpfs_clk_probe(struct platform_device *pdev)
return PTR_ERR(clk_data->msspll_base);
clk_data->hw_data.num = num_clks;
clk_data->dev = dev;
dev_set_drvdata(dev, clk_data);
ret = mpfs_clk_register_mssplls(dev, mpfs_msspll_clks, ARRAY_SIZE(mpfs_msspll_clks),
clk_data);
@ -481,14 +480,14 @@ static int mpfs_clk_probe(struct platform_device *pdev)
if (ret)
return ret;
return ret;
return mpfs_reset_controller_register(clk_data);
}
static const struct of_device_id mpfs_clk_of_match_table[] = {
{ .compatible = "microchip,mpfs-clkcfg", },
{}
};
MODULE_DEVICE_TABLE(of, mpfs_clk_match_table);
MODULE_DEVICE_TABLE(of, mpfs_clk_of_match_table);
static struct platform_driver mpfs_clk_driver = {
.probe = mpfs_clk_probe,
@ -511,4 +510,7 @@ static void __exit clk_mpfs_exit(void)
module_exit(clk_mpfs_exit);
MODULE_DESCRIPTION("Microchip PolarFire SoC Clock Driver");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Padmarao Begari <padmarao.begari@microchip.com>");
MODULE_AUTHOR("Daire McNamara <daire.mcnamara@microchip.com>");
MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>");
MODULE_LICENSE("GPL");

View File

@ -108,7 +108,13 @@ static const struct cpg_core_clk r8a779f0_core_clks[] __initconst = {
DEF_FIXED("cbfusa", R8A779F0_CLK_CBFUSA, CLK_EXTAL, 2, 1),
DEF_FIXED("cpex", R8A779F0_CLK_CPEX, CLK_EXTAL, 2, 1),
DEF_GEN4_SD("sd0", R8A779F0_CLK_SD0, CLK_SDSRC, 0x870),
DEF_FIXED("sasyncrt", R8A779F0_CLK_SASYNCRT, CLK_PLL5_DIV4, 48, 1),
DEF_FIXED("sasyncperd1", R8A779F0_CLK_SASYNCPERD1, CLK_PLL5_DIV4, 3, 1),
DEF_FIXED("sasyncperd2", R8A779F0_CLK_SASYNCPERD2, R8A779F0_CLK_SASYNCPERD1, 2, 1),
DEF_FIXED("sasyncperd4", R8A779F0_CLK_SASYNCPERD4, R8A779F0_CLK_SASYNCPERD1, 4, 1),
DEF_GEN4_SDH("sdh0", R8A779F0_CLK_SD0H, CLK_SDSRC, 0x870),
DEF_GEN4_SD("sd0", R8A779F0_CLK_SD0, R8A779F0_CLK_SD0H, 0x870),
DEF_BASE("rpc", R8A779F0_CLK_RPC, CLK_TYPE_GEN4_RPC, CLK_RPCSRC),
DEF_BASE("rpcd2", R8A779F0_CLK_RPCD2, CLK_TYPE_GEN4_RPCD2, R8A779F0_CLK_RPC),
@ -130,6 +136,10 @@ static const struct mssr_mod_clk r8a779f0_mod_clks[] __initconst = {
DEF_MOD("i2c3", 521, R8A779F0_CLK_S0D6_PER),
DEF_MOD("i2c4", 522, R8A779F0_CLK_S0D6_PER),
DEF_MOD("i2c5", 523, R8A779F0_CLK_S0D6_PER),
DEF_MOD("msiof0", 618, R8A779F0_CLK_MSO),
DEF_MOD("msiof1", 619, R8A779F0_CLK_MSO),
DEF_MOD("msiof2", 620, R8A779F0_CLK_MSO),
DEF_MOD("msiof3", 621, R8A779F0_CLK_MSO),
DEF_MOD("pcie0", 624, R8A779F0_CLK_S0D2),
DEF_MOD("pcie1", 625, R8A779F0_CLK_S0D2),
DEF_MOD("scif0", 702, R8A779F0_CLK_S0D12_PER),
@ -139,7 +149,16 @@ static const struct mssr_mod_clk r8a779f0_mod_clks[] __initconst = {
DEF_MOD("sdhi0", 706, R8A779F0_CLK_SD0),
DEF_MOD("sys-dmac0", 709, R8A779F0_CLK_S0D3_PER),
DEF_MOD("sys-dmac1", 710, R8A779F0_CLK_S0D3_PER),
DEF_MOD("tmu0", 713, R8A779F0_CLK_SASYNCRT),
DEF_MOD("tmu1", 714, R8A779F0_CLK_SASYNCPERD2),
DEF_MOD("tmu2", 715, R8A779F0_CLK_SASYNCPERD2),
DEF_MOD("tmu3", 716, R8A779F0_CLK_SASYNCPERD2),
DEF_MOD("tmu4", 717, R8A779F0_CLK_SASYNCPERD2),
DEF_MOD("wdt", 907, R8A779F0_CLK_R),
DEF_MOD("cmt0", 910, R8A779F0_CLK_R),
DEF_MOD("cmt1", 911, R8A779F0_CLK_R),
DEF_MOD("cmt2", 912, R8A779F0_CLK_R),
DEF_MOD("cmt3", 913, R8A779F0_CLK_R),
DEF_MOD("pfc0", 915, R8A779F0_CLK_CL16M),
DEF_MOD("tsc", 919, R8A779F0_CLK_CL16M),
DEF_MOD("ufs", 1514, R8A779F0_CLK_S0D4_HSC),

View File

@ -150,10 +150,24 @@ static const struct cpg_core_clk r8a779g0_core_clks[] __initconst = {
};
static const struct mssr_mod_clk r8a779g0_mod_clks[] __initconst = {
DEF_MOD("avb0", 211, R8A779G0_CLK_S0D4_HSC),
DEF_MOD("avb1", 212, R8A779G0_CLK_S0D4_HSC),
DEF_MOD("avb2", 213, R8A779G0_CLK_S0D4_HSC),
DEF_MOD("hscif0", 514, R8A779G0_CLK_S0D3_PER),
DEF_MOD("hscif1", 515, R8A779G0_CLK_S0D3_PER),
DEF_MOD("hscif2", 516, R8A779G0_CLK_S0D3_PER),
DEF_MOD("hscif3", 517, R8A779G0_CLK_S0D3_PER),
DEF_MOD("i2c0", 518, R8A779G0_CLK_S0D6_PER),
DEF_MOD("i2c1", 519, R8A779G0_CLK_S0D6_PER),
DEF_MOD("i2c2", 520, R8A779G0_CLK_S0D6_PER),
DEF_MOD("i2c3", 521, R8A779G0_CLK_S0D6_PER),
DEF_MOD("i2c4", 522, R8A779G0_CLK_S0D6_PER),
DEF_MOD("i2c5", 523, R8A779G0_CLK_S0D6_PER),
DEF_MOD("wdt1:wdt0", 907, R8A779G0_CLK_R),
DEF_MOD("pfc0", 915, R8A779G0_CLK_CL16M),
DEF_MOD("pfc1", 916, R8A779G0_CLK_CL16M),
DEF_MOD("pfc2", 917, R8A779G0_CLK_CL16M),
DEF_MOD("pfc3", 918, R8A779G0_CLK_CL16M),
};
/*

View File

@ -414,6 +414,7 @@ static const unsigned int r9a07g044_crit_mod_clks[] __initconst = {
MOD_CLK_BASE + R9A07G044_DMAC_ACLK,
};
#ifdef CONFIG_CLK_R9A07G044
const struct rzg2l_cpg_info r9a07g044_cpg_info = {
/* Core Clocks */
.core_clks = core_clks.common,
@ -436,6 +437,7 @@ const struct rzg2l_cpg_info r9a07g044_cpg_info = {
.has_clk_mon_regs = true,
};
#endif
#ifdef CONFIG_CLK_R9A07G054
const struct rzg2l_cpg_info r9a07g054_cpg_info = {

View File

@ -132,6 +132,8 @@ static const struct rzg2l_mod_clk r9a09g011_mod_clks[] __initconst = {
DEF_COUPLED("eth_chi", R9A09G011_ETH0_CLK_CHI, CLK_PLL2_100, 0x40c, 8),
DEF_MOD("eth_clk_gptp", R9A09G011_ETH0_GPTP_EXT, CLK_PLL2_100, 0x40c, 9),
DEF_MOD("syc_cnt_clk", R9A09G011_SYC_CNT_CLK, CLK_MAIN_24, 0x41c, 12),
DEF_MOD("iic_pclk0", R9A09G011_IIC_PCLK0, CLK_SEL_E, 0x420, 12),
DEF_MOD("iic_pclk1", R9A09G011_IIC_PCLK1, CLK_SEL_E, 0x424, 12),
DEF_MOD("wdt0_pclk", R9A09G011_WDT0_PCLK, CLK_SEL_E, 0x428, 12),
DEF_MOD("wdt0_clk", R9A09G011_WDT0_CLK, CLK_MAIN, 0x428, 13),
DEF_MOD("urt_pclk", R9A09G011_URT_PCLK, CLK_SEL_E, 0x438, 4),
@ -143,6 +145,8 @@ static const struct rzg2l_reset r9a09g011_resets[] = {
DEF_RST(R9A09G011_PFC_PRESETN, 0x600, 2),
DEF_RST_MON(R9A09G011_ETH0_RST_HW_N, 0x608, 11, 11),
DEF_RST_MON(R9A09G011_SYC_RST_N, 0x610, 9, 13),
DEF_RST(R9A09G011_IIC_GPA_PRESETN, 0x614, 8),
DEF_RST(R9A09G011_IIC_GPB_PRESETN, 0x614, 9),
DEF_RST_MON(R9A09G011_WDT0_PRESETN, 0x614, 12, 19),
};

View File

@ -23,6 +23,13 @@ config CLK_RV110X
help
Build the driver for RV110x Clock Driver.
config CLK_RV1126
bool "Rockchip RV1126 clock controller support"
depends on ARM || COMPILE_TEST
default y
help
Build the driver for RV1126 Clock Driver.
config CLK_RK3036
bool "Rockchip RK3036 clock controller support"
depends on ARM || COMPILE_TEST

View File

@ -17,6 +17,7 @@ clk-rockchip-$(CONFIG_RESET_CONTROLLER) += softrst.o
obj-$(CONFIG_CLK_PX30) += clk-px30.o
obj-$(CONFIG_CLK_RV110X) += clk-rv1108.o
obj-$(CONFIG_CLK_RV1126) += clk-rv1126.o
obj-$(CONFIG_CLK_RK3036) += clk-rk3036.o
obj-$(CONFIG_CLK_RK312X) += clk-rk3128.o
obj-$(CONFIG_CLK_RK3188) += clk-rk3188.o

File diff suppressed because it is too large Load Diff

View File

@ -40,6 +40,7 @@ static struct clk *rockchip_clk_register_branch(const char *name,
const char *const *parent_names, u8 num_parents,
void __iomem *base,
int muxdiv_offset, u8 mux_shift, u8 mux_width, u8 mux_flags,
u32 *mux_table,
int div_offset, u8 div_shift, u8 div_width, u8 div_flags,
struct clk_div_table *div_table, int gate_offset,
u8 gate_shift, u8 gate_flags, unsigned long flags,
@ -62,6 +63,7 @@ static struct clk *rockchip_clk_register_branch(const char *name,
mux->shift = mux_shift;
mux->mask = BIT(mux_width) - 1;
mux->flags = mux_flags;
mux->table = mux_table;
mux->lock = lock;
mux_ops = (mux_flags & CLK_MUX_READ_ONLY) ? &clk_mux_ro_ops
: &clk_mux_ops;
@ -270,6 +272,8 @@ static struct clk *rockchip_clk_register_frac_branch(
frac_mux->shift = child->mux_shift;
frac_mux->mask = BIT(child->mux_width) - 1;
frac_mux->flags = child->mux_flags;
if (child->mux_table)
frac_mux->table = child->mux_table;
frac_mux->lock = lock;
frac_mux->hw.init = &init;
@ -444,11 +448,21 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
/* catch simple muxes */
switch (list->branch_type) {
case branch_mux:
clk = clk_register_mux(NULL, list->name,
list->parent_names, list->num_parents,
flags, ctx->reg_base + list->muxdiv_offset,
list->mux_shift, list->mux_width,
list->mux_flags, &ctx->lock);
if (list->mux_table)
clk = clk_register_mux_table(NULL, list->name,
list->parent_names, list->num_parents,
flags,
ctx->reg_base + list->muxdiv_offset,
list->mux_shift, list->mux_width,
list->mux_flags, list->mux_table,
&ctx->lock);
else
clk = clk_register_mux(NULL, list->name,
list->parent_names, list->num_parents,
flags,
ctx->reg_base + list->muxdiv_offset,
list->mux_shift, list->mux_width,
list->mux_flags, &ctx->lock);
break;
case branch_muxgrf:
clk = rockchip_clk_register_muxgrf(list->name,
@ -506,7 +520,8 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
ctx->reg_base, list->muxdiv_offset,
list->mux_shift,
list->mux_width, list->mux_flags,
list->div_offset, list->div_shift, list->div_width,
list->mux_table, list->div_offset,
list->div_shift, list->div_width,
list->div_flags, list->div_table,
list->gate_offset, list->gate_shift,
list->gate_flags, flags, &ctx->lock);

View File

@ -79,6 +79,25 @@ struct clk;
#define RV1108_EMMC_CON0 0x1e8
#define RV1108_EMMC_CON1 0x1ec
#define RV1126_PMU_MODE 0x0
#define RV1126_PMU_PLL_CON(x) ((x) * 0x4 + 0x10)
#define RV1126_PMU_CLKSEL_CON(x) ((x) * 0x4 + 0x100)
#define RV1126_PMU_CLKGATE_CON(x) ((x) * 0x4 + 0x180)
#define RV1126_PMU_SOFTRST_CON(x) ((x) * 0x4 + 0x200)
#define RV1126_PLL_CON(x) ((x) * 0x4)
#define RV1126_MODE_CON 0x90
#define RV1126_CLKSEL_CON(x) ((x) * 0x4 + 0x100)
#define RV1126_CLKGATE_CON(x) ((x) * 0x4 + 0x280)
#define RV1126_SOFTRST_CON(x) ((x) * 0x4 + 0x300)
#define RV1126_GLB_SRST_FST 0x408
#define RV1126_GLB_SRST_SND 0x40c
#define RV1126_SDMMC_CON0 0x440
#define RV1126_SDMMC_CON1 0x444
#define RV1126_SDIO_CON0 0x448
#define RV1126_SDIO_CON1 0x44c
#define RV1126_EMMC_CON0 0x450
#define RV1126_EMMC_CON1 0x454
#define RK2928_PLL_CON(x) ((x) * 0x4)
#define RK2928_MODE_CON 0x40
#define RK2928_CLKSEL_CON(x) ((x) * 0x4 + 0x44)
@ -448,6 +467,7 @@ struct rockchip_clk_branch {
u8 mux_shift;
u8 mux_width;
u8 mux_flags;
u32 *mux_table;
int div_offset;
u8 div_shift;
u8 div_width;
@ -680,6 +700,22 @@ struct rockchip_clk_branch {
.gate_offset = -1, \
}
#define MUXTBL(_id, cname, pnames, f, o, s, w, mf, mt) \
{ \
.id = _id, \
.branch_type = branch_mux, \
.name = cname, \
.parent_names = pnames, \
.num_parents = ARRAY_SIZE(pnames), \
.flags = f, \
.muxdiv_offset = o, \
.mux_shift = s, \
.mux_width = w, \
.mux_flags = mf, \
.gate_offset = -1, \
.mux_table = mt, \
}
#define MUXGRF(_id, cname, pnames, f, o, s, w, mf) \
{ \
.id = _id, \

View File

@ -104,6 +104,8 @@ static struct ccu_nm pll_video0_4x_clk = {
.lock = BIT(28),
.n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
.m = _SUNXI_CCU_DIV(1, 1), /* input divider */
.min_rate = 252000000U,
.max_rate = 2400000000U,
.common = {
.reg = 0x040,
.hw.init = CLK_HW_INIT_PARENTS_DATA("pll-video0-4x", osc24M,
@ -126,6 +128,8 @@ static struct ccu_nm pll_video1_4x_clk = {
.lock = BIT(28),
.n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
.m = _SUNXI_CCU_DIV(1, 1), /* input divider */
.min_rate = 252000000U,
.max_rate = 2400000000U,
.common = {
.reg = 0x048,
.hw.init = CLK_HW_INIT_PARENTS_DATA("pll-video1-4x", osc24M,
@ -175,6 +179,8 @@ static struct ccu_nm pll_audio0_4x_clk = {
.m = _SUNXI_CCU_DIV(16, 6),
.sdm = _SUNXI_CCU_SDM(pll_audio0_sdm_table, BIT(24),
0x178, BIT(31)),
.min_rate = 180000000U,
.max_rate = 3000000000U,
.common = {
.reg = 0x078,
.features = CCU_FEATURE_SIGMA_DELTA_MOD,
@ -202,6 +208,8 @@ static struct ccu_nm pll_audio1_clk = {
.lock = BIT(28),
.n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
.m = _SUNXI_CCU_DIV(1, 1),
.min_rate = 180000000U,
.max_rate = 3000000000U,
.common = {
.reg = 0x080,
.hw.init = CLK_HW_INIT_PARENTS_DATA("pll-audio1", osc24M,

View File

@ -256,29 +256,19 @@ static int sunxi_de2_clk_probe(struct platform_device *pdev)
return PTR_ERR(reg);
bus_clk = devm_clk_get(&pdev->dev, "bus");
if (IS_ERR(bus_clk)) {
ret = PTR_ERR(bus_clk);
if (ret != -EPROBE_DEFER)
dev_err(&pdev->dev, "Couldn't get bus clk: %d\n", ret);
return ret;
}
if (IS_ERR(bus_clk))
return dev_err_probe(&pdev->dev, PTR_ERR(bus_clk),
"Couldn't get bus clk\n");
mod_clk = devm_clk_get(&pdev->dev, "mod");
if (IS_ERR(mod_clk)) {
ret = PTR_ERR(mod_clk);
if (ret != -EPROBE_DEFER)
dev_err(&pdev->dev, "Couldn't get mod clk: %d\n", ret);
return ret;
}
if (IS_ERR(mod_clk))
return dev_err_probe(&pdev->dev, PTR_ERR(mod_clk),
"Couldn't get mod clk\n");
rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
if (IS_ERR(rstc)) {
ret = PTR_ERR(rstc);
if (ret != -EPROBE_DEFER)
dev_err(&pdev->dev,
"Couldn't get reset control: %d\n", ret);
return ret;
}
if (IS_ERR(rstc))
return dev_err_probe(&pdev->dev, PTR_ERR(rstc),
"Couldn't get reset control\n");
/* The clocks need to be enabled for us to access the registers */
ret = clk_prepare_enable(bus_clk);

View File

@ -213,21 +213,14 @@ static int sun9i_a80_de_clk_probe(struct platform_device *pdev)
return PTR_ERR(reg);
bus_clk = devm_clk_get(&pdev->dev, "bus");
if (IS_ERR(bus_clk)) {
ret = PTR_ERR(bus_clk);
if (ret != -EPROBE_DEFER)
dev_err(&pdev->dev, "Couldn't get bus clk: %d\n", ret);
return ret;
}
if (IS_ERR(bus_clk))
return dev_err_probe(&pdev->dev, PTR_ERR(bus_clk),
"Couldn't get bus clk\n");
rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
if (IS_ERR(rstc)) {
ret = PTR_ERR(rstc);
if (ret != -EPROBE_DEFER)
dev_err(&pdev->dev,
"Couldn't get reset control: %d\n", ret);
return ret;
}
if (IS_ERR(rstc))
return dev_err_probe(&pdev->dev, PTR_ERR(rstc),
"Couldn't get reset control\n");
/* The bus clock needs to be enabled for us to access the registers */
ret = clk_prepare_enable(bus_clk);

View File

@ -101,12 +101,9 @@ static int sun9i_a80_usb_clk_probe(struct platform_device *pdev)
return PTR_ERR(reg);
bus_clk = devm_clk_get(&pdev->dev, "bus");
if (IS_ERR(bus_clk)) {
ret = PTR_ERR(bus_clk);
if (ret != -EPROBE_DEFER)
dev_err(&pdev->dev, "Couldn't get bus clk: %d\n", ret);
return ret;
}
if (IS_ERR(bus_clk))
return dev_err_probe(&pdev->dev, PTR_ERR(bus_clk),
"Couldn't get bus clk\n");
/* The bus clock needs to be enabled for us to access the registers */
ret = clk_prepare_enable(bus_clk);

View File

@ -152,6 +152,13 @@ config RESET_PISTACHIO
help
This enables the reset driver for ImgTec Pistachio SoCs.
config RESET_POLARFIRE_SOC
bool "Microchip PolarFire SoC (MPFS) Reset Driver"
depends on AUXILIARY_BUS && MCHP_CLK_MPFS
default MCHP_CLK_MPFS
help
This driver supports peripheral reset for the Microchip PolarFire SoC
config RESET_QCOM_AOSS
tristate "Qcom AOSS Reset Driver"
depends on ARCH_QCOM || COMPILE_TEST

View File

@ -22,6 +22,7 @@ obj-$(CONFIG_RESET_MESON_AUDIO_ARB) += reset-meson-audio-arb.o
obj-$(CONFIG_RESET_NPCM) += reset-npcm.o
obj-$(CONFIG_RESET_OXNAS) += reset-oxnas.o
obj-$(CONFIG_RESET_PISTACHIO) += reset-pistachio.o
obj-$(CONFIG_RESET_POLARFIRE_SOC) += reset-mpfs.o
obj-$(CONFIG_RESET_QCOM_AOSS) += reset-qcom-aoss.o
obj-$(CONFIG_RESET_QCOM_PDC) += reset-qcom-pdc.o
obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o
@ -40,4 +41,3 @@ obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o
obj-$(CONFIG_RESET_UNIPHIER_GLUE) += reset-uniphier-glue.o
obj-$(CONFIG_RESET_ZYNQ) += reset-zynq.o
obj-$(CONFIG_ARCH_ZYNQMP) += reset-zynqmp.o

157
drivers/reset/reset-mpfs.c Normal file
View File

@ -0,0 +1,157 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* PolarFire SoC (MPFS) Peripheral Clock Reset Controller
*
* Author: Conor Dooley <conor.dooley@microchip.com>
* Copyright (c) 2022 Microchip Technology Inc. and its subsidiaries.
*
*/
#include <linux/auxiliary_bus.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/reset-controller.h>
#include <dt-bindings/clock/microchip,mpfs-clock.h>
#include <soc/microchip/mpfs.h>
/*
* The ENVM reset is the lowest bit in the register & I am using the CLK_FOO
* defines in the dt to make things easier to configure - so this is accounting
* for the offset of 3 there.
*/
#define MPFS_PERIPH_OFFSET CLK_ENVM
#define MPFS_NUM_RESETS 30u
#define MPFS_SLEEP_MIN_US 100
#define MPFS_SLEEP_MAX_US 200
/* block concurrent access to the soft reset register */
static DEFINE_SPINLOCK(mpfs_reset_lock);
/*
* Peripheral clock resets
*/
static int mpfs_assert(struct reset_controller_dev *rcdev, unsigned long id)
{
unsigned long flags;
u32 reg;
spin_lock_irqsave(&mpfs_reset_lock, flags);
reg = mpfs_reset_read(rcdev->dev);
reg |= BIT(id);
mpfs_reset_write(rcdev->dev, reg);
spin_unlock_irqrestore(&mpfs_reset_lock, flags);
return 0;
}
static int mpfs_deassert(struct reset_controller_dev *rcdev, unsigned long id)
{
unsigned long flags;
u32 reg;
spin_lock_irqsave(&mpfs_reset_lock, flags);
reg = mpfs_reset_read(rcdev->dev);
reg &= ~BIT(id);
mpfs_reset_write(rcdev->dev, reg);
spin_unlock_irqrestore(&mpfs_reset_lock, flags);
return 0;
}
static int mpfs_status(struct reset_controller_dev *rcdev, unsigned long id)
{
u32 reg = mpfs_reset_read(rcdev->dev);
/*
* It is safe to return here as MPFS_NUM_RESETS makes sure the sign bit
* is never hit.
*/
return (reg & BIT(id));
}
static int mpfs_reset(struct reset_controller_dev *rcdev, unsigned long id)
{
mpfs_assert(rcdev, id);
usleep_range(MPFS_SLEEP_MIN_US, MPFS_SLEEP_MAX_US);
mpfs_deassert(rcdev, id);
return 0;
}
static const struct reset_control_ops mpfs_reset_ops = {
.reset = mpfs_reset,
.assert = mpfs_assert,
.deassert = mpfs_deassert,
.status = mpfs_status,
};
static int mpfs_reset_xlate(struct reset_controller_dev *rcdev,
const struct of_phandle_args *reset_spec)
{
unsigned int index = reset_spec->args[0];
/*
* CLK_RESERVED does not map to a clock, but it does map to a reset,
* so it has to be accounted for here. It is the reset for the fabric,
* so if this reset gets called - do not reset it.
*/
if (index == CLK_RESERVED) {
dev_err(rcdev->dev, "Resetting the fabric is not supported\n");
return -EINVAL;
}
if (index < MPFS_PERIPH_OFFSET || index >= (MPFS_PERIPH_OFFSET + rcdev->nr_resets)) {
dev_err(rcdev->dev, "Invalid reset index %u\n", index);
return -EINVAL;
}
return index - MPFS_PERIPH_OFFSET;
}
static int mpfs_reset_probe(struct auxiliary_device *adev,
const struct auxiliary_device_id *id)
{
struct device *dev = &adev->dev;
struct reset_controller_dev *rcdev;
rcdev = devm_kzalloc(dev, sizeof(*rcdev), GFP_KERNEL);
if (!rcdev)
return -ENOMEM;
rcdev->dev = dev;
rcdev->dev->parent = dev->parent;
rcdev->ops = &mpfs_reset_ops;
rcdev->of_node = dev->parent->of_node;
rcdev->of_reset_n_cells = 1;
rcdev->of_xlate = mpfs_reset_xlate;
rcdev->nr_resets = MPFS_NUM_RESETS;
return devm_reset_controller_register(dev, rcdev);
}
static const struct auxiliary_device_id mpfs_reset_ids[] = {
{
.name = "clk_mpfs.reset-mpfs",
},
{ }
};
MODULE_DEVICE_TABLE(auxiliary, mpfs_reset_ids);
static struct auxiliary_driver mpfs_reset_driver = {
.probe = mpfs_reset_probe,
.id_table = mpfs_reset_ids,
};
module_auxiliary_driver(mpfs_reset_driver);
MODULE_DESCRIPTION("Microchip PolarFire SoC Reset Driver");
MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS(MCHP_CLK_MPFS);

View File

@ -281,7 +281,6 @@
#define IMX8MM_CLK_CLKOUT2_DIV 256
#define IMX8MM_CLK_CLKOUT2 257
#define IMX8MM_CLK_END 258
#endif

View File

@ -196,6 +196,13 @@
#define IMX93_CLK_TMC_GATE 187
#define IMX93_CLK_PMRO_GATE 188
#define IMX93_CLK_32K 189
#define IMX93_CLK_END 190
#define IMX93_CLK_SAI1_IPG 190
#define IMX93_CLK_SAI2_IPG 191
#define IMX93_CLK_SAI3_IPG 192
#define IMX93_CLK_MU1_A_GATE 193
#define IMX93_CLK_MU1_B_GATE 194
#define IMX93_CLK_MU2_A_GATE 195
#define IMX93_CLK_MU2_B_GATE 196
#define IMX93_CLK_END 197
#endif

View File

@ -45,4 +45,27 @@
#define CLK_RTCREF 33
#define CLK_MSSPLL 34
/* Clock Conditioning Circuitry Clock IDs */
#define CLK_CCC_PLL0 0
#define CLK_CCC_PLL1 1
#define CLK_CCC_DLL0 2
#define CLK_CCC_DLL1 3
#define CLK_CCC_PLL0_OUT0 4
#define CLK_CCC_PLL0_OUT1 5
#define CLK_CCC_PLL0_OUT2 6
#define CLK_CCC_PLL0_OUT3 7
#define CLK_CCC_PLL1_OUT0 8
#define CLK_CCC_PLL1_OUT1 9
#define CLK_CCC_PLL1_OUT2 10
#define CLK_CCC_PLL1_OUT3 11
#define CLK_CCC_DLL0_OUT0 12
#define CLK_CCC_DLL0_OUT1 13
#define CLK_CCC_DLL1_OUT0 14
#define CLK_CCC_DLL1_OUT1 15
#endif /* _DT_BINDINGS_CLK_MICROCHIP_MPFS_H_ */

View File

@ -0,0 +1,632 @@
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
/*
* Copyright (c) 2019 Rockchip Electronics Co. Ltd.
* Author: Finley Xiao <finley.xiao@rock-chips.com>
*/
#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RV1126_H
#define _DT_BINDINGS_CLK_ROCKCHIP_RV1126_H
/* pmucru-clocks indices */
/* pll clocks */
#define PLL_GPLL 1
/* sclk (special clocks) */
#define CLK_OSC0_DIV32K 2
#define CLK_RTC32K 3
#define CLK_WIFI_DIV 4
#define CLK_WIFI_OSC0 5
#define CLK_WIFI 6
#define CLK_PMU 7
#define SCLK_UART1_DIV 8
#define SCLK_UART1_FRACDIV 9
#define SCLK_UART1_MUX 10
#define SCLK_UART1 11
#define CLK_I2C0 12
#define CLK_I2C2 13
#define CLK_CAPTURE_PWM0 14
#define CLK_PWM0 15
#define CLK_CAPTURE_PWM1 16
#define CLK_PWM1 17
#define CLK_SPI0 18
#define DBCLK_GPIO0 19
#define CLK_PMUPVTM 20
#define CLK_CORE_PMUPVTM 21
#define CLK_REF12M 22
#define CLK_USBPHY_OTG_REF 23
#define CLK_USBPHY_HOST_REF 24
#define CLK_REF24M 25
#define CLK_MIPIDSIPHY_REF 26
/* pclk */
#define PCLK_PDPMU 30
#define PCLK_PMU 31
#define PCLK_UART1 32
#define PCLK_I2C0 33
#define PCLK_I2C2 34
#define PCLK_PWM0 35
#define PCLK_PWM1 36
#define PCLK_SPI0 37
#define PCLK_GPIO0 38
#define PCLK_PMUSGRF 39
#define PCLK_PMUGRF 40
#define PCLK_PMUCRU 41
#define PCLK_CHIPVEROTP 42
#define PCLK_PDPMU_NIU 43
#define PCLK_PMUPVTM 44
#define PCLK_SCRKEYGEN 45
#define CLKPMU_NR_CLKS (PCLK_SCRKEYGEN + 1)
/* cru-clocks indices */
/* pll clocks */
#define PLL_APLL 1
#define PLL_DPLL 2
#define PLL_CPLL 3
#define PLL_HPLL 4
/* sclk (special clocks) */
#define ARMCLK 5
#define USB480M 6
#define CLK_CORE_CPUPVTM 7
#define CLK_CPUPVTM 8
#define CLK_SCR1 9
#define CLK_SCR1_CORE 10
#define CLK_SCR1_RTC 11
#define CLK_SCR1_JTAG 12
#define SCLK_UART0_DIV 13
#define SCLK_UART0_FRAC 14
#define SCLK_UART0_MUX 15
#define SCLK_UART0 16
#define SCLK_UART2_DIV 17
#define SCLK_UART2_FRAC 18
#define SCLK_UART2_MUX 19
#define SCLK_UART2 20
#define SCLK_UART3_DIV 21
#define SCLK_UART3_FRAC 22
#define SCLK_UART3_MUX 23
#define SCLK_UART3 24
#define SCLK_UART4_DIV 25
#define SCLK_UART4_FRAC 26
#define SCLK_UART4_MUX 27
#define SCLK_UART4 28
#define SCLK_UART5_DIV 29
#define SCLK_UART5_FRAC 30
#define SCLK_UART5_MUX 31
#define SCLK_UART5 32
#define CLK_I2C1 33
#define CLK_I2C3 34
#define CLK_I2C4 35
#define CLK_I2C5 36
#define CLK_SPI1 37
#define CLK_CAPTURE_PWM2 38
#define CLK_PWM2 39
#define DBCLK_GPIO1 40
#define DBCLK_GPIO2 41
#define DBCLK_GPIO3 42
#define DBCLK_GPIO4 43
#define CLK_SARADC 44
#define CLK_TIMER0 45
#define CLK_TIMER1 46
#define CLK_TIMER2 47
#define CLK_TIMER3 48
#define CLK_TIMER4 49
#define CLK_TIMER5 50
#define CLK_CAN 51
#define CLK_NPU_TSADC 52
#define CLK_NPU_TSADCPHY 53
#define CLK_CPU_TSADC 54
#define CLK_CPU_TSADCPHY 55
#define CLK_CRYPTO_CORE 56
#define CLK_CRYPTO_PKA 57
#define MCLK_I2S0_TX_DIV 58
#define MCLK_I2S0_TX_FRACDIV 59
#define MCLK_I2S0_TX_MUX 60
#define MCLK_I2S0_TX 61
#define MCLK_I2S0_RX_DIV 62
#define MCLK_I2S0_RX_FRACDIV 63
#define MCLK_I2S0_RX_MUX 64
#define MCLK_I2S0_RX 65
#define MCLK_I2S0_TX_OUT2IO 66
#define MCLK_I2S0_RX_OUT2IO 67
#define MCLK_I2S1_DIV 68
#define MCLK_I2S1_FRACDIV 69
#define MCLK_I2S1_MUX 70
#define MCLK_I2S1 71
#define MCLK_I2S1_OUT2IO 72
#define MCLK_I2S2_DIV 73
#define MCLK_I2S2_FRACDIV 74
#define MCLK_I2S2_MUX 75
#define MCLK_I2S2 76
#define MCLK_I2S2_OUT2IO 77
#define MCLK_PDM 78
#define SCLK_ADUPWM_DIV 79
#define SCLK_AUDPWM_FRACDIV 80
#define SCLK_AUDPWM_MUX 81
#define SCLK_AUDPWM 82
#define CLK_ACDCDIG_ADC 83
#define CLK_ACDCDIG_DAC 84
#define CLK_ACDCDIG_I2C 85
#define CLK_VENC_CORE 86
#define CLK_VDEC_CORE 87
#define CLK_VDEC_CA 88
#define CLK_VDEC_HEVC_CA 89
#define CLK_RGA_CORE 90
#define CLK_IEP_CORE 91
#define CLK_ISP_DIV 92
#define CLK_ISP_NP5 93
#define CLK_ISP_NUX 94
#define CLK_ISP 95
#define CLK_CIF_OUT_DIV 96
#define CLK_CIF_OUT_FRACDIV 97
#define CLK_CIF_OUT_MUX 98
#define CLK_CIF_OUT 99
#define CLK_MIPICSI_OUT_DIV 100
#define CLK_MIPICSI_OUT_FRACDIV 101
#define CLK_MIPICSI_OUT_MUX 102
#define CLK_MIPICSI_OUT 103
#define CLK_ISPP_DIV 104
#define CLK_ISPP_NP5 105
#define CLK_ISPP_NUX 106
#define CLK_ISPP 107
#define CLK_SDMMC 108
#define SCLK_SDMMC_DRV 109
#define SCLK_SDMMC_SAMPLE 110
#define CLK_SDIO 111
#define SCLK_SDIO_DRV 112
#define SCLK_SDIO_SAMPLE 113
#define CLK_EMMC 114
#define SCLK_EMMC_DRV 115
#define SCLK_EMMC_SAMPLE 116
#define CLK_NANDC 117
#define SCLK_SFC 118
#define CLK_USBHOST_UTMI_OHCI 119
#define CLK_USBOTG_REF 120
#define CLK_GMAC_DIV 121
#define CLK_GMAC_RGMII_M0 122
#define CLK_GMAC_SRC_M0 123
#define CLK_GMAC_RGMII_M1 124
#define CLK_GMAC_SRC_M1 125
#define CLK_GMAC_SRC 126
#define CLK_GMAC_REF 127
#define CLK_GMAC_TX_SRC 128
#define CLK_GMAC_TX_DIV5 129
#define CLK_GMAC_TX_DIV50 130
#define RGMII_MODE_CLK 131
#define CLK_GMAC_RX_SRC 132
#define CLK_GMAC_RX_DIV2 133
#define CLK_GMAC_RX_DIV20 134
#define RMII_MODE_CLK 135
#define CLK_GMAC_TX_RX 136
#define CLK_GMAC_PTPREF 137
#define CLK_GMAC_ETHERNET_OUT 138
#define CLK_DDRPHY 139
#define CLK_DDR_MON 140
#define TMCLK_DDR_MON 141
#define CLK_NPU_DIV 142
#define CLK_NPU_NP5 143
#define CLK_CORE_NPU 144
#define CLK_CORE_NPUPVTM 145
#define CLK_NPUPVTM 146
#define SCLK_DDRCLK 147
#define CLK_OTP 148
/* dclk */
#define DCLK_DECOM 150
#define DCLK_VOP_DIV 151
#define DCLK_VOP_FRACDIV 152
#define DCLK_VOP_MUX 153
#define DCLK_VOP 154
#define DCLK_CIF 155
#define DCLK_CIFLITE 156
/* aclk */
#define ACLK_PDBUS 160
#define ACLK_DMAC 161
#define ACLK_DCF 162
#define ACLK_SPINLOCK 163
#define ACLK_DECOM 164
#define ACLK_PDCRYPTO 165
#define ACLK_CRYPTO 166
#define ACLK_PDVEPU 167
#define ACLK_VENC 168
#define ACLK_PDVDEC 169
#define ACLK_PDJPEG 170
#define ACLK_VDEC 171
#define ACLK_JPEG 172
#define ACLK_PDVO 173
#define ACLK_RGA 174
#define ACLK_VOP 175
#define ACLK_IEP 176
#define ACLK_PDVI_DIV 177
#define ACLK_PDVI_NP5 178
#define ACLK_PDVI 179
#define ACLK_ISP 180
#define ACLK_CIF 181
#define ACLK_CIFLITE 182
#define ACLK_PDISPP_DIV 183
#define ACLK_PDISPP_NP5 184
#define ACLK_PDISPP 185
#define ACLK_ISPP 186
#define ACLK_PDPHP 187
#define ACLK_PDUSB 188
#define ACLK_USBOTG 189
#define ACLK_PDGMAC 190
#define ACLK_GMAC 191
#define ACLK_PDNPU_DIV 192
#define ACLK_PDNPU_NP5 193
#define ACLK_PDNPU 194
#define ACLK_NPU 195
/* hclk */
#define HCLK_PDCORE_NIU 200
#define HCLK_PDUSB 201
#define HCLK_PDCRYPTO 202
#define HCLK_CRYPTO 203
#define HCLK_PDAUDIO 204
#define HCLK_I2S0 205
#define HCLK_I2S1 206
#define HCLK_I2S2 207
#define HCLK_PDM 208
#define HCLK_AUDPWM 209
#define HCLK_PDVEPU 210
#define HCLK_VENC 211
#define HCLK_PDVDEC 212
#define HCLK_PDJPEG 213
#define HCLK_VDEC 214
#define HCLK_JPEG 215
#define HCLK_PDVO 216
#define HCLK_RGA 217
#define HCLK_VOP 218
#define HCLK_IEP 219
#define HCLK_PDVI 220
#define HCLK_ISP 221
#define HCLK_CIF 222
#define HCLK_CIFLITE 223
#define HCLK_PDISPP 224
#define HCLK_ISPP 225
#define HCLK_PDPHP 226
#define HCLK_PDSDMMC 227
#define HCLK_SDMMC 228
#define HCLK_PDSDIO 229
#define HCLK_SDIO 230
#define HCLK_PDNVM 231
#define HCLK_EMMC 232
#define HCLK_NANDC 233
#define HCLK_SFC 234
#define HCLK_SFCXIP 235
#define HCLK_PDBUS 236
#define HCLK_USBHOST 237
#define HCLK_USBHOST_ARB 238
#define HCLK_PDNPU 239
#define HCLK_NPU 240
/* pclk */
#define PCLK_CPUPVTM 245
#define PCLK_PDBUS 246
#define PCLK_DCF 247
#define PCLK_WDT 248
#define PCLK_MAILBOX 249
#define PCLK_UART0 250
#define PCLK_UART2 251
#define PCLK_UART3 252
#define PCLK_UART4 253
#define PCLK_UART5 254
#define PCLK_I2C1 255
#define PCLK_I2C3 256
#define PCLK_I2C4 257
#define PCLK_I2C5 258
#define PCLK_SPI1 259
#define PCLK_PWM2 261
#define PCLK_GPIO1 262
#define PCLK_GPIO2 263
#define PCLK_GPIO3 264
#define PCLK_GPIO4 265
#define PCLK_SARADC 266
#define PCLK_TIMER 267
#define PCLK_DECOM 268
#define PCLK_CAN 269
#define PCLK_NPU_TSADC 270
#define PCLK_CPU_TSADC 271
#define PCLK_ACDCDIG 272
#define PCLK_PDVO 273
#define PCLK_DSIHOST 274
#define PCLK_PDVI 275
#define PCLK_CSIHOST 276
#define PCLK_PDGMAC 277
#define PCLK_GMAC 278
#define PCLK_PDDDR 279
#define PCLK_DDR_MON 280
#define PCLK_PDNPU 281
#define PCLK_NPUPVTM 282
#define PCLK_PDTOP 283
#define PCLK_TOPCRU 284
#define PCLK_TOPGRF 285
#define PCLK_CPUEMADET 286
#define PCLK_DDRPHY 287
#define PCLK_DSIPHY 289
#define PCLK_CSIPHY0 290
#define PCLK_CSIPHY1 291
#define PCLK_USBPHY_HOST 292
#define PCLK_USBPHY_OTG 293
#define PCLK_OTP 294
#define CLK_NR_CLKS (PCLK_OTP + 1)
/* pmu soft-reset indices */
/* pmu_cru_softrst_con0 */
#define SRST_PDPMU_NIU_P 0
#define SRST_PMU_SGRF_P 1
#define SRST_PMU_SGRF_REMAP_P 2
#define SRST_I2C0_P 3
#define SRST_I2C0 4
#define SRST_I2C2_P 7
#define SRST_I2C2 8
#define SRST_UART1_P 9
#define SRST_UART1 10
#define SRST_PWM0_P 11
#define SRST_PWM0 12
#define SRST_PWM1_P 13
#define SRST_PWM1 14
#define SRST_DDR_FAIL_SAFE 15
/* pmu_cru_softrst_con1 */
#define SRST_GPIO0_P 17
#define SRST_GPIO0_DB 18
#define SRST_SPI0_P 19
#define SRST_SPI0 20
#define SRST_PMUGRF_P 21
#define SRST_CHIPVEROTP_P 22
#define SRST_PMUPVTM 24
#define SRST_PMUPVTM_P 25
#define SRST_PMUCRU_P 30
/* soft-reset indices */
/* cru_softrst_con0 */
#define SRST_CORE0_PO 0
#define SRST_CORE1_PO 1
#define SRST_CORE2_PO 2
#define SRST_CORE3_PO 3
#define SRST_CORE0 4
#define SRST_CORE1 5
#define SRST_CORE2 6
#define SRST_CORE3 7
#define SRST_CORE0_DBG 8
#define SRST_CORE1_DBG 9
#define SRST_CORE2_DBG 10
#define SRST_CORE3_DBG 11
#define SRST_NL2 12
#define SRST_CORE_NIU_A 13
#define SRST_DBG_DAPLITE_P 14
#define SRST_DAPLITE_P 15
/* cru_softrst_con1 */
#define SRST_PDBUS_NIU1_A 16
#define SRST_PDBUS_NIU1_H 17
#define SRST_PDBUS_NIU1_P 18
#define SRST_PDBUS_NIU2_A 19
#define SRST_PDBUS_NIU2_H 20
#define SRST_PDBUS_NIU3_A 21
#define SRST_PDBUS_NIU3_H 22
#define SRST_PDBUS_HOLD_NIU1_A 23
#define SRST_DBG_NIU_P 24
#define SRST_PDCORE_NIIU_H 25
#define SRST_MUC_NIU 26
#define SRST_DCF_A 29
#define SRST_DCF_P 30
#define SRST_SYSTEM_SRAM_A 31
/* cru_softrst_con2 */
#define SRST_I2C1_P 32
#define SRST_I2C1 33
#define SRST_I2C3_P 34
#define SRST_I2C3 35
#define SRST_I2C4_P 36
#define SRST_I2C4 37
#define SRST_I2C5_P 38
#define SRST_I2C5 39
#define SRST_SPI1_P 40
#define SRST_SPI1 41
#define SRST_MCU_CORE 42
#define SRST_PWM2_P 44
#define SRST_PWM2 45
#define SRST_SPINLOCK_A 46
/* cru_softrst_con3 */
#define SRST_UART0_P 48
#define SRST_UART0 49
#define SRST_UART2_P 50
#define SRST_UART2 51
#define SRST_UART3_P 52
#define SRST_UART3 53
#define SRST_UART4_P 54
#define SRST_UART4 55
#define SRST_UART5_P 56
#define SRST_UART5 57
#define SRST_WDT_P 58
#define SRST_SARADC_P 59
#define SRST_GRF_P 61
#define SRST_TIMER_P 62
#define SRST_MAILBOX_P 63
/* cru_softrst_con4 */
#define SRST_TIMER0 64
#define SRST_TIMER1 65
#define SRST_TIMER2 66
#define SRST_TIMER3 67
#define SRST_TIMER4 68
#define SRST_TIMER5 69
#define SRST_INTMUX_P 70
#define SRST_GPIO1_P 72
#define SRST_GPIO1_DB 73
#define SRST_GPIO2_P 74
#define SRST_GPIO2_DB 75
#define SRST_GPIO3_P 76
#define SRST_GPIO3_DB 77
#define SRST_GPIO4_P 78
#define SRST_GPIO4_DB 79
/* cru_softrst_con5 */
#define SRST_CAN_P 80
#define SRST_CAN 81
#define SRST_DECOM_A 85
#define SRST_DECOM_P 86
#define SRST_DECOM_D 87
#define SRST_PDCRYPTO_NIU_A 88
#define SRST_PDCRYPTO_NIU_H 89
#define SRST_CRYPTO_A 90
#define SRST_CRYPTO_H 91
#define SRST_CRYPTO_CORE 92
#define SRST_CRYPTO_PKA 93
#define SRST_SGRF_P 95
/* cru_softrst_con6 */
#define SRST_PDAUDIO_NIU_H 96
#define SRST_PDAUDIO_NIU_P 97
#define SRST_I2S0_H 98
#define SRST_I2S0_TX_M 99
#define SRST_I2S0_RX_M 100
#define SRST_I2S1_H 101
#define SRST_I2S1_M 102
#define SRST_I2S2_H 103
#define SRST_I2S2_M 104
#define SRST_PDM_H 105
#define SRST_PDM_M 106
#define SRST_AUDPWM_H 107
#define SRST_AUDPWM 108
#define SRST_ACDCDIG_P 109
#define SRST_ACDCDIG 110
/* cru_softrst_con7 */
#define SRST_PDVEPU_NIU_A 112
#define SRST_PDVEPU_NIU_H 113
#define SRST_VENC_A 114
#define SRST_VENC_H 115
#define SRST_VENC_CORE 116
#define SRST_PDVDEC_NIU_A 117
#define SRST_PDVDEC_NIU_H 118
#define SRST_VDEC_A 119
#define SRST_VDEC_H 120
#define SRST_VDEC_CORE 121
#define SRST_VDEC_CA 122
#define SRST_VDEC_HEVC_CA 123
#define SRST_PDJPEG_NIU_A 124
#define SRST_PDJPEG_NIU_H 125
#define SRST_JPEG_A 126
#define SRST_JPEG_H 127
/* cru_softrst_con8 */
#define SRST_PDVO_NIU_A 128
#define SRST_PDVO_NIU_H 129
#define SRST_PDVO_NIU_P 130
#define SRST_RGA_A 131
#define SRST_RGA_H 132
#define SRST_RGA_CORE 133
#define SRST_VOP_A 134
#define SRST_VOP_H 135
#define SRST_VOP_D 136
#define SRST_TXBYTEHS_DSIHOST 137
#define SRST_DSIHOST_P 138
#define SRST_IEP_A 139
#define SRST_IEP_H 140
#define SRST_IEP_CORE 141
#define SRST_ISP_RX_P 142
/* cru_softrst_con9 */
#define SRST_PDVI_NIU_A 144
#define SRST_PDVI_NIU_H 145
#define SRST_PDVI_NIU_P 146
#define SRST_ISP 147
#define SRST_CIF_A 148
#define SRST_CIF_H 149
#define SRST_CIF_D 150
#define SRST_CIF_P 151
#define SRST_CIF_I 152
#define SRST_CIF_RX_P 153
#define SRST_PDISPP_NIU_A 154
#define SRST_PDISPP_NIU_H 155
#define SRST_ISPP_A 156
#define SRST_ISPP_H 157
#define SRST_ISPP 158
#define SRST_CSIHOST_P 159
/* cru_softrst_con10 */
#define SRST_PDPHPMID_NIU_A 160
#define SRST_PDPHPMID_NIU_H 161
#define SRST_PDNVM_NIU_H 163
#define SRST_SDMMC_H 164
#define SRST_SDIO_H 165
#define SRST_EMMC_H 166
#define SRST_SFC_H 167
#define SRST_SFCXIP_H 168
#define SRST_SFC 169
#define SRST_NANDC_H 170
#define SRST_NANDC 171
#define SRST_PDSDMMC_H 173
#define SRST_PDSDIO_H 174
/* cru_softrst_con11 */
#define SRST_PDUSB_NIU_A 176
#define SRST_PDUSB_NIU_H 177
#define SRST_USBHOST_H 178
#define SRST_USBHOST_ARB_H 179
#define SRST_USBHOST_UTMI 180
#define SRST_USBOTG_A 181
#define SRST_USBPHY_OTG_P 182
#define SRST_USBPHY_HOST_P 183
#define SRST_USBPHYPOR_OTG 184
#define SRST_USBPHYPOR_HOST 185
#define SRST_PDGMAC_NIU_A 188
#define SRST_PDGMAC_NIU_P 189
#define SRST_GMAC_A 190
/* cru_softrst_con12 */
#define SRST_DDR_DFICTL_P 193
#define SRST_DDR_MON_P 194
#define SRST_DDR_STANDBY_P 195
#define SRST_DDR_GRF_P 196
#define SRST_DDR_MSCH_P 197
#define SRST_DDR_SPLIT_A 198
#define SRST_DDR_MSCH 199
#define SRST_DDR_DFICTL 202
#define SRST_DDR_STANDBY 203
#define SRST_NPUMCU_NIU 205
#define SRST_DDRPHY_P 206
#define SRST_DDRPHY 207
/* cru_softrst_con13 */
#define SRST_PDNPU_NIU_A 208
#define SRST_PDNPU_NIU_H 209
#define SRST_PDNPU_NIU_P 210
#define SRST_NPU_A 211
#define SRST_NPU_H 212
#define SRST_NPU 213
#define SRST_NPUPVTM_P 214
#define SRST_NPUPVTM 215
#define SRST_NPU_TSADC_P 216
#define SRST_NPU_TSADC 217
#define SRST_NPU_TSADCPHY 218
#define SRST_CIFLITE_A 220
#define SRST_CIFLITE_H 221
#define SRST_CIFLITE_D 222
#define SRST_CIFLITE_RX_P 223
/* cru_softrst_con14 */
#define SRST_TOPNIU_P 224
#define SRST_TOPCRU_P 225
#define SRST_TOPGRF_P 226
#define SRST_CPUEMADET_P 227
#define SRST_CSIPHY0_P 228
#define SRST_CSIPHY1_P 229
#define SRST_DSIPHY_P 230
#define SRST_CPU_TSADC_P 232
#define SRST_CPU_TSADC 233
#define SRST_CPU_TSADCPHY 234
#define SRST_CPUPVTM_P 235
#define SRST_CPUPVTM 236
#endif

View File

@ -40,4 +40,12 @@ struct mpfs_sys_controller *mpfs_sys_controller_get(struct device *dev);
#endif /* if IS_ENABLED(CONFIG_POLARFIRE_SOC_SYS_CTRL) */
#if IS_ENABLED(CONFIG_MCHP_CLK_MPFS)
u32 mpfs_reset_read(struct device *dev);
void mpfs_reset_write(struct device *dev, u32 val);
#endif /* if IS_ENABLED(CONFIG_MCHP_CLK_MPFS) */
#endif /* __SOC_MPFS_H__ */