Merge branches 'clk-xilinx', 'clk-kunit', 'clk-cs2000' and 'clk-renesas' into clk-next

- Kunit tests for clk-gate implementation
 - Convert Cirrus Logic CS2000P driver to regmap, yamlify DT binding and add
   support for dynamic mode

* clk-xilinx:
  clk: zynqmp: replace warn_once with pr_debug for failed clock ops

* clk-kunit:
  clk: gate: Add some kunit test suites

* clk-cs2000:
  clk: cs2000-cp: convert driver to regmap
  clk: cs2000-cp: freeze config during register fiddling
  clk: cs2000-cp: make clock skip setting configurable
  clk: cs2000-cp: add support for dynamic mode
  clk: cs2000-cp: Make aux output function controllable
  dt-bindings: clock: cs2000-cp: document cirrus,dynamic-mode
  dt-bindings: clock: cs2000-cp: document cirrus,clock-skip flag
  dt-bindings: clock: cs2000-cp: document aux-output-source
  dt-bindings: clock: convert cs2000-cp bindings to yaml

* clk-renesas:
  dt-bindings: clock: renesas: Make example 'clocks' parsable
  clk: rs9: Add Renesas 9-series PCIe clock generator driver
  clk: fixed-factor: Introduce devm_clk_hw_register_fixed_factor_index()
  dt-bindings: clk: rs9: Add Renesas 9-series I2C PCIe clock generator
  clk: renesas: r8a779f0: Add PFC clock
  clk: renesas: r8a779f0: Add I2C clocks
  clk: renesas: r8a779f0: Add WDT clock
  clk: renesas: r8a779f0: Fix RSW2 clock divider
  clk: renesas: rzg2l-cpg: Add support for RZ/V2L SoC
  dt-bindings: clock: renesas: Document RZ/V2L SoC
  dt-bindings: clock: Add R9A07G054 CPG Clock and Reset Definitions
  clk: renesas: r8a779a0: Add CANFD module clock
  clk: renesas: r9a07g044: Update multiplier and divider values for PLL2/3
  clk: renesas: r8a7799[05]: Add MLP clocks
  clk: renesas: r8a779f0: Add SYS-DMAC clocks
This commit is contained in:
Stephen Boyd 2022-03-29 10:18:37 -07:00
28 changed files with 1744 additions and 337 deletions

View file

@ -0,0 +1,91 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/cirrus,cs2000-cp.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Binding CIRRUS LOGIC Fractional-N Clock Synthesizer & Clock Multiplier
maintainers:
- Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
description: |
The CS2000-CP is an extremely versatile system clocking device that
utilizes a programmable phase lock loop.
Link: https://www.cirrus.com/products/cs2000/
properties:
compatible:
enum:
- cirrus,cs2000-cp
clocks:
description:
Common clock binding for CLK_IN, XTI/REF_CLK
minItems: 2
maxItems: 2
clock-names:
items:
- const: clk_in
- const: ref_clk
'#clock-cells':
const: 0
reg:
maxItems: 1
cirrus,aux-output-source:
description:
Specifies the function of the auxiliary clock output pin
$ref: /schemas/types.yaml#/definitions/uint32
enum:
- 0 # CS2000CP_AUX_OUTPUT_REF_CLK: ref_clk input
- 1 # CS2000CP_AUX_OUTPUT_CLK_IN: clk_in input
- 2 # CS2000CP_AUX_OUTPUT_CLK_OUT: clk_out output
- 3 # CS2000CP_AUX_OUTPUT_PLL_LOCK: pll lock status
default: 0
cirrus,clock-skip:
description:
This mode allows the PLL to maintain lock even when CLK_IN
has missing pulses for up to 20 ms.
$ref: /schemas/types.yaml#/definitions/flag
cirrus,dynamic-mode:
description:
In dynamic mode, the CLK_IN input is used to drive the
digital PLL of the silicon.
If not given, the static mode shall be used to derive the
output signal directly from the REF_CLK input.
$ref: /schemas/types.yaml#/definitions/flag
required:
- compatible
- reg
- clocks
- clock-names
- '#clock-cells'
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/cirrus,cs2000-cp.h>
i2c@0 {
reg = <0x0 0x100>;
#address-cells = <1>;
#size-cells = <0>;
clock-controller@4f {
#clock-cells = <0>;
compatible = "cirrus,cs2000-cp";
reg = <0x4f>;
clocks = <&rcar_sound 0>, <&x12_clk>;
clock-names = "clk_in", "ref_clk";
cirrus,aux-output-source = <CS2000CP_AUX_OUTPUT_CLK_OUT>;
};
};

View file

@ -1,22 +0,0 @@
CIRRUS LOGIC Fractional-N Clock Synthesizer & Clock Multiplier
Required properties:
- compatible: "cirrus,cs2000-cp"
- reg: The chip select number on the I2C bus
- clocks: common clock binding for CLK_IN, XTI/REF_CLK
- clock-names: CLK_IN : clk_in, XTI/REF_CLK : ref_clk
- #clock-cells: must be <0>
Example:
&i2c2 {
...
cs2000: clk_multiplier@4f {
#clock-cells = <0>;
compatible = "cirrus,cs2000-cp";
reg = <0x4f>;
clocks = <&rcar_sound 0>, <&x12_clk>;
clock-names = "clk_in", "ref_clk";
};
};

View file

@ -0,0 +1,97 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/renesas,9series.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Binding for Renesas 9-series I2C PCIe clock generators
description: |
The Renesas 9-series are I2C PCIe clock generators providing
from 1 to 20 output clocks.
When referencing the provided clock in the DT using phandle
and clock specifier, the following mapping applies:
- 9FGV0241:
0 -- DIF0
1 -- DIF1
maintainers:
- Marek Vasut <marex@denx.de>
properties:
compatible:
enum:
- renesas,9fgv0241
reg:
description: I2C device address
enum: [ 0x68, 0x6a ]
'#clock-cells':
const: 1
clocks:
items:
- description: XTal input clock
renesas,out-amplitude-microvolt:
enum: [ 600000, 700000, 800000, 900000 ]
description: Output clock signal amplitude
renesas,out-spread-spectrum:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [ 100000, 99750, 99500 ]
description: Output clock down spread in pcm (1/1000 of percent)
patternProperties:
"^DIF[0-19]$":
type: object
description:
Description of one of the outputs (DIF0..DIF19).
properties:
renesas,slew-rate:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [ 2000000, 3000000 ]
description: Output clock slew rate select in V/ns
additionalProperties: false
required:
- compatible
- reg
- clocks
- '#clock-cells'
additionalProperties: false
examples:
- |
/* 25MHz reference crystal */
ref25: ref25m {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <25000000>;
};
i2c@0 {
reg = <0x0 0x100>;
#address-cells = <1>;
#size-cells = <0>;
rs9: clock-generator@6a {
compatible = "renesas,9fgv0241";
reg = <0x6a>;
#clock-cells = <1>;
clocks = <&ref25m>;
DIF0 {
renesas,slew-rate = <3000000>;
};
};
};
...

View file

@ -51,6 +51,18 @@ additionalProperties: false
examples:
- |
#include <dt-bindings/clock/r8a73a4-clock.h>
cpg_clocks: cpg_clocks@e6150000 {
compatible = "renesas,r8a73a4-cpg-clocks";
reg = <0xe6150000 0x10000>;
clocks = <&extal1_clk>, <&extal2_clk>;
#clock-cells = <1>;
clock-output-names = "main", "pll0", "pll1", "pll2",
"pll2s", "pll2h", "z", "z2",
"i", "m3", "b", "m1", "m2",
"zx", "zs", "hp";
};
sdhi2_clk: sdhi2_clk@e615007c {
compatible = "renesas,r8a73a4-div6-clock", "renesas,cpg-div6-clock";
reg = <0xe615007c 4>;

View file

@ -4,13 +4,13 @@
$id: "http://devicetree.org/schemas/clock/renesas,rzg2l-cpg.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
title: Renesas RZ/G2L Clock Pulse Generator / Module Standby Mode
title: Renesas RZ/{G2L,V2L} Clock Pulse Generator / Module Standby Mode
maintainers:
- Geert Uytterhoeven <geert+renesas@glider.be>
description: |
On Renesas RZ/G2L SoC, the CPG (Clock Pulse Generator) and Module
On Renesas RZ/{G2L,V2L} SoC, the CPG (Clock Pulse Generator) and Module
Standby Mode share the same register block.
They provide the following functionalities:
@ -22,7 +22,9 @@ description: |
properties:
compatible:
const: renesas,r9a07g044-cpg # RZ/G2{L,LC}
enum:
- renesas,r9a07g044-cpg # RZ/G2{L,LC}
- renesas,r9a07g054-cpg # RZ/V2L
reg:
maxItems: 1
@ -40,9 +42,9 @@ properties:
description: |
- For CPG core clocks, the two clock specifier cells must be "CPG_CORE"
and a core clock reference, as defined in
<dt-bindings/clock/r9a07g044-cpg.h>
<dt-bindings/clock/r9a07g*-cpg.h>
- For module clocks, the two clock specifier cells must be "CPG_MOD" and
a module number, as defined in the <dt-bindings/clock/r9a07g044-cpg.h>.
a module number, as defined in the <dt-bindings/clock/r9a07g0*-cpg.h>.
const: 2
'#power-domain-cells':
@ -56,7 +58,7 @@ properties:
'#reset-cells':
description:
The single reset specifier cell must be the module number, as defined in
the <dt-bindings/clock/r9a07g044-cpg.h>.
the <dt-bindings/clock/r9a07g0*-cpg.h>.
const: 1
required:

3
drivers/clk/.kunitconfig Normal file
View file

@ -0,0 +1,3 @@
CONFIG_KUNIT=y
CONFIG_COMMON_CLK=y
CONFIG_CLK_GATE_KUNIT_TEST=y

View file

@ -197,6 +197,7 @@ config COMMON_CLK_CDCE925
config COMMON_CLK_CS2000_CP
tristate "Clock driver for CS2000 Fractional-N Clock Synthesizer & Clock Multiplier"
depends on I2C
select REGMAP_I2C
help
If you say yes here you get support for the CS2000 clock multiplier.
@ -337,6 +338,15 @@ config COMMON_CLK_OXNAS
help
Support for the OXNAS SoC Family clocks.
config COMMON_CLK_RS9_PCIE
tristate "Clock driver for Renesas 9-series PCIe clock generators"
depends on I2C
depends on OF
select REGMAP_I2C
help
This driver supports the Renesas 9-series PCIe clock generator
models 9FGV/9DBV/9DMV/9FGL/9DML/9QXL/9SQ.
config COMMON_CLK_VC5
tristate "Clock driver for IDT VersaClock 5,6 devices"
depends on I2C
@ -426,4 +436,12 @@ source "drivers/clk/x86/Kconfig"
source "drivers/clk/xilinx/Kconfig"
source "drivers/clk/zynqmp/Kconfig"
# Kunit test cases
config CLK_GATE_KUNIT_TEST
tristate "Basic gate type Kunit test" if !KUNIT_ALL_TESTS
depends on KUNIT
default KUNIT_ALL_TESTS
help
Kunit test for the basic clk gate type.
endif

View file

@ -6,6 +6,7 @@ obj-$(CONFIG_COMMON_CLK) += clk-divider.o
obj-$(CONFIG_COMMON_CLK) += clk-fixed-factor.o
obj-$(CONFIG_COMMON_CLK) += clk-fixed-rate.o
obj-$(CONFIG_COMMON_CLK) += clk-gate.o
obj-$(CONFIG_CLK_GATE_KUNIT_TEST) += clk-gate_test.o
obj-$(CONFIG_COMMON_CLK) += clk-multiplier.o
obj-$(CONFIG_COMMON_CLK) += clk-mux.o
obj-$(CONFIG_COMMON_CLK) += clk-composite.o
@ -67,6 +68,7 @@ obj-$(CONFIG_COMMON_CLK_STM32MP157) += clk-stm32mp1.o
obj-$(CONFIG_COMMON_CLK_TPS68470) += clk-tps68470.o
obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o
obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
obj-$(CONFIG_COMMON_CLK_RS9_PCIE) += clk-renesas-pcie.o
obj-$(CONFIG_COMMON_CLK_VC5) += clk-versaclock5.o
obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o

View file

@ -11,6 +11,7 @@
#include <linux/i2c.h>
#include <linux/of_device.h>
#include <linux/module.h>
#include <linux/regmap.h>
#define CH_MAX 4
#define RATIO_REG_SIZE 4
@ -39,6 +40,8 @@
/* DEVICE_CFG1 */
#define RSEL(x) (((x) & 0x3) << 3)
#define RSEL_MASK RSEL(0x3)
#define AUXOUTSRC(x) (((x) & 0x3) << 1)
#define AUXOUTSRC_MASK AUXOUTSRC(0x3)
#define ENDEV1 (0x1)
/* DEVICE_CFG2 */
@ -47,9 +50,10 @@
#define LOCKCLK_MASK LOCKCLK(0x3)
#define FRACNSRC_MASK (1 << 0)
#define FRACNSRC_STATIC (0 << 0)
#define FRACNSRC_DYNAMIC (1 << 1)
#define FRACNSRC_DYNAMIC (1 << 0)
/* GLOBAL_CFG */
#define FREEZE (1 << 7)
#define ENDEV2 (0x1)
/* FUNC_CFG1 */
@ -71,11 +75,40 @@
#define REF_CLK 1
#define CLK_MAX 2
static bool cs2000_readable_reg(struct device *dev, unsigned int reg)
{
return reg > 0;
}
static bool cs2000_writeable_reg(struct device *dev, unsigned int reg)
{
return reg != DEVICE_ID;
}
static bool cs2000_volatile_reg(struct device *dev, unsigned int reg)
{
return reg == DEVICE_CTRL;
}
static const struct regmap_config cs2000_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = FUNC_CFG2,
.readable_reg = cs2000_readable_reg,
.writeable_reg = cs2000_writeable_reg,
.volatile_reg = cs2000_volatile_reg,
};
struct cs2000_priv {
struct clk_hw hw;
struct i2c_client *client;
struct clk *clk_in;
struct clk *ref_clk;
struct regmap *regmap;
bool dynamic_mode;
bool lf_ratio;
bool clk_skip;
/* suspend/resume */
unsigned long saved_rate;
@ -94,55 +127,30 @@ static const struct i2c_device_id cs2000_id[] = {
};
MODULE_DEVICE_TABLE(i2c, cs2000_id);
#define cs2000_read(priv, addr) \
i2c_smbus_read_byte_data(priv_to_client(priv), addr)
#define cs2000_write(priv, addr, val) \
i2c_smbus_write_byte_data(priv_to_client(priv), addr, val)
static int cs2000_bset(struct cs2000_priv *priv, u8 addr, u8 mask, u8 val)
{
s32 data;
data = cs2000_read(priv, addr);
if (data < 0)
return data;
data &= ~mask;
data |= (val & mask);
return cs2000_write(priv, addr, data);
}
static int cs2000_enable_dev_config(struct cs2000_priv *priv, bool enable)
{
int ret;
ret = cs2000_bset(priv, DEVICE_CFG1, ENDEV1,
enable ? ENDEV1 : 0);
ret = regmap_update_bits(priv->regmap, DEVICE_CFG1, ENDEV1,
enable ? ENDEV1 : 0);
if (ret < 0)
return ret;
ret = cs2000_bset(priv, GLOBAL_CFG, ENDEV2,
enable ? ENDEV2 : 0);
ret = regmap_update_bits(priv->regmap, GLOBAL_CFG, ENDEV2,
enable ? ENDEV2 : 0);
if (ret < 0)
return ret;
ret = cs2000_bset(priv, FUNC_CFG1, CLKSKIPEN,
enable ? CLKSKIPEN : 0);
if (ret < 0)
return ret;
/* FIXME: for Static ratio mode */
ret = cs2000_bset(priv, FUNC_CFG2, LFRATIO_MASK,
LFRATIO_12_20);
ret = regmap_update_bits(priv->regmap, FUNC_CFG1, CLKSKIPEN,
(enable && priv->clk_skip) ? CLKSKIPEN : 0);
if (ret < 0)
return ret;
return 0;
}
static int cs2000_clk_in_bound_rate(struct cs2000_priv *priv,
u32 rate_in)
static int cs2000_ref_clk_bound_rate(struct cs2000_priv *priv,
u32 rate_in)
{
u32 val;
@ -155,21 +163,21 @@ static int cs2000_clk_in_bound_rate(struct cs2000_priv *priv,
else
return -EINVAL;
return cs2000_bset(priv, FUNC_CFG1,
REFCLKDIV_MASK,
REFCLKDIV(val));
return regmap_update_bits(priv->regmap, FUNC_CFG1,
REFCLKDIV_MASK,
REFCLKDIV(val));
}
static int cs2000_wait_pll_lock(struct cs2000_priv *priv)
{
struct device *dev = priv_to_dev(priv);
s32 val;
unsigned int i;
unsigned int i, val;
int ret;
for (i = 0; i < 256; i++) {
val = cs2000_read(priv, DEVICE_CTRL);
if (val < 0)
return val;
ret = regmap_read(priv->regmap, DEVICE_CTRL, &val);
if (ret < 0)
return ret;
if (!(val & PLL_UNLOCK))
return 0;
udelay(1);
@ -183,41 +191,43 @@ static int cs2000_wait_pll_lock(struct cs2000_priv *priv)
static int cs2000_clk_out_enable(struct cs2000_priv *priv, bool enable)
{
/* enable both AUX_OUT, CLK_OUT */
return cs2000_bset(priv, DEVICE_CTRL,
(AUXOUTDIS | CLKOUTDIS),
enable ? 0 :
(AUXOUTDIS | CLKOUTDIS));
return regmap_update_bits(priv->regmap, DEVICE_CTRL,
(AUXOUTDIS | CLKOUTDIS),
enable ? 0 :
(AUXOUTDIS | CLKOUTDIS));
}
static u32 cs2000_rate_to_ratio(u32 rate_in, u32 rate_out)
static u32 cs2000_rate_to_ratio(u32 rate_in, u32 rate_out, bool lf_ratio)
{
u64 ratio;
u32 multiplier = lf_ratio ? 12 : 20;
/*
* ratio = rate_out / rate_in * 2^20
* ratio = rate_out / rate_in * 2^multiplier
*
* To avoid over flow, rate_out is u64.
* The result should be u32.
*/
ratio = (u64)rate_out << 20;
ratio = (u64)rate_out << multiplier;
do_div(ratio, rate_in);
return ratio;
}
static unsigned long cs2000_ratio_to_rate(u32 ratio, u32 rate_in)
static unsigned long cs2000_ratio_to_rate(u32 ratio, u32 rate_in, bool lf_ratio)
{
u64 rate_out;
u32 multiplier = lf_ratio ? 12 : 20;
/*
* ratio = rate_out / rate_in * 2^20
* ratio = rate_out / rate_in * 2^multiplier
*
* To avoid over flow, rate_out is u64.
* The result should be u32 or unsigned long.
*/
rate_out = (u64)ratio * rate_in;
return rate_out >> 20;
return rate_out >> multiplier;
}
static int cs2000_ratio_set(struct cs2000_priv *priv,
@ -230,9 +240,9 @@ static int cs2000_ratio_set(struct cs2000_priv *priv,
if (CH_SIZE_ERR(ch))
return -EINVAL;
val = cs2000_rate_to_ratio(rate_in, rate_out);
val = cs2000_rate_to_ratio(rate_in, rate_out, priv->lf_ratio);
for (i = 0; i < RATIO_REG_SIZE; i++) {
ret = cs2000_write(priv,
ret = regmap_write(priv->regmap,
Ratio_Add(ch, i),
Ratio_Val(val, i));
if (ret < 0)
@ -244,14 +254,14 @@ static int cs2000_ratio_set(struct cs2000_priv *priv,
static u32 cs2000_ratio_get(struct cs2000_priv *priv, int ch)
{
s32 tmp;
unsigned int tmp, i;
u32 val;
unsigned int i;
int ret;
val = 0;
for (i = 0; i < RATIO_REG_SIZE; i++) {
tmp = cs2000_read(priv, Ratio_Add(ch, i));
if (tmp < 0)
ret = regmap_read(priv->regmap, Ratio_Add(ch, i), &tmp);
if (ret < 0)
return 0;
val |= Val_Ratio(tmp, i);
@ -263,22 +273,20 @@ static u32 cs2000_ratio_get(struct cs2000_priv *priv, int ch)
static int cs2000_ratio_select(struct cs2000_priv *priv, int ch)
{
int ret;
u8 fracnsrc;
if (CH_SIZE_ERR(ch))
return -EINVAL;
/*
* FIXME
*
* this driver supports static ratio mode only at this point.
*/
ret = cs2000_bset(priv, DEVICE_CFG1, RSEL_MASK, RSEL(ch));
ret = regmap_update_bits(priv->regmap, DEVICE_CFG1, RSEL_MASK, RSEL(ch));
if (ret < 0)
return ret;
ret = cs2000_bset(priv, DEVICE_CFG2,
(AUTORMOD | LOCKCLK_MASK | FRACNSRC_MASK),
(LOCKCLK(ch) | FRACNSRC_STATIC));
fracnsrc = priv->dynamic_mode ? FRACNSRC_DYNAMIC : FRACNSRC_STATIC;
ret = regmap_update_bits(priv->regmap, DEVICE_CFG2,
AUTORMOD | LOCKCLK_MASK | FRACNSRC_MASK,
LOCKCLK(ch) | fracnsrc);
if (ret < 0)
return ret;
@ -294,17 +302,39 @@ static unsigned long cs2000_recalc_rate(struct clk_hw *hw,
ratio = cs2000_ratio_get(priv, ch);
return cs2000_ratio_to_rate(ratio, parent_rate);
return cs2000_ratio_to_rate(ratio, parent_rate, priv->lf_ratio);
}
static long cs2000_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
struct cs2000_priv *priv = hw_to_priv(hw);
u32 ratio;
ratio = cs2000_rate_to_ratio(*parent_rate, rate);
ratio = cs2000_rate_to_ratio(*parent_rate, rate, priv->lf_ratio);
return cs2000_ratio_to_rate(ratio, *parent_rate);
return cs2000_ratio_to_rate(ratio, *parent_rate, priv->lf_ratio);
}
static int cs2000_select_ratio_mode(struct cs2000_priv *priv,
unsigned long rate,
unsigned long parent_rate)
{
/*
* From the datasheet:
*
* | It is recommended that the 12.20 High-Resolution format be
* | utilized whenever the desired ratio is less than 4096 since
* | the output frequency accuracy of the PLL is directly proportional
* | to the accuracy of the timing reference clock and the resolution
* | of the R_UD.
*
* This mode is only available in dynamic mode.
*/
priv->lf_ratio = priv->dynamic_mode && ((rate / parent_rate) > 4096);
return regmap_update_bits(priv->regmap, FUNC_CFG2, LFRATIO_MASK,
priv->lf_ratio ? LFRATIO_20_12 : LFRATIO_12_20);
}
static int __cs2000_set_rate(struct cs2000_priv *priv, int ch,
@ -313,7 +343,11 @@ static int __cs2000_set_rate(struct cs2000_priv *priv, int ch,
{
int ret;
ret = cs2000_clk_in_bound_rate(priv, parent_rate);
ret = regmap_update_bits(priv->regmap, GLOBAL_CFG, FREEZE, FREEZE);
if (ret < 0)
return ret;
ret = cs2000_select_ratio_mode(priv, rate, parent_rate);
if (ret < 0)
return ret;
@ -325,6 +359,10 @@ static int __cs2000_set_rate(struct cs2000_priv *priv, int ch,
if (ret < 0)
return ret;
ret = regmap_update_bits(priv->regmap, GLOBAL_CFG, FREEZE, 0);
if (ret < 0)
return ret;
priv->saved_rate = rate;
priv->saved_parent_rate = parent_rate;
@ -380,8 +418,13 @@ static void cs2000_disable(struct clk_hw *hw)
static u8 cs2000_get_parent(struct clk_hw *hw)
{
/* always return REF_CLK */
return REF_CLK;
struct cs2000_priv *priv = hw_to_priv(hw);
/*
* In dynamic mode, output rates are derived from CLK_IN.
* In static mode, CLK_IN is ignored, so we return REF_CLK instead.
*/
return priv->dynamic_mode ? CLK_IN : REF_CLK;
}
static const struct clk_ops cs2000_ops = {
@ -421,22 +464,44 @@ static int cs2000_clk_register(struct cs2000_priv *priv)
struct clk_init_data init;
const char *name = np->name;
static const char *parent_names[CLK_MAX];
u32 aux_out = 0;
int ref_clk_rate;
int ch = 0; /* it uses ch0 only at this point */
int rate;
int ret;
of_property_read_string(np, "clock-output-names", &name);
/*
* set default rate as 1/1.
* otherwise .set_rate which setup ratio
* is never called if user requests 1/1 rate
*/
rate = clk_get_rate(priv->ref_clk);
ret = __cs2000_set_rate(priv, ch, rate, rate);
priv->dynamic_mode = of_property_read_bool(np, "cirrus,dynamic-mode");
dev_info(dev, "operating in %s mode\n",
priv->dynamic_mode ? "dynamic" : "static");
of_property_read_u32(np, "cirrus,aux-output-source", &aux_out);
ret = regmap_update_bits(priv->regmap, DEVICE_CFG1,
AUXOUTSRC_MASK, AUXOUTSRC(aux_out));
if (ret < 0)
return ret;
priv->clk_skip = of_property_read_bool(np, "cirrus,clock-skip");
ref_clk_rate = clk_get_rate(priv->ref_clk);
ret = cs2000_ref_clk_bound_rate(priv, ref_clk_rate);
if (ret < 0)
return ret;
if (priv->dynamic_mode) {
/* Default to low-frequency mode to allow for large ratios */
priv->lf_ratio = true;
} else {
/*
* set default rate as 1/1.
* otherwise .set_rate which setup ratio
* is never called if user requests 1/1 rate
*/
ret = __cs2000_set_rate(priv, ch, ref_clk_rate, ref_clk_rate);
if (ret < 0)
return ret;
}
parent_names[CLK_IN] = __clk_get_name(priv->clk_in);
parent_names[REF_CLK] = __clk_get_name(priv->ref_clk);
@ -464,12 +529,13 @@ static int cs2000_clk_register(struct cs2000_priv *priv)
static int cs2000_version_print(struct cs2000_priv *priv)
{
struct device *dev = priv_to_dev(priv);
s32 val;
const char *revision;
unsigned int val;
int ret;
val = cs2000_read(priv, DEVICE_ID);
if (val < 0)
return val;
ret = regmap_read(priv->regmap, DEVICE_ID, &val);
if (ret < 0)
return ret;
/* CS2000 should be 0x0 */
if (val >> 3)
@ -518,6 +584,10 @@ static int cs2000_probe(struct i2c_client *client,
priv->client = client;
i2c_set_clientdata(client, priv);
priv->regmap = devm_regmap_init_i2c(client, &cs2000_regmap_config);
if (IS_ERR(priv->regmap))
return PTR_ERR(priv->regmap);
ret = cs2000_clk_get(priv);
if (ret < 0)
return ret;

View file

@ -131,6 +131,28 @@ __clk_hw_register_fixed_factor(struct device *dev, struct device_node *np,
return hw;
}
/**
* devm_clk_hw_register_fixed_factor_index - Register a fixed factor clock with
* parent from DT index
* @dev: device that is registering this clock
* @name: name of this clock
* @index: index of phandle in @dev 'clocks' property
* @flags: fixed factor flags
* @mult: multiplier
* @div: divider
*
* Return: Pointer to fixed factor clk_hw structure that was registered or
* an error pointer.
*/
struct clk_hw *devm_clk_hw_register_fixed_factor_index(struct device *dev,
const char *name, unsigned int index, unsigned long flags,
unsigned int mult, unsigned int div)
{
return __clk_hw_register_fixed_factor(dev, NULL, name, NULL, index,
flags, mult, div, true);
}
EXPORT_SYMBOL_GPL(devm_clk_hw_register_fixed_factor_index);
struct clk_hw *clk_hw_register_fixed_factor(struct device *dev,
const char *name, const char *parent_name, unsigned long flags,
unsigned int mult, unsigned int div)

464
drivers/clk/clk-gate_test.c Normal file
View file

@ -0,0 +1,464 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Kunit test for clk gate basic type
*/
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/platform_device.h>
#include <kunit/test.h>
static void clk_gate_register_test_dev(struct kunit *test)
{
struct clk_hw *ret;
struct platform_device *pdev;
pdev = platform_device_register_simple("test_gate_device", -1, NULL, 0);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
ret = clk_hw_register_gate(&pdev->dev, "test_gate", NULL, 0, NULL,
0, 0, NULL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ret);
KUNIT_EXPECT_STREQ(test, "test_gate", clk_hw_get_name(ret));
KUNIT_EXPECT_EQ(test, 0UL, clk_hw_get_flags(ret));
clk_hw_unregister_gate(ret);
platform_device_put(pdev);
}
static void clk_gate_register_test_parent_names(struct kunit *test)
{
struct clk_hw *parent;
struct clk_hw *ret;
parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
1000000);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
ret = clk_hw_register_gate(NULL, "test_gate", "test_parent", 0, NULL,
0, 0, NULL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ret);
KUNIT_EXPECT_PTR_EQ(test, parent, clk_hw_get_parent(ret));
clk_hw_unregister_gate(ret);
clk_hw_unregister_fixed_rate(parent);
}
static void clk_gate_register_test_parent_data(struct kunit *test)
{
struct clk_hw *parent;
struct clk_hw *ret;
struct clk_parent_data pdata = { };
parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
1000000);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
pdata.hw = parent;
ret = clk_hw_register_gate_parent_data(NULL, "test_gate", &pdata, 0,
NULL, 0, 0, NULL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ret);
KUNIT_EXPECT_PTR_EQ(test, parent, clk_hw_get_parent(ret));
clk_hw_unregister_gate(ret);
clk_hw_unregister_fixed_rate(parent);
}
static void clk_gate_register_test_parent_data_legacy(struct kunit *test)
{
struct clk_hw *parent;
struct clk_hw *ret;
struct clk_parent_data pdata = { };
parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
1000000);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
pdata.name = "test_parent";
ret = clk_hw_register_gate_parent_data(NULL, "test_gate", &pdata, 0,
NULL, 0, 0, NULL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ret);
KUNIT_EXPECT_PTR_EQ(test, parent, clk_hw_get_parent(ret));
clk_hw_unregister_gate(ret);
clk_hw_unregister_fixed_rate(parent);
}
static void clk_gate_register_test_parent_hw(struct kunit *test)
{
struct clk_hw *parent;
struct clk_hw *ret;
parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
1000000);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
ret = clk_hw_register_gate_parent_hw(NULL, "test_gate", parent, 0, NULL,
0, 0, NULL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ret);
KUNIT_EXPECT_PTR_EQ(test, parent, clk_hw_get_parent(ret));
clk_hw_unregister_gate(ret);
clk_hw_unregister_fixed_rate(parent);
}
static void clk_gate_register_test_hiword_invalid(struct kunit *test)
{
struct clk_hw *ret;
ret = clk_hw_register_gate(NULL, "test_gate", NULL, 0, NULL,
20, CLK_GATE_HIWORD_MASK, NULL);
KUNIT_EXPECT_TRUE(test, IS_ERR(ret));
}
static struct kunit_case clk_gate_register_test_cases[] = {
KUNIT_CASE(clk_gate_register_test_dev),
KUNIT_CASE(clk_gate_register_test_parent_names),
KUNIT_CASE(clk_gate_register_test_parent_data),
KUNIT_CASE(clk_gate_register_test_parent_data_legacy),
KUNIT_CASE(clk_gate_register_test_parent_hw),
KUNIT_CASE(clk_gate_register_test_hiword_invalid),
{}
};
static struct kunit_suite clk_gate_register_test_suite = {
.name = "clk-gate-register-test",
.test_cases = clk_gate_register_test_cases,
};
struct clk_gate_test_context {
void __iomem *fake_mem;
struct clk_hw *hw;
struct clk_hw *parent;
u32 fake_reg; /* Keep at end, KASAN can detect out of bounds */
};
static struct clk_gate_test_context *clk_gate_test_alloc_ctx(struct kunit *test)
{
struct clk_gate_test_context *ctx;
test->priv = ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
ctx->fake_mem = (void __force __iomem *)&ctx->fake_reg;
return ctx;
}
static void clk_gate_test_parent_rate(struct kunit *test)
{
struct clk_gate_test_context *ctx = test->priv;
struct clk_hw *parent = ctx->parent;
struct clk_hw *hw = ctx->hw;
unsigned long prate = clk_hw_get_rate(parent);
unsigned long rate = clk_hw_get_rate(hw);
KUNIT_EXPECT_EQ(test, prate, rate);
}
static void clk_gate_test_enable(struct kunit *test)
{
struct clk_gate_test_context *ctx = test->priv;
struct clk_hw *parent = ctx->parent;
struct clk_hw *hw = ctx->hw;
struct clk *clk = hw->clk;
u32 enable_val = BIT(5);
KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
KUNIT_EXPECT_EQ(test, enable_val, ctx->fake_reg);
KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(hw));
KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(hw));
KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(parent));
KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(parent));
}
static void clk_gate_test_disable(struct kunit *test)
{
struct clk_gate_test_context *ctx = test->priv;
struct clk_hw *parent = ctx->parent;
struct clk_hw *hw = ctx->hw;
struct clk *clk = hw->clk;
u32 enable_val = BIT(5);
u32 disable_val = 0;
KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
KUNIT_ASSERT_EQ(test, enable_val, ctx->fake_reg);
clk_disable_unprepare(clk);
KUNIT_EXPECT_EQ(test, disable_val, ctx->fake_reg);
KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(hw));
KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(hw));
KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(parent));
KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(parent));
}
static struct kunit_case clk_gate_test_cases[] = {
KUNIT_CASE(clk_gate_test_parent_rate),
KUNIT_CASE(clk_gate_test_enable),
KUNIT_CASE(clk_gate_test_disable),
{}
};
static int clk_gate_test_init(struct kunit *test)
{
struct clk_hw *parent;
struct clk_hw *hw;
struct clk_gate_test_context *ctx;
ctx = clk_gate_test_alloc_ctx(test);
parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
2000000);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
hw = clk_hw_register_gate_parent_hw(NULL, "test_gate", parent, 0,
ctx->fake_mem, 5, 0, NULL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
ctx->hw = hw;
ctx->parent = parent;
return 0;
}
static void clk_gate_test_exit(struct kunit *test)
{
struct clk_gate_test_context *ctx = test->priv;
clk_hw_unregister_gate(ctx->hw);
clk_hw_unregister_fixed_rate(ctx->parent);
}
static struct kunit_suite clk_gate_test_suite = {
.name = "clk-gate-test",
.init = clk_gate_test_init,
.exit = clk_gate_test_exit,
.test_cases = clk_gate_test_cases,
};
static void clk_gate_test_invert_enable(struct kunit *test)
{
struct clk_gate_test_context *ctx = test->priv;
struct clk_hw *parent = ctx->parent;
struct clk_hw *hw = ctx->hw;
struct clk *clk = hw->clk;
u32 enable_val = 0;
KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
KUNIT_EXPECT_EQ(test, enable_val, ctx->fake_reg);
KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(hw));
KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(hw));
KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(parent));
KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(parent));
}
static void clk_gate_test_invert_disable(struct kunit *test)
{
struct clk_gate_test_context *ctx = test->priv;
struct clk_hw *parent = ctx->parent;
struct clk_hw *hw = ctx->hw;
struct clk *clk = hw->clk;
u32 enable_val = 0;
u32 disable_val = BIT(15);
KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
KUNIT_ASSERT_EQ(test, enable_val, ctx->fake_reg);
clk_disable_unprepare(clk);
KUNIT_EXPECT_EQ(test, disable_val, ctx->fake_reg);
KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(hw));
KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(hw));
KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(parent));
KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(parent));
}
static struct kunit_case clk_gate_test_invert_cases[] = {
KUNIT_CASE(clk_gate_test_invert_enable),
KUNIT_CASE(clk_gate_test_invert_disable),
{}
};
static int clk_gate_test_invert_init(struct kunit *test)
{
struct clk_hw *parent;
struct clk_hw *hw;
struct clk_gate_test_context *ctx;
ctx = clk_gate_test_alloc_ctx(test);
parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
2000000);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
ctx->fake_reg = BIT(15); /* Default to off */
hw = clk_hw_register_gate_parent_hw(NULL, "test_gate", parent, 0,
ctx->fake_mem, 15,
CLK_GATE_SET_TO_DISABLE, NULL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
ctx->hw = hw;
ctx->parent = parent;
return 0;
}
static struct kunit_suite clk_gate_test_invert_suite = {
.name = "clk-gate-invert-test",
.init = clk_gate_test_invert_init,
.exit = clk_gate_test_exit,
.test_cases = clk_gate_test_invert_cases,
};
static void clk_gate_test_hiword_enable(struct kunit *test)
{
struct clk_gate_test_context *ctx = test->priv;
struct clk_hw *parent = ctx->parent;
struct clk_hw *hw = ctx->hw;
struct clk *clk = hw->clk;
u32 enable_val = BIT(9) | BIT(9 + 16);
KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
KUNIT_EXPECT_EQ(test, enable_val, ctx->fake_reg);
KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(hw));
KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(hw));
KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(parent));
KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(parent));
}
static void clk_gate_test_hiword_disable(struct kunit *test)
{
struct clk_gate_test_context *ctx = test->priv;
struct clk_hw *parent = ctx->parent;
struct clk_hw *hw = ctx->hw;
struct clk *clk = hw->clk;
u32 enable_val = BIT(9) | BIT(9 + 16);
u32 disable_val = BIT(9 + 16);
KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
KUNIT_ASSERT_EQ(test, enable_val, ctx->fake_reg);
clk_disable_unprepare(clk);
KUNIT_EXPECT_EQ(test, disable_val, ctx->fake_reg);
KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(hw));
KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(hw));
KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(parent));
KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(parent));
}
static struct kunit_case clk_gate_test_hiword_cases[] = {
KUNIT_CASE(clk_gate_test_hiword_enable),
KUNIT_CASE(clk_gate_test_hiword_disable),
{}
};
static int clk_gate_test_hiword_init(struct kunit *test)
{
struct clk_hw *parent;
struct clk_hw *hw;
struct clk_gate_test_context *ctx;
ctx = clk_gate_test_alloc_ctx(test);
parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
2000000);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
hw = clk_hw_register_gate_parent_hw(NULL, "test_gate", parent, 0,
ctx->fake_mem, 9,
CLK_GATE_HIWORD_MASK, NULL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
ctx->hw = hw;
ctx->parent = parent;
return 0;
}
static struct kunit_suite clk_gate_test_hiword_suite = {
.name = "clk-gate-hiword-test",
.init = clk_gate_test_hiword_init,
.exit = clk_gate_test_exit,
.test_cases = clk_gate_test_hiword_cases,
};
static void clk_gate_test_is_enabled(struct kunit *test)
{
struct clk_hw *hw;
struct clk_gate_test_context *ctx;
ctx = clk_gate_test_alloc_ctx(test);
ctx->fake_reg = BIT(7);
hw = clk_hw_register_gate(NULL, "test_gate", NULL, 0, ctx->fake_mem, 7,
0, NULL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
KUNIT_ASSERT_TRUE(test, clk_hw_is_enabled(hw));
clk_hw_unregister_gate(hw);
}
static void clk_gate_test_is_disabled(struct kunit *test)
{
struct clk_hw *hw;
struct clk_gate_test_context *ctx;
ctx = clk_gate_test_alloc_ctx(test);
ctx->fake_reg = BIT(4);
hw = clk_hw_register_gate(NULL, "test_gate", NULL, 0, ctx->fake_mem, 7,
0, NULL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
KUNIT_ASSERT_FALSE(test, clk_hw_is_enabled(hw));
clk_hw_unregister_gate(hw);
}
static void clk_gate_test_is_enabled_inverted(struct kunit *test)
{
struct clk_hw *hw;
struct clk_gate_test_context *ctx;
ctx = clk_gate_test_alloc_ctx(test);
ctx->fake_reg = BIT(31);
hw = clk_hw_register_gate(NULL, "test_gate", NULL, 0, ctx->fake_mem, 2,
CLK_GATE_SET_TO_DISABLE, NULL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
KUNIT_ASSERT_TRUE(test, clk_hw_is_enabled(hw));
clk_hw_unregister_gate(hw);
}
static void clk_gate_test_is_disabled_inverted(struct kunit *test)
{
struct clk_hw *hw;
struct clk_gate_test_context *ctx;
ctx = clk_gate_test_alloc_ctx(test);
ctx->fake_reg = BIT(29);
hw = clk_hw_register_gate(NULL, "test_gate", NULL, 0, ctx->fake_mem, 29,
CLK_GATE_SET_TO_DISABLE, NULL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
KUNIT_ASSERT_FALSE(test, clk_hw_is_enabled(hw));
clk_hw_unregister_gate(hw);
}
static struct kunit_case clk_gate_test_enabled_cases[] = {
KUNIT_CASE(clk_gate_test_is_enabled),
KUNIT_CASE(clk_gate_test_is_disabled),
KUNIT_CASE(clk_gate_test_is_enabled_inverted),
KUNIT_CASE(clk_gate_test_is_disabled_inverted),
{}
};
static struct kunit_suite clk_gate_test_enabled_suite = {
.name = "clk-gate-is_enabled-test",
.test_cases = clk_gate_test_enabled_cases,
};
kunit_test_suites(
&clk_gate_register_test_suite,
&clk_gate_test_suite,
&clk_gate_test_invert_suite,
&clk_gate_test_hiword_suite,
&clk_gate_test_enabled_suite
);
MODULE_LICENSE("GPL v2");

View file

@ -0,0 +1,322 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Driver for Renesas 9-series PCIe clock generator driver
*
* The following series can be supported:
* - 9FGV/9DBV/9DMV/9FGL/9DML/9QXL/9SQ
* Currently supported:
* - 9FGV0241
*
* Copyright (C) 2022 Marek Vasut <marex@denx.de>
*/
#include <linux/clk-provider.h>
#include <linux/i2c.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/regmap.h>
#define RS9_REG_OE 0x0
#define RS9_REG_OE_DIF_OE(n) BIT((n) + 1)
#define RS9_REG_SS 0x1
#define RS9_REG_SS_AMP_0V6 0x0
#define RS9_REG_SS_AMP_0V7 0x1
#define RS9_REG_SS_AMP_0V8 0x2
#define RS9_REG_SS_AMP_0V9 0x3
#define RS9_REG_SS_AMP_MASK 0x3
#define RS9_REG_SS_SSC_100 0
#define RS9_REG_SS_SSC_M025 (1 << 3)
#define RS9_REG_SS_SSC_M050 (3 << 3)
#define RS9_REG_SS_SSC_MASK (3 << 3)
#define RS9_REG_SS_SSC_LOCK BIT(5)
#define RS9_REG_SR 0x2
#define RS9_REG_SR_2V0_DIF(n) 0
#define RS9_REG_SR_3V0_DIF(n) BIT((n) + 1)
#define RS9_REG_SR_DIF_MASK(n) BIT((n) + 1)
#define RS9_REG_REF 0x3
#define RS9_REG_REF_OE BIT(4)
#define RS9_REG_REF_OD BIT(5)
#define RS9_REG_REF_SR_SLOWEST 0
#define RS9_REG_REF_SR_SLOW (1 << 6)
#define RS9_REG_REF_SR_FAST (2 << 6)
#define RS9_REG_REF_SR_FASTER (3 << 6)
#define RS9_REG_VID 0x5
#define RS9_REG_DID 0x6
#define RS9_REG_BCP 0x7
/* Supported Renesas 9-series models. */
enum rs9_model {
RENESAS_9FGV0241,
};
/* Structure to describe features of a particular 9-series model */
struct rs9_chip_info {
const enum rs9_model model;
unsigned int num_clks;
};
struct rs9_driver_data {
struct i2c_client *client;
struct regmap *regmap;
const struct rs9_chip_info *chip_info;
struct clk *pin_xin;
struct clk_hw *clk_dif[2];
u8 pll_amplitude;
u8 pll_ssc;
u8 clk_dif_sr;
};
/*
* Renesas 9-series i2c regmap
*/
static const struct regmap_range rs9_readable_ranges[] = {
regmap_reg_range(RS9_REG_OE, RS9_REG_REF),
regmap_reg_range(RS9_REG_VID, RS9_REG_BCP),
};
static const struct regmap_access_table rs9_readable_table = {
.yes_ranges = rs9_readable_ranges,
.n_yes_ranges = ARRAY_SIZE(rs9_readable_ranges),
};
static const struct regmap_range rs9_writeable_ranges[] = {
regmap_reg_range(RS9_REG_OE, RS9_REG_REF),
regmap_reg_range(RS9_REG_BCP, RS9_REG_BCP),
};
static const struct regmap_access_table rs9_writeable_table = {
.yes_ranges = rs9_writeable_ranges,
.n_yes_ranges = ARRAY_SIZE(rs9_writeable_ranges),
};
static const struct regmap_config rs9_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.cache_type = REGCACHE_FLAT,
.max_register = 0x8,
.rd_table = &rs9_readable_table,
.wr_table = &rs9_writeable_table,
};
static int rs9_get_output_config(struct rs9_driver_data *rs9, int idx)
{
struct i2c_client *client = rs9->client;
unsigned char name[5] = "DIF0";
struct device_node *np;
int ret;
u32 sr;
/* Set defaults */
rs9->clk_dif_sr &= ~RS9_REG_SR_DIF_MASK(idx);
rs9->clk_dif_sr |= RS9_REG_SR_3V0_DIF(idx);
snprintf(name, 5, "DIF%d", idx);
np = of_get_child_by_name(client->dev.of_node, name);
if (!np)
return 0;
/* Output clock slew rate */
ret = of_property_read_u32(np, "renesas,slew-rate", &sr);
of_node_put(np);
if (!ret) {
if (sr == 2000000) { /* 2V/ns */
rs9->clk_dif_sr &= ~RS9_REG_SR_DIF_MASK(idx);
rs9->clk_dif_sr |= RS9_REG_SR_2V0_DIF(idx);
} else if (sr == 3000000) { /* 3V/ns (default) */
rs9->clk_dif_sr &= ~RS9_REG_SR_DIF_MASK(idx);
rs9->clk_dif_sr |= RS9_REG_SR_3V0_DIF(idx);
} else
ret = dev_err_probe(&client->dev, -EINVAL,
"Invalid renesas,slew-rate value\n");
}
return ret;
}
static int rs9_get_common_config(struct rs9_driver_data *rs9)
{
struct i2c_client *client = rs9->client;
struct device_node *np = client->dev.of_node;
unsigned int amp, ssc;
int ret;
/* Set defaults */
rs9->pll_amplitude = RS9_REG_SS_AMP_0V7;
rs9->pll_ssc = RS9_REG_SS_SSC_100;
/* Output clock amplitude */
ret = of_property_read_u32(np, "renesas,out-amplitude-microvolt",
&amp);
if (!ret) {
if (amp == 600000) /* 0.6V */
rs9->pll_amplitude = RS9_REG_SS_AMP_0V6;
else if (amp == 700000) /* 0.7V (default) */
rs9->pll_amplitude = RS9_REG_SS_AMP_0V7;
else if (amp == 800000) /* 0.8V */
rs9->pll_amplitude = RS9_REG_SS_AMP_0V8;
else if (amp == 900000) /* 0.9V */
rs9->pll_amplitude = RS9_REG_SS_AMP_0V9;
else
return dev_err_probe(&client->dev, -EINVAL,
"Invalid renesas,out-amplitude-microvolt value\n");
}
/* Output clock spread spectrum */
ret = of_property_read_u32(np, "renesas,out-spread-spectrum", &ssc);
if (!ret) {
if (ssc == 100000) /* 100% ... no spread (default) */
rs9->pll_ssc = RS9_REG_SS_SSC_100;
else if (ssc == 99750) /* -0.25% ... down spread */
rs9->pll_ssc = RS9_REG_SS_SSC_M025;
else if (ssc == 99500) /* -0.50% ... down spread */
rs9->pll_ssc = RS9_REG_SS_SSC_M050;
else
return dev_err_probe(&client->dev, -EINVAL,
"Invalid renesas,out-spread-spectrum value\n");
}
return 0;
}
static void rs9_update_config(struct rs9_driver_data *rs9)
{
int i;
/* If amplitude is non-default, update it. */
if (rs9->pll_amplitude != RS9_REG_SS_AMP_0V7) {
regmap_update_bits(rs9->regmap, RS9_REG_SS, RS9_REG_SS_AMP_MASK,
rs9->pll_amplitude);
}
/* If SSC is non-default, update it. */
if (rs9->pll_ssc != RS9_REG_SS_SSC_100) {
regmap_update_bits(rs9->regmap, RS9_REG_SS, RS9_REG_SS_SSC_MASK,
rs9->pll_ssc);
}
for (i = 0; i < rs9->chip_info->num_clks; i++) {
if (rs9->clk_dif_sr & RS9_REG_SR_3V0_DIF(i))
continue;
regmap_update_bits(rs9->regmap, RS9_REG_SR, RS9_REG_SR_3V0_DIF(i),
rs9->clk_dif_sr & RS9_REG_SR_3V0_DIF(i));
}
}
static struct clk_hw *
rs9_of_clk_get(struct of_phandle_args *clkspec, void *data)
{
struct rs9_driver_data *rs9 = data;
unsigned int idx = clkspec->args[0];
return rs9->clk_dif[idx];
}
static int rs9_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
unsigned char name[5] = "DIF0";
struct rs9_driver_data *rs9;
struct clk_hw *hw;
int i, ret;
rs9 = devm_kzalloc(&client->dev, sizeof(*rs9), GFP_KERNEL);
if (!rs9)
return -ENOMEM;
i2c_set_clientdata(client, rs9);
rs9->client = client;
rs9->chip_info = device_get_match_data(&client->dev);
if (!rs9->chip_info)
return -EINVAL;
/* Fetch common configuration from DT (if specified) */
ret = rs9_get_common_config(rs9);
if (ret)
return ret;
/* Fetch DIFx output configuration from DT (if specified) */
for (i = 0; i < rs9->chip_info->num_clks; i++) {
ret = rs9_get_output_config(rs9, i);
if (ret)
return ret;
}
rs9->regmap = devm_regmap_init_i2c(client, &rs9_regmap_config);
if (IS_ERR(rs9->regmap))
return dev_err_probe(&client->dev, PTR_ERR(rs9->regmap),
"Failed to allocate register map\n");
/* Register clock */
for (i = 0; i < rs9->chip_info->num_clks; i++) {
snprintf(name, 5, "DIF%d", i);
hw = devm_clk_hw_register_fixed_factor_index(&client->dev, name,
0, 0, 4, 1);
if (IS_ERR(hw))
return PTR_ERR(hw);
rs9->clk_dif[i] = hw;
}
ret = devm_of_clk_add_hw_provider(&client->dev, rs9_of_clk_get, rs9);
if (!ret)
rs9_update_config(rs9);
return ret;
}
static int __maybe_unused rs9_suspend(struct device *dev)
{
struct rs9_driver_data *rs9 = dev_get_drvdata(dev);
regcache_cache_only(rs9->regmap, true);
regcache_mark_dirty(rs9->regmap);
return 0;
}
static int __maybe_unused rs9_resume(struct device *dev)
{
struct rs9_driver_data *rs9 = dev_get_drvdata(dev);
int ret;
regcache_cache_only(rs9->regmap, false);
ret = regcache_sync(rs9->regmap);
if (ret)
dev_err(dev, "Failed to restore register map: %d\n", ret);
return ret;
}
static const struct rs9_chip_info renesas_9fgv0241_info = {
.model = RENESAS_9FGV0241,
.num_clks = 2,
};
static const struct i2c_device_id rs9_id[] = {
{ "9fgv0241", .driver_data = RENESAS_9FGV0241 },
{ }
};
MODULE_DEVICE_TABLE(i2c, rs9_id);
static const struct of_device_id clk_rs9_of_match[] = {
{ .compatible = "renesas,9fgv0241", .data = &renesas_9fgv0241_info },
{ }
};
MODULE_DEVICE_TABLE(of, clk_rs9_of_match);
static SIMPLE_DEV_PM_OPS(rs9_pm_ops, rs9_suspend, rs9_resume);
static struct i2c_driver rs9_driver = {
.driver = {
.name = "clk-renesas-pcie-9series",
.pm = &rs9_pm_ops,
.of_match_table = clk_rs9_of_match,
},
.probe = rs9_probe,
.id_table = rs9_id,
};
module_i2c_driver(rs9_driver);
MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
MODULE_DESCRIPTION("Renesas 9-series PCIe clock generator driver");
MODULE_LICENSE("GPL");

View file

@ -34,6 +34,7 @@ config CLK_RENESAS
select CLK_R8A779F0 if ARCH_R8A779F0
select CLK_R9A06G032 if ARCH_R9A06G032
select CLK_R9A07G044 if ARCH_R9A07G044
select CLK_R9A07G054 if ARCH_R9A07G054
select CLK_SH73A0 if ARCH_SH73A0
if CLK_RENESAS
@ -163,6 +164,10 @@ config CLK_R9A07G044
bool "RZ/G2L clock support" if COMPILE_TEST
select CLK_RZG2L
config CLK_R9A07G054
bool "RZ/V2L clock support" if COMPILE_TEST
select CLK_RZG2L
config CLK_SH73A0
bool "SH-Mobile AG5 clock support" if COMPILE_TEST
select CLK_RENESAS_CPG_MSTP
@ -195,7 +200,7 @@ config CLK_RCAR_USB2_CLOCK_SEL
This is a driver for R-Car USB2 clock selector
config CLK_RZG2L
bool "Renesas RZ/G2L family clock support" if COMPILE_TEST
bool "Renesas RZ/{G2L,V2L} family clock support" if COMPILE_TEST
select RESET_CONTROLLER
# Generic

View file

@ -31,6 +31,7 @@ obj-$(CONFIG_CLK_R8A779A0) += r8a779a0-cpg-mssr.o
obj-$(CONFIG_CLK_R8A779F0) += r8a779f0-cpg-mssr.o
obj-$(CONFIG_CLK_R9A06G032) += r9a06g032-clocks.o
obj-$(CONFIG_CLK_R9A07G044) += r9a07g044-cpg.o
obj-$(CONFIG_CLK_R9A07G054) += r9a07g044-cpg.o
obj-$(CONFIG_CLK_SH73A0) += clk-sh73a0.o
# Family

View file

@ -200,6 +200,7 @@ static const struct mssr_mod_clk r8a77990_mod_clks[] __initconst = {
DEF_MOD("du0", 724, R8A77990_CLK_S1D1),
DEF_MOD("lvds", 727, R8A77990_CLK_S2D1),
DEF_MOD("mlp", 802, R8A77990_CLK_S2D1),
DEF_MOD("vin5", 806, R8A77990_CLK_S1D2),
DEF_MOD("vin4", 807, R8A77990_CLK_S1D2),
DEF_MOD("etheravb", 812, R8A77990_CLK_S3D2),

View file

@ -160,6 +160,7 @@ static const struct mssr_mod_clk r8a77995_mod_clks[] __initconst = {
DEF_MOD("du1", 723, R8A77995_CLK_S1D1),
DEF_MOD("du0", 724, R8A77995_CLK_S1D1),
DEF_MOD("lvds", 727, R8A77995_CLK_S2D1),
DEF_MOD("mlp", 802, R8A77995_CLK_S2D1),
DEF_MOD("vin4", 807, R8A77995_CLK_S1D2),
DEF_MOD("etheravb", 812, R8A77995_CLK_S3D2),
DEF_MOD("imr0", 823, R8A77995_CLK_S1D2),

View file

@ -136,6 +136,7 @@ static const struct mssr_mod_clk r8a779a0_mod_clks[] __initconst = {
DEF_MOD("avb3", 214, R8A779A0_CLK_S3D2),
DEF_MOD("avb4", 215, R8A779A0_CLK_S3D2),
DEF_MOD("avb5", 216, R8A779A0_CLK_S3D2),
DEF_MOD("canfd0", 328, R8A779A0_CLK_CANFD),
DEF_MOD("csi40", 331, R8A779A0_CLK_CSI0),
DEF_MOD("csi41", 400, R8A779A0_CLK_CSI0),
DEF_MOD("csi42", 401, R8A779A0_CLK_CSI0),

View file

@ -103,7 +103,7 @@ static const struct cpg_core_clk r8a779f0_core_clks[] __initconst = {
DEF_FIXED("s0d12_hsc", R8A779F0_CLK_S0D12_HSC, CLK_S0, 12, 1),
DEF_FIXED("cl16m_hsc", R8A779F0_CLK_CL16M_HSC, CLK_S0, 48, 1),
DEF_FIXED("s0d2_cc", R8A779F0_CLK_S0D2_CC, CLK_S0, 2, 1),
DEF_FIXED("rsw2", R8A779F0_CLK_RSW2, CLK_PLL5, 2, 1),
DEF_FIXED("rsw2", R8A779F0_CLK_RSW2, CLK_PLL5_DIV2, 5, 1),
DEF_FIXED("cbfusa", R8A779F0_CLK_CBFUSA, CLK_EXTAL, 2, 1),
DEF_FIXED("cpex", R8A779F0_CLK_CPEX, CLK_EXTAL, 2, 1),
@ -115,10 +115,24 @@ static const struct cpg_core_clk r8a779f0_core_clks[] __initconst = {
};
static const struct mssr_mod_clk r8a779f0_mod_clks[] __initconst = {
DEF_MOD("i2c0", 518, R8A779F0_CLK_S0D6_PER),
DEF_MOD("i2c1", 519, R8A779F0_CLK_S0D6_PER),
DEF_MOD("i2c2", 520, R8A779F0_CLK_S0D6_PER),
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("scif0", 702, R8A779F0_CLK_S0D12_PER),
DEF_MOD("scif1", 703, R8A779F0_CLK_S0D12_PER),
DEF_MOD("scif3", 704, R8A779F0_CLK_S0D12_PER),
DEF_MOD("scif4", 705, R8A779F0_CLK_S0D12_PER),
DEF_MOD("sys-dmac0", 709, R8A779F0_CLK_S0D3_PER),
DEF_MOD("sys-dmac1", 710, R8A779F0_CLK_S0D3_PER),
DEF_MOD("wdt", 907, R8A779F0_CLK_R),
DEF_MOD("pfc0", 915, R8A779F0_CLK_CL16M),
};
static const unsigned int r8a779f0_crit_mod_clks[] __initconst = {
MOD_CLK_ID(907), /* WDT */
};
/*
@ -175,6 +189,10 @@ const struct cpg_mssr_info r8a779f0_cpg_mssr_info __initconst = {
.num_mod_clks = ARRAY_SIZE(r8a779f0_mod_clks),
.num_hw_mod_clks = 28 * 32,
/* Critical Module Clocks */
.crit_mod_clks = r8a779f0_crit_mod_clks,
.num_crit_mod_clks = ARRAY_SIZE(r8a779f0_crit_mod_clks),
/* Callbacks */
.init = r8a779f0_cpg_mssr_init,
.cpg_clk_register = rcar_gen4_cpg_clk_register,

View file

@ -11,12 +11,13 @@
#include <linux/kernel.h>
#include <dt-bindings/clock/r9a07g044-cpg.h>
#include <dt-bindings/clock/r9a07g054-cpg.h>
#include "rzg2l-cpg.h"
enum clk_ids {
/* Core Clock Outputs exported to DT */
LAST_DT_CORE_CLK = R9A07G044_CLK_P0_DIV2,
LAST_DT_CORE_CLK = R9A07G054_CLK_DRP_A,
/* External Input Clocks */
CLK_EXTAL,
@ -80,200 +81,222 @@ static const char * const sel_pll6_2[] = { ".pll6_250", ".pll5_250" };
static const char * const sel_shdi[] = { ".clk_533", ".clk_400", ".clk_266" };
static const char * const sel_gpu2[] = { ".pll6", ".pll3_div2_2" };
static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = {
/* External Clock Inputs */
DEF_INPUT("extal", CLK_EXTAL),
static const struct {
struct cpg_core_clk common[44];
#ifdef CONFIG_CLK_R9A07G054
struct cpg_core_clk drp[0];
#endif
} core_clks __initconst = {
.common = {
/* External Clock Inputs */
DEF_INPUT("extal", CLK_EXTAL),
/* Internal Core Clocks */
DEF_FIXED(".osc", R9A07G044_OSCCLK, CLK_EXTAL, 1, 1),
DEF_FIXED(".osc_div1000", CLK_OSC_DIV1000, CLK_EXTAL, 1, 1000),
DEF_SAMPLL(".pll1", CLK_PLL1, CLK_EXTAL, PLL146_CONF(0)),
DEF_FIXED(".pll2", CLK_PLL2, CLK_EXTAL, 133, 2),
DEF_FIXED(".pll3", CLK_PLL3, CLK_EXTAL, 133, 2),
DEF_FIXED(".pll3_400", CLK_PLL3_400, CLK_PLL3, 1, 4),
DEF_FIXED(".pll3_533", CLK_PLL3_533, CLK_PLL3, 1, 3),
/* Internal Core Clocks */
DEF_FIXED(".osc", R9A07G044_OSCCLK, CLK_EXTAL, 1, 1),
DEF_FIXED(".osc_div1000", CLK_OSC_DIV1000, CLK_EXTAL, 1, 1000),
DEF_SAMPLL(".pll1", CLK_PLL1, CLK_EXTAL, PLL146_CONF(0)),
DEF_FIXED(".pll2", CLK_PLL2, CLK_EXTAL, 200, 3),
DEF_FIXED(".pll3", CLK_PLL3, CLK_EXTAL, 200, 3),
DEF_FIXED(".pll3_400", CLK_PLL3_400, CLK_PLL3, 1, 4),
DEF_FIXED(".pll3_533", CLK_PLL3_533, CLK_PLL3, 1, 3),
DEF_FIXED(".pll5", CLK_PLL5, CLK_EXTAL, 125, 1),
DEF_FIXED(".pll5_fout3", CLK_PLL5_FOUT3, CLK_PLL5, 1, 6),
DEF_FIXED(".pll5", CLK_PLL5, CLK_EXTAL, 125, 1),
DEF_FIXED(".pll5_fout3", CLK_PLL5_FOUT3, CLK_PLL5, 1, 6),
DEF_FIXED(".pll6", CLK_PLL6, CLK_EXTAL, 125, 6),
DEF_FIXED(".pll6", CLK_PLL6, CLK_EXTAL, 125, 6),
DEF_FIXED(".pll2_div2", CLK_PLL2_DIV2, CLK_PLL2, 1, 2),
DEF_FIXED(".clk_800", CLK_PLL2_800, CLK_PLL2, 1, 2),
DEF_FIXED(".clk_533", CLK_PLL2_SDHI_533, CLK_PLL2, 1, 3),
DEF_FIXED(".clk_400", CLK_PLL2_SDHI_400, CLK_PLL2_800, 1, 2),
DEF_FIXED(".clk_266", CLK_PLL2_SDHI_266, CLK_PLL2_SDHI_533, 1, 2),
DEF_FIXED(".pll2_div2", CLK_PLL2_DIV2, CLK_PLL2, 1, 2),
DEF_FIXED(".clk_800", CLK_PLL2_800, CLK_PLL2, 1, 2),
DEF_FIXED(".clk_533", CLK_PLL2_SDHI_533, CLK_PLL2, 1, 3),
DEF_FIXED(".clk_400", CLK_PLL2_SDHI_400, CLK_PLL2_800, 1, 2),
DEF_FIXED(".clk_266", CLK_PLL2_SDHI_266, CLK_PLL2_SDHI_533, 1, 2),
DEF_FIXED(".pll2_div2_8", CLK_PLL2_DIV2_8, CLK_PLL2_DIV2, 1, 8),
DEF_FIXED(".pll2_div2_10", CLK_PLL2_DIV2_10, CLK_PLL2_DIV2, 1, 10),
DEF_FIXED(".pll2_div2_8", CLK_PLL2_DIV2_8, CLK_PLL2_DIV2, 1, 8),
DEF_FIXED(".pll2_div2_10", CLK_PLL2_DIV2_10, CLK_PLL2_DIV2, 1, 10),
DEF_FIXED(".pll3_div2", CLK_PLL3_DIV2, CLK_PLL3, 1, 2),
DEF_FIXED(".pll3_div2_2", CLK_PLL3_DIV2_2, CLK_PLL3_DIV2, 1, 2),
DEF_FIXED(".pll3_div2_4", CLK_PLL3_DIV2_4, CLK_PLL3_DIV2, 1, 4),
DEF_FIXED(".pll3_div2_4_2", CLK_PLL3_DIV2_4_2, CLK_PLL3_DIV2_4, 1, 2),
DEF_MUX(".sel_pll3_3", CLK_SEL_PLL3_3, SEL_PLL3_3,
sel_pll3_3, ARRAY_SIZE(sel_pll3_3), 0, CLK_MUX_READ_ONLY),
DEF_DIV("divpl3c", CLK_DIV_PLL3_C, CLK_SEL_PLL3_3,
DIVPL3C, dtable_1_32, CLK_DIVIDER_HIWORD_MASK),
DEF_FIXED(".pll3_div2", CLK_PLL3_DIV2, CLK_PLL3, 1, 2),
DEF_FIXED(".pll3_div2_2", CLK_PLL3_DIV2_2, CLK_PLL3_DIV2, 1, 2),
DEF_FIXED(".pll3_div2_4", CLK_PLL3_DIV2_4, CLK_PLL3_DIV2, 1, 4),
DEF_FIXED(".pll3_div2_4_2", CLK_PLL3_DIV2_4_2, CLK_PLL3_DIV2_4, 1, 2),
DEF_MUX(".sel_pll3_3", CLK_SEL_PLL3_3, SEL_PLL3_3,
sel_pll3_3, ARRAY_SIZE(sel_pll3_3), 0, CLK_MUX_READ_ONLY),
DEF_DIV("divpl3c", CLK_DIV_PLL3_C, CLK_SEL_PLL3_3,
DIVPL3C, dtable_1_32, CLK_DIVIDER_HIWORD_MASK),
DEF_FIXED(".pll5_250", CLK_PLL5_250, CLK_PLL5_FOUT3, 1, 2),
DEF_FIXED(".pll6_250", CLK_PLL6_250, CLK_PLL6, 1, 2),
DEF_MUX(".sel_gpu2", CLK_SEL_GPU2, SEL_GPU2,
sel_gpu2, ARRAY_SIZE(sel_gpu2), 0, CLK_MUX_READ_ONLY),
DEF_FIXED(".pll5_250", CLK_PLL5_250, CLK_PLL5_FOUT3, 1, 2),
DEF_FIXED(".pll6_250", CLK_PLL6_250, CLK_PLL6, 1, 2),
DEF_MUX(".sel_gpu2", CLK_SEL_GPU2, SEL_GPU2,
sel_gpu2, ARRAY_SIZE(sel_gpu2), 0, CLK_MUX_READ_ONLY),
/* Core output clk */
DEF_DIV("I", R9A07G044_CLK_I, CLK_PLL1, DIVPL1A, dtable_1_8,
CLK_DIVIDER_HIWORD_MASK),
DEF_DIV("P0", R9A07G044_CLK_P0, CLK_PLL2_DIV2_8, DIVPL2A,
dtable_1_32, CLK_DIVIDER_HIWORD_MASK),
DEF_FIXED("P0_DIV2", R9A07G044_CLK_P0_DIV2, R9A07G044_CLK_P0, 1, 2),
DEF_FIXED("TSU", R9A07G044_CLK_TSU, CLK_PLL2_DIV2_10, 1, 1),
DEF_DIV("P1", R9A07G044_CLK_P1, CLK_PLL3_DIV2_4,
DIVPL3B, dtable_1_32, CLK_DIVIDER_HIWORD_MASK),
DEF_FIXED("P1_DIV2", CLK_P1_DIV2, R9A07G044_CLK_P1, 1, 2),
DEF_DIV("P2", R9A07G044_CLK_P2, CLK_PLL3_DIV2_4_2,
DIVPL3A, dtable_1_32, CLK_DIVIDER_HIWORD_MASK),
DEF_FIXED("M0", R9A07G044_CLK_M0, CLK_PLL3_DIV2_4, 1, 1),
DEF_FIXED("ZT", R9A07G044_CLK_ZT, CLK_PLL3_DIV2_4_2, 1, 1),
DEF_MUX("HP", R9A07G044_CLK_HP, SEL_PLL6_2,
sel_pll6_2, ARRAY_SIZE(sel_pll6_2), 0, CLK_MUX_HIWORD_MASK),
DEF_FIXED("SPI0", R9A07G044_CLK_SPI0, CLK_DIV_PLL3_C, 1, 2),
DEF_FIXED("SPI1", R9A07G044_CLK_SPI1, CLK_DIV_PLL3_C, 1, 4),
DEF_SD_MUX("SD0", R9A07G044_CLK_SD0, SEL_SDHI0,
sel_shdi, ARRAY_SIZE(sel_shdi)),
DEF_SD_MUX("SD1", R9A07G044_CLK_SD1, SEL_SDHI1,
sel_shdi, ARRAY_SIZE(sel_shdi)),
DEF_FIXED("SD0_DIV4", CLK_SD0_DIV4, R9A07G044_CLK_SD0, 1, 4),
DEF_FIXED("SD1_DIV4", CLK_SD1_DIV4, R9A07G044_CLK_SD1, 1, 4),
DEF_DIV("G", R9A07G044_CLK_G, CLK_SEL_GPU2, DIVGPU, dtable_1_8,
CLK_DIVIDER_HIWORD_MASK),
/* Core output clk */
DEF_DIV("I", R9A07G044_CLK_I, CLK_PLL1, DIVPL1A, dtable_1_8,
CLK_DIVIDER_HIWORD_MASK),
DEF_DIV("P0", R9A07G044_CLK_P0, CLK_PLL2_DIV2_8, DIVPL2A,
dtable_1_32, CLK_DIVIDER_HIWORD_MASK),
DEF_FIXED("P0_DIV2", R9A07G044_CLK_P0_DIV2, R9A07G044_CLK_P0, 1, 2),
DEF_FIXED("TSU", R9A07G044_CLK_TSU, CLK_PLL2_DIV2_10, 1, 1),
DEF_DIV("P1", R9A07G044_CLK_P1, CLK_PLL3_DIV2_4,
DIVPL3B, dtable_1_32, CLK_DIVIDER_HIWORD_MASK),
DEF_FIXED("P1_DIV2", CLK_P1_DIV2, R9A07G044_CLK_P1, 1, 2),
DEF_DIV("P2", R9A07G044_CLK_P2, CLK_PLL3_DIV2_4_2,
DIVPL3A, dtable_1_32, CLK_DIVIDER_HIWORD_MASK),
DEF_FIXED("M0", R9A07G044_CLK_M0, CLK_PLL3_DIV2_4, 1, 1),
DEF_FIXED("ZT", R9A07G044_CLK_ZT, CLK_PLL3_DIV2_4_2, 1, 1),
DEF_MUX("HP", R9A07G044_CLK_HP, SEL_PLL6_2,
sel_pll6_2, ARRAY_SIZE(sel_pll6_2), 0, CLK_MUX_HIWORD_MASK),
DEF_FIXED("SPI0", R9A07G044_CLK_SPI0, CLK_DIV_PLL3_C, 1, 2),
DEF_FIXED("SPI1", R9A07G044_CLK_SPI1, CLK_DIV_PLL3_C, 1, 4),
DEF_SD_MUX("SD0", R9A07G044_CLK_SD0, SEL_SDHI0,
sel_shdi, ARRAY_SIZE(sel_shdi)),
DEF_SD_MUX("SD1", R9A07G044_CLK_SD1, SEL_SDHI1,
sel_shdi, ARRAY_SIZE(sel_shdi)),
DEF_FIXED("SD0_DIV4", CLK_SD0_DIV4, R9A07G044_CLK_SD0, 1, 4),
DEF_FIXED("SD1_DIV4", CLK_SD1_DIV4, R9A07G044_CLK_SD1, 1, 4),
DEF_DIV("G", R9A07G044_CLK_G, CLK_SEL_GPU2, DIVGPU, dtable_1_8,
CLK_DIVIDER_HIWORD_MASK),
},
#ifdef CONFIG_CLK_R9A07G054
.drp = {
},
#endif
};
static struct rzg2l_mod_clk r9a07g044_mod_clks[] = {
DEF_MOD("gic", R9A07G044_GIC600_GICCLK, R9A07G044_CLK_P1,
0x514, 0),
DEF_MOD("ia55_pclk", R9A07G044_IA55_PCLK, R9A07G044_CLK_P2,
0x518, 0),
DEF_MOD("ia55_clk", R9A07G044_IA55_CLK, R9A07G044_CLK_P1,
0x518, 1),
DEF_MOD("dmac_aclk", R9A07G044_DMAC_ACLK, R9A07G044_CLK_P1,
0x52c, 0),
DEF_MOD("dmac_pclk", R9A07G044_DMAC_PCLK, CLK_P1_DIV2,
0x52c, 1),
DEF_MOD("ostm0_pclk", R9A07G044_OSTM0_PCLK, R9A07G044_CLK_P0,
0x534, 0),
DEF_MOD("ostm1_clk", R9A07G044_OSTM1_PCLK, R9A07G044_CLK_P0,
0x534, 1),
DEF_MOD("ostm2_pclk", R9A07G044_OSTM2_PCLK, R9A07G044_CLK_P0,
0x534, 2),
DEF_MOD("wdt0_pclk", R9A07G044_WDT0_PCLK, R9A07G044_CLK_P0,
0x548, 0),
DEF_MOD("wdt0_clk", R9A07G044_WDT0_CLK, R9A07G044_OSCCLK,
0x548, 1),
DEF_MOD("wdt1_pclk", R9A07G044_WDT1_PCLK, R9A07G044_CLK_P0,
0x548, 2),
DEF_MOD("wdt1_clk", R9A07G044_WDT1_CLK, R9A07G044_OSCCLK,
0x548, 3),
DEF_MOD("wdt2_pclk", R9A07G044_WDT2_PCLK, R9A07G044_CLK_P0,
0x548, 4),
DEF_MOD("wdt2_clk", R9A07G044_WDT2_CLK, R9A07G044_OSCCLK,
0x548, 5),
DEF_MOD("spi_clk2", R9A07G044_SPI_CLK2, R9A07G044_CLK_SPI1,
0x550, 0),
DEF_MOD("spi_clk", R9A07G044_SPI_CLK, R9A07G044_CLK_SPI0,
0x550, 1),
DEF_MOD("sdhi0_imclk", R9A07G044_SDHI0_IMCLK, CLK_SD0_DIV4,
0x554, 0),
DEF_MOD("sdhi0_imclk2", R9A07G044_SDHI0_IMCLK2, CLK_SD0_DIV4,
0x554, 1),
DEF_MOD("sdhi0_clk_hs", R9A07G044_SDHI0_CLK_HS, R9A07G044_CLK_SD0,
0x554, 2),
DEF_MOD("sdhi0_aclk", R9A07G044_SDHI0_ACLK, R9A07G044_CLK_P1,
0x554, 3),
DEF_MOD("sdhi1_imclk", R9A07G044_SDHI1_IMCLK, CLK_SD1_DIV4,
0x554, 4),
DEF_MOD("sdhi1_imclk2", R9A07G044_SDHI1_IMCLK2, CLK_SD1_DIV4,
0x554, 5),
DEF_MOD("sdhi1_clk_hs", R9A07G044_SDHI1_CLK_HS, R9A07G044_CLK_SD1,
0x554, 6),
DEF_MOD("sdhi1_aclk", R9A07G044_SDHI1_ACLK, R9A07G044_CLK_P1,
0x554, 7),
DEF_MOD("gpu_clk", R9A07G044_GPU_CLK, R9A07G044_CLK_G,
0x558, 0),
DEF_MOD("gpu_axi_clk", R9A07G044_GPU_AXI_CLK, R9A07G044_CLK_P1,
0x558, 1),
DEF_MOD("gpu_ace_clk", R9A07G044_GPU_ACE_CLK, R9A07G044_CLK_P1,
0x558, 2),
DEF_MOD("ssi0_pclk", R9A07G044_SSI0_PCLK2, R9A07G044_CLK_P0,
0x570, 0),
DEF_MOD("ssi0_sfr", R9A07G044_SSI0_PCLK_SFR, R9A07G044_CLK_P0,
0x570, 1),
DEF_MOD("ssi1_pclk", R9A07G044_SSI1_PCLK2, R9A07G044_CLK_P0,
0x570, 2),
DEF_MOD("ssi1_sfr", R9A07G044_SSI1_PCLK_SFR, R9A07G044_CLK_P0,
0x570, 3),
DEF_MOD("ssi2_pclk", R9A07G044_SSI2_PCLK2, R9A07G044_CLK_P0,
0x570, 4),
DEF_MOD("ssi2_sfr", R9A07G044_SSI2_PCLK_SFR, R9A07G044_CLK_P0,
0x570, 5),
DEF_MOD("ssi3_pclk", R9A07G044_SSI3_PCLK2, R9A07G044_CLK_P0,
0x570, 6),
DEF_MOD("ssi3_sfr", R9A07G044_SSI3_PCLK_SFR, R9A07G044_CLK_P0,
0x570, 7),
DEF_MOD("usb0_host", R9A07G044_USB_U2H0_HCLK, R9A07G044_CLK_P1,
0x578, 0),
DEF_MOD("usb1_host", R9A07G044_USB_U2H1_HCLK, R9A07G044_CLK_P1,
0x578, 1),
DEF_MOD("usb0_func", R9A07G044_USB_U2P_EXR_CPUCLK, R9A07G044_CLK_P1,
0x578, 2),
DEF_MOD("usb_pclk", R9A07G044_USB_PCLK, R9A07G044_CLK_P1,
0x578, 3),
DEF_COUPLED("eth0_axi", R9A07G044_ETH0_CLK_AXI, R9A07G044_CLK_M0,
0x57c, 0),
DEF_COUPLED("eth0_chi", R9A07G044_ETH0_CLK_CHI, R9A07G044_CLK_ZT,
0x57c, 0),
DEF_COUPLED("eth1_axi", R9A07G044_ETH1_CLK_AXI, R9A07G044_CLK_M0,
0x57c, 1),
DEF_COUPLED("eth1_chi", R9A07G044_ETH1_CLK_CHI, R9A07G044_CLK_ZT,
0x57c, 1),
DEF_MOD("i2c0", R9A07G044_I2C0_PCLK, R9A07G044_CLK_P0,
0x580, 0),
DEF_MOD("i2c1", R9A07G044_I2C1_PCLK, R9A07G044_CLK_P0,
0x580, 1),
DEF_MOD("i2c2", R9A07G044_I2C2_PCLK, R9A07G044_CLK_P0,
0x580, 2),
DEF_MOD("i2c3", R9A07G044_I2C3_PCLK, R9A07G044_CLK_P0,
0x580, 3),
DEF_MOD("scif0", R9A07G044_SCIF0_CLK_PCK, R9A07G044_CLK_P0,
0x584, 0),
DEF_MOD("scif1", R9A07G044_SCIF1_CLK_PCK, R9A07G044_CLK_P0,
0x584, 1),
DEF_MOD("scif2", R9A07G044_SCIF2_CLK_PCK, R9A07G044_CLK_P0,
0x584, 2),
DEF_MOD("scif3", R9A07G044_SCIF3_CLK_PCK, R9A07G044_CLK_P0,
0x584, 3),
DEF_MOD("scif4", R9A07G044_SCIF4_CLK_PCK, R9A07G044_CLK_P0,
0x584, 4),
DEF_MOD("sci0", R9A07G044_SCI0_CLKP, R9A07G044_CLK_P0,
0x588, 0),
DEF_MOD("sci1", R9A07G044_SCI1_CLKP, R9A07G044_CLK_P0,
0x588, 1),
DEF_MOD("rspi0", R9A07G044_RSPI0_CLKB, R9A07G044_CLK_P0,
0x590, 0),
DEF_MOD("rspi1", R9A07G044_RSPI1_CLKB, R9A07G044_CLK_P0,
0x590, 1),
DEF_MOD("rspi2", R9A07G044_RSPI2_CLKB, R9A07G044_CLK_P0,
0x590, 2),
DEF_MOD("canfd", R9A07G044_CANFD_PCLK, R9A07G044_CLK_P0,
0x594, 0),
DEF_MOD("gpio", R9A07G044_GPIO_HCLK, R9A07G044_OSCCLK,
0x598, 0),
DEF_MOD("adc_adclk", R9A07G044_ADC_ADCLK, R9A07G044_CLK_TSU,
0x5a8, 0),
DEF_MOD("adc_pclk", R9A07G044_ADC_PCLK, R9A07G044_CLK_P0,
0x5a8, 1),
DEF_MOD("tsu_pclk", R9A07G044_TSU_PCLK, R9A07G044_CLK_TSU,
0x5ac, 0),
static const struct {
struct rzg2l_mod_clk common[62];
#ifdef CONFIG_CLK_R9A07G054
struct rzg2l_mod_clk drp[0];
#endif
} mod_clks = {
.common = {
DEF_MOD("gic", R9A07G044_GIC600_GICCLK, R9A07G044_CLK_P1,
0x514, 0),
DEF_MOD("ia55_pclk", R9A07G044_IA55_PCLK, R9A07G044_CLK_P2,
0x518, 0),
DEF_MOD("ia55_clk", R9A07G044_IA55_CLK, R9A07G044_CLK_P1,
0x518, 1),
DEF_MOD("dmac_aclk", R9A07G044_DMAC_ACLK, R9A07G044_CLK_P1,
0x52c, 0),
DEF_MOD("dmac_pclk", R9A07G044_DMAC_PCLK, CLK_P1_DIV2,
0x52c, 1),
DEF_MOD("ostm0_pclk", R9A07G044_OSTM0_PCLK, R9A07G044_CLK_P0,
0x534, 0),
DEF_MOD("ostm1_clk", R9A07G044_OSTM1_PCLK, R9A07G044_CLK_P0,
0x534, 1),
DEF_MOD("ostm2_pclk", R9A07G044_OSTM2_PCLK, R9A07G044_CLK_P0,
0x534, 2),
DEF_MOD("wdt0_pclk", R9A07G044_WDT0_PCLK, R9A07G044_CLK_P0,
0x548, 0),
DEF_MOD("wdt0_clk", R9A07G044_WDT0_CLK, R9A07G044_OSCCLK,
0x548, 1),
DEF_MOD("wdt1_pclk", R9A07G044_WDT1_PCLK, R9A07G044_CLK_P0,
0x548, 2),
DEF_MOD("wdt1_clk", R9A07G044_WDT1_CLK, R9A07G044_OSCCLK,
0x548, 3),
DEF_MOD("wdt2_pclk", R9A07G044_WDT2_PCLK, R9A07G044_CLK_P0,
0x548, 4),
DEF_MOD("wdt2_clk", R9A07G044_WDT2_CLK, R9A07G044_OSCCLK,
0x548, 5),
DEF_MOD("spi_clk2", R9A07G044_SPI_CLK2, R9A07G044_CLK_SPI1,
0x550, 0),
DEF_MOD("spi_clk", R9A07G044_SPI_CLK, R9A07G044_CLK_SPI0,
0x550, 1),
DEF_MOD("sdhi0_imclk", R9A07G044_SDHI0_IMCLK, CLK_SD0_DIV4,
0x554, 0),
DEF_MOD("sdhi0_imclk2", R9A07G044_SDHI0_IMCLK2, CLK_SD0_DIV4,
0x554, 1),
DEF_MOD("sdhi0_clk_hs", R9A07G044_SDHI0_CLK_HS, R9A07G044_CLK_SD0,
0x554, 2),
DEF_MOD("sdhi0_aclk", R9A07G044_SDHI0_ACLK, R9A07G044_CLK_P1,
0x554, 3),
DEF_MOD("sdhi1_imclk", R9A07G044_SDHI1_IMCLK, CLK_SD1_DIV4,
0x554, 4),
DEF_MOD("sdhi1_imclk2", R9A07G044_SDHI1_IMCLK2, CLK_SD1_DIV4,
0x554, 5),
DEF_MOD("sdhi1_clk_hs", R9A07G044_SDHI1_CLK_HS, R9A07G044_CLK_SD1,
0x554, 6),
DEF_MOD("sdhi1_aclk", R9A07G044_SDHI1_ACLK, R9A07G044_CLK_P1,
0x554, 7),
DEF_MOD("gpu_clk", R9A07G044_GPU_CLK, R9A07G044_CLK_G,
0x558, 0),
DEF_MOD("gpu_axi_clk", R9A07G044_GPU_AXI_CLK, R9A07G044_CLK_P1,
0x558, 1),
DEF_MOD("gpu_ace_clk", R9A07G044_GPU_ACE_CLK, R9A07G044_CLK_P1,
0x558, 2),
DEF_MOD("ssi0_pclk", R9A07G044_SSI0_PCLK2, R9A07G044_CLK_P0,
0x570, 0),
DEF_MOD("ssi0_sfr", R9A07G044_SSI0_PCLK_SFR, R9A07G044_CLK_P0,
0x570, 1),
DEF_MOD("ssi1_pclk", R9A07G044_SSI1_PCLK2, R9A07G044_CLK_P0,
0x570, 2),
DEF_MOD("ssi1_sfr", R9A07G044_SSI1_PCLK_SFR, R9A07G044_CLK_P0,
0x570, 3),
DEF_MOD("ssi2_pclk", R9A07G044_SSI2_PCLK2, R9A07G044_CLK_P0,
0x570, 4),
DEF_MOD("ssi2_sfr", R9A07G044_SSI2_PCLK_SFR, R9A07G044_CLK_P0,
0x570, 5),
DEF_MOD("ssi3_pclk", R9A07G044_SSI3_PCLK2, R9A07G044_CLK_P0,
0x570, 6),
DEF_MOD("ssi3_sfr", R9A07G044_SSI3_PCLK_SFR, R9A07G044_CLK_P0,
0x570, 7),
DEF_MOD("usb0_host", R9A07G044_USB_U2H0_HCLK, R9A07G044_CLK_P1,
0x578, 0),
DEF_MOD("usb1_host", R9A07G044_USB_U2H1_HCLK, R9A07G044_CLK_P1,
0x578, 1),
DEF_MOD("usb0_func", R9A07G044_USB_U2P_EXR_CPUCLK, R9A07G044_CLK_P1,
0x578, 2),
DEF_MOD("usb_pclk", R9A07G044_USB_PCLK, R9A07G044_CLK_P1,
0x578, 3),
DEF_COUPLED("eth0_axi", R9A07G044_ETH0_CLK_AXI, R9A07G044_CLK_M0,
0x57c, 0),
DEF_COUPLED("eth0_chi", R9A07G044_ETH0_CLK_CHI, R9A07G044_CLK_ZT,
0x57c, 0),
DEF_COUPLED("eth1_axi", R9A07G044_ETH1_CLK_AXI, R9A07G044_CLK_M0,
0x57c, 1),
DEF_COUPLED("eth1_chi", R9A07G044_ETH1_CLK_CHI, R9A07G044_CLK_ZT,
0x57c, 1),
DEF_MOD("i2c0", R9A07G044_I2C0_PCLK, R9A07G044_CLK_P0,
0x580, 0),
DEF_MOD("i2c1", R9A07G044_I2C1_PCLK, R9A07G044_CLK_P0,
0x580, 1),
DEF_MOD("i2c2", R9A07G044_I2C2_PCLK, R9A07G044_CLK_P0,
0x580, 2),
DEF_MOD("i2c3", R9A07G044_I2C3_PCLK, R9A07G044_CLK_P0,
0x580, 3),
DEF_MOD("scif0", R9A07G044_SCIF0_CLK_PCK, R9A07G044_CLK_P0,
0x584, 0),
DEF_MOD("scif1", R9A07G044_SCIF1_CLK_PCK, R9A07G044_CLK_P0,
0x584, 1),
DEF_MOD("scif2", R9A07G044_SCIF2_CLK_PCK, R9A07G044_CLK_P0,
0x584, 2),
DEF_MOD("scif3", R9A07G044_SCIF3_CLK_PCK, R9A07G044_CLK_P0,
0x584, 3),
DEF_MOD("scif4", R9A07G044_SCIF4_CLK_PCK, R9A07G044_CLK_P0,
0x584, 4),
DEF_MOD("sci0", R9A07G044_SCI0_CLKP, R9A07G044_CLK_P0,
0x588, 0),
DEF_MOD("sci1", R9A07G044_SCI1_CLKP, R9A07G044_CLK_P0,
0x588, 1),
DEF_MOD("rspi0", R9A07G044_RSPI0_CLKB, R9A07G044_CLK_P0,
0x590, 0),
DEF_MOD("rspi1", R9A07G044_RSPI1_CLKB, R9A07G044_CLK_P0,
0x590, 1),
DEF_MOD("rspi2", R9A07G044_RSPI2_CLKB, R9A07G044_CLK_P0,
0x590, 2),
DEF_MOD("canfd", R9A07G044_CANFD_PCLK, R9A07G044_CLK_P0,
0x594, 0),
DEF_MOD("gpio", R9A07G044_GPIO_HCLK, R9A07G044_OSCCLK,
0x598, 0),
DEF_MOD("adc_adclk", R9A07G044_ADC_ADCLK, R9A07G044_CLK_TSU,
0x5a8, 0),
DEF_MOD("adc_pclk", R9A07G044_ADC_PCLK, R9A07G044_CLK_P0,
0x5a8, 1),
DEF_MOD("tsu_pclk", R9A07G044_TSU_PCLK, R9A07G044_CLK_TSU,
0x5ac, 0),
},
#ifdef CONFIG_CLK_R9A07G054
.drp = {
},
#endif
};
static struct rzg2l_reset r9a07g044_resets[] = {
@ -336,8 +359,8 @@ static const unsigned int r9a07g044_crit_mod_clks[] __initconst = {
const struct rzg2l_cpg_info r9a07g044_cpg_info = {
/* Core Clocks */
.core_clks = r9a07g044_core_clks,
.num_core_clks = ARRAY_SIZE(r9a07g044_core_clks),
.core_clks = core_clks.common,
.num_core_clks = ARRAY_SIZE(core_clks.common),
.last_dt_core_clk = LAST_DT_CORE_CLK,
.num_total_core_clks = MOD_CLK_BASE,
@ -346,11 +369,34 @@ const struct rzg2l_cpg_info r9a07g044_cpg_info = {
.num_crit_mod_clks = ARRAY_SIZE(r9a07g044_crit_mod_clks),
/* Module Clocks */
.mod_clks = r9a07g044_mod_clks,
.num_mod_clks = ARRAY_SIZE(r9a07g044_mod_clks),
.mod_clks = mod_clks.common,
.num_mod_clks = ARRAY_SIZE(mod_clks.common),
.num_hw_mod_clks = R9A07G044_TSU_PCLK + 1,
/* Resets */
.resets = r9a07g044_resets,
.num_resets = ARRAY_SIZE(r9a07g044_resets),
.num_resets = R9A07G044_TSU_PRESETN + 1, /* Last reset ID + 1 */
};
#ifdef CONFIG_CLK_R9A07G054
const struct rzg2l_cpg_info r9a07g054_cpg_info = {
/* Core Clocks */
.core_clks = core_clks.common,
.num_core_clks = ARRAY_SIZE(core_clks.common) + ARRAY_SIZE(core_clks.drp),
.last_dt_core_clk = LAST_DT_CORE_CLK,
.num_total_core_clks = MOD_CLK_BASE,
/* Critical Module Clocks */
.crit_mod_clks = r9a07g044_crit_mod_clks,
.num_crit_mod_clks = ARRAY_SIZE(r9a07g044_crit_mod_clks),
/* Module Clocks */
.mod_clks = mod_clks.common,
.num_mod_clks = ARRAY_SIZE(mod_clks.common) + ARRAY_SIZE(mod_clks.drp),
.num_hw_mod_clks = R9A07G054_STPAI_ACLK_DRP + 1,
/* Resets */
.resets = r9a07g044_resets,
.num_resets = R9A07G054_STPAI_ARESETN + 1, /* Last reset ID + 1 */
};
#endif

View file

@ -952,6 +952,12 @@ static const struct of_device_id rzg2l_cpg_match[] = {
.compatible = "renesas,r9a07g044-cpg",
.data = &r9a07g044_cpg_info,
},
#endif
#ifdef CONFIG_CLK_R9A07G054
{
.compatible = "renesas,r9a07g054-cpg",
.data = &r9a07g054_cpg_info,
},
#endif
{ /* sentinel */ }
};

View file

@ -203,5 +203,6 @@ struct rzg2l_cpg_info {
};
extern const struct rzg2l_cpg_info r9a07g044_cpg_info;
extern const struct rzg2l_cpg_info r9a07g054_cpg_info;
#endif

View file

@ -41,8 +41,8 @@ static int zynqmp_clk_gate_enable(struct clk_hw *hw)
ret = zynqmp_pm_clock_enable(clk_id);
if (ret)
pr_warn_once("%s() clock enabled failed for %s, ret = %d\n",
__func__, clk_name, ret);
pr_debug("%s() clock enable failed for %s (id %d), ret = %d\n",
__func__, clk_name, clk_id, ret);
return ret;
}
@ -61,8 +61,8 @@ static void zynqmp_clk_gate_disable(struct clk_hw *hw)
ret = zynqmp_pm_clock_disable(clk_id);
if (ret)
pr_warn_once("%s() clock disable failed for %s, ret = %d\n",
__func__, clk_name, ret);
pr_debug("%s() clock disable failed for %s (id %d), ret = %d\n",
__func__, clk_name, clk_id, ret);
}
/**
@ -80,8 +80,8 @@ static int zynqmp_clk_gate_is_enabled(struct clk_hw *hw)
ret = zynqmp_pm_clock_getstate(clk_id, &state);
if (ret) {
pr_warn_once("%s() clock get state failed for %s, ret = %d\n",
__func__, clk_name, ret);
pr_debug("%s() clock get state failed for %s, ret = %d\n",
__func__, clk_name, ret);
return -EIO;
}

View file

@ -51,8 +51,8 @@ static u8 zynqmp_clk_mux_get_parent(struct clk_hw *hw)
ret = zynqmp_pm_clock_getparent(clk_id, &val);
if (ret) {
pr_warn_once("%s() getparent failed for clock: %s, ret = %d\n",
__func__, clk_name, ret);
pr_debug("%s() getparent failed for clock: %s, ret = %d\n",
__func__, clk_name, ret);
/*
* clk_core_get_parent_by_index() takes num_parents as incorrect
* index which is exactly what I want to return here
@ -80,8 +80,8 @@ static int zynqmp_clk_mux_set_parent(struct clk_hw *hw, u8 index)
ret = zynqmp_pm_clock_setparent(clk_id, index);
if (ret)
pr_warn_once("%s() set parent failed for clock: %s, ret = %d\n",
__func__, clk_name, ret);
pr_debug("%s() set parent failed for clock: %s, ret = %d\n",
__func__, clk_name, ret);
return ret;
}

View file

@ -89,8 +89,8 @@ static unsigned long zynqmp_clk_divider_recalc_rate(struct clk_hw *hw,
ret = zynqmp_pm_clock_getdivider(clk_id, &div);
if (ret)
pr_warn_once("%s() get divider failed for %s, ret = %d\n",
__func__, clk_name, ret);
pr_debug("%s() get divider failed for %s, ret = %d\n",
__func__, clk_name, ret);
if (div_type == TYPE_DIV1)
value = div & 0xFFFF;
@ -177,8 +177,8 @@ static long zynqmp_clk_divider_round_rate(struct clk_hw *hw,
ret = zynqmp_pm_clock_getdivider(clk_id, &bestdiv);
if (ret)
pr_warn_once("%s() get divider failed for %s, ret = %d\n",
__func__, clk_name, ret);
pr_debug("%s() get divider failed for %s, ret = %d\n",
__func__, clk_name, ret);
if (div_type == TYPE_DIV1)
bestdiv = bestdiv & 0xFFFF;
else
@ -244,8 +244,8 @@ static int zynqmp_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
ret = zynqmp_pm_clock_setdivider(clk_id, div);
if (ret)
pr_warn_once("%s() set divider failed for %s, ret = %d\n",
__func__, clk_name, ret);
pr_debug("%s() set divider failed for %s, ret = %d\n",
__func__, clk_name, ret);
return ret;
}

View file

@ -56,8 +56,8 @@ static inline enum pll_mode zynqmp_pll_get_mode(struct clk_hw *hw)
ret = zynqmp_pm_get_pll_frac_mode(clk_id, ret_payload);
if (ret) {
pr_warn_once("%s() PLL get frac mode failed for %s, ret = %d\n",
__func__, clk_name, ret);
pr_debug("%s() PLL get frac mode failed for %s, ret = %d\n",
__func__, clk_name, ret);
return PLL_MODE_ERROR;
}
@ -84,8 +84,8 @@ static inline void zynqmp_pll_set_mode(struct clk_hw *hw, bool on)
ret = zynqmp_pm_set_pll_frac_mode(clk_id, mode);
if (ret)
pr_warn_once("%s() PLL set frac mode failed for %s, ret = %d\n",
__func__, clk_name, ret);
pr_debug("%s() PLL set frac mode failed for %s, ret = %d\n",
__func__, clk_name, ret);
else
clk->set_pll_mode = true;
}
@ -145,8 +145,8 @@ static unsigned long zynqmp_pll_recalc_rate(struct clk_hw *hw,
ret = zynqmp_pm_clock_getdivider(clk_id, &fbdiv);
if (ret) {
pr_warn_once("%s() get divider failed for %s, ret = %d\n",
__func__, clk_name, ret);
pr_debug("%s() get divider failed for %s, ret = %d\n",
__func__, clk_name, ret);
return 0ul;
}
@ -200,8 +200,8 @@ static int zynqmp_pll_set_rate(struct clk_hw *hw, unsigned long rate,
WARN(1, "More than allowed devices are using the %s, which is forbidden\n",
clk_name);
else if (ret)
pr_warn_once("%s() set divider failed for %s, ret = %d\n",
__func__, clk_name, ret);
pr_debug("%s() set divider failed for %s, ret = %d\n",
__func__, clk_name, ret);
zynqmp_pm_set_pll_frac_data(clk_id, f);
return rate + frac;
@ -211,8 +211,8 @@ static int zynqmp_pll_set_rate(struct clk_hw *hw, unsigned long rate,
fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX);
ret = zynqmp_pm_clock_setdivider(clk_id, fbdiv);
if (ret)
pr_warn_once("%s() set divider failed for %s, ret = %d\n",
__func__, clk_name, ret);
pr_debug("%s() set divider failed for %s, ret = %d\n",
__func__, clk_name, ret);
return parent_rate * fbdiv;
}
@ -233,8 +233,8 @@ static int zynqmp_pll_is_enabled(struct clk_hw *hw)
ret = zynqmp_pm_clock_getstate(clk_id, &state);
if (ret) {
pr_warn_once("%s() clock get state failed for %s, ret = %d\n",
__func__, clk_name, ret);
pr_debug("%s() clock get state failed for %s, ret = %d\n",
__func__, clk_name, ret);
return -EIO;
}
@ -265,8 +265,8 @@ static int zynqmp_pll_enable(struct clk_hw *hw)
ret = zynqmp_pm_clock_enable(clk_id);
if (ret)
pr_warn_once("%s() clock enable failed for %s, ret = %d\n",
__func__, clk_name, ret);
pr_debug("%s() clock enable failed for %s, ret = %d\n",
__func__, clk_name, ret);
return ret;
}
@ -287,8 +287,8 @@ static void zynqmp_pll_disable(struct clk_hw *hw)
ret = zynqmp_pm_clock_disable(clk_id);
if (ret)
pr_warn_once("%s() clock disable failed for %s, ret = %d\n",
__func__, clk_name, ret);
pr_debug("%s() clock disable failed for %s, ret = %d\n",
__func__, clk_name, ret);
}
static const struct clk_ops zynqmp_pll_ops = {

View file

@ -0,0 +1,14 @@
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
/*
* Copyright (C) 2021 Daniel Mack
*/
#ifndef __DT_BINDINGS_CS2000CP_CLK_H
#define __DT_BINDINGS_CS2000CP_CLK_H
#define CS2000CP_AUX_OUTPUT_REF_CLK 0
#define CS2000CP_AUX_OUTPUT_CLK_IN 1
#define CS2000CP_AUX_OUTPUT_CLK_OUT 2
#define CS2000CP_AUX_OUTPUT_PLL_LOCK 3
#endif /* __DT_BINDINGS_CS2000CP_CLK_H */

View file

@ -0,0 +1,229 @@
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
*
* Copyright (C) 2022 Renesas Electronics Corp.
*/
#ifndef __DT_BINDINGS_CLOCK_R9A07G054_CPG_H__
#define __DT_BINDINGS_CLOCK_R9A07G054_CPG_H__
#include <dt-bindings/clock/renesas-cpg-mssr.h>
/* R9A07G054 CPG Core Clocks */
#define R9A07G054_CLK_I 0
#define R9A07G054_CLK_I2 1
#define R9A07G054_CLK_G 2
#define R9A07G054_CLK_S0 3
#define R9A07G054_CLK_S1 4
#define R9A07G054_CLK_SPI0 5
#define R9A07G054_CLK_SPI1 6
#define R9A07G054_CLK_SD0 7
#define R9A07G054_CLK_SD1 8
#define R9A07G054_CLK_M0 9
#define R9A07G054_CLK_M1 10
#define R9A07G054_CLK_M2 11
#define R9A07G054_CLK_M3 12
#define R9A07G054_CLK_M4 13
#define R9A07G054_CLK_HP 14
#define R9A07G054_CLK_TSU 15
#define R9A07G054_CLK_ZT 16
#define R9A07G054_CLK_P0 17
#define R9A07G054_CLK_P1 18
#define R9A07G054_CLK_P2 19
#define R9A07G054_CLK_AT 20
#define R9A07G054_OSCCLK 21
#define R9A07G054_CLK_P0_DIV2 22
#define R9A07G054_CLK_DRP_M 23
#define R9A07G054_CLK_DRP_D 24
#define R9A07G054_CLK_DRP_A 25
/* R9A07G054 Module Clocks */
#define R9A07G054_CA55_SCLK 0
#define R9A07G054_CA55_PCLK 1
#define R9A07G054_CA55_ATCLK 2
#define R9A07G054_CA55_GICCLK 3
#define R9A07G054_CA55_PERICLK 4
#define R9A07G054_CA55_ACLK 5
#define R9A07G054_CA55_TSCLK 6
#define R9A07G054_GIC600_GICCLK 7
#define R9A07G054_IA55_CLK 8
#define R9A07G054_IA55_PCLK 9
#define R9A07G054_MHU_PCLK 10
#define R9A07G054_SYC_CNT_CLK 11
#define R9A07G054_DMAC_ACLK 12
#define R9A07G054_DMAC_PCLK 13
#define R9A07G054_OSTM0_PCLK 14
#define R9A07G054_OSTM1_PCLK 15
#define R9A07G054_OSTM2_PCLK 16
#define R9A07G054_MTU_X_MCK_MTU3 17
#define R9A07G054_POE3_CLKM_POE 18
#define R9A07G054_GPT_PCLK 19
#define R9A07G054_POEG_A_CLKP 20
#define R9A07G054_POEG_B_CLKP 21
#define R9A07G054_POEG_C_CLKP 22
#define R9A07G054_POEG_D_CLKP 23
#define R9A07G054_WDT0_PCLK 24
#define R9A07G054_WDT0_CLK 25
#define R9A07G054_WDT1_PCLK 26
#define R9A07G054_WDT1_CLK 27
#define R9A07G054_WDT2_PCLK 28
#define R9A07G054_WDT2_CLK 29
#define R9A07G054_SPI_CLK2 30
#define R9A07G054_SPI_CLK 31
#define R9A07G054_SDHI0_IMCLK 32
#define R9A07G054_SDHI0_IMCLK2 33
#define R9A07G054_SDHI0_CLK_HS 34
#define R9A07G054_SDHI0_ACLK 35
#define R9A07G054_SDHI1_IMCLK 36
#define R9A07G054_SDHI1_IMCLK2 37
#define R9A07G054_SDHI1_CLK_HS 38
#define R9A07G054_SDHI1_ACLK 39
#define R9A07G054_GPU_CLK 40
#define R9A07G054_GPU_AXI_CLK 41
#define R9A07G054_GPU_ACE_CLK 42
#define R9A07G054_ISU_ACLK 43
#define R9A07G054_ISU_PCLK 44
#define R9A07G054_H264_CLK_A 45
#define R9A07G054_H264_CLK_P 46
#define R9A07G054_CRU_SYSCLK 47
#define R9A07G054_CRU_VCLK 48
#define R9A07G054_CRU_PCLK 49
#define R9A07G054_CRU_ACLK 50
#define R9A07G054_MIPI_DSI_PLLCLK 51
#define R9A07G054_MIPI_DSI_SYSCLK 52
#define R9A07G054_MIPI_DSI_ACLK 53
#define R9A07G054_MIPI_DSI_PCLK 54
#define R9A07G054_MIPI_DSI_VCLK 55
#define R9A07G054_MIPI_DSI_LPCLK 56
#define R9A07G054_LCDC_CLK_A 57
#define R9A07G054_LCDC_CLK_P 58
#define R9A07G054_LCDC_CLK_D 59
#define R9A07G054_SSI0_PCLK2 60
#define R9A07G054_SSI0_PCLK_SFR 61
#define R9A07G054_SSI1_PCLK2 62
#define R9A07G054_SSI1_PCLK_SFR 63
#define R9A07G054_SSI2_PCLK2 64
#define R9A07G054_SSI2_PCLK_SFR 65
#define R9A07G054_SSI3_PCLK2 66
#define R9A07G054_SSI3_PCLK_SFR 67
#define R9A07G054_SRC_CLKP 68
#define R9A07G054_USB_U2H0_HCLK 69
#define R9A07G054_USB_U2H1_HCLK 70
#define R9A07G054_USB_U2P_EXR_CPUCLK 71
#define R9A07G054_USB_PCLK 72
#define R9A07G054_ETH0_CLK_AXI 73
#define R9A07G054_ETH0_CLK_CHI 74
#define R9A07G054_ETH1_CLK_AXI 75
#define R9A07G054_ETH1_CLK_CHI 76
#define R9A07G054_I2C0_PCLK 77
#define R9A07G054_I2C1_PCLK 78
#define R9A07G054_I2C2_PCLK 79
#define R9A07G054_I2C3_PCLK 80
#define R9A07G054_SCIF0_CLK_PCK 81
#define R9A07G054_SCIF1_CLK_PCK 82
#define R9A07G054_SCIF2_CLK_PCK 83
#define R9A07G054_SCIF3_CLK_PCK 84
#define R9A07G054_SCIF4_CLK_PCK 85
#define R9A07G054_SCI0_CLKP 86
#define R9A07G054_SCI1_CLKP 87
#define R9A07G054_IRDA_CLKP 88
#define R9A07G054_RSPI0_CLKB 89
#define R9A07G054_RSPI1_CLKB 90
#define R9A07G054_RSPI2_CLKB 91
#define R9A07G054_CANFD_PCLK 92
#define R9A07G054_GPIO_HCLK 93
#define R9A07G054_ADC_ADCLK 94
#define R9A07G054_ADC_PCLK 95
#define R9A07G054_TSU_PCLK 96
#define R9A07G054_STPAI_INITCLK 97
#define R9A07G054_STPAI_ACLK 98
#define R9A07G054_STPAI_MCLK 99
#define R9A07G054_STPAI_DCLKIN 100
#define R9A07G054_STPAI_ACLK_DRP 101
/* R9A07G054 Resets */
#define R9A07G054_CA55_RST_1_0 0
#define R9A07G054_CA55_RST_1_1 1
#define R9A07G054_CA55_RST_3_0 2
#define R9A07G054_CA55_RST_3_1 3
#define R9A07G054_CA55_RST_4 4
#define R9A07G054_CA55_RST_5 5
#define R9A07G054_CA55_RST_6 6
#define R9A07G054_CA55_RST_7 7
#define R9A07G054_CA55_RST_8 8
#define R9A07G054_CA55_RST_9 9
#define R9A07G054_CA55_RST_10 10
#define R9A07G054_CA55_RST_11 11
#define R9A07G054_CA55_RST_12 12
#define R9A07G054_GIC600_GICRESET_N 13
#define R9A07G054_GIC600_DBG_GICRESET_N 14
#define R9A07G054_IA55_RESETN 15
#define R9A07G054_MHU_RESETN 16
#define R9A07G054_DMAC_ARESETN 17
#define R9A07G054_DMAC_RST_ASYNC 18
#define R9A07G054_SYC_RESETN 19
#define R9A07G054_OSTM0_PRESETZ 20
#define R9A07G054_OSTM1_PRESETZ 21
#define R9A07G054_OSTM2_PRESETZ 22
#define R9A07G054_MTU_X_PRESET_MTU3 23
#define R9A07G054_POE3_RST_M_REG 24
#define R9A07G054_GPT_RST_C 25
#define R9A07G054_POEG_A_RST 26
#define R9A07G054_POEG_B_RST 27
#define R9A07G054_POEG_C_RST 28
#define R9A07G054_POEG_D_RST 29
#define R9A07G054_WDT0_PRESETN 30
#define R9A07G054_WDT1_PRESETN 31
#define R9A07G054_WDT2_PRESETN 32
#define R9A07G054_SPI_RST 33
#define R9A07G054_SDHI0_IXRST 34
#define R9A07G054_SDHI1_IXRST 35
#define R9A07G054_GPU_RESETN 36
#define R9A07G054_GPU_AXI_RESETN 37
#define R9A07G054_GPU_ACE_RESETN 38
#define R9A07G054_ISU_ARESETN 39
#define R9A07G054_ISU_PRESETN 40
#define R9A07G054_H264_X_RESET_VCP 41
#define R9A07G054_H264_CP_PRESET_P 42
#define R9A07G054_CRU_CMN_RSTB 43
#define R9A07G054_CRU_PRESETN 44
#define R9A07G054_CRU_ARESETN 45
#define R9A07G054_MIPI_DSI_CMN_RSTB 46
#define R9A07G054_MIPI_DSI_ARESET_N 47
#define R9A07G054_MIPI_DSI_PRESET_N 48
#define R9A07G054_LCDC_RESET_N 49
#define R9A07G054_SSI0_RST_M2_REG 50
#define R9A07G054_SSI1_RST_M2_REG 51
#define R9A07G054_SSI2_RST_M2_REG 52
#define R9A07G054_SSI3_RST_M2_REG 53
#define R9A07G054_SRC_RST 54
#define R9A07G054_USB_U2H0_HRESETN 55
#define R9A07G054_USB_U2H1_HRESETN 56
#define R9A07G054_USB_U2P_EXL_SYSRST 57
#define R9A07G054_USB_PRESETN 58
#define R9A07G054_ETH0_RST_HW_N 59
#define R9A07G054_ETH1_RST_HW_N 60
#define R9A07G054_I2C0_MRST 61
#define R9A07G054_I2C1_MRST 62
#define R9A07G054_I2C2_MRST 63
#define R9A07G054_I2C3_MRST 64
#define R9A07G054_SCIF0_RST_SYSTEM_N 65
#define R9A07G054_SCIF1_RST_SYSTEM_N 66
#define R9A07G054_SCIF2_RST_SYSTEM_N 67
#define R9A07G054_SCIF3_RST_SYSTEM_N 68
#define R9A07G054_SCIF4_RST_SYSTEM_N 69
#define R9A07G054_SCI0_RST 70
#define R9A07G054_SCI1_RST 71
#define R9A07G054_IRDA_RST 72
#define R9A07G054_RSPI0_RST 73
#define R9A07G054_RSPI1_RST 74
#define R9A07G054_RSPI2_RST 75
#define R9A07G054_CANFD_RSTP_N 76
#define R9A07G054_CANFD_RSTC_N 77
#define R9A07G054_GPIO_RSTN 78
#define R9A07G054_GPIO_PORT_RESETN 79
#define R9A07G054_GPIO_SPARE_RESETN 80
#define R9A07G054_ADC_PRESETN 81
#define R9A07G054_ADC_ADRST_N 82
#define R9A07G054_TSU_PRESETN 83
#define R9A07G054_STPAI_ARESETN 84
#endif /* __DT_BINDINGS_CLOCK_R9A07G054_CPG_H__ */

View file

@ -1003,6 +1003,9 @@ void clk_hw_unregister_fixed_factor(struct clk_hw *hw);
struct clk_hw *devm_clk_hw_register_fixed_factor(struct device *dev,
const char *name, const char *parent_name, unsigned long flags,
unsigned int mult, unsigned int div);
struct clk_hw *devm_clk_hw_register_fixed_factor_index(struct device *dev,
const char *name, unsigned int index, unsigned long flags,
unsigned int mult, unsigned int div);
/**
* struct clk_fractional_divider - adjustable fractional divider clock
*