Commit 1a86e99f authored by Stephen Boyd's avatar Stephen Boyd

Merge branches 'clk-starfive', 'clk-fractional' and 'clk-devmof' into clk-next

 - Shrink size of clk_fractional_divider a little
 - Convert various clk drivers to devm_of_clk_add_hw_provider()

* clk-starfive:
  clk: starfive: Delete the redundant dev_set_drvdata() in JH7110 clock drivers
  clk: starfive: Avoid casting iomem pointers
  MAINTAINERS: generalise StarFive clk/reset entries
  reset: starfive: Add StarFive JH7110 reset driver
  clk: starfive: Add StarFive JH7110 always-on clock driver
  clk: starfive: Add StarFive JH7110 system clock driver
  reset: starfive: jh71x0: Use 32bit I/O on 32bit registers
  reset: starfive: Rename "jh7100" to "jh71x0" for the common code
  reset: starfive: Extract the common JH71X0 reset code
  reset: starfive: Factor out common JH71X0 reset code
  reset: Create subdirectory for StarFive drivers
  reset: starfive: Replace SOC_STARFIVE with ARCH_STARFIVE
  clk: starfive: Rename "jh7100" to "jh71x0" for the common code
  clk: starfive: Rename clk-starfive-jh7100.h to clk-starfive-jh71x0.h
  clk: starfive: Factor out common JH7100 and JH7110 code
  clk: starfive: Replace SOC_STARFIVE with ARCH_STARFIVE
  dt-bindings: clock: Add StarFive JH7110 always-on clock and reset generator
  dt-bindings: clock: Add StarFive JH7110 system clock and reset generator

* clk-fractional:
  clk: Remove mmask and nmask fields in struct clk_fractional_divider
  clk: rockchip: Remove values for mmask and nmask in struct clk_fractional_divider
  clk: imx: Remove values for mmask and nmask in struct clk_fractional_divider
  clk: Compute masks for fractional_divider clk when needed.

* clk-devmof:
  clk: uniphier: Use managed `of_clk_add_hw_provider()`
  clk: si5351: Use managed `of_clk_add_hw_provider()`
  clk: si570: Use managed `of_clk_add_hw_provider()`
  clk: si514: Use managed `of_clk_add_hw_provider()`
  clk: lmk04832: Use managed `of_clk_add_hw_provider()`
  clk: hsdk-pll: Use managed `of_clk_add_hw_provider()`
  clk: cdce706: Use managed `of_clk_add_hw_provider()`
  clk: axs10x: Use managed `of_clk_add_hw_provider()`
  clk: axm5516: Use managed `of_clk_add_hw_provider()`
  clk: axi-clkgen: Use managed `of_clk_add_hw_provider()`
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/starfive,jh7110-aoncrg.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: StarFive JH7110 Always-On Clock and Reset Generator
maintainers:
- Emil Renner Berthing <kernel@esmil.dk>
properties:
compatible:
const: starfive,jh7110-aoncrg
reg:
maxItems: 1
clocks:
oneOf:
- items:
- description: Main Oscillator (24 MHz)
- description: GMAC0 RMII reference or GMAC0 RGMII RX
- description: STG AXI/AHB
- description: APB Bus
- description: GMAC0 GTX
- items:
- description: Main Oscillator (24 MHz)
- description: GMAC0 RMII reference or GMAC0 RGMII RX
- description: STG AXI/AHB or GMAC0 RGMII RX
- description: APB Bus or STG AXI/AHB
- description: GMAC0 GTX or APB Bus
- description: RTC Oscillator (32.768 kHz) or GMAC0 GTX
- items:
- description: Main Oscillator (24 MHz)
- description: GMAC0 RMII reference
- description: GMAC0 RGMII RX
- description: STG AXI/AHB
- description: APB Bus
- description: GMAC0 GTX
- description: RTC Oscillator (32.768 kHz)
clock-names:
oneOf:
- minItems: 5
items:
- const: osc
- enum:
- gmac0_rmii_refin
- gmac0_rgmii_rxin
- const: stg_axiahb
- const: apb_bus
- const: gmac0_gtxclk
- const: rtc_osc
- minItems: 6
items:
- const: osc
- const: gmac0_rmii_refin
- const: gmac0_rgmii_rxin
- const: stg_axiahb
- const: apb_bus
- const: gmac0_gtxclk
- const: rtc_osc
'#clock-cells':
const: 1
description:
See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
'#reset-cells':
const: 1
description:
See <dt-bindings/reset/starfive,jh7110-crg.h> for valid indices.
required:
- compatible
- reg
- clocks
- clock-names
- '#clock-cells'
- '#reset-cells'
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/starfive,jh7110-crg.h>
clock-controller@17000000 {
compatible = "starfive,jh7110-aoncrg";
reg = <0x17000000 0x10000>;
clocks = <&osc>, <&gmac0_rmii_refin>,
<&gmac0_rgmii_rxin>,
<&syscrg JH7110_SYSCLK_STG_AXIAHB>,
<&syscrg JH7110_SYSCLK_APB_BUS>,
<&syscrg JH7110_SYSCLK_GMAC0_GTXCLK>,
<&rtc_osc>;
clock-names = "osc", "gmac0_rmii_refin",
"gmac0_rgmii_rxin", "stg_axiahb",
"apb_bus", "gmac0_gtxclk",
"rtc_osc";
#clock-cells = <1>;
#reset-cells = <1>;
};
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/starfive,jh7110-syscrg.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: StarFive JH7110 System Clock and Reset Generator
maintainers:
- Emil Renner Berthing <kernel@esmil.dk>
properties:
compatible:
const: starfive,jh7110-syscrg
reg:
maxItems: 1
clocks:
oneOf:
- items:
- description: Main Oscillator (24 MHz)
- description: GMAC1 RMII reference or GMAC1 RGMII RX
- description: External I2S TX bit clock
- description: External I2S TX left/right channel clock
- description: External I2S RX bit clock
- description: External I2S RX left/right channel clock
- description: External TDM clock
- description: External audio master clock
- items:
- description: Main Oscillator (24 MHz)
- description: GMAC1 RMII reference
- description: GMAC1 RGMII RX
- description: External I2S TX bit clock
- description: External I2S TX left/right channel clock
- description: External I2S RX bit clock
- description: External I2S RX left/right channel clock
- description: External TDM clock
- description: External audio master clock
clock-names:
oneOf:
- items:
- const: osc
- enum:
- gmac1_rmii_refin
- gmac1_rgmii_rxin
- const: i2stx_bclk_ext
- const: i2stx_lrck_ext
- const: i2srx_bclk_ext
- const: i2srx_lrck_ext
- const: tdm_ext
- const: mclk_ext
- items:
- const: osc
- const: gmac1_rmii_refin
- const: gmac1_rgmii_rxin
- const: i2stx_bclk_ext
- const: i2stx_lrck_ext
- const: i2srx_bclk_ext
- const: i2srx_lrck_ext
- const: tdm_ext
- const: mclk_ext
'#clock-cells':
const: 1
description:
See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
'#reset-cells':
const: 1
description:
See <dt-bindings/reset/starfive,jh7110-crg.h> for valid indices.
required:
- compatible
- reg
- clocks
- clock-names
- '#clock-cells'
- '#reset-cells'
additionalProperties: false
examples:
- |
clock-controller@13020000 {
compatible = "starfive,jh7110-syscrg";
reg = <0x13020000 0x10000>;
clocks = <&osc>, <&gmac1_rmii_refin>,
<&gmac1_rgmii_rxin>,
<&i2stx_bclk_ext>, <&i2stx_lrck_ext>,
<&i2srx_bclk_ext>, <&i2srx_lrck_ext>,
<&tdm_ext>, <&mclk_ext>;
clock-names = "osc", "gmac1_rmii_refin",
"gmac1_rgmii_rxin",
"i2stx_bclk_ext", "i2stx_lrck_ext",
"i2srx_bclk_ext", "i2srx_lrck_ext",
"tdm_ext", "mclk_ext";
#clock-cells = <1>;
#reset-cells = <1>;
};
......@@ -19908,19 +19908,20 @@ M: Emil Renner Berthing <kernel@esmil.dk>
S: Maintained
F: arch/riscv/boot/dts/starfive/
STARFIVE JH7100 CLOCK DRIVERS
M: Emil Renner Berthing <kernel@esmil.dk>
S: Maintained
F: Documentation/devicetree/bindings/clock/starfive,jh7100-*.yaml
F: drivers/clk/starfive/clk-starfive-jh7100*
F: include/dt-bindings/clock/starfive-jh7100*.h
STARFIVE JH7110 MMC/SD/SDIO DRIVER
M: William Qiu <william.qiu@starfivetech.com>
S: Supported
F: Documentation/devicetree/bindings/mmc/starfive*
F: drivers/mmc/host/dw_mmc-starfive.c
STARFIVE JH71X0 CLOCK DRIVERS
M: Emil Renner Berthing <kernel@esmil.dk>
M: Hal Feng <hal.feng@starfivetech.com>
S: Maintained
F: Documentation/devicetree/bindings/clock/starfive,jh71*.yaml
F: drivers/clk/starfive/clk-starfive-jh71*
F: include/dt-bindings/clock/starfive?jh71*.h
STARFIVE JH71X0 PINCTRL DRIVERS
M: Emil Renner Berthing <kernel@esmil.dk>
M: Jianlong Huang <jianlong.huang@starfivetech.com>
......@@ -19931,12 +19932,13 @@ F: drivers/pinctrl/starfive/pinctrl-starfive-jh71*
F: include/dt-bindings/pinctrl/pinctrl-starfive-jh7100.h
F: include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h
STARFIVE JH7100 RESET CONTROLLER DRIVER
STARFIVE JH71X0 RESET CONTROLLER DRIVERS
M: Emil Renner Berthing <kernel@esmil.dk>
M: Hal Feng <hal.feng@starfivetech.com>
S: Maintained
F: Documentation/devicetree/bindings/reset/starfive,jh7100-reset.yaml
F: drivers/reset/reset-starfive-jh7100.c
F: include/dt-bindings/reset/starfive-jh7100.h
F: drivers/reset/starfive/reset-starfive-jh71*
F: include/dt-bindings/reset/starfive?jh71*.h
STARFIVE JH71XX PMU CONTROLLER DRIVER
M: Walker Chen <walker.chen@starfivetech.com>
......
......@@ -120,7 +120,7 @@ obj-$(CONFIG_PLAT_SPEAR) += spear/
obj-y += sprd/
obj-$(CONFIG_ARCH_STI) += st/
obj-$(CONFIG_ARCH_STM32) += stm32/
obj-$(CONFIG_SOC_STARFIVE) += starfive/
obj-y += starfive/
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
obj-y += sunxi-ng/
obj-$(CONFIG_ARCH_TEGRA) += tegra/
......
......@@ -253,15 +253,10 @@ static int axs10x_pll_clk_probe(struct platform_device *pdev)
return ret;
}
return of_clk_add_hw_provider(dev->of_node, of_clk_hw_simple_get,
return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get,
&pll_clk->hw);
}
static void axs10x_pll_clk_remove(struct platform_device *pdev)
{
of_clk_del_provider(pdev->dev.of_node);
}
static void __init of_axs10x_pll_clk_setup(struct device_node *node)
{
const char *parent_name;
......@@ -331,7 +326,6 @@ static struct platform_driver axs10x_pll_clk_driver = {
.of_match_table = axs10x_pll_clk_id,
},
.probe = axs10x_pll_clk_probe,
.remove_new = axs10x_pll_clk_remove,
};
builtin_platform_driver(axs10x_pll_clk_driver);
......
......@@ -553,15 +553,10 @@ static int axi_clkgen_probe(struct platform_device *pdev)
if (ret)
return ret;
return of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_simple_get,
return devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_simple_get,
&axi_clkgen->clk_hw);
}
static void axi_clkgen_remove(struct platform_device *pdev)
{
of_clk_del_provider(pdev->dev.of_node);
}
static const struct of_device_id axi_clkgen_ids[] = {
{
.compatible = "adi,zynqmp-axi-clkgen-2.00.a",
......@@ -581,7 +576,6 @@ static struct platform_driver axi_clkgen_driver = {
.of_match_table = axi_clkgen_ids,
},
.probe = axi_clkgen_probe,
.remove_new = axi_clkgen_remove,
};
module_platform_driver(axi_clkgen_driver);
......
......@@ -569,17 +569,11 @@ static int axmclk_probe(struct platform_device *pdev)
return ret;
}
return of_clk_add_hw_provider(dev->of_node, of_clk_axmclk_get, NULL);
}
static void axmclk_remove(struct platform_device *pdev)
{
of_clk_del_provider(pdev->dev.of_node);
return devm_of_clk_add_hw_provider(dev, of_clk_axmclk_get, NULL);
}
static struct platform_driver axmclk_driver = {
.probe = axmclk_probe,
.remove_new = axmclk_remove,
.driver = {
.name = "clk-axm5516",
.of_match_table = axmclk_match_table,
......
......@@ -661,16 +661,10 @@ static int cdce706_probe(struct i2c_client *client)
ret = cdce706_register_clkouts(cdce);
if (ret < 0)
return ret;
return of_clk_add_hw_provider(client->dev.of_node, of_clk_cdce_get,
return devm_of_clk_add_hw_provider(&client->dev, of_clk_cdce_get,
cdce);
}
static void cdce706_remove(struct i2c_client *client)
{
of_clk_del_provider(client->dev.of_node);
}
#ifdef CONFIG_OF
static const struct of_device_id cdce706_dt_match[] = {
{ .compatible = "ti,cdce706" },
......@@ -691,7 +685,6 @@ static struct i2c_driver cdce706_i2c_driver = {
.of_match_table = of_match_ptr(cdce706_dt_match),
},
.probe_new = cdce706_probe,
.remove = cdce706_remove,
.id_table = cdce706_id,
};
module_i2c_driver(cdce706_i2c_driver);
......
......@@ -71,6 +71,7 @@ static void clk_fd_get_div(struct clk_hw *hw, struct u32_fract *fract)
struct clk_fractional_divider *fd = to_clk_fd(hw);
unsigned long flags = 0;
unsigned long m, n;
u32 mmask, nmask;
u32 val;
if (fd->lock)
......@@ -85,8 +86,11 @@ static void clk_fd_get_div(struct clk_hw *hw, struct u32_fract *fract)
else
__release(fd->lock);
m = (val & fd->mmask) >> fd->mshift;
n = (val & fd->nmask) >> fd->nshift;
mmask = GENMASK(fd->mwidth - 1, 0) << fd->mshift;
nmask = GENMASK(fd->nwidth - 1, 0) << fd->nshift;
m = (val & mmask) >> fd->mshift;
n = (val & nmask) >> fd->nshift;
if (fd->flags & CLK_FRAC_DIVIDER_ZERO_BASED) {
m++;
......@@ -166,6 +170,7 @@ static int clk_fd_set_rate(struct clk_hw *hw, unsigned long rate,
struct clk_fractional_divider *fd = to_clk_fd(hw);
unsigned long flags = 0;
unsigned long m, n;
u32 mmask, nmask;
u32 val;
rational_best_approximation(rate, parent_rate,
......@@ -182,8 +187,11 @@ static int clk_fd_set_rate(struct clk_hw *hw, unsigned long rate,
else
__acquire(fd->lock);
mmask = GENMASK(fd->mwidth - 1, 0) << fd->mshift;
nmask = GENMASK(fd->nwidth - 1, 0) << fd->nshift;
val = clk_fd_readl(fd);
val &= ~(fd->mmask | fd->nmask);
val &= ~(mmask | nmask);
val |= (m << fd->mshift) | (n << fd->nshift);
clk_fd_writel(fd, val);
......@@ -260,10 +268,8 @@ struct clk_hw *clk_hw_register_fractional_divider(struct device *dev,
fd->reg = reg;
fd->mshift = mshift;
fd->mwidth = mwidth;
fd->mmask = GENMASK(mwidth - 1, 0) << mshift;
fd->nshift = nshift;
fd->nwidth = nwidth;
fd->nmask = GENMASK(nwidth - 1, 0) << nshift;
fd->flags = clk_divider_flags;
fd->lock = lock;
fd->hw.init = &init;
......
......@@ -346,15 +346,10 @@ static int hsdk_pll_clk_probe(struct platform_device *pdev)
return ret;
}
return of_clk_add_hw_provider(dev->of_node, of_clk_hw_simple_get,
return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get,
&pll_clk->hw);
}
static void hsdk_pll_clk_remove(struct platform_device *pdev)
{
of_clk_del_provider(pdev->dev.of_node);
}
static void __init of_hsdk_pll_clk_setup(struct device_node *node)
{
int ret;
......@@ -431,6 +426,5 @@ static struct platform_driver hsdk_pll_clk_driver = {
.of_match_table = hsdk_pll_clk_id,
},
.probe = hsdk_pll_clk_probe,
.remove_new = hsdk_pll_clk_remove,
};
builtin_platform_driver(hsdk_pll_clk_driver);
......@@ -1522,7 +1522,7 @@ static int lmk04832_probe(struct spi_device *spi)
}
lmk->clk_data->num = info->num_channels;
ret = of_clk_add_hw_provider(lmk->dev->of_node, of_clk_hw_onecell_get,
ret = devm_of_clk_add_hw_provider(lmk->dev, of_clk_hw_onecell_get,
lmk->clk_data);
if (ret) {
dev_err(lmk->dev, "failed to add provider (%d)\n", ret);
......@@ -1547,7 +1547,6 @@ static void lmk04832_remove(struct spi_device *spi)
struct lmk04832 *lmk = spi_get_drvdata(spi);
clk_disable_unprepare(lmk->oscin);
of_clk_del_provider(spi->dev.of_node);
}
static const struct spi_device_id lmk04832_id[] = {
......
......@@ -360,7 +360,7 @@ static int si514_probe(struct i2c_client *client)
dev_err(&client->dev, "clock registration failed\n");
return err;
}
err = of_clk_add_hw_provider(client->dev.of_node, of_clk_hw_simple_get,
err = devm_of_clk_add_hw_provider(&client->dev, of_clk_hw_simple_get,
&data->hw);
if (err) {
dev_err(&client->dev, "unable to add clk provider\n");
......@@ -370,11 +370,6 @@ static int si514_probe(struct i2c_client *client)
return 0;
}
static void si514_remove(struct i2c_client *client)
{
of_clk_del_provider(client->dev.of_node);
}
static const struct i2c_device_id si514_id[] = {
{ "si514", 0 },
{ }
......@@ -393,7 +388,6 @@ static struct i2c_driver si514_driver = {
.of_match_table = clk_si514_of_match,
},
.probe_new = si514_probe,
.remove = si514_remove,
.id_table = si514_id,
};
module_i2c_driver(si514_driver);
......
......@@ -1641,7 +1641,7 @@ static int si5351_i2c_probe(struct i2c_client *client)
}
}
ret = of_clk_add_hw_provider(client->dev.of_node, si53351_of_clk_get,
ret = devm_of_clk_add_hw_provider(&client->dev, si53351_of_clk_get,
drvdata);
if (ret) {
dev_err(&client->dev, "unable to add clk provider\n");
......@@ -1651,18 +1651,12 @@ static int si5351_i2c_probe(struct i2c_client *client)
return 0;
}
static void si5351_i2c_remove(struct i2c_client *client)
{
of_clk_del_provider(client->dev.of_node);
}
static struct i2c_driver si5351_driver = {
.driver = {
.name = "si5351",
.of_match_table = of_match_ptr(si5351_dt_ids),
},
.probe_new = si5351_i2c_probe,
.remove = si5351_i2c_remove,
.id_table = si5351_i2c_ids,
};
module_i2c_driver(si5351_driver);
......
......@@ -474,7 +474,7 @@ static int si570_probe(struct i2c_client *client)
dev_err(&client->dev, "clock registration failed\n");
return err;
}
err = of_clk_add_hw_provider(client->dev.of_node, of_clk_hw_simple_get,
err = devm_of_clk_add_hw_provider(&client->dev, of_clk_hw_simple_get,
&data->hw);
if (err) {
dev_err(&client->dev, "unable to add clk provider\n");
......@@ -485,11 +485,9 @@ static int si570_probe(struct i2c_client *client)
if (!of_property_read_u32(client->dev.of_node, "clock-frequency",
&initial_fout)) {
err = clk_set_rate(data->hw.clk, initial_fout);
if (err) {
of_clk_del_provider(client->dev.of_node);
if (err)
return err;
}
}
/* Display a message indicating that we've successfully registered */
dev_info(&client->dev, "registered, current frequency %llu Hz\n",
......@@ -498,11 +496,6 @@ static int si570_probe(struct i2c_client *client)
return 0;
}
static void si570_remove(struct i2c_client *client)
{
of_clk_del_provider(client->dev.of_node);
}
static const struct of_device_id clk_si570_of_match[] = {
{ .compatible = "silabs,si570" },
{ .compatible = "silabs,si571" },
......@@ -518,7 +511,6 @@ static struct i2c_driver si570_driver = {
.of_match_table = clk_si570_of_match,
},
.probe_new = si570_probe,
.remove = si570_remove,
.id_table = si570_id,
};
module_i2c_driver(si570_driver);
......
......@@ -19,10 +19,8 @@
#define PCG_CGC_SHIFT 30
#define PCG_FRAC_SHIFT 3
#define PCG_FRAC_WIDTH 1
#define PCG_FRAC_MASK BIT(3)
#define PCG_PCD_SHIFT 0
#define PCG_PCD_WIDTH 3
#define PCG_PCD_MASK 0x7
#define SW_RST BIT(28)
......@@ -102,10 +100,8 @@ static struct clk_hw *imx_ulp_clk_hw_composite(const char *name,
fd->reg = reg;
fd->mshift = PCG_FRAC_SHIFT;
fd->mwidth = PCG_FRAC_WIDTH;
fd->mmask = PCG_FRAC_MASK;
fd->nshift = PCG_PCD_SHIFT;
fd->nwidth = PCG_PCD_WIDTH;
fd->nmask = PCG_PCD_MASK;
fd->flags = CLK_FRAC_DIVIDER_ZERO_BASED;
if (has_swrst)
fd->lock = &imx_ccm_lock;
......
......@@ -244,10 +244,8 @@ static struct clk *rockchip_clk_register_frac_branch(
div->reg = base + muxdiv_offset;
div->mshift = 16;
div->mwidth = 16;
div->mmask = GENMASK(div->mwidth - 1, 0) << div->mshift;
div->nshift = 0;
div->nwidth = 16;
div->nmask = GENMASK(div->nwidth - 1, 0) << div->nshift;
div->lock = lock;
div->approximation = rockchip_fractional_approximation;
div_ops = &clk_fractional_divider_ops;
......
# SPDX-License-Identifier: GPL-2.0
config CLK_STARFIVE_JH71X0
bool
config CLK_STARFIVE_JH7100
bool "StarFive JH7100 clock support"
depends on SOC_STARFIVE || COMPILE_TEST
default SOC_STARFIVE
depends on ARCH_STARFIVE || COMPILE_TEST
select CLK_STARFIVE_JH71X0
default ARCH_STARFIVE
help
Say yes here to support the clock controller on the StarFive JH7100
SoC.
......@@ -11,7 +15,30 @@ config CLK_STARFIVE_JH7100
config CLK_STARFIVE_JH7100_AUDIO
tristate "StarFive JH7100 audio clock support"
depends on CLK_STARFIVE_JH7100
default m if SOC_STARFIVE
select CLK_STARFIVE_JH71X0
default m if ARCH_STARFIVE
help
Say Y or M here to support the audio clocks on the StarFive JH7100
SoC.
config CLK_STARFIVE_JH7110_SYS
bool "StarFive JH7110 system clock support"
depends on ARCH_STARFIVE || COMPILE_TEST
select AUXILIARY_BUS
select CLK_STARFIVE_JH71X0
select RESET_STARFIVE_JH7110
default ARCH_STARFIVE
help
Say yes here to support the system clock controller on the
StarFive JH7110 SoC.
config CLK_STARFIVE_JH7110_AON
tristate "StarFive JH7110 always-on clock support"
depends on CLK_STARFIVE_JH7110_SYS
select AUXILIARY_BUS
select CLK_STARFIVE_JH71X0
select RESET_STARFIVE_JH7110
default m if ARCH_STARFIVE
help
Say yes here to support the always-on clock controller on the
StarFive JH7110 SoC.
# SPDX-License-Identifier: GPL-2.0
# StarFive Clock
obj-$(CONFIG_CLK_STARFIVE_JH71X0) += clk-starfive-jh71x0.o
obj-$(CONFIG_CLK_STARFIVE_JH7100) += clk-starfive-jh7100.o
obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO) += clk-starfive-jh7100-audio.o
obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS) += clk-starfive-jh7110-sys.o
obj-$(CONFIG_CLK_STARFIVE_JH7110_AON) += clk-starfive-jh7110-aon.o
......@@ -16,7 +16,7 @@
#include <dt-bindings/clock/starfive-jh7100-audio.h>
#include "clk-starfive-jh7100.h"
#include "clk-starfive-jh71x0.h"
/* external clocks */
#define JH7100_AUDCLK_AUDIO_SRC (JH7100_AUDCLK_END + 0)
......@@ -28,66 +28,66 @@
#define JH7100_AUDCLK_I2SDAC_LRCLK_IOPAD (JH7100_AUDCLK_END + 6)
#define JH7100_AUDCLK_VAD_INTMEM (JH7100_AUDCLK_END + 7)
static const struct jh7100_clk_data jh7100_audclk_data[] = {
JH7100__GMD(JH7100_AUDCLK_ADC_MCLK, "adc_mclk", 0, 15, 2,
static const struct jh71x0_clk_data jh7100_audclk_data[] = {
JH71X0__GMD(JH7100_AUDCLK_ADC_MCLK, "adc_mclk", 0, 15, 2,
JH7100_AUDCLK_AUDIO_SRC,
JH7100_AUDCLK_AUDIO_12288),
JH7100__GMD(JH7100_AUDCLK_I2S1_MCLK, "i2s1_mclk", 0, 15, 2,
JH71X0__GMD(JH7100_AUDCLK_I2S1_MCLK, "i2s1_mclk", 0, 15, 2,
JH7100_AUDCLK_AUDIO_SRC,
JH7100_AUDCLK_AUDIO_12288),
JH7100_GATE(JH7100_AUDCLK_I2SADC_APB, "i2sadc_apb", 0, JH7100_AUDCLK_APB0_BUS),
JH7100_MDIV(JH7100_AUDCLK_I2SADC_BCLK, "i2sadc_bclk", 31, 2,
JH71X0_GATE(JH7100_AUDCLK_I2SADC_APB, "i2sadc_apb", 0, JH7100_AUDCLK_APB0_BUS),
JH71X0_MDIV(JH7100_AUDCLK_I2SADC_BCLK, "i2sadc_bclk", 31, 2,
JH7100_AUDCLK_ADC_MCLK,
JH7100_AUDCLK_I2SADC_BCLK_IOPAD),
JH7100__INV(JH7100_AUDCLK_I2SADC_BCLK_N, "i2sadc_bclk_n", JH7100_AUDCLK_I2SADC_BCLK),
JH7100_MDIV(JH7100_AUDCLK_I2SADC_LRCLK, "i2sadc_lrclk", 63, 3,
JH71X0__INV(JH7100_AUDCLK_I2SADC_BCLK_N, "i2sadc_bclk_n", JH7100_AUDCLK_I2SADC_BCLK),
JH71X0_MDIV(JH7100_AUDCLK_I2SADC_LRCLK, "i2sadc_lrclk", 63, 3,
JH7100_AUDCLK_I2SADC_BCLK_N,
JH7100_AUDCLK_I2SADC_LRCLK_IOPAD,
JH7100_AUDCLK_I2SADC_BCLK),
JH7100_GATE(JH7100_AUDCLK_PDM_APB, "pdm_apb", 0, JH7100_AUDCLK_APB0_BUS),
JH7100__GMD(JH7100_AUDCLK_PDM_MCLK, "pdm_mclk", 0, 15, 2,
JH71X0_GATE(JH7100_AUDCLK_PDM_APB, "pdm_apb", 0, JH7100_AUDCLK_APB0_BUS),
JH71X0__GMD(JH7100_AUDCLK_PDM_MCLK, "pdm_mclk", 0, 15, 2,
JH7100_AUDCLK_AUDIO_SRC,
JH7100_AUDCLK_AUDIO_12288),
JH7100_GATE(JH7100_AUDCLK_I2SVAD_APB, "i2svad_apb", 0, JH7100_AUDCLK_APB0_BUS),
JH7100__GMD(JH7100_AUDCLK_SPDIF, "spdif", 0, 15, 2,
JH71X0_GATE(JH7100_AUDCLK_I2SVAD_APB, "i2svad_apb", 0, JH7100_AUDCLK_APB0_BUS),
JH71X0__GMD(JH7100_AUDCLK_SPDIF, "spdif", 0, 15, 2,
JH7100_AUDCLK_AUDIO_SRC,
JH7100_AUDCLK_AUDIO_12288),
JH7100_GATE(JH7100_AUDCLK_SPDIF_APB, "spdif_apb", 0, JH7100_AUDCLK_APB0_BUS),
JH7100_GATE(JH7100_AUDCLK_PWMDAC_APB, "pwmdac_apb", 0, JH7100_AUDCLK_APB0_BUS),
JH7100__GMD(JH7100_AUDCLK_DAC_MCLK, "dac_mclk", 0, 15, 2,
JH71X0_GATE(JH7100_AUDCLK_SPDIF_APB, "spdif_apb", 0, JH7100_AUDCLK_APB0_BUS),
JH71X0_GATE(JH7100_AUDCLK_PWMDAC_APB, "pwmdac_apb", 0, JH7100_AUDCLK_APB0_BUS),
JH71X0__GMD(JH7100_AUDCLK_DAC_MCLK, "dac_mclk", 0, 15, 2,
JH7100_AUDCLK_AUDIO_SRC,
JH7100_AUDCLK_AUDIO_12288),
JH7100_GATE(JH7100_AUDCLK_I2SDAC_APB, "i2sdac_apb", 0, JH7100_AUDCLK_APB0_BUS),
JH7100_MDIV(JH7100_AUDCLK_I2SDAC_BCLK, "i2sdac_bclk", 31, 2,
JH71X0_GATE(JH7100_AUDCLK_I2SDAC_APB, "i2sdac_apb", 0, JH7100_AUDCLK_APB0_BUS),
JH71X0_MDIV(JH7100_AUDCLK_I2SDAC_BCLK, "i2sdac_bclk", 31, 2,
JH7100_AUDCLK_DAC_MCLK,
JH7100_AUDCLK_I2SDAC_BCLK_IOPAD),
JH7100__INV(JH7100_AUDCLK_I2SDAC_BCLK_N, "i2sdac_bclk_n", JH7100_AUDCLK_I2SDAC_BCLK),
JH7100_MDIV(JH7100_AUDCLK_I2SDAC_LRCLK, "i2sdac_lrclk", 31, 2,
JH71X0__INV(JH7100_AUDCLK_I2SDAC_BCLK_N, "i2sdac_bclk_n", JH7100_AUDCLK_I2SDAC_BCLK),
JH71X0_MDIV(JH7100_AUDCLK_I2SDAC_LRCLK, "i2sdac_lrclk", 31, 2,
JH7100_AUDCLK_I2S1_MCLK,
JH7100_AUDCLK_I2SDAC_BCLK_IOPAD),
JH7100_GATE(JH7100_AUDCLK_I2S1_APB, "i2s1_apb", 0, JH7100_AUDCLK_APB0_BUS),
JH7100_MDIV(JH7100_AUDCLK_I2S1_BCLK, "i2s1_bclk", 31, 2,
JH71X0_GATE(JH7100_AUDCLK_I2S1_APB, "i2s1_apb", 0, JH7100_AUDCLK_APB0_BUS),
JH71X0_MDIV(JH7100_AUDCLK_I2S1_BCLK, "i2s1_bclk", 31, 2,
JH7100_AUDCLK_I2S1_MCLK,
JH7100_AUDCLK_I2SDAC_BCLK_IOPAD),
JH7100__INV(JH7100_AUDCLK_I2S1_BCLK_N, "i2s1_bclk_n", JH7100_AUDCLK_I2S1_BCLK),
JH7100_MDIV(JH7100_AUDCLK_I2S1_LRCLK, "i2s1_lrclk", 63, 3,
JH71X0__INV(JH7100_AUDCLK_I2S1_BCLK_N, "i2s1_bclk_n", JH7100_AUDCLK_I2S1_BCLK),
JH71X0_MDIV(JH7100_AUDCLK_I2S1_LRCLK, "i2s1_lrclk", 63, 3,
JH7100_AUDCLK_I2S1_BCLK_N,
JH7100_AUDCLK_I2SDAC_LRCLK_IOPAD),
JH7100_GATE(JH7100_AUDCLK_I2SDAC16K_APB, "i2s1dac16k_apb", 0, JH7100_AUDCLK_APB0_BUS),
JH7100__DIV(JH7100_AUDCLK_APB0_BUS, "apb0_bus", 8, JH7100_AUDCLK_DOM7AHB_BUS),
JH7100_GATE(JH7100_AUDCLK_DMA1P_AHB, "dma1p_ahb", 0, JH7100_AUDCLK_DOM7AHB_BUS),
JH7100_GATE(JH7100_AUDCLK_USB_APB, "usb_apb", CLK_IGNORE_UNUSED, JH7100_AUDCLK_APB_EN),
JH7100_GDIV(JH7100_AUDCLK_USB_LPM, "usb_lpm", CLK_IGNORE_UNUSED, 4, JH7100_AUDCLK_USB_APB),
JH7100_GDIV(JH7100_AUDCLK_USB_STB, "usb_stb", CLK_IGNORE_UNUSED, 3, JH7100_AUDCLK_USB_APB),
JH7100__DIV(JH7100_AUDCLK_APB_EN, "apb_en", 8, JH7100_AUDCLK_DOM7AHB_BUS),
JH7100__MUX(JH7100_AUDCLK_VAD_MEM, "vad_mem", 2,
JH71X0_GATE(JH7100_AUDCLK_I2SDAC16K_APB, "i2s1dac16k_apb", 0, JH7100_AUDCLK_APB0_BUS),
JH71X0__DIV(JH7100_AUDCLK_APB0_BUS, "apb0_bus", 8, JH7100_AUDCLK_DOM7AHB_BUS),
JH71X0_GATE(JH7100_AUDCLK_DMA1P_AHB, "dma1p_ahb", 0, JH7100_AUDCLK_DOM7AHB_BUS),
JH71X0_GATE(JH7100_AUDCLK_USB_APB, "usb_apb", CLK_IGNORE_UNUSED, JH7100_AUDCLK_APB_EN),
JH71X0_GDIV(JH7100_AUDCLK_USB_LPM, "usb_lpm", CLK_IGNORE_UNUSED, 4, JH7100_AUDCLK_USB_APB),
JH71X0_GDIV(JH7100_AUDCLK_USB_STB, "usb_stb", CLK_IGNORE_UNUSED, 3, JH7100_AUDCLK_USB_APB),
JH71X0__DIV(JH7100_AUDCLK_APB_EN, "apb_en", 8, JH7100_AUDCLK_DOM7AHB_BUS),
JH71X0__MUX(JH7100_AUDCLK_VAD_MEM, "vad_mem", 2,
JH7100_AUDCLK_VAD_INTMEM,
JH7100_AUDCLK_AUDIO_12288),
};
static struct clk_hw *jh7100_audclk_get(struct of_phandle_args *clkspec, void *data)
{
struct jh7100_clk_priv *priv = data;
struct jh71x0_clk_priv *priv = data;
unsigned int idx = clkspec->args[0];
if (idx < JH7100_AUDCLK_END)
......@@ -98,7 +98,7 @@ static struct clk_hw *jh7100_audclk_get(struct of_phandle_args *clkspec, void *d
static int jh7100_audclk_probe(struct platform_device *pdev)
{
struct jh7100_clk_priv *priv;
struct jh71x0_clk_priv *priv;
unsigned int idx;
int ret;
......@@ -117,12 +117,12 @@ static int jh7100_audclk_probe(struct platform_device *pdev)
struct clk_parent_data parents[4] = {};
struct clk_init_data init = {
.name = jh7100_audclk_data[idx].name,
.ops = starfive_jh7100_clk_ops(max),
.ops = starfive_jh71x0_clk_ops(max),
.parent_data = parents,
.num_parents = ((max & JH7100_CLK_MUX_MASK) >> JH7100_CLK_MUX_SHIFT) + 1,
.num_parents = ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
.flags = jh7100_audclk_data[idx].flags,
};
struct jh7100_clk *clk = &priv->reg[idx];
struct jh71x0_clk *clk = &priv->reg[idx];
unsigned int i;
for (i = 0; i < init.num_parents; i++) {
......@@ -140,7 +140,7 @@ static int jh7100_audclk_probe(struct platform_device *pdev)
clk->hw.init = &init;
clk->idx = idx;
clk->max_div = max & JH7100_CLK_DIV_MASK;
clk->max_div = max & JH71X0_CLK_DIV_MASK;
ret = devm_clk_hw_register(priv->dev, &clk->hw);
if (ret)
......
This diff is collapsed.
// SPDX-License-Identifier: GPL-2.0
/*
* StarFive JH7110 Always-On Clock Driver
*
* Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
* Copyright (C) 2022 StarFive Technology Co., Ltd.
*/
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <dt-bindings/clock/starfive,jh7110-crg.h>
#include "clk-starfive-jh7110.h"
/* external clocks */
#define JH7110_AONCLK_OSC (JH7110_AONCLK_END + 0)
#define JH7110_AONCLK_GMAC0_RMII_REFIN (JH7110_AONCLK_END + 1)
#define JH7110_AONCLK_GMAC0_RGMII_RXIN (JH7110_AONCLK_END + 2)
#define JH7110_AONCLK_STG_AXIAHB (JH7110_AONCLK_END + 3)
#define JH7110_AONCLK_APB_BUS (JH7110_AONCLK_END + 4)
#define JH7110_AONCLK_GMAC0_GTXCLK (JH7110_AONCLK_END + 5)
#define JH7110_AONCLK_RTC_OSC (JH7110_AONCLK_END + 6)
static const struct jh71x0_clk_data jh7110_aonclk_data[] = {
/* source */
JH71X0__DIV(JH7110_AONCLK_OSC_DIV4, "osc_div4", 4, JH7110_AONCLK_OSC),
JH71X0__MUX(JH7110_AONCLK_APB_FUNC, "apb_func", 2,
JH7110_AONCLK_OSC_DIV4,
JH7110_AONCLK_OSC),
/* gmac0 */
JH71X0_GATE(JH7110_AONCLK_GMAC0_AHB, "gmac0_ahb", 0, JH7110_AONCLK_STG_AXIAHB),
JH71X0_GATE(JH7110_AONCLK_GMAC0_AXI, "gmac0_axi", 0, JH7110_AONCLK_STG_AXIAHB),
JH71X0__DIV(JH7110_AONCLK_GMAC0_RMII_RTX, "gmac0_rmii_rtx", 30,
JH7110_AONCLK_GMAC0_RMII_REFIN),
JH71X0_GMUX(JH7110_AONCLK_GMAC0_TX, "gmac0_tx",
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, 2,
JH7110_AONCLK_GMAC0_GTXCLK,
JH7110_AONCLK_GMAC0_RMII_RTX),
JH71X0__INV(JH7110_AONCLK_GMAC0_TX_INV, "gmac0_tx_inv", JH7110_AONCLK_GMAC0_TX),
JH71X0__MUX(JH7110_AONCLK_GMAC0_RX, "gmac0_rx", 2,
JH7110_AONCLK_GMAC0_RGMII_RXIN,
JH7110_AONCLK_GMAC0_RMII_RTX),
JH71X0__INV(JH7110_AONCLK_GMAC0_RX_INV, "gmac0_rx_inv", JH7110_AONCLK_GMAC0_RX),
/* otpc */
JH71X0_GATE(JH7110_AONCLK_OTPC_APB, "otpc_apb", 0, JH7110_AONCLK_APB_BUS),
/* rtc */
JH71X0_GATE(JH7110_AONCLK_RTC_APB, "rtc_apb", 0, JH7110_AONCLK_APB_BUS),
JH71X0__DIV(JH7110_AONCLK_RTC_INTERNAL, "rtc_internal", 1022, JH7110_AONCLK_OSC),
JH71X0__MUX(JH7110_AONCLK_RTC_32K, "rtc_32k", 2,
JH7110_AONCLK_RTC_OSC,
JH7110_AONCLK_RTC_INTERNAL),
JH71X0_GATE(JH7110_AONCLK_RTC_CAL, "rtc_cal", 0, JH7110_AONCLK_OSC),
};
static struct clk_hw *jh7110_aonclk_get(struct of_phandle_args *clkspec, void *data)
{
struct jh71x0_clk_priv *priv = data;
unsigned int idx = clkspec->args[0];
if (idx < JH7110_AONCLK_END)
return &priv->reg[idx].hw;
return ERR_PTR(-EINVAL);
}
static int jh7110_aoncrg_probe(struct platform_device *pdev)
{
struct jh71x0_clk_priv *priv;
unsigned int idx;
int ret;
priv = devm_kzalloc(&pdev->dev,
struct_size(priv, reg, JH7110_AONCLK_END),
GFP_KERNEL);
if (!priv)
return -ENOMEM;
spin_lock_init(&priv->rmw_lock);
priv->dev = &pdev->dev;
priv->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->base))
return PTR_ERR(priv->base);
for (idx = 0; idx < JH7110_AONCLK_END; idx++) {
u32 max = jh7110_aonclk_data[idx].max;
struct clk_parent_data parents[4] = {};
struct clk_init_data init = {
.name = jh7110_aonclk_data[idx].name,
.ops = starfive_jh71x0_clk_ops(max),
.parent_data = parents,
.num_parents =
((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
.flags = jh7110_aonclk_data[idx].flags,
};
struct jh71x0_clk *clk = &priv->reg[idx];
unsigned int i;
for (i = 0; i < init.num_parents; i++) {
unsigned int pidx = jh7110_aonclk_data[idx].parents[i];
if (pidx < JH7110_AONCLK_END)
parents[i].hw = &priv->reg[pidx].hw;
else if (pidx == JH7110_AONCLK_OSC)
parents[i].fw_name = "osc";
else if (pidx == JH7110_AONCLK_GMAC0_RMII_REFIN)
parents[i].fw_name = "gmac0_rmii_refin";
else if (pidx == JH7110_AONCLK_GMAC0_RGMII_RXIN)
parents[i].fw_name = "gmac0_rgmii_rxin";
else if (pidx == JH7110_AONCLK_STG_AXIAHB)
parents[i].fw_name = "stg_axiahb";
else if (pidx == JH7110_AONCLK_APB_BUS)
parents[i].fw_name = "apb_bus";
else if (pidx == JH7110_AONCLK_GMAC0_GTXCLK)
parents[i].fw_name = "gmac0_gtxclk";
else if (pidx == JH7110_AONCLK_RTC_OSC)
parents[i].fw_name = "rtc_osc";
}
clk->hw.init = &init;
clk->idx = idx;
clk->max_div = max & JH71X0_CLK_DIV_MASK;
ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
if (ret)
return ret;
}
ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_aonclk_get, priv);
if (ret)
return ret;
return jh7110_reset_controller_register(priv, "rst-aon", 1);
}
static const struct of_device_id jh7110_aoncrg_match[] = {
{ .compatible = "starfive,jh7110-aoncrg" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, jh7110_aoncrg_match);
static struct platform_driver jh7110_aoncrg_driver = {
.probe = jh7110_aoncrg_probe,
.driver = {
.name = "clk-starfive-jh7110-aon",
.of_match_table = jh7110_aoncrg_match,
},
};
module_platform_driver(jh7110_aoncrg_driver);
MODULE_AUTHOR("Emil Renner Berthing");
MODULE_DESCRIPTION("StarFive JH7110 always-on clock driver");
MODULE_LICENSE("GPL");
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __CLK_STARFIVE_JH7110_H
#define __CLK_STARFIVE_JH7110_H
#include "clk-starfive-jh71x0.h"
int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv,
const char *adev_name,
u32 adev_id);
#endif
// SPDX-License-Identifier: GPL-2.0
/*
* StarFive JH71X0 Clock Generator Driver
*
* Copyright (C) 2021-2022 Emil Renner Berthing <kernel@esmil.dk>
*/
#include <linux/clk-provider.h>
#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/io.h>
#include "clk-starfive-jh71x0.h"
static struct jh71x0_clk *jh71x0_clk_from(struct clk_hw *hw)
{
return container_of(hw, struct jh71x0_clk, hw);
}
static struct jh71x0_clk_priv *jh71x0_priv_from(struct jh71x0_clk *clk)
{
return container_of(clk, struct jh71x0_clk_priv, reg[clk->idx]);
}
static u32 jh71x0_clk_reg_get(struct jh71x0_clk *clk)
{
struct jh71x0_clk_priv *priv = jh71x0_priv_from(clk);
void __iomem *reg = priv->base + 4 * clk->idx;
return readl_relaxed(reg);
}
static void jh71x0_clk_reg_rmw(struct jh71x0_clk *clk, u32 mask, u32 value)
{
struct jh71x0_clk_priv *priv = jh71x0_priv_from(clk);
void __iomem *reg = priv->base + 4 * clk->idx;
unsigned long flags;
spin_lock_irqsave(&priv->rmw_lock, flags);
value |= readl_relaxed(reg) & ~mask;
writel_relaxed(value, reg);
spin_unlock_irqrestore(&priv->rmw_lock, flags);
}
static int jh71x0_clk_enable(struct clk_hw *hw)
{
struct jh71x0_clk *clk = jh71x0_clk_from(hw);
jh71x0_clk_reg_rmw(clk, JH71X0_CLK_ENABLE, JH71X0_CLK_ENABLE);
return 0;
}
static void jh71x0_clk_disable(struct clk_hw *hw)
{
struct jh71x0_clk *clk = jh71x0_clk_from(hw);
jh71x0_clk_reg_rmw(clk, JH71X0_CLK_ENABLE, 0);
}
static int jh71x0_clk_is_enabled(struct clk_hw *hw)
{
struct jh71x0_clk *clk = jh71x0_clk_from(hw);
return !!(jh71x0_clk_reg_get(clk) & JH71X0_CLK_ENABLE);
}
static unsigned long jh71x0_clk_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct jh71x0_clk *clk = jh71x0_clk_from(hw);
u32 div = jh71x0_clk_reg_get(clk) & JH71X0_CLK_DIV_MASK;
return div ? parent_rate / div : 0;
}
static int jh71x0_clk_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
struct jh71x0_clk *clk = jh71x0_clk_from(hw);
unsigned long parent = req->best_parent_rate;
unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
unsigned long div = min_t(unsigned long, DIV_ROUND_UP(parent, rate), clk->max_div);
unsigned long result = parent / div;
/*
* we want the result clamped by min_rate and max_rate if possible:
* case 1: div hits the max divider value, which means it's less than
* parent / rate, so the result is greater than rate and min_rate in
* particular. we can't do anything about result > max_rate because the
* divider doesn't go any further.
* case 2: div = DIV_ROUND_UP(parent, rate) which means the result is
* always lower or equal to rate and max_rate. however the result may
* turn out lower than min_rate, but then the next higher rate is fine:
* div - 1 = ceil(parent / rate) - 1 < parent / rate
* and thus
* min_rate <= rate < parent / (div - 1)
*/
if (result < req->min_rate && div > 1)
result = parent / (div - 1);
req->rate = result;
return 0;
}
static int jh71x0_clk_set_rate(struct clk_hw *hw,
unsigned long rate,
unsigned long parent_rate)
{
struct jh71x0_clk *clk = jh71x0_clk_from(hw);
unsigned long div = clamp(DIV_ROUND_CLOSEST(parent_rate, rate),
1UL, (unsigned long)clk->max_div);
jh71x0_clk_reg_rmw(clk, JH71X0_CLK_DIV_MASK, div);
return 0;
}
static unsigned long jh71x0_clk_frac_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct jh71x0_clk *clk = jh71x0_clk_from(hw);
u32 reg = jh71x0_clk_reg_get(clk);
unsigned long div100 = 100 * (reg & JH71X0_CLK_INT_MASK) +
((reg & JH71X0_CLK_FRAC_MASK) >> JH71X0_CLK_FRAC_SHIFT);
return (div100 >= JH71X0_CLK_FRAC_MIN) ? 100 * parent_rate / div100 : 0;
}
static int jh71x0_clk_frac_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
unsigned long parent100 = 100 * req->best_parent_rate;
unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
unsigned long div100 = clamp(DIV_ROUND_CLOSEST(parent100, rate),
JH71X0_CLK_FRAC_MIN, JH71X0_CLK_FRAC_MAX);
unsigned long result = parent100 / div100;
/* clamp the result as in jh71x0_clk_determine_rate() above */
if (result > req->max_rate && div100 < JH71X0_CLK_FRAC_MAX)
result = parent100 / (div100 + 1);
if (result < req->min_rate && div100 > JH71X0_CLK_FRAC_MIN)
result = parent100 / (div100 - 1);
req->rate = result;
return 0;
}
static int jh71x0_clk_frac_set_rate(struct clk_hw *hw,
unsigned long rate,
unsigned long parent_rate)
{
struct jh71x0_clk *clk = jh71x0_clk_from(hw);
unsigned long div100 = clamp(DIV_ROUND_CLOSEST(100 * parent_rate, rate),
JH71X0_CLK_FRAC_MIN, JH71X0_CLK_FRAC_MAX);
u32 value = ((div100 % 100) << JH71X0_CLK_FRAC_SHIFT) | (div100 / 100);
jh71x0_clk_reg_rmw(clk, JH71X0_CLK_DIV_MASK, value);
return 0;
}
static u8 jh71x0_clk_get_parent(struct clk_hw *hw)
{
struct jh71x0_clk *clk = jh71x0_clk_from(hw);
u32 value = jh71x0_clk_reg_get(clk);
return (value & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT;
}
static int jh71x0_clk_set_parent(struct clk_hw *hw, u8 index)
{
struct jh71x0_clk *clk = jh71x0_clk_from(hw);
u32 value = (u32)index << JH71X0_CLK_MUX_SHIFT;
jh71x0_clk_reg_rmw(clk, JH71X0_CLK_MUX_MASK, value);
return 0;
}
static int jh71x0_clk_mux_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
return clk_mux_determine_rate_flags(hw, req, 0);
}
static int jh71x0_clk_get_phase(struct clk_hw *hw)
{
struct jh71x0_clk *clk = jh71x0_clk_from(hw);
u32 value = jh71x0_clk_reg_get(clk);
return (value & JH71X0_CLK_INVERT) ? 180 : 0;
}
static int jh71x0_clk_set_phase(struct clk_hw *hw, int degrees)
{
struct jh71x0_clk *clk = jh71x0_clk_from(hw);
u32 value;
if (degrees == 0)
value = 0;
else if (degrees == 180)
value = JH71X0_CLK_INVERT;
else
return -EINVAL;
jh71x0_clk_reg_rmw(clk, JH71X0_CLK_INVERT, value);
return 0;
}
#ifdef CONFIG_DEBUG_FS
static void jh71x0_clk_debug_init(struct clk_hw *hw, struct dentry *dentry)
{
static const struct debugfs_reg32 jh71x0_clk_reg = {
.name = "CTRL",
.offset = 0,
};
struct jh71x0_clk *clk = jh71x0_clk_from(hw);
struct jh71x0_clk_priv *priv = jh71x0_priv_from(clk);
struct debugfs_regset32 *regset;
regset = devm_kzalloc(priv->dev, sizeof(*regset), GFP_KERNEL);
if (!regset)
return;
regset->regs = &jh71x0_clk_reg;
regset->nregs = 1;
regset->base = priv->base + 4 * clk->idx;
debugfs_create_regset32("registers", 0400, dentry, regset);
}
#else
#define jh71x0_clk_debug_init NULL
#endif
static const struct clk_ops jh71x0_clk_gate_ops = {
.enable = jh71x0_clk_enable,
.disable = jh71x0_clk_disable,
.is_enabled = jh71x0_clk_is_enabled,
.debug_init = jh71x0_clk_debug_init,
};
static const struct clk_ops jh71x0_clk_div_ops = {
.recalc_rate = jh71x0_clk_recalc_rate,
.determine_rate = jh71x0_clk_determine_rate,
.set_rate = jh71x0_clk_set_rate,
.debug_init = jh71x0_clk_debug_init,
};
static const struct clk_ops jh71x0_clk_fdiv_ops = {
.recalc_rate = jh71x0_clk_frac_recalc_rate,
.determine_rate = jh71x0_clk_frac_determine_rate,
.set_rate = jh71x0_clk_frac_set_rate,
.debug_init = jh71x0_clk_debug_init,
};
static const struct clk_ops jh71x0_clk_gdiv_ops = {
.enable = jh71x0_clk_enable,
.disable = jh71x0_clk_disable,
.is_enabled = jh71x0_clk_is_enabled,
.recalc_rate = jh71x0_clk_recalc_rate,
.determine_rate = jh71x0_clk_determine_rate,
.set_rate = jh71x0_clk_set_rate,
.debug_init = jh71x0_clk_debug_init,
};
static const struct clk_ops jh71x0_clk_mux_ops = {
.determine_rate = jh71x0_clk_mux_determine_rate,
.set_parent = jh71x0_clk_set_parent,
.get_parent = jh71x0_clk_get_parent,
.debug_init = jh71x0_clk_debug_init,
};
static const struct clk_ops jh71x0_clk_gmux_ops = {
.enable = jh71x0_clk_enable,
.disable = jh71x0_clk_disable,
.is_enabled = jh71x0_clk_is_enabled,
.determine_rate = jh71x0_clk_mux_determine_rate,
.set_parent = jh71x0_clk_set_parent,
.get_parent = jh71x0_clk_get_parent,
.debug_init = jh71x0_clk_debug_init,
};
static const struct clk_ops jh71x0_clk_mdiv_ops = {
.recalc_rate = jh71x0_clk_recalc_rate,
.determine_rate = jh71x0_clk_determine_rate,
.get_parent = jh71x0_clk_get_parent,
.set_parent = jh71x0_clk_set_parent,
.set_rate = jh71x0_clk_set_rate,
.debug_init = jh71x0_clk_debug_init,
};
static const struct clk_ops jh71x0_clk_gmd_ops = {
.enable = jh71x0_clk_enable,
.disable = jh71x0_clk_disable,
.is_enabled = jh71x0_clk_is_enabled,
.recalc_rate = jh71x0_clk_recalc_rate,
.determine_rate = jh71x0_clk_determine_rate,
.get_parent = jh71x0_clk_get_parent,
.set_parent = jh71x0_clk_set_parent,
.set_rate = jh71x0_clk_set_rate,
.debug_init = jh71x0_clk_debug_init,
};
static const struct clk_ops jh71x0_clk_inv_ops = {
.get_phase = jh71x0_clk_get_phase,
.set_phase = jh71x0_clk_set_phase,
.debug_init = jh71x0_clk_debug_init,
};
const struct clk_ops *starfive_jh71x0_clk_ops(u32 max)
{
if (max & JH71X0_CLK_DIV_MASK) {
if (max & JH71X0_CLK_MUX_MASK) {
if (max & JH71X0_CLK_ENABLE)
return &jh71x0_clk_gmd_ops;
return &jh71x0_clk_mdiv_ops;
}
if (max & JH71X0_CLK_ENABLE)
return &jh71x0_clk_gdiv_ops;
if (max == JH71X0_CLK_FRAC_MAX)
return &jh71x0_clk_fdiv_ops;
return &jh71x0_clk_div_ops;
}
if (max & JH71X0_CLK_MUX_MASK) {
if (max & JH71X0_CLK_ENABLE)
return &jh71x0_clk_gmux_ops;
return &jh71x0_clk_mux_ops;
}
if (max & JH71X0_CLK_ENABLE)
return &jh71x0_clk_gate_ops;
return &jh71x0_clk_inv_ops;
}
EXPORT_SYMBOL_GPL(starfive_jh71x0_clk_ops);
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __CLK_STARFIVE_JH7100_H
#define __CLK_STARFIVE_JH7100_H
#ifndef __CLK_STARFIVE_JH71X0_H
#define __CLK_STARFIVE_JH71X0_H
#include <linux/bits.h>
#include <linux/clk-provider.h>
#include <linux/device.h>
#include <linux/spinlock.h>
/* register fields */
#define JH7100_CLK_ENABLE BIT(31)
#define JH7100_CLK_INVERT BIT(30)
#define JH7100_CLK_MUX_MASK GENMASK(27, 24)
#define JH7100_CLK_MUX_SHIFT 24
#define JH7100_CLK_DIV_MASK GENMASK(23, 0)
#define JH7100_CLK_FRAC_MASK GENMASK(15, 8)
#define JH7100_CLK_FRAC_SHIFT 8
#define JH7100_CLK_INT_MASK GENMASK(7, 0)
#define JH71X0_CLK_ENABLE BIT(31)
#define JH71X0_CLK_INVERT BIT(30)
#define JH71X0_CLK_MUX_MASK GENMASK(27, 24)
#define JH71X0_CLK_MUX_SHIFT 24
#define JH71X0_CLK_DIV_MASK GENMASK(23, 0)
#define JH71X0_CLK_FRAC_MASK GENMASK(15, 8)
#define JH71X0_CLK_FRAC_SHIFT 8
#define JH71X0_CLK_INT_MASK GENMASK(7, 0)
/* fractional divider min/max */
#define JH7100_CLK_FRAC_MIN 100UL
#define JH7100_CLK_FRAC_MAX 25599UL
#define JH71X0_CLK_FRAC_MIN 100UL
#define JH71X0_CLK_FRAC_MAX 25599UL
/* clock data */
struct jh7100_clk_data {
struct jh71x0_clk_data {
const char *name;
unsigned long flags;
u32 max;
u8 parents[4];
};
#define JH7100_GATE(_idx, _name, _flags, _parent) [_idx] = { \
#define JH71X0_GATE(_idx, _name, _flags, _parent) \
[_idx] = { \
.name = _name, \
.flags = CLK_SET_RATE_PARENT | (_flags), \
.max = JH7100_CLK_ENABLE, \
.max = JH71X0_CLK_ENABLE, \
.parents = { [0] = _parent }, \
}
#define JH7100__DIV(_idx, _name, _max, _parent) [_idx] = { \
#define JH71X0__DIV(_idx, _name, _max, _parent) \
[_idx] = { \
.name = _name, \
.flags = 0, \
.max = _max, \
.parents = { [0] = _parent }, \
}
#define JH7100_GDIV(_idx, _name, _flags, _max, _parent) [_idx] = { \
#define JH71X0_GDIV(_idx, _name, _flags, _max, _parent) \
[_idx] = { \
.name = _name, \
.flags = _flags, \
.max = JH7100_CLK_ENABLE | (_max), \
.max = JH71X0_CLK_ENABLE | (_max), \
.parents = { [0] = _parent }, \
}
#define JH7100_FDIV(_idx, _name, _parent) [_idx] = { \
#define JH71X0_FDIV(_idx, _name, _parent) \
[_idx] = { \
.name = _name, \
.flags = 0, \
.max = JH7100_CLK_FRAC_MAX, \
.max = JH71X0_CLK_FRAC_MAX, \
.parents = { [0] = _parent }, \
}
#define JH7100__MUX(_idx, _name, _nparents, ...) [_idx] = { \
#define JH71X0__MUX(_idx, _name, _nparents, ...) \
[_idx] = { \
.name = _name, \
.flags = 0, \
.max = ((_nparents) - 1) << JH7100_CLK_MUX_SHIFT, \
.max = ((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT, \
.parents = { __VA_ARGS__ }, \
}
#define JH7100_GMUX(_idx, _name, _flags, _nparents, ...) [_idx] = { \
#define JH71X0_GMUX(_idx, _name, _flags, _nparents, ...) \
[_idx] = { \
.name = _name, \
.flags = _flags, \
.max = JH7100_CLK_ENABLE | \
(((_nparents) - 1) << JH7100_CLK_MUX_SHIFT), \
.max = JH71X0_CLK_ENABLE | \
(((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT), \
.parents = { __VA_ARGS__ }, \
}
#define JH7100_MDIV(_idx, _name, _max, _nparents, ...) [_idx] = { \
#define JH71X0_MDIV(_idx, _name, _max, _nparents, ...) \
[_idx] = { \
.name = _name, \
.flags = 0, \
.max = (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT) | (_max), \
.max = (((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT) | (_max), \
.parents = { __VA_ARGS__ }, \
}
#define JH7100__GMD(_idx, _name, _flags, _max, _nparents, ...) [_idx] = { \
#define JH71X0__GMD(_idx, _name, _flags, _max, _nparents, ...) \
[_idx] = { \
.name = _name, \
.flags = _flags, \
.max = JH7100_CLK_ENABLE | \
(((_nparents) - 1) << JH7100_CLK_MUX_SHIFT) | (_max), \
.max = JH71X0_CLK_ENABLE | \
(((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT) | (_max), \
.parents = { __VA_ARGS__ }, \
}
#define JH7100__INV(_idx, _name, _parent) [_idx] = { \
#define JH71X0__INV(_idx, _name, _parent) \
[_idx] = { \
.name = _name, \
.flags = CLK_SET_RATE_PARENT, \
.max = JH7100_CLK_INVERT, \
.max = JH71X0_CLK_INVERT, \
.parents = { [0] = _parent }, \
}
struct jh7100_clk {
struct jh71x0_clk {
struct clk_hw hw;
unsigned int idx;
unsigned int max_div;
};
struct jh7100_clk_priv {
struct jh71x0_clk_priv {
/* protect clk enable and set rate/parent from happening at the same time */
spinlock_t rmw_lock;
struct device *dev;
void __iomem *base;
struct clk_hw *pll[3];
struct jh7100_clk reg[];
struct jh71x0_clk reg[];
};
const struct clk_ops *starfive_jh7100_clk_ops(u32 max);
const struct clk_ops *starfive_jh71x0_clk_ops(u32 max);
#endif
......@@ -87,15 +87,10 @@ static int uniphier_clk_probe(struct platform_device *pdev)
hw_data->hws[p->idx] = hw;
}
return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
hw_data);
}
static void uniphier_clk_remove(struct platform_device *pdev)
{
of_clk_del_provider(pdev->dev.of_node);
}
static const struct of_device_id uniphier_clk_match[] = {
/* System clock */
{
......@@ -218,7 +213,6 @@ static const struct of_device_id uniphier_clk_match[] = {
static struct platform_driver uniphier_clk_driver = {
.probe = uniphier_clk_probe,
.remove_new = uniphier_clk_remove,
.driver = {
.name = "uniphier-clk",
.of_match_table = uniphier_clk_match,
......
......@@ -232,13 +232,6 @@ config RESET_SOCFPGA
This enables the reset driver for the SoCFPGA ARMv7 platforms. This
driver gets initialized early during platform init calls.
config RESET_STARFIVE_JH7100
bool "StarFive JH7100 Reset Driver"
depends on SOC_STARFIVE || COMPILE_TEST
default SOC_STARFIVE
help
This enables the reset controller driver for the StarFive JH7100 SoC.
config RESET_SUNPLUS
bool "Sunplus SoCs Reset Driver" if COMPILE_TEST
default ARCH_SUNPLUS
......@@ -320,6 +313,7 @@ config RESET_ZYNQ
help
This enables the reset controller driver for Xilinx Zynq SoCs.
source "drivers/reset/starfive/Kconfig"
source "drivers/reset/sti/Kconfig"
source "drivers/reset/hisilicon/Kconfig"
source "drivers/reset/tegra/Kconfig"
......
# SPDX-License-Identifier: GPL-2.0
obj-y += core.o
obj-y += hisilicon/
obj-y += starfive/
obj-$(CONFIG_ARCH_STI) += sti/
obj-$(CONFIG_ARCH_TEGRA) += tegra/
obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o
......@@ -30,7 +31,6 @@ obj-$(CONFIG_RESET_RZG2L_USBPHY_CTRL) += reset-rzg2l-usbphy-ctrl.o
obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
obj-$(CONFIG_RESET_SUNPLUS) += reset-sunplus.o
obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o
......
# SPDX-License-Identifier: GPL-2.0-only
config RESET_STARFIVE_JH71X0
bool
config RESET_STARFIVE_JH7100
bool "StarFive JH7100 Reset Driver"
depends on ARCH_STARFIVE || COMPILE_TEST
select RESET_STARFIVE_JH71X0
default ARCH_STARFIVE
help
This enables the reset controller driver for the StarFive JH7100 SoC.
config RESET_STARFIVE_JH7110
bool "StarFive JH7110 Reset Driver"
depends on AUXILIARY_BUS && CLK_STARFIVE_JH7110_SYS
select RESET_STARFIVE_JH71X0
default ARCH_STARFIVE
help
This enables the reset controller driver for the StarFive JH7110 SoC.
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_RESET_STARFIVE_JH71X0) += reset-starfive-jh71x0.o
obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
obj-$(CONFIG_RESET_STARFIVE_JH7110) += reset-starfive-jh7110.o
......@@ -5,14 +5,10 @@
* Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
*/
#include <linux/bitmap.h>
#include <linux/io.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include <linux/iopoll.h>
#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include <linux/reset-controller.h>
#include <linux/spinlock.h>
#include "reset-starfive-jh71x0.h"
#include <dt-bindings/reset/starfive-jh7100.h>
......@@ -34,128 +30,33 @@
* lines don't though, so store the expected value of the status registers when
* all lines are asserted.
*/
static const u64 jh7100_reset_asserted[2] = {
static const u32 jh7100_reset_asserted[4] = {
/* STATUS0 */
BIT_ULL_MASK(JH7100_RST_U74) |
BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
BIT(JH7100_RST_U74 % 32) |
BIT(JH7100_RST_VP6_DRESET % 32) |
BIT(JH7100_RST_VP6_BRESET % 32),
/* STATUS1 */
BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
BIT(JH7100_RST_HIFI4_DRESET % 32) |
BIT(JH7100_RST_HIFI4_BRESET % 32),
/* STATUS2 */
BIT_ULL_MASK(JH7100_RST_E24) |
BIT(JH7100_RST_E24 % 32),
/* STATUS3 */
0,
};
struct jh7100_reset {
struct reset_controller_dev rcdev;
/* protect registers against concurrent read-modify-write */
spinlock_t lock;
void __iomem *base;
};
static inline struct jh7100_reset *
jh7100_reset_from(struct reset_controller_dev *rcdev)
{
return container_of(rcdev, struct jh7100_reset, rcdev);
}
static int jh7100_reset_update(struct reset_controller_dev *rcdev,
unsigned long id, bool assert)
{
struct jh7100_reset *data = jh7100_reset_from(rcdev);
unsigned long offset = BIT_ULL_WORD(id);
u64 mask = BIT_ULL_MASK(id);
void __iomem *reg_assert = data->base + JH7100_RESET_ASSERT0 + offset * sizeof(u64);
void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
u64 done = jh7100_reset_asserted[offset] & mask;
u64 value;
unsigned long flags;
int ret;
if (!assert)
done ^= mask;
spin_lock_irqsave(&data->lock, flags);
value = readq(reg_assert);
if (assert)
value |= mask;
else
value &= ~mask;
writeq(value, reg_assert);
/* if the associated clock is gated, deasserting might otherwise hang forever */
ret = readq_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
spin_unlock_irqrestore(&data->lock, flags);
return ret;
}
static int jh7100_reset_assert(struct reset_controller_dev *rcdev,
unsigned long id)
{
return jh7100_reset_update(rcdev, id, true);
}
static int jh7100_reset_deassert(struct reset_controller_dev *rcdev,
unsigned long id)
{
return jh7100_reset_update(rcdev, id, false);
}
static int jh7100_reset_reset(struct reset_controller_dev *rcdev,
unsigned long id)
{
int ret;
ret = jh7100_reset_assert(rcdev, id);
if (ret)
return ret;
return jh7100_reset_deassert(rcdev, id);
}
static int jh7100_reset_status(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct jh7100_reset *data = jh7100_reset_from(rcdev);
unsigned long offset = BIT_ULL_WORD(id);
u64 mask = BIT_ULL_MASK(id);
void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
u64 value = readq(reg_status);
return !((value ^ jh7100_reset_asserted[offset]) & mask);
}
static const struct reset_control_ops jh7100_reset_ops = {
.assert = jh7100_reset_assert,
.deassert = jh7100_reset_deassert,
.reset = jh7100_reset_reset,
.status = jh7100_reset_status,
};
static int __init jh7100_reset_probe(struct platform_device *pdev)
{
struct jh7100_reset *data;
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
data->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(data->base))
return PTR_ERR(data->base);
void __iomem *base = devm_platform_ioremap_resource(pdev, 0);
data->rcdev.ops = &jh7100_reset_ops;
data->rcdev.owner = THIS_MODULE;
data->rcdev.nr_resets = JH7100_RSTN_END;
data->rcdev.dev = &pdev->dev;
data->rcdev.of_node = pdev->dev.of_node;
spin_lock_init(&data->lock);
if (IS_ERR(base))
return PTR_ERR(base);
return devm_reset_controller_register(&pdev->dev, &data->rcdev);
return reset_starfive_jh71x0_register(&pdev->dev, pdev->dev.of_node,
base + JH7100_RESET_ASSERT0,
base + JH7100_RESET_STATUS0,
jh7100_reset_asserted,
JH7100_RSTN_END,
THIS_MODULE);
}
static const struct of_device_id jh7100_reset_dt_ids[] = {
......
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Reset driver for the StarFive JH7110 SoC
*
* Copyright (C) 2022 StarFive Technology Co., Ltd.
*/
#include <linux/auxiliary_bus.h>
#include <soc/starfive/reset-starfive-jh71x0.h>
#include "reset-starfive-jh71x0.h"
#include <dt-bindings/reset/starfive,jh7110-crg.h>
struct jh7110_reset_info {
unsigned int nr_resets;
unsigned int assert_offset;
unsigned int status_offset;
};
static const struct jh7110_reset_info jh7110_sys_info = {
.nr_resets = JH7110_SYSRST_END,
.assert_offset = 0x2F8,
.status_offset = 0x308,
};
static const struct jh7110_reset_info jh7110_aon_info = {
.nr_resets = JH7110_AONRST_END,
.assert_offset = 0x38,
.status_offset = 0x3C,
};
static int jh7110_reset_probe(struct auxiliary_device *adev,
const struct auxiliary_device_id *id)
{
struct jh7110_reset_info *info = (struct jh7110_reset_info *)(id->driver_data);
struct jh71x0_reset_adev *rdev = to_jh71x0_reset_adev(adev);
void __iomem *base = rdev->base;
if (!info || !base)
return -ENODEV;
return reset_starfive_jh71x0_register(&adev->dev, adev->dev.parent->of_node,
base + info->assert_offset,
base + info->status_offset,
NULL,
info->nr_resets,
NULL);
}
static const struct auxiliary_device_id jh7110_reset_ids[] = {
{
.name = "clk_starfive_jh7110_sys.rst-sys",
.driver_data = (kernel_ulong_t)&jh7110_sys_info,
},
{
.name = "clk_starfive_jh7110_sys.rst-aon",
.driver_data = (kernel_ulong_t)&jh7110_aon_info,
},
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(auxiliary, jh7110_reset_ids);
static struct auxiliary_driver jh7110_reset_driver = {
.probe = jh7110_reset_probe,
.id_table = jh7110_reset_ids,
};
module_auxiliary_driver(jh7110_reset_driver);
MODULE_AUTHOR("Hal Feng <hal.feng@starfivetech.com>");
MODULE_DESCRIPTION("StarFive JH7110 reset driver");
MODULE_LICENSE("GPL");
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Reset driver for the StarFive JH71X0 SoCs
*
* Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
*/
#include <linux/bitmap.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/reset-controller.h>
#include <linux/spinlock.h>
#include "reset-starfive-jh71x0.h"
struct jh71x0_reset {
struct reset_controller_dev rcdev;
/* protect registers against concurrent read-modify-write */
spinlock_t lock;
void __iomem *assert;
void __iomem *status;
const u32 *asserted;
};
static inline struct jh71x0_reset *
jh71x0_reset_from(struct reset_controller_dev *rcdev)
{
return container_of(rcdev, struct jh71x0_reset, rcdev);
}
static int jh71x0_reset_update(struct reset_controller_dev *rcdev,
unsigned long id, bool assert)
{
struct jh71x0_reset *data = jh71x0_reset_from(rcdev);
unsigned long offset = id / 32;
u32 mask = BIT(id % 32);
void __iomem *reg_assert = data->assert + offset * sizeof(u32);
void __iomem *reg_status = data->status + offset * sizeof(u32);
u32 done = data->asserted ? data->asserted[offset] & mask : 0;
u32 value;
unsigned long flags;
int ret;
if (!assert)
done ^= mask;
spin_lock_irqsave(&data->lock, flags);
value = readl(reg_assert);
if (assert)
value |= mask;
else
value &= ~mask;
writel(value, reg_assert);
/* if the associated clock is gated, deasserting might otherwise hang forever */
ret = readl_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
spin_unlock_irqrestore(&data->lock, flags);
return ret;
}
static int jh71x0_reset_assert(struct reset_controller_dev *rcdev,
unsigned long id)
{
return jh71x0_reset_update(rcdev, id, true);
}
static int jh71x0_reset_deassert(struct reset_controller_dev *rcdev,
unsigned long id)
{
return jh71x0_reset_update(rcdev, id, false);
}
static int jh71x0_reset_reset(struct reset_controller_dev *rcdev,
unsigned long id)
{
int ret;
ret = jh71x0_reset_assert(rcdev, id);
if (ret)
return ret;
return jh71x0_reset_deassert(rcdev, id);
}
static int jh71x0_reset_status(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct jh71x0_reset *data = jh71x0_reset_from(rcdev);
unsigned long offset = id / 32;
u32 mask = BIT(id % 32);
void __iomem *reg_status = data->status + offset * sizeof(u32);
u32 value = readl(reg_status);
return !((value ^ data->asserted[offset]) & mask);
}
static const struct reset_control_ops jh71x0_reset_ops = {
.assert = jh71x0_reset_assert,
.deassert = jh71x0_reset_deassert,
.reset = jh71x0_reset_reset,
.status = jh71x0_reset_status,
};
int reset_starfive_jh71x0_register(struct device *dev, struct device_node *of_node,
void __iomem *assert, void __iomem *status,
const u32 *asserted, unsigned int nr_resets,
struct module *owner)
{
struct jh71x0_reset *data;
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
data->rcdev.ops = &jh71x0_reset_ops;
data->rcdev.owner = owner;
data->rcdev.nr_resets = nr_resets;
data->rcdev.dev = dev;
data->rcdev.of_node = of_node;
spin_lock_init(&data->lock);
data->assert = assert;
data->status = status;
data->asserted = asserted;
return devm_reset_controller_register(dev, &data->rcdev);
}
EXPORT_SYMBOL_GPL(reset_starfive_jh71x0_register);
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
*/
#ifndef __RESET_STARFIVE_JH71X0_H
#define __RESET_STARFIVE_JH71X0_H
int reset_starfive_jh71x0_register(struct device *dev, struct device_node *of_node,
void __iomem *assert, void __iomem *status,
const u32 *asserted, unsigned int nr_resets,
struct module *owner);
#endif /* __RESET_STARFIVE_JH71X0_H */
/* SPDX-License-Identifier: GPL-2.0 OR MIT */
/*
* Copyright 2022 Emil Renner Berthing <kernel@esmil.dk>
*/
#ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__
#define __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__
/* SYSCRG clocks */
#define JH7110_SYSCLK_CPU_ROOT 0
#define JH7110_SYSCLK_CPU_CORE 1
#define JH7110_SYSCLK_CPU_BUS 2
#define JH7110_SYSCLK_GPU_ROOT 3
#define JH7110_SYSCLK_PERH_ROOT 4
#define JH7110_SYSCLK_BUS_ROOT 5
#define JH7110_SYSCLK_NOCSTG_BUS 6
#define JH7110_SYSCLK_AXI_CFG0 7
#define JH7110_SYSCLK_STG_AXIAHB 8
#define JH7110_SYSCLK_AHB0 9
#define JH7110_SYSCLK_AHB1 10
#define JH7110_SYSCLK_APB_BUS 11
#define JH7110_SYSCLK_APB0 12
#define JH7110_SYSCLK_PLL0_DIV2 13
#define JH7110_SYSCLK_PLL1_DIV2 14
#define JH7110_SYSCLK_PLL2_DIV2 15
#define JH7110_SYSCLK_AUDIO_ROOT 16
#define JH7110_SYSCLK_MCLK_INNER 17
#define JH7110_SYSCLK_MCLK 18
#define JH7110_SYSCLK_MCLK_OUT 19
#define JH7110_SYSCLK_ISP_2X 20
#define JH7110_SYSCLK_ISP_AXI 21
#define JH7110_SYSCLK_GCLK0 22
#define JH7110_SYSCLK_GCLK1 23
#define JH7110_SYSCLK_GCLK2 24
#define JH7110_SYSCLK_CORE 25
#define JH7110_SYSCLK_CORE1 26
#define JH7110_SYSCLK_CORE2 27
#define JH7110_SYSCLK_CORE3 28
#define JH7110_SYSCLK_CORE4 29
#define JH7110_SYSCLK_DEBUG 30
#define JH7110_SYSCLK_RTC_TOGGLE 31
#define JH7110_SYSCLK_TRACE0 32
#define JH7110_SYSCLK_TRACE1 33
#define JH7110_SYSCLK_TRACE2 34
#define JH7110_SYSCLK_TRACE3 35
#define JH7110_SYSCLK_TRACE4 36
#define JH7110_SYSCLK_TRACE_COM 37
#define JH7110_SYSCLK_NOC_BUS_CPU_AXI 38
#define JH7110_SYSCLK_NOC_BUS_AXICFG0_AXI 39
#define JH7110_SYSCLK_OSC_DIV2 40
#define JH7110_SYSCLK_PLL1_DIV4 41
#define JH7110_SYSCLK_PLL1_DIV8 42
#define JH7110_SYSCLK_DDR_BUS 43
#define JH7110_SYSCLK_DDR_AXI 44
#define JH7110_SYSCLK_GPU_CORE 45
#define JH7110_SYSCLK_GPU_CORE_CLK 46
#define JH7110_SYSCLK_GPU_SYS_CLK 47
#define JH7110_SYSCLK_GPU_APB 48
#define JH7110_SYSCLK_GPU_RTC_TOGGLE 49
#define JH7110_SYSCLK_NOC_BUS_GPU_AXI 50
#define JH7110_SYSCLK_ISP_TOP_CORE 51
#define JH7110_SYSCLK_ISP_TOP_AXI 52
#define JH7110_SYSCLK_NOC_BUS_ISP_AXI 53
#define JH7110_SYSCLK_HIFI4_CORE 54
#define JH7110_SYSCLK_HIFI4_AXI 55
#define JH7110_SYSCLK_AXI_CFG1_MAIN 56
#define JH7110_SYSCLK_AXI_CFG1_AHB 57
#define JH7110_SYSCLK_VOUT_SRC 58
#define JH7110_SYSCLK_VOUT_AXI 59
#define JH7110_SYSCLK_NOC_BUS_DISP_AXI 60
#define JH7110_SYSCLK_VOUT_TOP_AHB 61
#define JH7110_SYSCLK_VOUT_TOP_AXI 62
#define JH7110_SYSCLK_VOUT_TOP_HDMITX0_MCLK 63
#define JH7110_SYSCLK_VOUT_TOP_MIPIPHY_REF 64
#define JH7110_SYSCLK_JPEGC_AXI 65
#define JH7110_SYSCLK_CODAJ12_AXI 66
#define JH7110_SYSCLK_CODAJ12_CORE 67
#define JH7110_SYSCLK_CODAJ12_APB 68
#define JH7110_SYSCLK_VDEC_AXI 69
#define JH7110_SYSCLK_WAVE511_AXI 70
#define JH7110_SYSCLK_WAVE511_BPU 71
#define JH7110_SYSCLK_WAVE511_VCE 72
#define JH7110_SYSCLK_WAVE511_APB 73
#define JH7110_SYSCLK_VDEC_JPG 74
#define JH7110_SYSCLK_VDEC_MAIN 75
#define JH7110_SYSCLK_NOC_BUS_VDEC_AXI 76
#define JH7110_SYSCLK_VENC_AXI 77
#define JH7110_SYSCLK_WAVE420L_AXI 78
#define JH7110_SYSCLK_WAVE420L_BPU 79
#define JH7110_SYSCLK_WAVE420L_VCE 80
#define JH7110_SYSCLK_WAVE420L_APB 81
#define JH7110_SYSCLK_NOC_BUS_VENC_AXI 82
#define JH7110_SYSCLK_AXI_CFG0_MAIN_DIV 83
#define JH7110_SYSCLK_AXI_CFG0_MAIN 84
#define JH7110_SYSCLK_AXI_CFG0_HIFI4 85
#define JH7110_SYSCLK_AXIMEM2_AXI 86
#define JH7110_SYSCLK_QSPI_AHB 87
#define JH7110_SYSCLK_QSPI_APB 88
#define JH7110_SYSCLK_QSPI_REF_SRC 89
#define JH7110_SYSCLK_QSPI_REF 90
#define JH7110_SYSCLK_SDIO0_AHB 91
#define JH7110_SYSCLK_SDIO1_AHB 92
#define JH7110_SYSCLK_SDIO0_SDCARD 93
#define JH7110_SYSCLK_SDIO1_SDCARD 94
#define JH7110_SYSCLK_USB_125M 95
#define JH7110_SYSCLK_NOC_BUS_STG_AXI 96
#define JH7110_SYSCLK_GMAC1_AHB 97
#define JH7110_SYSCLK_GMAC1_AXI 98
#define JH7110_SYSCLK_GMAC_SRC 99
#define JH7110_SYSCLK_GMAC1_GTXCLK 100
#define JH7110_SYSCLK_GMAC1_RMII_RTX 101
#define JH7110_SYSCLK_GMAC1_PTP 102
#define JH7110_SYSCLK_GMAC1_RX 103
#define JH7110_SYSCLK_GMAC1_RX_INV 104
#define JH7110_SYSCLK_GMAC1_TX 105
#define JH7110_SYSCLK_GMAC1_TX_INV 106
#define JH7110_SYSCLK_GMAC1_GTXC 107
#define JH7110_SYSCLK_GMAC0_GTXCLK 108
#define JH7110_SYSCLK_GMAC0_PTP 109
#define JH7110_SYSCLK_GMAC_PHY 110
#define JH7110_SYSCLK_GMAC0_GTXC 111
#define JH7110_SYSCLK_IOMUX_APB 112
#define JH7110_SYSCLK_MAILBOX_APB 113
#define JH7110_SYSCLK_INT_CTRL_APB 114
#define JH7110_SYSCLK_CAN0_APB 115
#define JH7110_SYSCLK_CAN0_TIMER 116
#define JH7110_SYSCLK_CAN0_CAN 117
#define JH7110_SYSCLK_CAN1_APB 118
#define JH7110_SYSCLK_CAN1_TIMER 119
#define JH7110_SYSCLK_CAN1_CAN 120
#define JH7110_SYSCLK_PWM_APB 121
#define JH7110_SYSCLK_WDT_APB 122
#define JH7110_SYSCLK_WDT_CORE 123
#define JH7110_SYSCLK_TIMER_APB 124
#define JH7110_SYSCLK_TIMER0 125
#define JH7110_SYSCLK_TIMER1 126
#define JH7110_SYSCLK_TIMER2 127
#define JH7110_SYSCLK_TIMER3 128
#define JH7110_SYSCLK_TEMP_APB 129
#define JH7110_SYSCLK_TEMP_CORE 130
#define JH7110_SYSCLK_SPI0_APB 131
#define JH7110_SYSCLK_SPI1_APB 132
#define JH7110_SYSCLK_SPI2_APB 133
#define JH7110_SYSCLK_SPI3_APB 134
#define JH7110_SYSCLK_SPI4_APB 135
#define JH7110_SYSCLK_SPI5_APB 136
#define JH7110_SYSCLK_SPI6_APB 137
#define JH7110_SYSCLK_I2C0_APB 138
#define JH7110_SYSCLK_I2C1_APB 139
#define JH7110_SYSCLK_I2C2_APB 140
#define JH7110_SYSCLK_I2C3_APB 141
#define JH7110_SYSCLK_I2C4_APB 142
#define JH7110_SYSCLK_I2C5_APB 143
#define JH7110_SYSCLK_I2C6_APB 144
#define JH7110_SYSCLK_UART0_APB 145
#define JH7110_SYSCLK_UART0_CORE 146
#define JH7110_SYSCLK_UART1_APB 147
#define JH7110_SYSCLK_UART1_CORE 148
#define JH7110_SYSCLK_UART2_APB 149
#define JH7110_SYSCLK_UART2_CORE 150
#define JH7110_SYSCLK_UART3_APB 151
#define JH7110_SYSCLK_UART3_CORE 152
#define JH7110_SYSCLK_UART4_APB 153
#define JH7110_SYSCLK_UART4_CORE 154
#define JH7110_SYSCLK_UART5_APB 155
#define JH7110_SYSCLK_UART5_CORE 156
#define JH7110_SYSCLK_PWMDAC_APB 157
#define JH7110_SYSCLK_PWMDAC_CORE 158
#define JH7110_SYSCLK_SPDIF_APB 159
#define JH7110_SYSCLK_SPDIF_CORE 160
#define JH7110_SYSCLK_I2STX0_APB 161
#define JH7110_SYSCLK_I2STX0_BCLK_MST 162
#define JH7110_SYSCLK_I2STX0_BCLK_MST_INV 163
#define JH7110_SYSCLK_I2STX0_LRCK_MST 164
#define JH7110_SYSCLK_I2STX0_BCLK 165
#define JH7110_SYSCLK_I2STX0_BCLK_INV 166
#define JH7110_SYSCLK_I2STX0_LRCK 167
#define JH7110_SYSCLK_I2STX1_APB 168
#define JH7110_SYSCLK_I2STX1_BCLK_MST 169
#define JH7110_SYSCLK_I2STX1_BCLK_MST_INV 170
#define JH7110_SYSCLK_I2STX1_LRCK_MST 171
#define JH7110_SYSCLK_I2STX1_BCLK 172
#define JH7110_SYSCLK_I2STX1_BCLK_INV 173
#define JH7110_SYSCLK_I2STX1_LRCK 174
#define JH7110_SYSCLK_I2SRX_APB 175
#define JH7110_SYSCLK_I2SRX_BCLK_MST 176
#define JH7110_SYSCLK_I2SRX_BCLK_MST_INV 177
#define JH7110_SYSCLK_I2SRX_LRCK_MST 178
#define JH7110_SYSCLK_I2SRX_BCLK 179
#define JH7110_SYSCLK_I2SRX_BCLK_INV 180
#define JH7110_SYSCLK_I2SRX_LRCK 181
#define JH7110_SYSCLK_PDM_DMIC 182
#define JH7110_SYSCLK_PDM_APB 183
#define JH7110_SYSCLK_TDM_AHB 184
#define JH7110_SYSCLK_TDM_APB 185
#define JH7110_SYSCLK_TDM_INTERNAL 186
#define JH7110_SYSCLK_TDM_TDM 187
#define JH7110_SYSCLK_TDM_TDM_INV 188
#define JH7110_SYSCLK_JTAG_CERTIFICATION_TRNG 189
#define JH7110_SYSCLK_END 190
/* AONCRG clocks */
#define JH7110_AONCLK_OSC_DIV4 0
#define JH7110_AONCLK_APB_FUNC 1
#define JH7110_AONCLK_GMAC0_AHB 2
#define JH7110_AONCLK_GMAC0_AXI 3
#define JH7110_AONCLK_GMAC0_RMII_RTX 4
#define JH7110_AONCLK_GMAC0_TX 5
#define JH7110_AONCLK_GMAC0_TX_INV 6
#define JH7110_AONCLK_GMAC0_RX 7
#define JH7110_AONCLK_GMAC0_RX_INV 8
#define JH7110_AONCLK_OTPC_APB 9
#define JH7110_AONCLK_RTC_APB 10
#define JH7110_AONCLK_RTC_INTERNAL 11
#define JH7110_AONCLK_RTC_32K 12
#define JH7110_AONCLK_RTC_CAL 13
#define JH7110_AONCLK_END 14
#endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__ */
/* SPDX-License-Identifier: GPL-2.0 OR MIT */
/*
* Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
*/
#ifndef __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__
#define __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__
/* SYSCRG resets */
#define JH7110_SYSRST_JTAG_APB 0
#define JH7110_SYSRST_SYSCON_APB 1
#define JH7110_SYSRST_IOMUX_APB 2
#define JH7110_SYSRST_BUS 3
#define JH7110_SYSRST_DEBUG 4
#define JH7110_SYSRST_CORE0 5
#define JH7110_SYSRST_CORE1 6
#define JH7110_SYSRST_CORE2 7
#define JH7110_SYSRST_CORE3 8
#define JH7110_SYSRST_CORE4 9
#define JH7110_SYSRST_CORE0_ST 10
#define JH7110_SYSRST_CORE1_ST 11
#define JH7110_SYSRST_CORE2_ST 12
#define JH7110_SYSRST_CORE3_ST 13
#define JH7110_SYSRST_CORE4_ST 14
#define JH7110_SYSRST_TRACE0 15
#define JH7110_SYSRST_TRACE1 16
#define JH7110_SYSRST_TRACE2 17
#define JH7110_SYSRST_TRACE3 18
#define JH7110_SYSRST_TRACE4 19
#define JH7110_SYSRST_TRACE_COM 20
#define JH7110_SYSRST_GPU_APB 21
#define JH7110_SYSRST_GPU_DOMA 22
#define JH7110_SYSRST_NOC_BUS_APB 23
#define JH7110_SYSRST_NOC_BUS_AXICFG0_AXI 24
#define JH7110_SYSRST_NOC_BUS_CPU_AXI 25
#define JH7110_SYSRST_NOC_BUS_DISP_AXI 26
#define JH7110_SYSRST_NOC_BUS_GPU_AXI 27
#define JH7110_SYSRST_NOC_BUS_ISP_AXI 28
#define JH7110_SYSRST_NOC_BUS_DDRC 29
#define JH7110_SYSRST_NOC_BUS_STG_AXI 30
#define JH7110_SYSRST_NOC_BUS_VDEC_AXI 31
#define JH7110_SYSRST_NOC_BUS_VENC_AXI 32
#define JH7110_SYSRST_AXI_CFG1_AHB 33
#define JH7110_SYSRST_AXI_CFG1_MAIN 34
#define JH7110_SYSRST_AXI_CFG0_MAIN 35
#define JH7110_SYSRST_AXI_CFG0_MAIN_DIV 36
#define JH7110_SYSRST_AXI_CFG0_HIFI4 37
#define JH7110_SYSRST_DDR_AXI 38
#define JH7110_SYSRST_DDR_OSC 39
#define JH7110_SYSRST_DDR_APB 40
#define JH7110_SYSRST_ISP_TOP 41
#define JH7110_SYSRST_ISP_TOP_AXI 42
#define JH7110_SYSRST_VOUT_TOP_SRC 43
#define JH7110_SYSRST_CODAJ12_AXI 44
#define JH7110_SYSRST_CODAJ12_CORE 45
#define JH7110_SYSRST_CODAJ12_APB 46
#define JH7110_SYSRST_WAVE511_AXI 47
#define JH7110_SYSRST_WAVE511_BPU 48
#define JH7110_SYSRST_WAVE511_VCE 49
#define JH7110_SYSRST_WAVE511_APB 50
#define JH7110_SYSRST_VDEC_JPG 51
#define JH7110_SYSRST_VDEC_MAIN 52
#define JH7110_SYSRST_AXIMEM0_AXI 53
#define JH7110_SYSRST_WAVE420L_AXI 54
#define JH7110_SYSRST_WAVE420L_BPU 55
#define JH7110_SYSRST_WAVE420L_VCE 56
#define JH7110_SYSRST_WAVE420L_APB 57
#define JH7110_SYSRST_AXIMEM1_AXI 58
#define JH7110_SYSRST_AXIMEM2_AXI 59
#define JH7110_SYSRST_INTMEM 60
#define JH7110_SYSRST_QSPI_AHB 61
#define JH7110_SYSRST_QSPI_APB 62
#define JH7110_SYSRST_QSPI_REF 63
#define JH7110_SYSRST_SDIO0_AHB 64
#define JH7110_SYSRST_SDIO1_AHB 65
#define JH7110_SYSRST_GMAC1_AXI 66
#define JH7110_SYSRST_GMAC1_AHB 67
#define JH7110_SYSRST_MAILBOX_APB 68
#define JH7110_SYSRST_SPI0_APB 69
#define JH7110_SYSRST_SPI1_APB 70
#define JH7110_SYSRST_SPI2_APB 71
#define JH7110_SYSRST_SPI3_APB 72
#define JH7110_SYSRST_SPI4_APB 73
#define JH7110_SYSRST_SPI5_APB 74
#define JH7110_SYSRST_SPI6_APB 75
#define JH7110_SYSRST_I2C0_APB 76
#define JH7110_SYSRST_I2C1_APB 77
#define JH7110_SYSRST_I2C2_APB 78
#define JH7110_SYSRST_I2C3_APB 79
#define JH7110_SYSRST_I2C4_APB 80
#define JH7110_SYSRST_I2C5_APB 81
#define JH7110_SYSRST_I2C6_APB 82
#define JH7110_SYSRST_UART0_APB 83
#define JH7110_SYSRST_UART0_CORE 84
#define JH7110_SYSRST_UART1_APB 85
#define JH7110_SYSRST_UART1_CORE 86
#define JH7110_SYSRST_UART2_APB 87
#define JH7110_SYSRST_UART2_CORE 88
#define JH7110_SYSRST_UART3_APB 89
#define JH7110_SYSRST_UART3_CORE 90
#define JH7110_SYSRST_UART4_APB 91
#define JH7110_SYSRST_UART4_CORE 92
#define JH7110_SYSRST_UART5_APB 93
#define JH7110_SYSRST_UART5_CORE 94
#define JH7110_SYSRST_SPDIF_APB 95
#define JH7110_SYSRST_PWMDAC_APB 96
#define JH7110_SYSRST_PDM_DMIC 97
#define JH7110_SYSRST_PDM_APB 98
#define JH7110_SYSRST_I2SRX_APB 99
#define JH7110_SYSRST_I2SRX_BCLK 100
#define JH7110_SYSRST_I2STX0_APB 101
#define JH7110_SYSRST_I2STX0_BCLK 102
#define JH7110_SYSRST_I2STX1_APB 103
#define JH7110_SYSRST_I2STX1_BCLK 104
#define JH7110_SYSRST_TDM_AHB 105
#define JH7110_SYSRST_TDM_CORE 106
#define JH7110_SYSRST_TDM_APB 107
#define JH7110_SYSRST_PWM_APB 108
#define JH7110_SYSRST_WDT_APB 109
#define JH7110_SYSRST_WDT_CORE 110
#define JH7110_SYSRST_CAN0_APB 111
#define JH7110_SYSRST_CAN0_CORE 112
#define JH7110_SYSRST_CAN0_TIMER 113
#define JH7110_SYSRST_CAN1_APB 114
#define JH7110_SYSRST_CAN1_CORE 115
#define JH7110_SYSRST_CAN1_TIMER 116
#define JH7110_SYSRST_TIMER_APB 117
#define JH7110_SYSRST_TIMER0 118
#define JH7110_SYSRST_TIMER1 119
#define JH7110_SYSRST_TIMER2 120
#define JH7110_SYSRST_TIMER3 121
#define JH7110_SYSRST_INT_CTRL_APB 122
#define JH7110_SYSRST_TEMP_APB 123
#define JH7110_SYSRST_TEMP_CORE 124
#define JH7110_SYSRST_JTAG_CERTIFICATION 125
#define JH7110_SYSRST_END 126
/* AONCRG resets */
#define JH7110_AONRST_GMAC0_AXI 0
#define JH7110_AONRST_GMAC0_AHB 1
#define JH7110_AONRST_IOMUX 2
#define JH7110_AONRST_PMU_APB 3
#define JH7110_AONRST_PMU_WKUP 4
#define JH7110_AONRST_RTC_APB 5
#define JH7110_AONRST_RTC_CAL 6
#define JH7110_AONRST_RTC_32K 7
#define JH7110_AONRST_END 8
#endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__ */
......@@ -1154,10 +1154,8 @@ struct clk_fractional_divider {
void __iomem *reg;
u8 mshift;
u8 mwidth;
u32 mmask;
u8 nshift;
u8 nwidth;
u32 nmask;
u8 flags;
void (*approximation)(struct clk_hw *hw,
unsigned long rate, unsigned long *parent_rate,
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __SOC_STARFIVE_RESET_JH71X0_H
#define __SOC_STARFIVE_RESET_JH71X0_H
#include <linux/auxiliary_bus.h>
#include <linux/compiler_types.h>
#include <linux/container_of.h>
struct jh71x0_reset_adev {
void __iomem *base;
struct auxiliary_device adev;
};
#define to_jh71x0_reset_adev(_adev) \
container_of((_adev), struct jh71x0_reset_adev, adev)
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment