mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 18:13:41 +02:00
clk: renesas: Updates for v6.13 (take two)
- Add RTC power domain and Battery Backup Function (VBATTB) clock
support for the RZ/G3S SoC,
- Add the devm_clk_hw_register_gate_parent_hw() helper,
- Miscellaneous fixes and improvements.
-----BEGIN PGP SIGNATURE-----
iHUEABYIAB0WIQQ9qaHoIs/1I4cXmEiKwlD9ZEnxcAUCZysgwAAKCRCKwlD9ZEnx
cF0AAP9mV/Dl4xB2+FZ5W82/9Ei2sWBlUyHCZDrhMjtrUA58LQEA0D/bAUL0lLTV
Z/drm4xYTOKxm4QReFxzJbd7gNTRXwA=
=M/H8
-----END PGP SIGNATURE-----
Merge tag 'renesas-clk-for-v6.13-tag2' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers into clk-renesas
Pull more Renesas clk driver updates from Geert Uytterhoeven:
- Add RTC power domain and Battery Backup Function (VBATTB) clock
support for the Renesas RZ/G3S SoC
- Add the devm_clk_hw_register_gate_parent_hw() helper
* tag 'renesas-clk-for-v6.13-tag2' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers:
clk: renesas: vbattb: Add VBATTB clock driver
clk: Add devm_clk_hw_register_gate_parent_hw()
clk: renesas: rzg2l: Fix FOUTPOSTDIV clk
dt-bindings: clock: renesas,r9a08g045-vbattb: Document VBATTB
clk: renesas: r9a08g045: Add power domain for RTC
clk: renesas: r9a08g045: Mark the watchdog and always-on PM domains as IRQ safe
clk: renesas: rzg2l-cpg: Use GENPD_FLAG_* flags instead of local ones
clk: renesas: rzg2l-cpg: Move PM domain power on in rzg2l_cpg_pd_setup()
dt-bindings: clock: r9a08g045-cpg: Add power domain ID for RTC
This commit is contained in:
commit
0c159634c9
|
|
@ -0,0 +1,84 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/renesas,r9a08g045-vbattb.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Renesas Battery Backup Function (VBATTB)
|
||||
|
||||
description:
|
||||
Renesas VBATTB is an always on powered module (backed by battery) which
|
||||
controls the RTC clock (VBATTCLK), tamper detection logic and a small
|
||||
general usage memory (128B).
|
||||
|
||||
maintainers:
|
||||
- Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: renesas,r9a08g045-vbattb
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
- description: tamper detector interrupt
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: VBATTB module clock
|
||||
- description: RTC input clock (crystal or external clock device)
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: bclk
|
||||
- const: rtx
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: VBATTB module reset
|
||||
|
||||
quartz-load-femtofarads:
|
||||
description: load capacitance of the on board crystal
|
||||
enum: [ 4000, 7000, 9000, 12500 ]
|
||||
default: 4000
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- '#clock-cells'
|
||||
- power-domains
|
||||
- resets
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/r9a08g045-cpg.h>
|
||||
#include <dt-bindings/clock/renesas,r9a08g045-vbattb.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
clock-controller@1005c000 {
|
||||
compatible = "renesas,r9a08g045-vbattb";
|
||||
reg = <0x1005c000 0x1000>;
|
||||
interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cpg CPG_MOD R9A08G045_VBAT_BCLK>, <&vbattb_xtal>;
|
||||
clock-names = "bclk", "rtx";
|
||||
assigned-clocks = <&vbattb VBATTB_MUX>;
|
||||
assigned-clock-parents = <&vbattb VBATTB_XC>;
|
||||
#clock-cells = <1>;
|
||||
power-domains = <&cpg>;
|
||||
resets = <&cpg R9A08G045_VBAT_BRESETN>;
|
||||
quartz-load-femtofarads = <12500>;
|
||||
};
|
||||
|
|
@ -237,6 +237,11 @@ config CLK_RZV2H
|
|||
bool "RZ/V2H(P) family clock support" if COMPILE_TEST
|
||||
select RESET_CONTROLLER
|
||||
|
||||
config CLK_RENESAS_VBATTB
|
||||
tristate "Renesas VBATTB clock controller"
|
||||
depends on ARCH_RZG2L || COMPILE_TEST
|
||||
select RESET_CONTROLLER
|
||||
|
||||
# Generic
|
||||
config CLK_RENESAS_CPG_MSSR
|
||||
bool "CPG/MSSR clock support" if COMPILE_TEST
|
||||
|
|
|
|||
|
|
@ -53,3 +53,4 @@ obj-$(CONFIG_CLK_RZV2H) += rzv2h-cpg.o
|
|||
obj-$(CONFIG_CLK_RENESAS_CPG_MSSR) += renesas-cpg-mssr.o
|
||||
obj-$(CONFIG_CLK_RENESAS_CPG_MSTP) += clk-mstp.o
|
||||
obj-$(CONFIG_CLK_RENESAS_DIV6) += clk-div6.o
|
||||
obj-$(CONFIG_CLK_RENESAS_VBATTB) += clk-vbattb.o
|
||||
|
|
|
|||
205
drivers/clk/renesas/clk-vbattb.c
Normal file
205
drivers/clk/renesas/clk-vbattb.c
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* VBATTB clock driver
|
||||
*
|
||||
* Copyright (C) 2024 Renesas Electronics Corp.
|
||||
*/
|
||||
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/reset.h>
|
||||
|
||||
#include <dt-bindings/clock/renesas,r9a08g045-vbattb.h>
|
||||
|
||||
#define VBATTB_BKSCCR 0x1c
|
||||
#define VBATTB_BKSCCR_SOSEL 6
|
||||
#define VBATTB_SOSCCR2 0x24
|
||||
#define VBATTB_SOSCCR2_SOSTP2 0
|
||||
#define VBATTB_XOSCCR 0x30
|
||||
#define VBATTB_XOSCCR_OUTEN 16
|
||||
#define VBATTB_XOSCCR_XSEL GENMASK(1, 0)
|
||||
#define VBATTB_XOSCCR_XSEL_4_PF 0x0
|
||||
#define VBATTB_XOSCCR_XSEL_7_PF 0x1
|
||||
#define VBATTB_XOSCCR_XSEL_9_PF 0x2
|
||||
#define VBATTB_XOSCCR_XSEL_12_5_PF 0x3
|
||||
|
||||
/**
|
||||
* struct vbattb_clk - VBATTB clock data structure
|
||||
* @base: base address
|
||||
* @lock: lock
|
||||
*/
|
||||
struct vbattb_clk {
|
||||
void __iomem *base;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
static int vbattb_clk_validate_load_capacitance(u32 *reg_lc, u32 of_lc)
|
||||
{
|
||||
switch (of_lc) {
|
||||
case 4000:
|
||||
*reg_lc = VBATTB_XOSCCR_XSEL_4_PF;
|
||||
break;
|
||||
case 7000:
|
||||
*reg_lc = VBATTB_XOSCCR_XSEL_7_PF;
|
||||
break;
|
||||
case 9000:
|
||||
*reg_lc = VBATTB_XOSCCR_XSEL_9_PF;
|
||||
break;
|
||||
case 12500:
|
||||
*reg_lc = VBATTB_XOSCCR_XSEL_12_5_PF;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vbattb_clk_action(void *data)
|
||||
{
|
||||
struct device *dev = data;
|
||||
struct reset_control *rstc = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = reset_control_assert(rstc);
|
||||
if (ret)
|
||||
dev_err(dev, "Failed to de-assert reset!");
|
||||
|
||||
ret = pm_runtime_put_sync(dev);
|
||||
if (ret < 0)
|
||||
dev_err(dev, "Failed to runtime suspend!");
|
||||
|
||||
of_clk_del_provider(dev->of_node);
|
||||
}
|
||||
|
||||
static int vbattb_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct clk_parent_data parent_data = {};
|
||||
struct clk_hw_onecell_data *clk_data;
|
||||
const struct clk_hw *parent_hws[2];
|
||||
struct device *dev = &pdev->dev;
|
||||
struct reset_control *rstc;
|
||||
struct vbattb_clk *vbclk;
|
||||
u32 of_lc, reg_lc;
|
||||
struct clk_hw *hw;
|
||||
/* 4 clocks are exported: VBATTB_XC, VBATTB_XBYP, VBATTB_MUX, VBATTB_VBATTCLK. */
|
||||
u8 num_clks = 4;
|
||||
int ret;
|
||||
|
||||
/* Default to 4pF as this is not needed if external clock device is connected. */
|
||||
of_lc = 4000;
|
||||
of_property_read_u32(np, "quartz-load-femtofarads", &of_lc);
|
||||
|
||||
ret = vbattb_clk_validate_load_capacitance(®_lc, of_lc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
vbclk = devm_kzalloc(dev, sizeof(*vbclk), GFP_KERNEL);
|
||||
if (!vbclk)
|
||||
return -ENOMEM;
|
||||
|
||||
clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, num_clks), GFP_KERNEL);
|
||||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
clk_data->num = num_clks;
|
||||
|
||||
vbclk->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(vbclk->base))
|
||||
return PTR_ERR(vbclk->base);
|
||||
|
||||
ret = devm_pm_runtime_enable(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
rstc = devm_reset_control_get_shared(dev, NULL);
|
||||
if (IS_ERR(rstc))
|
||||
return PTR_ERR(rstc);
|
||||
|
||||
ret = pm_runtime_resume_and_get(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = reset_control_deassert(rstc);
|
||||
if (ret) {
|
||||
pm_runtime_put_sync(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_set_drvdata(dev, rstc);
|
||||
ret = devm_add_action_or_reset(dev, vbattb_clk_action, dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
spin_lock_init(&vbclk->lock);
|
||||
|
||||
parent_data.fw_name = "rtx";
|
||||
hw = devm_clk_hw_register_gate_parent_data(dev, "xc", &parent_data, 0,
|
||||
vbclk->base + VBATTB_SOSCCR2,
|
||||
VBATTB_SOSCCR2_SOSTP2,
|
||||
CLK_GATE_SET_TO_DISABLE, &vbclk->lock);
|
||||
if (IS_ERR(hw))
|
||||
return PTR_ERR(hw);
|
||||
clk_data->hws[VBATTB_XC] = hw;
|
||||
|
||||
hw = devm_clk_hw_register_fixed_factor_fwname(dev, np, "xbyp", "rtx", 0, 1, 1);
|
||||
if (IS_ERR(hw))
|
||||
return PTR_ERR(hw);
|
||||
clk_data->hws[VBATTB_XBYP] = hw;
|
||||
|
||||
parent_hws[0] = clk_data->hws[VBATTB_XC];
|
||||
parent_hws[1] = clk_data->hws[VBATTB_XBYP];
|
||||
hw = devm_clk_hw_register_mux_parent_hws(dev, "mux", parent_hws, 2, 0,
|
||||
vbclk->base + VBATTB_BKSCCR,
|
||||
VBATTB_BKSCCR_SOSEL,
|
||||
1, 0, &vbclk->lock);
|
||||
if (IS_ERR(hw))
|
||||
return PTR_ERR(hw);
|
||||
clk_data->hws[VBATTB_MUX] = hw;
|
||||
|
||||
/* Set load capacitance before registering the VBATTCLK clock. */
|
||||
scoped_guard(spinlock, &vbclk->lock) {
|
||||
u32 val = readl_relaxed(vbclk->base + VBATTB_XOSCCR);
|
||||
|
||||
val &= ~VBATTB_XOSCCR_XSEL;
|
||||
val |= reg_lc;
|
||||
writel_relaxed(val, vbclk->base + VBATTB_XOSCCR);
|
||||
}
|
||||
|
||||
/* This feeds the RTC counter clock and it needs to stay on. */
|
||||
hw = devm_clk_hw_register_gate_parent_hw(dev, "vbattclk", hw, CLK_IS_CRITICAL,
|
||||
vbclk->base + VBATTB_XOSCCR,
|
||||
VBATTB_XOSCCR_OUTEN, 0,
|
||||
&vbclk->lock);
|
||||
|
||||
if (IS_ERR(hw))
|
||||
return PTR_ERR(hw);
|
||||
clk_data->hws[VBATTB_VBATTCLK] = hw;
|
||||
|
||||
return of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
|
||||
}
|
||||
|
||||
static const struct of_device_id vbattb_clk_match[] = {
|
||||
{ .compatible = "renesas,r9a08g045-vbattb" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, vbattb_clk_match);
|
||||
|
||||
static struct platform_driver vbattb_clk_driver = {
|
||||
.driver = {
|
||||
.name = "renesas-vbattb-clk",
|
||||
.of_match_table = vbattb_clk_match,
|
||||
},
|
||||
.probe = vbattb_clk_probe,
|
||||
};
|
||||
module_platform_driver(vbattb_clk_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Renesas VBATTB Clock Driver");
|
||||
MODULE_AUTHOR("Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -9,6 +9,7 @@
|
|||
#include <linux/device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/pm_domain.h>
|
||||
|
||||
#include <dt-bindings/clock/r9a08g045-cpg.h>
|
||||
|
||||
|
|
@ -266,61 +267,50 @@ static const struct rzg2l_cpg_pm_domain_init_data r9a08g045_pm_domains[] = {
|
|||
/* Keep always-on domain on the first position for proper domains registration. */
|
||||
DEF_PD("always-on", R9A08G045_PD_ALWAYS_ON,
|
||||
DEF_REG_CONF(0, 0),
|
||||
RZG2L_PD_F_ALWAYS_ON),
|
||||
GENPD_FLAG_ALWAYS_ON | GENPD_FLAG_IRQ_SAFE),
|
||||
DEF_PD("gic", R9A08G045_PD_GIC,
|
||||
DEF_REG_CONF(CPG_BUS_ACPU_MSTOP, BIT(3)),
|
||||
RZG2L_PD_F_ALWAYS_ON),
|
||||
GENPD_FLAG_ALWAYS_ON),
|
||||
DEF_PD("ia55", R9A08G045_PD_IA55,
|
||||
DEF_REG_CONF(CPG_BUS_PERI_CPU_MSTOP, BIT(13)),
|
||||
RZG2L_PD_F_ALWAYS_ON),
|
||||
GENPD_FLAG_ALWAYS_ON),
|
||||
DEF_PD("dmac", R9A08G045_PD_DMAC,
|
||||
DEF_REG_CONF(CPG_BUS_REG1_MSTOP, GENMASK(3, 0)),
|
||||
RZG2L_PD_F_ALWAYS_ON),
|
||||
GENPD_FLAG_ALWAYS_ON),
|
||||
DEF_PD("wdt0", R9A08G045_PD_WDT0,
|
||||
DEF_REG_CONF(CPG_BUS_REG0_MSTOP, BIT(0)),
|
||||
RZG2L_PD_F_NONE),
|
||||
GENPD_FLAG_IRQ_SAFE),
|
||||
DEF_PD("sdhi0", R9A08G045_PD_SDHI0,
|
||||
DEF_REG_CONF(CPG_BUS_PERI_COM_MSTOP, BIT(0)),
|
||||
RZG2L_PD_F_NONE),
|
||||
DEF_REG_CONF(CPG_BUS_PERI_COM_MSTOP, BIT(0)), 0),
|
||||
DEF_PD("sdhi1", R9A08G045_PD_SDHI1,
|
||||
DEF_REG_CONF(CPG_BUS_PERI_COM_MSTOP, BIT(1)),
|
||||
RZG2L_PD_F_NONE),
|
||||
DEF_REG_CONF(CPG_BUS_PERI_COM_MSTOP, BIT(1)), 0),
|
||||
DEF_PD("sdhi2", R9A08G045_PD_SDHI2,
|
||||
DEF_REG_CONF(CPG_BUS_PERI_COM_MSTOP, BIT(11)),
|
||||
RZG2L_PD_F_NONE),
|
||||
DEF_REG_CONF(CPG_BUS_PERI_COM_MSTOP, BIT(11)), 0),
|
||||
DEF_PD("usb0", R9A08G045_PD_USB0,
|
||||
DEF_REG_CONF(CPG_BUS_PERI_COM_MSTOP, GENMASK(6, 5)),
|
||||
RZG2L_PD_F_NONE),
|
||||
DEF_REG_CONF(CPG_BUS_PERI_COM_MSTOP, GENMASK(6, 5)), 0),
|
||||
DEF_PD("usb1", R9A08G045_PD_USB1,
|
||||
DEF_REG_CONF(CPG_BUS_PERI_COM_MSTOP, BIT(7)),
|
||||
RZG2L_PD_F_NONE),
|
||||
DEF_REG_CONF(CPG_BUS_PERI_COM_MSTOP, BIT(7)), 0),
|
||||
DEF_PD("usb-phy", R9A08G045_PD_USB_PHY,
|
||||
DEF_REG_CONF(CPG_BUS_PERI_COM_MSTOP, BIT(4)),
|
||||
RZG2L_PD_F_NONE),
|
||||
DEF_REG_CONF(CPG_BUS_PERI_COM_MSTOP, BIT(4)), 0),
|
||||
DEF_PD("eth0", R9A08G045_PD_ETHER0,
|
||||
DEF_REG_CONF(CPG_BUS_PERI_COM_MSTOP, BIT(2)),
|
||||
RZG2L_PD_F_NONE),
|
||||
DEF_REG_CONF(CPG_BUS_PERI_COM_MSTOP, BIT(2)), 0),
|
||||
DEF_PD("eth1", R9A08G045_PD_ETHER1,
|
||||
DEF_REG_CONF(CPG_BUS_PERI_COM_MSTOP, BIT(3)),
|
||||
RZG2L_PD_F_NONE),
|
||||
DEF_REG_CONF(CPG_BUS_PERI_COM_MSTOP, BIT(3)), 0),
|
||||
DEF_PD("i2c0", R9A08G045_PD_I2C0,
|
||||
DEF_REG_CONF(CPG_BUS_MCPU2_MSTOP, BIT(10)),
|
||||
RZG2L_PD_F_NONE),
|
||||
DEF_REG_CONF(CPG_BUS_MCPU2_MSTOP, BIT(10)), 0),
|
||||
DEF_PD("i2c1", R9A08G045_PD_I2C1,
|
||||
DEF_REG_CONF(CPG_BUS_MCPU2_MSTOP, BIT(11)),
|
||||
RZG2L_PD_F_NONE),
|
||||
DEF_REG_CONF(CPG_BUS_MCPU2_MSTOP, BIT(11)), 0),
|
||||
DEF_PD("i2c2", R9A08G045_PD_I2C2,
|
||||
DEF_REG_CONF(CPG_BUS_MCPU2_MSTOP, BIT(12)),
|
||||
RZG2L_PD_F_NONE),
|
||||
DEF_REG_CONF(CPG_BUS_MCPU2_MSTOP, BIT(12)), 0),
|
||||
DEF_PD("i2c3", R9A08G045_PD_I2C3,
|
||||
DEF_REG_CONF(CPG_BUS_MCPU2_MSTOP, BIT(13)),
|
||||
RZG2L_PD_F_NONE),
|
||||
DEF_REG_CONF(CPG_BUS_MCPU2_MSTOP, BIT(13)), 0),
|
||||
DEF_PD("scif0", R9A08G045_PD_SCIF0,
|
||||
DEF_REG_CONF(CPG_BUS_MCPU2_MSTOP, BIT(1)),
|
||||
RZG2L_PD_F_NONE),
|
||||
DEF_REG_CONF(CPG_BUS_MCPU2_MSTOP, BIT(1)), 0),
|
||||
DEF_PD("vbat", R9A08G045_PD_VBAT,
|
||||
DEF_REG_CONF(CPG_BUS_MCPU3_MSTOP, BIT(8)),
|
||||
RZG2L_PD_F_ALWAYS_ON),
|
||||
GENPD_FLAG_ALWAYS_ON),
|
||||
DEF_PD("rtc", R9A08G045_PD_RTC,
|
||||
DEF_REG_CONF(CPG_BUS_MCPU3_MSTOP, BIT(7)), 0),
|
||||
};
|
||||
|
||||
const struct rzg2l_cpg_info r9a08g045_cpg_info = {
|
||||
|
|
|
|||
|
|
@ -548,7 +548,7 @@ static unsigned long
|
|||
rzg2l_cpg_get_foutpostdiv_rate(struct rzg2l_pll5_param *params,
|
||||
unsigned long rate)
|
||||
{
|
||||
unsigned long foutpostdiv_rate;
|
||||
unsigned long foutpostdiv_rate, foutvco_rate;
|
||||
|
||||
params->pl5_intin = rate / MEGA;
|
||||
params->pl5_fracin = div_u64(((u64)rate % MEGA) << 24, MEGA);
|
||||
|
|
@ -557,10 +557,11 @@ rzg2l_cpg_get_foutpostdiv_rate(struct rzg2l_pll5_param *params,
|
|||
params->pl5_postdiv2 = 1;
|
||||
params->pl5_spread = 0x16;
|
||||
|
||||
foutpostdiv_rate =
|
||||
EXTAL_FREQ_IN_MEGA_HZ * MEGA / params->pl5_refdiv *
|
||||
((((params->pl5_intin << 24) + params->pl5_fracin)) >> 24) /
|
||||
(params->pl5_postdiv1 * params->pl5_postdiv2);
|
||||
foutvco_rate = div_u64(mul_u32_u32(EXTAL_FREQ_IN_MEGA_HZ * MEGA,
|
||||
(params->pl5_intin << 24) + params->pl5_fracin),
|
||||
params->pl5_refdiv) >> 24;
|
||||
foutpostdiv_rate = DIV_ROUND_CLOSEST_ULL(foutvco_rate,
|
||||
params->pl5_postdiv1 * params->pl5_postdiv2);
|
||||
|
||||
return foutpostdiv_rate;
|
||||
}
|
||||
|
|
@ -1680,23 +1681,31 @@ static int rzg2l_cpg_power_off(struct generic_pm_domain *domain)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __init rzg2l_cpg_pd_setup(struct rzg2l_cpg_pd *pd, bool always_on)
|
||||
static int __init rzg2l_cpg_pd_setup(struct rzg2l_cpg_pd *pd)
|
||||
{
|
||||
bool always_on = !!(pd->genpd.flags & GENPD_FLAG_ALWAYS_ON);
|
||||
struct dev_power_governor *governor;
|
||||
int ret;
|
||||
|
||||
if (always_on)
|
||||
governor = &pm_domain_always_on_gov;
|
||||
else
|
||||
governor = &simple_qos_governor;
|
||||
|
||||
pd->genpd.flags |= GENPD_FLAG_PM_CLK | GENPD_FLAG_ACTIVE_WAKEUP;
|
||||
pd->genpd.attach_dev = rzg2l_cpg_attach_dev;
|
||||
pd->genpd.detach_dev = rzg2l_cpg_detach_dev;
|
||||
if (always_on) {
|
||||
pd->genpd.flags |= GENPD_FLAG_ALWAYS_ON;
|
||||
governor = &pm_domain_always_on_gov;
|
||||
} else {
|
||||
pd->genpd.power_on = rzg2l_cpg_power_on;
|
||||
pd->genpd.power_off = rzg2l_cpg_power_off;
|
||||
governor = &simple_qos_governor;
|
||||
}
|
||||
pd->genpd.power_on = rzg2l_cpg_power_on;
|
||||
pd->genpd.power_off = rzg2l_cpg_power_off;
|
||||
|
||||
return pm_genpd_init(&pd->genpd, governor, !always_on);
|
||||
ret = pm_genpd_init(&pd->genpd, governor, !always_on);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (always_on)
|
||||
ret = rzg2l_cpg_power_on(&pd->genpd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __init rzg2l_cpg_add_clk_domain(struct rzg2l_cpg_priv *priv)
|
||||
|
|
@ -1711,8 +1720,9 @@ static int __init rzg2l_cpg_add_clk_domain(struct rzg2l_cpg_priv *priv)
|
|||
return -ENOMEM;
|
||||
|
||||
pd->genpd.name = np->name;
|
||||
pd->genpd.flags = GENPD_FLAG_ALWAYS_ON;
|
||||
pd->priv = priv;
|
||||
ret = rzg2l_cpg_pd_setup(pd, true);
|
||||
ret = rzg2l_cpg_pd_setup(pd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -1777,7 +1787,6 @@ static int __init rzg2l_cpg_add_pm_domains(struct rzg2l_cpg_priv *priv)
|
|||
return ret;
|
||||
|
||||
for (unsigned int i = 0; i < info->num_pm_domains; i++) {
|
||||
bool always_on = !!(info->pm_domains[i].flags & RZG2L_PD_F_ALWAYS_ON);
|
||||
struct rzg2l_cpg_pd *pd;
|
||||
|
||||
pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
|
||||
|
|
@ -1785,20 +1794,15 @@ static int __init rzg2l_cpg_add_pm_domains(struct rzg2l_cpg_priv *priv)
|
|||
return -ENOMEM;
|
||||
|
||||
pd->genpd.name = info->pm_domains[i].name;
|
||||
pd->genpd.flags = info->pm_domains[i].genpd_flags;
|
||||
pd->conf = info->pm_domains[i].conf;
|
||||
pd->id = info->pm_domains[i].id;
|
||||
pd->priv = priv;
|
||||
|
||||
ret = rzg2l_cpg_pd_setup(pd, always_on);
|
||||
ret = rzg2l_cpg_pd_setup(pd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (always_on) {
|
||||
ret = rzg2l_cpg_power_on(&pd->genpd);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
domains->domains[i] = &pd->genpd;
|
||||
/* Parent should be on the very first entry of info->pm_domains[]. */
|
||||
if (!i) {
|
||||
|
|
|
|||
|
|
@ -270,14 +270,14 @@ struct rzg2l_cpg_pm_domain_conf {
|
|||
* struct rzg2l_cpg_pm_domain_init_data - PM domain init data
|
||||
* @name: PM domain name
|
||||
* @conf: PM domain configuration
|
||||
* @flags: RZG2L PM domain flags (see RZG2L_PD_F_*)
|
||||
* @genpd_flags: genpd flags (see GENPD_FLAG_*)
|
||||
* @id: PM domain ID (similar to the ones defined in
|
||||
* include/dt-bindings/clock/<soc-id>-cpg.h)
|
||||
*/
|
||||
struct rzg2l_cpg_pm_domain_init_data {
|
||||
const char * const name;
|
||||
struct rzg2l_cpg_pm_domain_conf conf;
|
||||
u32 flags;
|
||||
u32 genpd_flags;
|
||||
u16 id;
|
||||
};
|
||||
|
||||
|
|
@ -288,13 +288,9 @@ struct rzg2l_cpg_pm_domain_init_data {
|
|||
.conf = { \
|
||||
.mstop = (_mstop_conf), \
|
||||
}, \
|
||||
.flags = (_flags), \
|
||||
.genpd_flags = (_flags), \
|
||||
}
|
||||
|
||||
/* Power domain flags. */
|
||||
#define RZG2L_PD_F_ALWAYS_ON BIT(0)
|
||||
#define RZG2L_PD_F_NONE (0)
|
||||
|
||||
/**
|
||||
* struct rzg2l_cpg_info - SoC-specific CPG Description
|
||||
*
|
||||
|
|
|
|||
|
|
@ -308,5 +308,6 @@
|
|||
#define R9A08G045_PD_DDR 64
|
||||
#define R9A08G045_PD_TZCDDR 65
|
||||
#define R9A08G045_PD_OTFDE_DDR 66
|
||||
#define R9A08G045_PD_RTC 67
|
||||
|
||||
#endif /* __DT_BINDINGS_CLOCK_R9A08G045_CPG_H__ */
|
||||
|
|
|
|||
13
include/dt-bindings/clock/renesas,r9a08g045-vbattb.h
Normal file
13
include/dt-bindings/clock/renesas,r9a08g045-vbattb.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
*
|
||||
* Copyright (C) 2024 Renesas Electronics Corp.
|
||||
*/
|
||||
#ifndef __DT_BINDINGS_CLOCK_R9A08G045_VBATTB_H__
|
||||
#define __DT_BINDINGS_CLOCK_R9A08G045_VBATTB_H__
|
||||
|
||||
#define VBATTB_XC 0
|
||||
#define VBATTB_XBYP 1
|
||||
#define VBATTB_MUX 2
|
||||
#define VBATTB_VBATTCLK 3
|
||||
|
||||
#endif /* __DT_BINDINGS_CLOCK_R9A08G045_VBATTB_H__ */
|
||||
|
|
@ -622,6 +622,24 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
|
|||
__devm_clk_hw_register_gate((dev), NULL, (name), (parent_name), NULL, \
|
||||
NULL, (flags), (reg), (bit_idx), \
|
||||
(clk_gate_flags), (lock))
|
||||
/**
|
||||
* devm_clk_hw_register_gate_parent_hw - register a gate clock with the clock
|
||||
* framework
|
||||
* @dev: device that is registering this clock
|
||||
* @name: name of this clock
|
||||
* @parent_hw: pointer to parent clk
|
||||
* @flags: framework-specific flags for this clock
|
||||
* @reg: register address to control gating of this clock
|
||||
* @bit_idx: which bit in the register controls gating of this clock
|
||||
* @clk_gate_flags: gate-specific flags for this clock
|
||||
* @lock: shared register lock for this clock
|
||||
*/
|
||||
#define devm_clk_hw_register_gate_parent_hw(dev, name, parent_hw, flags, \
|
||||
reg, bit_idx, clk_gate_flags, \
|
||||
lock) \
|
||||
__devm_clk_hw_register_gate((dev), NULL, (name), NULL, (parent_hw), \
|
||||
NULL, (flags), (reg), (bit_idx), \
|
||||
(clk_gate_flags), (lock))
|
||||
/**
|
||||
* devm_clk_hw_register_gate_parent_data - register a gate clock with the
|
||||
* clock framework
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user