Skip to content

Commit

Permalink
Merge branches 'clk-baikal', 'clk-broadcom', 'clk-vc5' and 'clk-versa…
Browse files Browse the repository at this point in the history
…clock' into clk-next

 - Convert Baikal-T1 CCU driver to platform driver
 - Split reset support out of primary Baikal-T1 CCU driver
 - Add some missing clks required for RPiVid Video Decoder on RaspberryPi
 - Mark PLLC critical on bcm2835
 - Support for Renesas VersaClock7 clock generator family

* clk-baikal:
  clk: baikal-t1: Convert to platform device driver
  clk: baikal-t1: Add DDR/PCIe directly controlled resets support
  dt-bindings: clk: baikal-t1: Add DDR/PCIe reset IDs
  clk: baikal-t1: Move reset-controls code into a dedicated module
  clk: baikal-t1: Add SATA internal ref clock buffer
  clk: baikal-t1: Add shared xGMAC ref/ptp clocks internal parent
  clk: baikal-t1: Fix invalid xGMAC PTP clock divider
  clk: vc5: Fix 5P49V6901 outputs disabling when enabling FOD

* clk-broadcom:
  clk: bcm: rpi: Add support for VEC clock
  clk: bcm: rpi: Handle pixel clock in firmware
  clk: bcm: rpi: Add support HEVC clock
  clk: bcm2835: fix bcm2835_clock_rate_from_divisor declaration
  clk: bcm2835: Round UART input clock up
  clk: bcm2835: Make peripheral PLLC critical

* clk-vc5:
  clk: vc5: Add support for IDT/Renesas VersaClock 5P49V6975
  dt-bindings: clock: vc5: Add 5P49V6975
  clk: vc5: Use regmap_{set,clear}_bits() where appropriate
  clk: vc5: Check IO access results

* clk-versaclock:
  clk: Renesas versaclock7 ccf device driver
  dt-bindings: Renesas versaclock7 device tree bindings
  • Loading branch information
bebarino committed Oct 4, 2022
5 parents b7f257c + c4e0544 + 1777cb6 + d847383 + 48c5e98 commit f9efefd
Show file tree
Hide file tree
Showing 19 changed files with 2,182 additions and 224 deletions.
2 changes: 2 additions & 0 deletions Documentation/devicetree/bindings/clock/idt,versaclock5.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ properties:
- idt,5p49v5935
- idt,5p49v6901
- idt,5p49v6965
- idt,5p49v6975

reg:
description: I2C device address
Expand Down Expand Up @@ -134,6 +135,7 @@ allOf:
enum:
- idt,5p49v5933
- idt,5p49v5935
- idt,5p49v6975
then:
# Devices with builtin crystal + optional external input
properties:
Expand Down
64 changes: 64 additions & 0 deletions Documentation/devicetree/bindings/clock/renesas,versaclock7.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/renesas,versaclock7.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Renesas Versaclock7 Programmable Clock Device Tree Bindings

maintainers:
- Alex Helms <alexander.helms.jy@renesas.com>

description: |
Renesas Versaclock7 is a family of configurable clock generator and
jitter attenuator ICs with fractional and integer dividers.
properties:
'#clock-cells':
const: 1

compatible:
enum:
- renesas,rc21008a

reg:
maxItems: 1

clocks:
items:
- description: External crystal or oscillator

clock-names:
items:
- const: xin

required:
- '#clock-cells'
- compatible
- reg
- clocks
- clock-names

additionalProperties: false

examples:
- |
vc7_xin: clock {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <49152000>;
};
i2c@0 {
reg = <0x0 0x100>;
#address-cells = <1>;
#size-cells = <0>;
vc7: clock-controller@9 {
compatible = "renesas,rc21008a";
reg = <0x9>;
#clock-cells = <1>;
clocks = <&vc7_xin>;
clock-names = "xin";
};
};
6 changes: 6 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -17442,6 +17442,12 @@ S: Maintained
F: Documentation/devicetree/bindings/mtd/renesas-nandc.yaml
F: drivers/mtd/nand/raw/renesas-nand-controller.c

RENESAS VERSACLOCK 7 CLOCK DRIVER
M: Alex Helms <alexander.helms.jy@renesas.com>
S: Maintained
F: Documentation/devicetree/bindings/clock/renesas,versaclock7.yaml
F: drivers/clk/clk-versaclock7.c

RESET CONTROLLER FRAMEWORK
M: Philipp Zabel <p.zabel@pengutronix.de>
S: Maintained
Expand Down
9 changes: 9 additions & 0 deletions drivers/clk/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,15 @@ config COMMON_CLK_VC5
This driver supports the IDT VersaClock 5 and VersaClock 6
programmable clock generators.

config COMMON_CLK_VC7
tristate "Clock driver for Renesas Versaclock 7 devices"
depends on I2C
depends on OF
select REGMAP_I2C
help
Renesas Versaclock7 is a family of configurable clock generator
and jitter attenuator ICs with fractional and integer dividers.

config COMMON_CLK_STM32MP135
def_bool COMMON_CLK && MACH_STM32MP13
help
Expand Down
1 change: 1 addition & 0 deletions drivers/clk/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o
obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
obj-$(CONFIG_COMMON_CLK_RS9_PCIE) += clk-renesas-pcie.o
obj-$(CONFIG_COMMON_CLK_VC5) += clk-versaclock5.o
obj-$(CONFIG_COMMON_CLK_VC7) += clk-versaclock7.o
obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o

Expand Down
12 changes: 11 additions & 1 deletion drivers/clk/baikal-t1/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ config CLK_BT1_CCU_PLL

config CLK_BT1_CCU_DIV
bool "Baikal-T1 CCU Dividers support"
select RESET_CONTROLLER
select MFD_SYSCON
default MIPS_BAIKAL_T1
help
Expand All @@ -39,4 +38,15 @@ config CLK_BT1_CCU_DIV
either gateable or ungateable. Some of the CCU dividers can be as well
used to reset the domains they're supplying clock to.

config CLK_BT1_CCU_RST
bool "Baikal-T1 CCU Resets support"
select RESET_CONTROLLER
select MFD_SYSCON
default MIPS_BAIKAL_T1
help
Enable this to support the CCU reset blocks responsible for the
AXI-bus and some subsystems reset. These are mainly the
self-deasserted reset controls but there are several lines which
can be directly asserted/de-asserted (PCIe and DDR sub-domains).

endif
1 change: 1 addition & 0 deletions drivers/clk/baikal-t1/Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_CLK_BT1_CCU_PLL) += ccu-pll.o clk-ccu-pll.o
obj-$(CONFIG_CLK_BT1_CCU_DIV) += ccu-div.o clk-ccu-div.o
obj-$(CONFIG_CLK_BT1_CCU_RST) += ccu-rst.o
84 changes: 65 additions & 19 deletions drivers/clk/baikal-t1/ccu-div.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@
#define CCU_DIV_CTL_CLKDIV_MASK(_width) \
GENMASK((_width) + CCU_DIV_CTL_CLKDIV_FLD - 1, CCU_DIV_CTL_CLKDIV_FLD)
#define CCU_DIV_CTL_LOCK_SHIFTED BIT(27)
#define CCU_DIV_CTL_GATE_REF_BUF BIT(28)
#define CCU_DIV_CTL_LOCK_NORMAL BIT(31)

#define CCU_DIV_RST_DELAY_US 1
#define CCU_DIV_LOCK_CHECK_RETRIES 50

#define CCU_DIV_CLKDIV_MIN 0
Expand Down Expand Up @@ -170,6 +170,40 @@ static int ccu_div_gate_is_enabled(struct clk_hw *hw)
return !!(val & CCU_DIV_CTL_EN);
}

static int ccu_div_buf_enable(struct clk_hw *hw)
{
struct ccu_div *div = to_ccu_div(hw);
unsigned long flags;

spin_lock_irqsave(&div->lock, flags);
regmap_update_bits(div->sys_regs, div->reg_ctl,
CCU_DIV_CTL_GATE_REF_BUF, 0);
spin_unlock_irqrestore(&div->lock, flags);

return 0;
}

static void ccu_div_buf_disable(struct clk_hw *hw)
{
struct ccu_div *div = to_ccu_div(hw);
unsigned long flags;

spin_lock_irqsave(&div->lock, flags);
regmap_update_bits(div->sys_regs, div->reg_ctl,
CCU_DIV_CTL_GATE_REF_BUF, CCU_DIV_CTL_GATE_REF_BUF);
spin_unlock_irqrestore(&div->lock, flags);
}

static int ccu_div_buf_is_enabled(struct clk_hw *hw)
{
struct ccu_div *div = to_ccu_div(hw);
u32 val = 0;

regmap_read(div->sys_regs, div->reg_ctl, &val);

return !(val & CCU_DIV_CTL_GATE_REF_BUF);
}

static unsigned long ccu_div_var_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
Expand Down Expand Up @@ -288,24 +322,6 @@ static int ccu_div_fixed_set_rate(struct clk_hw *hw, unsigned long rate,
return 0;
}

int ccu_div_reset_domain(struct ccu_div *div)
{
unsigned long flags;

if (!div || !(div->features & CCU_DIV_RESET_DOMAIN))
return -EINVAL;

spin_lock_irqsave(&div->lock, flags);
regmap_update_bits(div->sys_regs, div->reg_ctl,
CCU_DIV_CTL_RST, CCU_DIV_CTL_RST);
spin_unlock_irqrestore(&div->lock, flags);

/* The next delay must be enough to cover all the resets. */
udelay(CCU_DIV_RST_DELAY_US);

return 0;
}

#ifdef CONFIG_DEBUG_FS

struct ccu_div_dbgfs_bit {
Expand All @@ -323,6 +339,7 @@ static const struct ccu_div_dbgfs_bit ccu_div_bits[] = {
CCU_DIV_DBGFS_BIT_ATTR("div_en", CCU_DIV_CTL_EN),
CCU_DIV_DBGFS_BIT_ATTR("div_rst", CCU_DIV_CTL_RST),
CCU_DIV_DBGFS_BIT_ATTR("div_bypass", CCU_DIV_CTL_SET_CLKDIV),
CCU_DIV_DBGFS_BIT_ATTR("div_buf", CCU_DIV_CTL_GATE_REF_BUF),
CCU_DIV_DBGFS_BIT_ATTR("div_lock", CCU_DIV_CTL_LOCK_NORMAL)
};

Expand Down Expand Up @@ -441,6 +458,9 @@ static void ccu_div_var_debug_init(struct clk_hw *hw, struct dentry *dentry)
continue;
}

if (!strcmp("div_buf", name))
continue;

bits[didx] = ccu_div_bits[bidx];
bits[didx].div = div;

Expand Down Expand Up @@ -477,6 +497,21 @@ static void ccu_div_gate_debug_init(struct clk_hw *hw, struct dentry *dentry)
&ccu_div_dbgfs_fixed_clkdiv_fops);
}

static void ccu_div_buf_debug_init(struct clk_hw *hw, struct dentry *dentry)
{
struct ccu_div *div = to_ccu_div(hw);
struct ccu_div_dbgfs_bit *bit;

bit = kmalloc(sizeof(*bit), GFP_KERNEL);
if (!bit)
return;

*bit = ccu_div_bits[3];
bit->div = div;
debugfs_create_file_unsafe(bit->name, ccu_div_dbgfs_mode, dentry, bit,
&ccu_div_dbgfs_bit_fops);
}

static void ccu_div_fixed_debug_init(struct clk_hw *hw, struct dentry *dentry)
{
struct ccu_div *div = to_ccu_div(hw);
Expand All @@ -489,6 +524,7 @@ static void ccu_div_fixed_debug_init(struct clk_hw *hw, struct dentry *dentry)

#define ccu_div_var_debug_init NULL
#define ccu_div_gate_debug_init NULL
#define ccu_div_buf_debug_init NULL
#define ccu_div_fixed_debug_init NULL

#endif /* !CONFIG_DEBUG_FS */
Expand Down Expand Up @@ -520,6 +556,13 @@ static const struct clk_ops ccu_div_gate_ops = {
.debug_init = ccu_div_gate_debug_init
};

static const struct clk_ops ccu_div_buf_ops = {
.enable = ccu_div_buf_enable,
.disable = ccu_div_buf_disable,
.is_enabled = ccu_div_buf_is_enabled,
.debug_init = ccu_div_buf_debug_init
};

static const struct clk_ops ccu_div_fixed_ops = {
.recalc_rate = ccu_div_fixed_recalc_rate,
.round_rate = ccu_div_fixed_round_rate,
Expand Down Expand Up @@ -566,6 +609,8 @@ struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *div_init)
} else if (div_init->type == CCU_DIV_GATE) {
hw_init.ops = &ccu_div_gate_ops;
div->divider = div_init->divider;
} else if (div_init->type == CCU_DIV_BUF) {
hw_init.ops = &ccu_div_buf_ops;
} else if (div_init->type == CCU_DIV_FIXED) {
hw_init.ops = &ccu_div_fixed_ops;
div->divider = div_init->divider;
Expand All @@ -579,6 +624,7 @@ struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *div_init)
goto err_free_div;
}
parent_data.fw_name = div_init->parent_name;
parent_data.name = div_init->parent_name;
hw_init.parent_data = &parent_data;
hw_init.num_parents = 1;

Expand Down
17 changes: 14 additions & 3 deletions drivers/clk/baikal-t1/ccu-div.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,26 @@
#include <linux/bits.h>
#include <linux/of.h>

/*
* CCU Divider private clock IDs
* @CCU_SYS_SATA_CLK: CCU SATA internal clock
* @CCU_SYS_XGMAC_CLK: CCU XGMAC internal clock
*/
#define CCU_SYS_SATA_CLK -1
#define CCU_SYS_XGMAC_CLK -2

/*
* CCU Divider private flags
* @CCU_DIV_BASIC: Basic divider clock required by the kernel as early as
* possible.
* @CCU_DIV_SKIP_ONE: Due to some reason divider can't be set to 1.
* It can be 0 though, which is functionally the same.
* @CCU_DIV_SKIP_ONE_TO_THREE: For some reason divider can't be within [1,3].
* It can be either 0 or greater than 3.
* @CCU_DIV_LOCK_SHIFTED: Find lock-bit at non-standard position.
* @CCU_DIV_RESET_DOMAIN: Provide reset clock domain method.
* @CCU_DIV_RESET_DOMAIN: There is a clock domain reset handle.
*/
#define CCU_DIV_BASIC BIT(0)
#define CCU_DIV_SKIP_ONE BIT(1)
#define CCU_DIV_SKIP_ONE_TO_THREE BIT(2)
#define CCU_DIV_LOCK_SHIFTED BIT(3)
Expand All @@ -31,11 +42,13 @@
* enum ccu_div_type - CCU Divider types
* @CCU_DIV_VAR: Clocks gate with variable divider.
* @CCU_DIV_GATE: Clocks gate with fixed divider.
* @CCU_DIV_BUF: Clock gate with no divider.
* @CCU_DIV_FIXED: Ungateable clock with fixed divider.
*/
enum ccu_div_type {
CCU_DIV_VAR,
CCU_DIV_GATE,
CCU_DIV_BUF,
CCU_DIV_FIXED
};

Expand Down Expand Up @@ -105,6 +118,4 @@ struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *init);

void ccu_div_hw_unregister(struct ccu_div *div);

int ccu_div_reset_domain(struct ccu_div *div);

#endif /* __CLK_BT1_CCU_DIV_H__ */
8 changes: 8 additions & 0 deletions drivers/clk/baikal-t1/ccu-pll.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@
#include <linux/bits.h>
#include <linux/of.h>

/*
* CCU PLL private flags
* @CCU_PLL_BASIC: Basic PLL required by the kernel as early as possible.
*/
#define CCU_PLL_BASIC BIT(0)

/*
* struct ccu_pll_init_data - CCU PLL initialization data
* @id: Clock private identifier.
Expand All @@ -22,6 +28,7 @@
* @sys_regs: Baikal-T1 System Controller registers map.
* @np: Pointer to the node describing the CCU PLLs.
* @flags: PLL clock flags.
* @features: PLL private features.
*/
struct ccu_pll_init_data {
unsigned int id;
Expand All @@ -31,6 +38,7 @@ struct ccu_pll_init_data {
struct regmap *sys_regs;
struct device_node *np;
unsigned long flags;
unsigned long features;
};

/*
Expand Down
Loading

0 comments on commit f9efefd

Please sign in to comment.