mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-13 14:24:11 +08:00
Merge branches 'clk-lmk04832', 'clk-stm', 'clk-rohm', 'clk-actions' and 'clk-ingenic' into clk-next
- Texas Instruments' LMK04832 Ultra Low-Noise JESD204B Compliant Clock Jitter Cleaner With Dual Loop PLLs - Support secure mode of STM32MP1 SoCs - Improve clock support for Actions S500 SoC * clk-lmk04832: clk: lmk04832: Use of match table clk: lmk04832: Depend on SPI clk: lmk04832: add support for digital delay clk: add support for the lmk04832 dt-bindings: clock: add ti,lmk04832 bindings * clk-stm: clk: stm32mp1: new compatible for secure RCC support dt-bindings: clock: stm32mp1 new compatible for secure rcc dt-bindings: reset: add MCU HOLD BOOT ID for SCMI reset domains on stm32mp15 dt-bindings: reset: add IDs for SCMI reset domains on stm32mp15 dt-bindings: clock: add IDs for SCMI clocks on stm32mp15 reset: stm32mp1: remove stm32mp1 reset clk: stm32mp1: move RCC reset controller into RCC clock driver clk: stm32mp1: convert to module driver clk: stm32mp1: remove intermediate pll clocks clk: stm32mp1: merge 'ck_hse_rtc' and 'ck_rtc' into one clock clk: stm32mp1: merge 'clk-hsi-div' and 'ck_hsi' into one clock * clk-rohm: clk: bd718xx: Drop BD70528 support * clk-actions: clk: actions: Add NIC and ETHERNET clock support for Actions S500 SoC dt-bindings: clock: Add NIC and ETHERNET bindings for Actions S500 SoC clk: actions: Fix AHPPREDIV-H-AHB clock chain on Owl S500 SoC clk: actions: Fix bisp_factor_table based clocks on Owl S500 SoC clk: actions: Fix SD clocks factor table on Owl S500 SoC clk: actions: Fix UART clock dividers on Owl S500 SoC * clk-ingenic: clk: ingenic: Add support for the JZ4760 clk: ingenic: Support overriding PLLs M/N/OD calc algorithm clk: ingenic: Remove pll_info.no_bypass_bit clk: ingenic: Read bypass register only when there is one clk: Support bypassing dividers dt-bindings: clock: ingenic: Add ingenic,jz4760{,b}-cgu compatibles
This commit is contained in:
commit
4f47c91fc6
@ -22,6 +22,8 @@ select:
|
||||
enum:
|
||||
- ingenic,jz4740-cgu
|
||||
- ingenic,jz4725b-cgu
|
||||
- ingenic,jz4760-cgu
|
||||
- ingenic,jz4760b-cgu
|
||||
- ingenic,jz4770-cgu
|
||||
- ingenic,jz4780-cgu
|
||||
- ingenic,x1000-cgu
|
||||
@ -49,6 +51,8 @@ properties:
|
||||
- enum:
|
||||
- ingenic,jz4740-cgu
|
||||
- ingenic,jz4725b-cgu
|
||||
- ingenic,jz4760-cgu
|
||||
- ingenic,jz4760b-cgu
|
||||
- ingenic,jz4770-cgu
|
||||
- ingenic,jz4780-cgu
|
||||
- ingenic,x1000-cgu
|
||||
|
@ -54,7 +54,9 @@ properties:
|
||||
|
||||
compatible:
|
||||
items:
|
||||
- const: st,stm32mp1-rcc
|
||||
- enum:
|
||||
- st,stm32mp1-rcc-secure
|
||||
- st,stm32mp1-rcc
|
||||
- const: syscon
|
||||
|
||||
reg:
|
||||
@ -71,7 +73,7 @@ additionalProperties: false
|
||||
examples:
|
||||
- |
|
||||
rcc: rcc@50000000 {
|
||||
compatible = "st,stm32mp1-rcc", "syscon";
|
||||
compatible = "st,stm32mp1-rcc-secure", "syscon";
|
||||
reg = <0x50000000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
|
209
Documentation/devicetree/bindings/clock/ti,lmk04832.yaml
Normal file
209
Documentation/devicetree/bindings/clock/ti,lmk04832.yaml
Normal file
@ -0,0 +1,209 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/ti,lmk04832.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Clock bindings for the Texas Instruments LMK04832
|
||||
|
||||
maintainers:
|
||||
- Liam Beguin <liambeguin@gmail.com>
|
||||
|
||||
description: |
|
||||
Devicetree binding for the LMK04832, a clock conditioner with JEDEC JESD204B
|
||||
support. The LMK04832 is pin compatible with the LMK0482x family.
|
||||
|
||||
Link to datasheet, https://www.ti.com/lit/ds/symlink/lmk04832.pdf
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- ti,lmk04832
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
||||
'#size-cells':
|
||||
const: 0
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
spi-max-frequency:
|
||||
maximum: 5000000
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: PLL2 reference clock.
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: oscin
|
||||
|
||||
reset-gpios:
|
||||
maxItems: 1
|
||||
|
||||
ti,spi-4wire-rdbk:
|
||||
description: |
|
||||
Select SPI 4wire readback pin configuration.
|
||||
Available readback pins are,
|
||||
CLKin_SEL0 0
|
||||
CLKin_SEL1 1
|
||||
RESET 2
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1, 2]
|
||||
default: 1
|
||||
|
||||
ti,vco-hz:
|
||||
description: Optional to set VCO frequency of the PLL in Hertz.
|
||||
|
||||
ti,sysref-ddly:
|
||||
description: SYSREF digital delay value.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 8
|
||||
maximum: 8191
|
||||
default: 8
|
||||
|
||||
ti,sysref-mux:
|
||||
description: |
|
||||
SYSREF Mux configuration.
|
||||
Available options are,
|
||||
Normal SYNC 0
|
||||
Re-clocked 1
|
||||
SYSREF Pulser 2
|
||||
SYSREF Continuous 3
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1, 2, 3]
|
||||
default: 3
|
||||
|
||||
ti,sync-mode:
|
||||
description: SYNC pin configuration.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1, 2]
|
||||
default: 1
|
||||
|
||||
ti,sysref-pulse-count:
|
||||
description:
|
||||
Number of SYSREF pulses to send when SYSREF is not in continuous mode.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [1, 2, 4, 8]
|
||||
default: 4
|
||||
|
||||
patternProperties:
|
||||
"@[0-9a-d]+$":
|
||||
type: object
|
||||
description:
|
||||
Child nodes used to configure output clocks.
|
||||
|
||||
properties:
|
||||
reg:
|
||||
description:
|
||||
clock output identifier.
|
||||
minimum: 0
|
||||
maximum: 13
|
||||
|
||||
ti,clkout-fmt:
|
||||
description:
|
||||
Clock output format.
|
||||
Available options are,
|
||||
Powerdown 0x00
|
||||
LVDS 0x01
|
||||
HSDS 6 mA 0x02
|
||||
HSDS 8 mA 0x03
|
||||
LVPECL 1600 mV 0x04
|
||||
LVPECL 2000 mV 0x05
|
||||
LCPECL 0x06
|
||||
CML 16 mA 0x07
|
||||
CML 24 mA 0x08
|
||||
CML 32 mA 0x09
|
||||
CMOS (Off/Inverted) 0x0a
|
||||
CMOS (Normal/Off) 0x0b
|
||||
CMOS (Inverted/Inverted) 0x0c
|
||||
CMOS (Inverted/Normal) 0x0d
|
||||
CMOS (Normal/Inverted) 0x0e
|
||||
CMOS (Normal/Normal) 0x0f
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 15
|
||||
|
||||
ti,clkout-sysref:
|
||||
description:
|
||||
Select SYSREF clock path for output clock.
|
||||
type: boolean
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- '#clock-cells'
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
clocks {
|
||||
lmk04832_oscin: oscin {
|
||||
compatible = "fixed-clock";
|
||||
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <122880000>;
|
||||
clock-output-names = "lmk04832-oscin";
|
||||
};
|
||||
};
|
||||
|
||||
spi0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
lmk04832: clock-controller@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
reg = <0>;
|
||||
|
||||
compatible = "ti,lmk04832";
|
||||
spi-max-frequency = <781250>;
|
||||
|
||||
reset-gpios = <&gpio_lmk 0 0 0>;
|
||||
|
||||
#clock-cells = <1>;
|
||||
clocks = <&lmk04832_oscin>;
|
||||
clock-names = "oscin";
|
||||
|
||||
ti,spi-4wire-rdbk = <0>;
|
||||
ti,vco-hz = <2457600000>;
|
||||
|
||||
assigned-clocks =
|
||||
<&lmk04832 0>, <&lmk04832 1>,
|
||||
<&lmk04832 2>, <&lmk04832 3>,
|
||||
<&lmk04832 4>,
|
||||
<&lmk04832 6>, <&lmk04832 7>,
|
||||
<&lmk04832 10>, <&lmk04832 11>;
|
||||
assigned-clock-rates =
|
||||
<122880000>, <384000>,
|
||||
<122880000>, <384000>,
|
||||
<122880000>,
|
||||
<153600000>, <384000>,
|
||||
<614400000>, <384000>;
|
||||
|
||||
clkout0@0 {
|
||||
reg = <0>;
|
||||
ti,clkout-fmt = <0x01>; // LVDS
|
||||
};
|
||||
|
||||
clkout1@1 {
|
||||
reg = <1>;
|
||||
ti,clkout-fmt = <0x01>; // LVDS
|
||||
ti,clkout-sysref;
|
||||
};
|
||||
};
|
||||
};
|
@ -51,6 +51,14 @@ config CLK_HSDK
|
||||
This driver supports the HSDK core, system, ddr, tunnel and hdmi PLLs
|
||||
control.
|
||||
|
||||
config LMK04832
|
||||
tristate "Ti LMK04832 JESD204B Compliant Clock Jitter Cleaner"
|
||||
depends on SPI
|
||||
select REGMAP_SPI
|
||||
help
|
||||
Say yes here to build support for Texas Instruments' LMK04832 Ultra
|
||||
Low-Noise JESD204B Compliant Clock Jitter Cleaner With Dual Loop PLLs
|
||||
|
||||
config COMMON_CLK_MAX77686
|
||||
tristate "Clock driver for Maxim 77620/77686/77802 MFD"
|
||||
depends on MFD_MAX77686 || MFD_MAX77620 || COMPILE_TEST
|
||||
@ -331,6 +339,16 @@ config COMMON_CLK_STM32MP157
|
||||
help
|
||||
Support for stm32mp157 SoC family clocks
|
||||
|
||||
config COMMON_CLK_STM32MP157_SCMI
|
||||
bool "stm32mp157 Clock driver with Trusted Firmware"
|
||||
depends on COMMON_CLK_STM32MP157
|
||||
select COMMON_CLK_SCMI
|
||||
select ARM_SCMI_PROTOCOL
|
||||
default y
|
||||
help
|
||||
Support for stm32mp157 SoC family clocks with Trusted Firmware using
|
||||
SCMI protocol.
|
||||
|
||||
config COMMON_CLK_STM32F
|
||||
def_bool COMMON_CLK && (MACH_STM32F429 || MACH_STM32F469 || MACH_STM32F746)
|
||||
help
|
||||
@ -354,10 +372,10 @@ config COMMON_CLK_MMP2_AUDIO
|
||||
|
||||
config COMMON_CLK_BD718XX
|
||||
tristate "Clock driver for 32K clk gates on ROHM PMICs"
|
||||
depends on MFD_ROHM_BD718XX || MFD_ROHM_BD70528 || MFD_ROHM_BD71828
|
||||
depends on MFD_ROHM_BD718XX || MFD_ROHM_BD71828
|
||||
help
|
||||
This driver supports ROHM BD71837, ROHM BD71847, ROHM BD71828 and
|
||||
ROHM BD70528 PMICs clock gates.
|
||||
This driver supports ROHM BD71837, BD71847, BD71850, BD71815
|
||||
and BD71828 PMICs clock gates.
|
||||
|
||||
config COMMON_CLK_FIXED_MMIO
|
||||
bool "Clock driver for Memory Mapped Fixed values"
|
||||
|
@ -36,6 +36,7 @@ obj-$(CONFIG_MACH_ASPEED_G6) += clk-ast2600.o
|
||||
obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o
|
||||
obj-$(CONFIG_CLK_HSDK) += clk-hsdk-pll.o
|
||||
obj-$(CONFIG_COMMON_CLK_K210) += clk-k210.o
|
||||
obj-$(CONFIG_LMK04832) += clk-lmk04832.o
|
||||
obj-$(CONFIG_COMMON_CLK_LOCHNAGAR) += clk-lochnagar.o
|
||||
obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
|
||||
obj-$(CONFIG_COMMON_CLK_MAX9485) += clk-max9485.o
|
||||
|
@ -113,6 +113,7 @@ static const char * const sensor_clk_mux_p[] = { "hosc", "bisp_clk" };
|
||||
static const char * const sd_clk_mux_p[] = { "dev_clk", "nand_pll_clk" };
|
||||
static const char * const pwm_clk_mux_p[] = { "losc", "hosc" };
|
||||
static const char * const ahbprediv_clk_mux_p[] = { "dev_clk", "display_pll_clk", "nand_pll_clk", "ddr_pll_clk" };
|
||||
static const char * const nic_clk_mux_p[] = { "dev_clk", "display_pll_clk", "nand_pll_clk", "ddr_pll_clk" };
|
||||
static const char * const uart_clk_mux_p[] = { "hosc", "dev_pll_clk" };
|
||||
static const char * const de_clk_mux_p[] = { "display_pll_clk", "dev_clk" };
|
||||
static const char * const i2s_clk_mux_p[] = { "audio_pll_clk" };
|
||||
@ -127,8 +128,7 @@ static struct clk_factor_table sd_factor_table[] = {
|
||||
{ 12, 1, 13 }, { 13, 1, 14 }, { 14, 1, 15 }, { 15, 1, 16 },
|
||||
{ 16, 1, 17 }, { 17, 1, 18 }, { 18, 1, 19 }, { 19, 1, 20 },
|
||||
{ 20, 1, 21 }, { 21, 1, 22 }, { 22, 1, 23 }, { 23, 1, 24 },
|
||||
{ 24, 1, 25 }, { 25, 1, 26 }, { 26, 1, 27 }, { 27, 1, 28 },
|
||||
{ 28, 1, 29 }, { 29, 1, 30 }, { 30, 1, 31 }, { 31, 1, 32 },
|
||||
{ 24, 1, 25 },
|
||||
|
||||
/* bit8: /128 */
|
||||
{ 256, 1, 1 * 128 }, { 257, 1, 2 * 128 }, { 258, 1, 3 * 128 }, { 259, 1, 4 * 128 },
|
||||
@ -137,19 +137,20 @@ static struct clk_factor_table sd_factor_table[] = {
|
||||
{ 268, 1, 13 * 128 }, { 269, 1, 14 * 128 }, { 270, 1, 15 * 128 }, { 271, 1, 16 * 128 },
|
||||
{ 272, 1, 17 * 128 }, { 273, 1, 18 * 128 }, { 274, 1, 19 * 128 }, { 275, 1, 20 * 128 },
|
||||
{ 276, 1, 21 * 128 }, { 277, 1, 22 * 128 }, { 278, 1, 23 * 128 }, { 279, 1, 24 * 128 },
|
||||
{ 280, 1, 25 * 128 }, { 281, 1, 26 * 128 }, { 282, 1, 27 * 128 }, { 283, 1, 28 * 128 },
|
||||
{ 284, 1, 29 * 128 }, { 285, 1, 30 * 128 }, { 286, 1, 31 * 128 }, { 287, 1, 32 * 128 },
|
||||
{ 280, 1, 25 * 128 },
|
||||
{ 0, 0, 0 },
|
||||
};
|
||||
|
||||
static struct clk_factor_table bisp_factor_table[] = {
|
||||
{ 0, 1, 1 }, { 1, 1, 2 }, { 2, 1, 3 }, { 3, 1, 4 },
|
||||
{ 4, 1, 5 }, { 5, 1, 6 }, { 6, 1, 7 }, { 7, 1, 8 },
|
||||
static struct clk_factor_table de_factor_table[] = {
|
||||
{ 0, 1, 1 }, { 1, 2, 3 }, { 2, 1, 2 }, { 3, 2, 5 },
|
||||
{ 4, 1, 3 }, { 5, 1, 4 }, { 6, 1, 6 }, { 7, 1, 8 },
|
||||
{ 8, 1, 12 },
|
||||
{ 0, 0, 0 },
|
||||
};
|
||||
|
||||
static struct clk_factor_table ahb_factor_table[] = {
|
||||
{ 1, 1, 2 }, { 2, 1, 3 },
|
||||
static struct clk_factor_table hde_factor_table[] = {
|
||||
{ 0, 1, 1 }, { 1, 2, 3 }, { 2, 1, 2 }, { 3, 2, 5 },
|
||||
{ 4, 1, 3 }, { 5, 1, 4 }, { 6, 1, 6 }, { 7, 1, 8 },
|
||||
{ 0, 0, 0 },
|
||||
};
|
||||
|
||||
@ -158,6 +159,13 @@ static struct clk_div_table rmii_ref_div_table[] = {
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
static struct clk_div_table std12rate_div_table[] = {
|
||||
{ 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 },
|
||||
{ 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 },
|
||||
{ 8, 9 }, { 9, 10 }, { 10, 11 }, { 11, 12 },
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
static struct clk_div_table i2s_div_table[] = {
|
||||
{ 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 },
|
||||
{ 4, 6 }, { 5, 8 }, { 6, 12 }, { 7, 16 },
|
||||
@ -174,7 +182,6 @@ static struct clk_div_table nand_div_table[] = {
|
||||
|
||||
/* mux clock */
|
||||
static OWL_MUX(dev_clk, "dev_clk", dev_clk_mux_p, CMU_DEVPLL, 12, 1, CLK_SET_RATE_PARENT);
|
||||
static OWL_MUX(ahbprediv_clk, "ahbprediv_clk", ahbprediv_clk_mux_p, CMU_BUSCLK1, 8, 3, CLK_SET_RATE_PARENT);
|
||||
|
||||
/* gate clocks */
|
||||
static OWL_GATE(gpio_clk, "gpio_clk", "apb_clk", CMU_DEVCLKEN0, 18, 0, 0);
|
||||
@ -187,45 +194,60 @@ static OWL_GATE(timer_clk, "timer_clk", "hosc", CMU_DEVCLKEN1, 27, 0, 0);
|
||||
static OWL_GATE(hdmi_clk, "hdmi_clk", "hosc", CMU_DEVCLKEN1, 3, 0, 0);
|
||||
|
||||
/* divider clocks */
|
||||
static OWL_DIVIDER(h_clk, "h_clk", "ahbprediv_clk", CMU_BUSCLK1, 12, 2, NULL, 0, 0);
|
||||
static OWL_DIVIDER(apb_clk, "apb_clk", "ahb_clk", CMU_BUSCLK1, 14, 2, NULL, 0, 0);
|
||||
static OWL_DIVIDER(h_clk, "h_clk", "ahbprediv_clk", CMU_BUSCLK1, 2, 2, NULL, 0, 0);
|
||||
static OWL_DIVIDER(apb_clk, "apb_clk", "nic_clk", CMU_BUSCLK1, 14, 2, NULL, 0, 0);
|
||||
static OWL_DIVIDER(rmii_ref_clk, "rmii_ref_clk", "ethernet_pll_clk", CMU_ETHERNETPLL, 1, 1, rmii_ref_div_table, 0, 0);
|
||||
|
||||
/* factor clocks */
|
||||
static OWL_FACTOR(ahb_clk, "ahb_clk", "h_clk", CMU_BUSCLK1, 2, 2, ahb_factor_table, 0, 0);
|
||||
static OWL_FACTOR(de1_clk, "de_clk1", "de_clk", CMU_DECLK, 0, 3, bisp_factor_table, 0, 0);
|
||||
static OWL_FACTOR(de2_clk, "de_clk2", "de_clk", CMU_DECLK, 4, 3, bisp_factor_table, 0, 0);
|
||||
static OWL_FACTOR(de1_clk, "de_clk1", "de_clk", CMU_DECLK, 0, 4, de_factor_table, 0, 0);
|
||||
static OWL_FACTOR(de2_clk, "de_clk2", "de_clk", CMU_DECLK, 4, 4, de_factor_table, 0, 0);
|
||||
|
||||
/* composite clocks */
|
||||
static OWL_COMP_DIV(nic_clk, "nic_clk", nic_clk_mux_p,
|
||||
OWL_MUX_HW(CMU_BUSCLK1, 4, 3),
|
||||
{ 0 },
|
||||
OWL_DIVIDER_HW(CMU_BUSCLK1, 16, 2, 0, NULL),
|
||||
0);
|
||||
|
||||
static OWL_COMP_DIV(ahbprediv_clk, "ahbprediv_clk", ahbprediv_clk_mux_p,
|
||||
OWL_MUX_HW(CMU_BUSCLK1, 8, 3),
|
||||
{ 0 },
|
||||
OWL_DIVIDER_HW(CMU_BUSCLK1, 12, 2, 0, NULL),
|
||||
CLK_SET_RATE_PARENT);
|
||||
|
||||
static OWL_COMP_FIXED_FACTOR(ahb_clk, "ahb_clk", "h_clk",
|
||||
{ 0 },
|
||||
1, 1, 0);
|
||||
|
||||
static OWL_COMP_FACTOR(vce_clk, "vce_clk", hde_clk_mux_p,
|
||||
OWL_MUX_HW(CMU_VCECLK, 4, 2),
|
||||
OWL_GATE_HW(CMU_DEVCLKEN0, 26, 0),
|
||||
OWL_FACTOR_HW(CMU_VCECLK, 0, 3, 0, bisp_factor_table),
|
||||
OWL_FACTOR_HW(CMU_VCECLK, 0, 3, 0, hde_factor_table),
|
||||
0);
|
||||
|
||||
static OWL_COMP_FACTOR(vde_clk, "vde_clk", hde_clk_mux_p,
|
||||
OWL_MUX_HW(CMU_VDECLK, 4, 2),
|
||||
OWL_GATE_HW(CMU_DEVCLKEN0, 25, 0),
|
||||
OWL_FACTOR_HW(CMU_VDECLK, 0, 3, 0, bisp_factor_table),
|
||||
OWL_FACTOR_HW(CMU_VDECLK, 0, 3, 0, hde_factor_table),
|
||||
0);
|
||||
|
||||
static OWL_COMP_FACTOR(bisp_clk, "bisp_clk", bisp_clk_mux_p,
|
||||
static OWL_COMP_DIV(bisp_clk, "bisp_clk", bisp_clk_mux_p,
|
||||
OWL_MUX_HW(CMU_BISPCLK, 4, 1),
|
||||
OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0),
|
||||
OWL_FACTOR_HW(CMU_BISPCLK, 0, 3, 0, bisp_factor_table),
|
||||
OWL_DIVIDER_HW(CMU_BISPCLK, 0, 4, 0, std12rate_div_table),
|
||||
0);
|
||||
|
||||
static OWL_COMP_FACTOR(sensor0_clk, "sensor0_clk", sensor_clk_mux_p,
|
||||
static OWL_COMP_DIV(sensor0_clk, "sensor0_clk", sensor_clk_mux_p,
|
||||
OWL_MUX_HW(CMU_SENSORCLK, 4, 1),
|
||||
OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0),
|
||||
OWL_FACTOR_HW(CMU_SENSORCLK, 0, 3, 0, bisp_factor_table),
|
||||
CLK_IGNORE_UNUSED);
|
||||
OWL_DIVIDER_HW(CMU_SENSORCLK, 0, 4, 0, std12rate_div_table),
|
||||
0);
|
||||
|
||||
static OWL_COMP_FACTOR(sensor1_clk, "sensor1_clk", sensor_clk_mux_p,
|
||||
static OWL_COMP_DIV(sensor1_clk, "sensor1_clk", sensor_clk_mux_p,
|
||||
OWL_MUX_HW(CMU_SENSORCLK, 4, 1),
|
||||
OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0),
|
||||
OWL_FACTOR_HW(CMU_SENSORCLK, 8, 3, 0, bisp_factor_table),
|
||||
CLK_IGNORE_UNUSED);
|
||||
OWL_DIVIDER_HW(CMU_SENSORCLK, 8, 4, 0, std12rate_div_table),
|
||||
0);
|
||||
|
||||
static OWL_COMP_FACTOR(sd0_clk, "sd0_clk", sd_clk_mux_p,
|
||||
OWL_MUX_HW(CMU_SD0CLK, 9, 1),
|
||||
@ -302,10 +324,14 @@ static OWL_COMP_FIXED_FACTOR(i2c3_clk, "i2c3_clk", "ethernet_pll_clk",
|
||||
OWL_GATE_HW(CMU_DEVCLKEN1, 31, 0),
|
||||
1, 5, 0);
|
||||
|
||||
static OWL_COMP_FIXED_FACTOR(ethernet_clk, "ethernet_clk", "ethernet_pll_clk",
|
||||
OWL_GATE_HW(CMU_DEVCLKEN1, 22, 0),
|
||||
1, 20, 0);
|
||||
|
||||
static OWL_COMP_DIV(uart0_clk, "uart0_clk", uart_clk_mux_p,
|
||||
OWL_MUX_HW(CMU_UART0CLK, 16, 1),
|
||||
OWL_GATE_HW(CMU_DEVCLKEN1, 6, 0),
|
||||
OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
|
||||
OWL_DIVIDER_HW(CMU_UART0CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
|
||||
CLK_IGNORE_UNUSED);
|
||||
|
||||
static OWL_COMP_DIV(uart1_clk, "uart1_clk", uart_clk_mux_p,
|
||||
@ -317,31 +343,31 @@ static OWL_COMP_DIV(uart1_clk, "uart1_clk", uart_clk_mux_p,
|
||||
static OWL_COMP_DIV(uart2_clk, "uart2_clk", uart_clk_mux_p,
|
||||
OWL_MUX_HW(CMU_UART2CLK, 16, 1),
|
||||
OWL_GATE_HW(CMU_DEVCLKEN1, 8, 0),
|
||||
OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
|
||||
OWL_DIVIDER_HW(CMU_UART2CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
|
||||
CLK_IGNORE_UNUSED);
|
||||
|
||||
static OWL_COMP_DIV(uart3_clk, "uart3_clk", uart_clk_mux_p,
|
||||
OWL_MUX_HW(CMU_UART3CLK, 16, 1),
|
||||
OWL_GATE_HW(CMU_DEVCLKEN1, 19, 0),
|
||||
OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
|
||||
OWL_DIVIDER_HW(CMU_UART3CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
|
||||
CLK_IGNORE_UNUSED);
|
||||
|
||||
static OWL_COMP_DIV(uart4_clk, "uart4_clk", uart_clk_mux_p,
|
||||
OWL_MUX_HW(CMU_UART4CLK, 16, 1),
|
||||
OWL_GATE_HW(CMU_DEVCLKEN1, 20, 0),
|
||||
OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
|
||||
OWL_DIVIDER_HW(CMU_UART4CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
|
||||
CLK_IGNORE_UNUSED);
|
||||
|
||||
static OWL_COMP_DIV(uart5_clk, "uart5_clk", uart_clk_mux_p,
|
||||
OWL_MUX_HW(CMU_UART5CLK, 16, 1),
|
||||
OWL_GATE_HW(CMU_DEVCLKEN1, 21, 0),
|
||||
OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
|
||||
OWL_DIVIDER_HW(CMU_UART5CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
|
||||
CLK_IGNORE_UNUSED);
|
||||
|
||||
static OWL_COMP_DIV(uart6_clk, "uart6_clk", uart_clk_mux_p,
|
||||
OWL_MUX_HW(CMU_UART6CLK, 16, 1),
|
||||
OWL_GATE_HW(CMU_DEVCLKEN1, 18, 0),
|
||||
OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
|
||||
OWL_DIVIDER_HW(CMU_UART6CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
|
||||
CLK_IGNORE_UNUSED);
|
||||
|
||||
static OWL_COMP_DIV(i2srx_clk, "i2srx_clk", i2s_clk_mux_p,
|
||||
@ -436,6 +462,8 @@ static struct owl_clk_common *s500_clks[] = {
|
||||
&apb_clk.common,
|
||||
&dmac_clk.common,
|
||||
&gpio_clk.common,
|
||||
&nic_clk.common,
|
||||
ðernet_clk.common,
|
||||
};
|
||||
|
||||
static struct clk_hw_onecell_data s500_hw_clks = {
|
||||
@ -495,6 +523,8 @@ static struct clk_hw_onecell_data s500_hw_clks = {
|
||||
[CLK_APB] = &apb_clk.common.hw,
|
||||
[CLK_DMAC] = &dmac_clk.common.hw,
|
||||
[CLK_GPIO] = &gpio_clk.common.hw,
|
||||
[CLK_NIC] = &nic_clk.common.hw,
|
||||
[CLK_ETHERNET] = ðernet_clk.common.hw,
|
||||
},
|
||||
.num = CLK_NR_CLKS,
|
||||
};
|
||||
|
@ -15,15 +15,13 @@
|
||||
/* clk control registers */
|
||||
/* BD71815 */
|
||||
#define BD71815_REG_OUT32K 0x1d
|
||||
/* BD70528 */
|
||||
#define BD70528_REG_OUT32K 0x2c
|
||||
/* BD71828 */
|
||||
#define BD71828_REG_OUT32K 0x4B
|
||||
/* BD71837 and BD71847 */
|
||||
#define BD718XX_REG_OUT32K 0x2E
|
||||
|
||||
/*
|
||||
* BD71837, BD71847, BD70528 and BD71828 all use bit [0] to clk output control
|
||||
* BD71837, BD71847, and BD71828 all use bit [0] to clk output control
|
||||
*/
|
||||
#define CLK_OUT_EN_MASK BIT(0)
|
||||
|
||||
@ -116,10 +114,6 @@ static int bd71837_clk_probe(struct platform_device *pdev)
|
||||
c->reg = BD71828_REG_OUT32K;
|
||||
c->mask = CLK_OUT_EN_MASK;
|
||||
break;
|
||||
case ROHM_CHIP_TYPE_BD70528:
|
||||
c->reg = BD70528_REG_OUT32K;
|
||||
c->mask = CLK_OUT_EN_MASK;
|
||||
break;
|
||||
case ROHM_CHIP_TYPE_BD71815:
|
||||
c->reg = BD71815_REG_OUT32K;
|
||||
c->mask = CLK_OUT_EN_MASK;
|
||||
@ -150,7 +144,6 @@ static int bd71837_clk_probe(struct platform_device *pdev)
|
||||
static const struct platform_device_id bd718x7_clk_id[] = {
|
||||
{ "bd71837-clk", ROHM_CHIP_TYPE_BD71837 },
|
||||
{ "bd71847-clk", ROHM_CHIP_TYPE_BD71847 },
|
||||
{ "bd70528-clk", ROHM_CHIP_TYPE_BD70528 },
|
||||
{ "bd71828-clk", ROHM_CHIP_TYPE_BD71828 },
|
||||
{ "bd71815-clk", ROHM_CHIP_TYPE_BD71815 },
|
||||
{ },
|
||||
@ -168,6 +161,6 @@ static struct platform_driver bd71837_clk = {
|
||||
module_platform_driver(bd71837_clk);
|
||||
|
||||
MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
|
||||
MODULE_DESCRIPTION("BD718(15/18/28/37/47/50) and BD70528 chip clk driver");
|
||||
MODULE_DESCRIPTION("BD718(15/18/28/37/47/50) and chip clk driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:bd718xx-clk");
|
||||
|
1599
drivers/clk/clk-lmk04832.c
Normal file
1599
drivers/clk/clk-lmk04832.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -10,8 +10,11 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/reset-controller.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
@ -245,7 +248,7 @@ static const char * const dsi_src[] = {
|
||||
};
|
||||
|
||||
static const char * const rtc_src[] = {
|
||||
"off", "ck_lse", "ck_lsi", "ck_hse_rtc"
|
||||
"off", "ck_lse", "ck_lsi", "ck_hse"
|
||||
};
|
||||
|
||||
static const char * const mco1_src[] = {
|
||||
@ -469,7 +472,7 @@ static const struct clk_ops mp1_gate_clk_ops = {
|
||||
.is_enabled = clk_gate_is_enabled,
|
||||
};
|
||||
|
||||
static struct clk_hw *_get_stm32_mux(void __iomem *base,
|
||||
static struct clk_hw *_get_stm32_mux(struct device *dev, void __iomem *base,
|
||||
const struct stm32_mux_cfg *cfg,
|
||||
spinlock_t *lock)
|
||||
{
|
||||
@ -478,7 +481,7 @@ static struct clk_hw *_get_stm32_mux(void __iomem *base,
|
||||
struct clk_hw *mux_hw;
|
||||
|
||||
if (cfg->mmux) {
|
||||
mmux = kzalloc(sizeof(*mmux), GFP_KERNEL);
|
||||
mmux = devm_kzalloc(dev, sizeof(*mmux), GFP_KERNEL);
|
||||
if (!mmux)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@ -493,7 +496,7 @@ static struct clk_hw *_get_stm32_mux(void __iomem *base,
|
||||
cfg->mmux->hws[cfg->mmux->nbr_clk++] = mux_hw;
|
||||
|
||||
} else {
|
||||
mux = kzalloc(sizeof(*mux), GFP_KERNEL);
|
||||
mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
|
||||
if (!mux)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@ -509,13 +512,13 @@ static struct clk_hw *_get_stm32_mux(void __iomem *base,
|
||||
return mux_hw;
|
||||
}
|
||||
|
||||
static struct clk_hw *_get_stm32_div(void __iomem *base,
|
||||
static struct clk_hw *_get_stm32_div(struct device *dev, void __iomem *base,
|
||||
const struct stm32_div_cfg *cfg,
|
||||
spinlock_t *lock)
|
||||
{
|
||||
struct clk_divider *div;
|
||||
|
||||
div = kzalloc(sizeof(*div), GFP_KERNEL);
|
||||
div = devm_kzalloc(dev, sizeof(*div), GFP_KERNEL);
|
||||
|
||||
if (!div)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
@ -530,16 +533,16 @@ static struct clk_hw *_get_stm32_div(void __iomem *base,
|
||||
return &div->hw;
|
||||
}
|
||||
|
||||
static struct clk_hw *
|
||||
_get_stm32_gate(void __iomem *base,
|
||||
const struct stm32_gate_cfg *cfg, spinlock_t *lock)
|
||||
static struct clk_hw *_get_stm32_gate(struct device *dev, void __iomem *base,
|
||||
const struct stm32_gate_cfg *cfg,
|
||||
spinlock_t *lock)
|
||||
{
|
||||
struct stm32_clk_mgate *mgate;
|
||||
struct clk_gate *gate;
|
||||
struct clk_hw *gate_hw;
|
||||
|
||||
if (cfg->mgate) {
|
||||
mgate = kzalloc(sizeof(*mgate), GFP_KERNEL);
|
||||
mgate = devm_kzalloc(dev, sizeof(*mgate), GFP_KERNEL);
|
||||
if (!mgate)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@ -554,7 +557,7 @@ _get_stm32_gate(void __iomem *base,
|
||||
gate_hw = &mgate->gate.hw;
|
||||
|
||||
} else {
|
||||
gate = kzalloc(sizeof(*gate), GFP_KERNEL);
|
||||
gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL);
|
||||
if (!gate)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@ -592,7 +595,7 @@ clk_stm32_register_gate_ops(struct device *dev,
|
||||
if (cfg->ops)
|
||||
init.ops = cfg->ops;
|
||||
|
||||
hw = _get_stm32_gate(base, cfg, lock);
|
||||
hw = _get_stm32_gate(dev, base, cfg, lock);
|
||||
if (IS_ERR(hw))
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@ -623,7 +626,7 @@ clk_stm32_register_composite(struct device *dev,
|
||||
gate_ops = NULL;
|
||||
|
||||
if (cfg->mux) {
|
||||
mux_hw = _get_stm32_mux(base, cfg->mux, lock);
|
||||
mux_hw = _get_stm32_mux(dev, base, cfg->mux, lock);
|
||||
|
||||
if (!IS_ERR(mux_hw)) {
|
||||
mux_ops = &clk_mux_ops;
|
||||
@ -634,7 +637,7 @@ clk_stm32_register_composite(struct device *dev,
|
||||
}
|
||||
|
||||
if (cfg->div) {
|
||||
div_hw = _get_stm32_div(base, cfg->div, lock);
|
||||
div_hw = _get_stm32_div(dev, base, cfg->div, lock);
|
||||
|
||||
if (!IS_ERR(div_hw)) {
|
||||
div_ops = &clk_divider_ops;
|
||||
@ -645,7 +648,7 @@ clk_stm32_register_composite(struct device *dev,
|
||||
}
|
||||
|
||||
if (cfg->gate) {
|
||||
gate_hw = _get_stm32_gate(base, cfg->gate, lock);
|
||||
gate_hw = _get_stm32_gate(dev, base, cfg->gate, lock);
|
||||
|
||||
if (!IS_ERR(gate_hw)) {
|
||||
gate_ops = &clk_gate_ops;
|
||||
@ -731,6 +734,7 @@ struct stm32_pll_obj {
|
||||
spinlock_t *lock;
|
||||
void __iomem *reg;
|
||||
struct clk_hw hw;
|
||||
struct clk_mux mux;
|
||||
};
|
||||
|
||||
#define to_pll(_hw) container_of(_hw, struct stm32_pll_obj, hw)
|
||||
@ -745,6 +749,8 @@ struct stm32_pll_obj {
|
||||
#define FRAC_MASK 0x1FFF
|
||||
#define FRAC_SHIFT 3
|
||||
#define FRACLE BIT(16)
|
||||
#define PLL_MUX_SHIFT 0
|
||||
#define PLL_MUX_MASK 3
|
||||
|
||||
static int __pll_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
@ -856,16 +862,29 @@ static int pll_is_enabled(struct clk_hw *hw)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u8 pll_get_parent(struct clk_hw *hw)
|
||||
{
|
||||
struct stm32_pll_obj *clk_elem = to_pll(hw);
|
||||
struct clk_hw *mux_hw = &clk_elem->mux.hw;
|
||||
|
||||
__clk_hw_set_clk(mux_hw, hw);
|
||||
|
||||
return clk_mux_ops.get_parent(mux_hw);
|
||||
}
|
||||
|
||||
static const struct clk_ops pll_ops = {
|
||||
.enable = pll_enable,
|
||||
.disable = pll_disable,
|
||||
.recalc_rate = pll_recalc_rate,
|
||||
.is_enabled = pll_is_enabled,
|
||||
.get_parent = pll_get_parent,
|
||||
};
|
||||
|
||||
static struct clk_hw *clk_register_pll(struct device *dev, const char *name,
|
||||
const char *parent_name,
|
||||
const char * const *parent_names,
|
||||
int num_parents,
|
||||
void __iomem *reg,
|
||||
void __iomem *mux_reg,
|
||||
unsigned long flags,
|
||||
spinlock_t *lock)
|
||||
{
|
||||
@ -874,15 +893,22 @@ static struct clk_hw *clk_register_pll(struct device *dev, const char *name,
|
||||
struct clk_hw *hw;
|
||||
int err;
|
||||
|
||||
element = kzalloc(sizeof(*element), GFP_KERNEL);
|
||||
element = devm_kzalloc(dev, sizeof(*element), GFP_KERNEL);
|
||||
if (!element)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
init.name = name;
|
||||
init.ops = &pll_ops;
|
||||
init.flags = flags;
|
||||
init.parent_names = &parent_name;
|
||||
init.num_parents = 1;
|
||||
init.parent_names = parent_names;
|
||||
init.num_parents = num_parents;
|
||||
|
||||
element->mux.lock = lock;
|
||||
element->mux.reg = mux_reg;
|
||||
element->mux.shift = PLL_MUX_SHIFT;
|
||||
element->mux.mask = PLL_MUX_MASK;
|
||||
element->mux.flags = CLK_MUX_READ_ONLY;
|
||||
element->mux.reg = mux_reg;
|
||||
|
||||
element->hw.init = &init;
|
||||
element->reg = reg;
|
||||
@ -891,10 +917,8 @@ static struct clk_hw *clk_register_pll(struct device *dev, const char *name,
|
||||
hw = &element->hw;
|
||||
err = clk_hw_register(dev, hw);
|
||||
|
||||
if (err) {
|
||||
kfree(element);
|
||||
if (err)
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
return hw;
|
||||
}
|
||||
@ -1005,7 +1029,7 @@ static struct clk_hw *clk_register_cktim(struct device *dev, const char *name,
|
||||
struct clk_hw *hw;
|
||||
int err;
|
||||
|
||||
tim_ker = kzalloc(sizeof(*tim_ker), GFP_KERNEL);
|
||||
tim_ker = devm_kzalloc(dev, sizeof(*tim_ker), GFP_KERNEL);
|
||||
if (!tim_ker)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@ -1023,16 +1047,56 @@ static struct clk_hw *clk_register_cktim(struct device *dev, const char *name,
|
||||
hw = &tim_ker->hw;
|
||||
err = clk_hw_register(dev, hw);
|
||||
|
||||
if (err) {
|
||||
kfree(tim_ker);
|
||||
if (err)
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
return hw;
|
||||
}
|
||||
|
||||
/* The divider of RTC clock concerns only ck_hse clock */
|
||||
#define HSE_RTC 3
|
||||
|
||||
static unsigned long clk_divider_rtc_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
if (clk_hw_get_parent(hw) == clk_hw_get_parent_by_index(hw, HSE_RTC))
|
||||
return clk_divider_ops.recalc_rate(hw, parent_rate);
|
||||
|
||||
return parent_rate;
|
||||
}
|
||||
|
||||
static int clk_divider_rtc_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
if (clk_hw_get_parent(hw) == clk_hw_get_parent_by_index(hw, HSE_RTC))
|
||||
return clk_divider_ops.set_rate(hw, rate, parent_rate);
|
||||
|
||||
return parent_rate;
|
||||
}
|
||||
|
||||
static int clk_divider_rtc_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
|
||||
{
|
||||
unsigned long best_parent_rate = req->best_parent_rate;
|
||||
|
||||
if (req->best_parent_hw == clk_hw_get_parent_by_index(hw, HSE_RTC)) {
|
||||
req->rate = clk_divider_ops.round_rate(hw, req->rate, &best_parent_rate);
|
||||
req->best_parent_rate = best_parent_rate;
|
||||
} else {
|
||||
req->rate = best_parent_rate;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops rtc_div_clk_ops = {
|
||||
.recalc_rate = clk_divider_rtc_recalc_rate,
|
||||
.set_rate = clk_divider_rtc_set_rate,
|
||||
.determine_rate = clk_divider_rtc_determine_rate
|
||||
};
|
||||
|
||||
struct stm32_pll_cfg {
|
||||
u32 offset;
|
||||
u32 muxoff;
|
||||
};
|
||||
|
||||
static struct clk_hw *_clk_register_pll(struct device *dev,
|
||||
@ -1042,8 +1106,11 @@ static struct clk_hw *_clk_register_pll(struct device *dev,
|
||||
{
|
||||
struct stm32_pll_cfg *stm_pll_cfg = cfg->cfg;
|
||||
|
||||
return clk_register_pll(dev, cfg->name, cfg->parent_name,
|
||||
base + stm_pll_cfg->offset, cfg->flags, lock);
|
||||
return clk_register_pll(dev, cfg->name, cfg->parent_names,
|
||||
cfg->num_parents,
|
||||
base + stm_pll_cfg->offset,
|
||||
base + stm_pll_cfg->muxoff,
|
||||
cfg->flags, lock);
|
||||
}
|
||||
|
||||
struct stm32_cktim_cfg {
|
||||
@ -1153,14 +1220,16 @@ _clk_stm32_register_composite(struct device *dev,
|
||||
.func = _clk_hw_register_mux,\
|
||||
}
|
||||
|
||||
#define PLL(_id, _name, _parent, _flags, _offset)\
|
||||
#define PLL(_id, _name, _parents, _flags, _offset_p, _offset_mux)\
|
||||
{\
|
||||
.id = _id,\
|
||||
.name = _name,\
|
||||
.parent_name = _parent,\
|
||||
.flags = _flags,\
|
||||
.parent_names = _parents,\
|
||||
.num_parents = ARRAY_SIZE(_parents),\
|
||||
.flags = CLK_IGNORE_UNUSED | (_flags),\
|
||||
.cfg = &(struct stm32_pll_cfg) {\
|
||||
.offset = _offset,\
|
||||
.offset = _offset_p,\
|
||||
.muxoff = _offset_mux,\
|
||||
},\
|
||||
.func = _clk_register_pll,\
|
||||
}
|
||||
@ -1243,6 +1312,10 @@ _clk_stm32_register_composite(struct device *dev,
|
||||
_STM32_DIV(_div_offset, _div_shift, _div_width,\
|
||||
_div_flags, _div_table, NULL)\
|
||||
|
||||
#define _DIV_RTC(_div_offset, _div_shift, _div_width, _div_flags, _div_table)\
|
||||
_STM32_DIV(_div_offset, _div_shift, _div_width,\
|
||||
_div_flags, _div_table, &rtc_div_clk_ops)
|
||||
|
||||
#define _STM32_MUX(_offset, _shift, _width, _mux_flags, _mmux, _ops)\
|
||||
.mux = &(struct stm32_mux_cfg) {\
|
||||
&(struct mux_cfg) {\
|
||||
@ -1657,36 +1730,26 @@ static const struct stm32_mux_cfg ker_mux_cfg[M_LAST] = {
|
||||
};
|
||||
|
||||
static const struct clock_config stm32mp1_clock_cfg[] = {
|
||||
/* Oscillator divider */
|
||||
DIV(NO_ID, "clk-hsi-div", "clk-hsi", CLK_DIVIDER_POWER_OF_TWO,
|
||||
RCC_HSICFGR, 0, 2, CLK_DIVIDER_READ_ONLY),
|
||||
|
||||
/* External / Internal Oscillators */
|
||||
GATE_MP1(CK_HSE, "ck_hse", "clk-hse", 0, RCC_OCENSETR, 8, 0),
|
||||
/* ck_csi is used by IO compensation and should be critical */
|
||||
GATE_MP1(CK_CSI, "ck_csi", "clk-csi", CLK_IS_CRITICAL,
|
||||
RCC_OCENSETR, 4, 0),
|
||||
GATE_MP1(CK_HSI, "ck_hsi", "clk-hsi-div", 0, RCC_OCENSETR, 0, 0),
|
||||
COMPOSITE(CK_HSI, "ck_hsi", PARENT("clk-hsi"), 0,
|
||||
_GATE_MP1(RCC_OCENSETR, 0, 0),
|
||||
_NO_MUX,
|
||||
_DIV(RCC_HSICFGR, 0, 2, CLK_DIVIDER_POWER_OF_TWO |
|
||||
CLK_DIVIDER_READ_ONLY, NULL)),
|
||||
GATE(CK_LSI, "ck_lsi", "clk-lsi", 0, RCC_RDLSICR, 0, 0),
|
||||
GATE(CK_LSE, "ck_lse", "clk-lse", 0, RCC_BDCR, 0, 0),
|
||||
|
||||
FIXED_FACTOR(CK_HSE_DIV2, "clk-hse-div2", "ck_hse", 0, 1, 2),
|
||||
|
||||
/* ref clock pll */
|
||||
MUX(NO_ID, "ref1", ref12_parents, CLK_OPS_PARENT_ENABLE, RCC_RCK12SELR,
|
||||
0, 2, CLK_MUX_READ_ONLY),
|
||||
|
||||
MUX(NO_ID, "ref3", ref3_parents, CLK_OPS_PARENT_ENABLE, RCC_RCK3SELR,
|
||||
0, 2, CLK_MUX_READ_ONLY),
|
||||
|
||||
MUX(NO_ID, "ref4", ref4_parents, CLK_OPS_PARENT_ENABLE, RCC_RCK4SELR,
|
||||
0, 2, CLK_MUX_READ_ONLY),
|
||||
|
||||
/* PLLs */
|
||||
PLL(PLL1, "pll1", "ref1", CLK_IGNORE_UNUSED, RCC_PLL1CR),
|
||||
PLL(PLL2, "pll2", "ref1", CLK_IGNORE_UNUSED, RCC_PLL2CR),
|
||||
PLL(PLL3, "pll3", "ref3", CLK_IGNORE_UNUSED, RCC_PLL3CR),
|
||||
PLL(PLL4, "pll4", "ref4", CLK_IGNORE_UNUSED, RCC_PLL4CR),
|
||||
PLL(PLL1, "pll1", ref12_parents, 0, RCC_PLL1CR, RCC_RCK12SELR),
|
||||
PLL(PLL2, "pll2", ref12_parents, 0, RCC_PLL2CR, RCC_RCK12SELR),
|
||||
PLL(PLL3, "pll3", ref3_parents, 0, RCC_PLL3CR, RCC_RCK3SELR),
|
||||
PLL(PLL4, "pll4", ref4_parents, 0, RCC_PLL4CR, RCC_RCK4SELR),
|
||||
|
||||
/* ODF */
|
||||
COMPOSITE(PLL1_P, "pll1_p", PARENT("pll1"), 0,
|
||||
@ -1965,13 +2028,10 @@ static const struct clock_config stm32mp1_clock_cfg[] = {
|
||||
_DIV(RCC_ETHCKSELR, 4, 4, 0, NULL)),
|
||||
|
||||
/* RTC clock */
|
||||
DIV(NO_ID, "ck_hse_rtc", "ck_hse", 0, RCC_RTCDIVR, 0, 6, 0),
|
||||
|
||||
COMPOSITE(RTC, "ck_rtc", rtc_src, CLK_OPS_PARENT_ENABLE |
|
||||
CLK_SET_RATE_PARENT,
|
||||
COMPOSITE(RTC, "ck_rtc", rtc_src, CLK_OPS_PARENT_ENABLE,
|
||||
_GATE(RCC_BDCR, 20, 0),
|
||||
_MUX(RCC_BDCR, 16, 2, 0),
|
||||
_NO_DIV),
|
||||
_DIV_RTC(RCC_RTCDIVR, 0, 6, 0, NULL)),
|
||||
|
||||
/* MCO clocks */
|
||||
COMPOSITE(CK_MCO1, "ck_mco1", mco1_src, CLK_OPS_PARENT_ENABLE |
|
||||
@ -1996,16 +2056,76 @@ static const struct clock_config stm32mp1_clock_cfg[] = {
|
||||
_DIV(RCC_DBGCFGR, 0, 3, 0, ck_trace_div_table)),
|
||||
};
|
||||
|
||||
struct stm32_clock_match_data {
|
||||
static const u32 stm32mp1_clock_secured[] = {
|
||||
CK_HSE,
|
||||
CK_HSI,
|
||||
CK_CSI,
|
||||
CK_LSI,
|
||||
CK_LSE,
|
||||
PLL1,
|
||||
PLL2,
|
||||
PLL1_P,
|
||||
PLL2_P,
|
||||
PLL2_Q,
|
||||
PLL2_R,
|
||||
CK_MPU,
|
||||
CK_AXI,
|
||||
SPI6,
|
||||
I2C4,
|
||||
I2C6,
|
||||
USART1,
|
||||
RTCAPB,
|
||||
TZC1,
|
||||
TZC2,
|
||||
TZPC,
|
||||
IWDG1,
|
||||
BSEC,
|
||||
STGEN,
|
||||
GPIOZ,
|
||||
CRYP1,
|
||||
HASH1,
|
||||
RNG1,
|
||||
BKPSRAM,
|
||||
RNG1_K,
|
||||
STGEN_K,
|
||||
SPI6_K,
|
||||
I2C4_K,
|
||||
I2C6_K,
|
||||
USART1_K,
|
||||
RTC,
|
||||
};
|
||||
|
||||
static bool stm32_check_security(const struct clock_config *cfg)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(stm32mp1_clock_secured); i++)
|
||||
if (cfg->id == stm32mp1_clock_secured[i])
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
struct stm32_rcc_match_data {
|
||||
const struct clock_config *cfg;
|
||||
unsigned int num;
|
||||
unsigned int maxbinding;
|
||||
u32 clear_offset;
|
||||
bool (*check_security)(const struct clock_config *cfg);
|
||||
};
|
||||
|
||||
static struct stm32_clock_match_data stm32mp1_data = {
|
||||
static struct stm32_rcc_match_data stm32mp1_data = {
|
||||
.cfg = stm32mp1_clock_cfg,
|
||||
.num = ARRAY_SIZE(stm32mp1_clock_cfg),
|
||||
.maxbinding = STM32MP1_LAST_CLK,
|
||||
.clear_offset = RCC_CLR,
|
||||
};
|
||||
|
||||
static struct stm32_rcc_match_data stm32mp1_data_secure = {
|
||||
.cfg = stm32mp1_clock_cfg,
|
||||
.num = ARRAY_SIZE(stm32mp1_clock_cfg),
|
||||
.maxbinding = STM32MP1_LAST_CLK,
|
||||
.clear_offset = RCC_CLR,
|
||||
.check_security = &stm32_check_security
|
||||
};
|
||||
|
||||
static const struct of_device_id stm32mp1_match_data[] = {
|
||||
@ -2013,8 +2133,13 @@ static const struct of_device_id stm32mp1_match_data[] = {
|
||||
.compatible = "st,stm32mp1-rcc",
|
||||
.data = &stm32mp1_data,
|
||||
},
|
||||
{
|
||||
.compatible = "st,stm32mp1-rcc-secure",
|
||||
.data = &stm32mp1_data_secure,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, stm32mp1_match_data);
|
||||
|
||||
static int stm32_register_hw_clk(struct device *dev,
|
||||
struct clk_hw_onecell_data *clk_data,
|
||||
@ -2040,28 +2165,126 @@ static int stm32_register_hw_clk(struct device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stm32_rcc_init(struct device_node *np,
|
||||
void __iomem *base,
|
||||
const struct of_device_id *match_data)
|
||||
{
|
||||
struct clk_hw_onecell_data *clk_data;
|
||||
struct clk_hw **hws;
|
||||
const struct of_device_id *match;
|
||||
const struct stm32_clock_match_data *data;
|
||||
int err, n, max_binding;
|
||||
#define STM32_RESET_ID_MASK GENMASK(15, 0)
|
||||
|
||||
match = of_match_node(match_data, np);
|
||||
if (!match) {
|
||||
pr_err("%s: match data not found\n", __func__);
|
||||
return -ENODEV;
|
||||
struct stm32_reset_data {
|
||||
/* reset lock */
|
||||
spinlock_t lock;
|
||||
struct reset_controller_dev rcdev;
|
||||
void __iomem *membase;
|
||||
u32 clear_offset;
|
||||
};
|
||||
|
||||
static inline struct stm32_reset_data *
|
||||
to_stm32_reset_data(struct reset_controller_dev *rcdev)
|
||||
{
|
||||
return container_of(rcdev, struct stm32_reset_data, rcdev);
|
||||
}
|
||||
|
||||
static int stm32_reset_update(struct reset_controller_dev *rcdev,
|
||||
unsigned long id, bool assert)
|
||||
{
|
||||
struct stm32_reset_data *data = to_stm32_reset_data(rcdev);
|
||||
int reg_width = sizeof(u32);
|
||||
int bank = id / (reg_width * BITS_PER_BYTE);
|
||||
int offset = id % (reg_width * BITS_PER_BYTE);
|
||||
|
||||
if (data->clear_offset) {
|
||||
void __iomem *addr;
|
||||
|
||||
addr = data->membase + (bank * reg_width);
|
||||
if (!assert)
|
||||
addr += data->clear_offset;
|
||||
|
||||
writel(BIT(offset), addr);
|
||||
|
||||
} else {
|
||||
unsigned long flags;
|
||||
u32 reg;
|
||||
|
||||
spin_lock_irqsave(&data->lock, flags);
|
||||
|
||||
reg = readl(data->membase + (bank * reg_width));
|
||||
|
||||
if (assert)
|
||||
reg |= BIT(offset);
|
||||
else
|
||||
reg &= ~BIT(offset);
|
||||
|
||||
writel(reg, data->membase + (bank * reg_width));
|
||||
|
||||
spin_unlock_irqrestore(&data->lock, flags);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stm32_reset_assert(struct reset_controller_dev *rcdev,
|
||||
unsigned long id)
|
||||
{
|
||||
return stm32_reset_update(rcdev, id, true);
|
||||
}
|
||||
|
||||
static int stm32_reset_deassert(struct reset_controller_dev *rcdev,
|
||||
unsigned long id)
|
||||
{
|
||||
return stm32_reset_update(rcdev, id, false);
|
||||
}
|
||||
|
||||
static int stm32_reset_status(struct reset_controller_dev *rcdev,
|
||||
unsigned long id)
|
||||
{
|
||||
struct stm32_reset_data *data = to_stm32_reset_data(rcdev);
|
||||
int reg_width = sizeof(u32);
|
||||
int bank = id / (reg_width * BITS_PER_BYTE);
|
||||
int offset = id % (reg_width * BITS_PER_BYTE);
|
||||
u32 reg;
|
||||
|
||||
reg = readl(data->membase + (bank * reg_width));
|
||||
|
||||
return !!(reg & BIT(offset));
|
||||
}
|
||||
|
||||
static const struct reset_control_ops stm32_reset_ops = {
|
||||
.assert = stm32_reset_assert,
|
||||
.deassert = stm32_reset_deassert,
|
||||
.status = stm32_reset_status,
|
||||
};
|
||||
|
||||
static int stm32_rcc_reset_init(struct device *dev, void __iomem *base,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
const struct stm32_rcc_match_data *data = match->data;
|
||||
struct stm32_reset_data *reset_data = NULL;
|
||||
|
||||
data = match->data;
|
||||
|
||||
reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL);
|
||||
if (!reset_data)
|
||||
return -ENOMEM;
|
||||
|
||||
reset_data->membase = base;
|
||||
reset_data->rcdev.owner = THIS_MODULE;
|
||||
reset_data->rcdev.ops = &stm32_reset_ops;
|
||||
reset_data->rcdev.of_node = dev_of_node(dev);
|
||||
reset_data->rcdev.nr_resets = STM32_RESET_ID_MASK;
|
||||
reset_data->clear_offset = data->clear_offset;
|
||||
|
||||
return reset_controller_register(&reset_data->rcdev);
|
||||
}
|
||||
|
||||
static int stm32_rcc_clock_init(struct device *dev, void __iomem *base,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
const struct stm32_rcc_match_data *data = match->data;
|
||||
struct clk_hw_onecell_data *clk_data;
|
||||
struct clk_hw **hws;
|
||||
int err, n, max_binding;
|
||||
|
||||
max_binding = data->maxbinding;
|
||||
|
||||
clk_data = kzalloc(struct_size(clk_data, hws, max_binding),
|
||||
GFP_KERNEL);
|
||||
clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, max_binding),
|
||||
GFP_KERNEL);
|
||||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -2073,36 +2296,139 @@ static int stm32_rcc_init(struct device_node *np,
|
||||
hws[n] = ERR_PTR(-ENOENT);
|
||||
|
||||
for (n = 0; n < data->num; n++) {
|
||||
err = stm32_register_hw_clk(NULL, clk_data, base, &rlock,
|
||||
if (data->check_security && data->check_security(&data->cfg[n]))
|
||||
continue;
|
||||
|
||||
err = stm32_register_hw_clk(dev, clk_data, base, &rlock,
|
||||
&data->cfg[n]);
|
||||
if (err) {
|
||||
pr_err("%s: can't register %s\n", __func__,
|
||||
data->cfg[n].name);
|
||||
|
||||
kfree(clk_data);
|
||||
dev_err(dev, "Can't register clk %s: %d\n",
|
||||
data->cfg[n].name, err);
|
||||
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
|
||||
return of_clk_add_hw_provider(dev_of_node(dev), of_clk_hw_onecell_get, clk_data);
|
||||
}
|
||||
|
||||
static void stm32mp1_rcc_init(struct device_node *np)
|
||||
static int stm32_rcc_init(struct device *dev, void __iomem *base,
|
||||
const struct of_device_id *match_data)
|
||||
{
|
||||
const struct of_device_id *match;
|
||||
int err;
|
||||
|
||||
match = of_match_node(match_data, dev_of_node(dev));
|
||||
if (!match) {
|
||||
dev_err(dev, "match data not found\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* RCC Reset Configuration */
|
||||
err = stm32_rcc_reset_init(dev, base, match);
|
||||
if (err) {
|
||||
pr_err("stm32mp1 reset failed to initialize\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* RCC Clock Configuration */
|
||||
err = stm32_rcc_clock_init(dev, base, match);
|
||||
if (err) {
|
||||
pr_err("stm32mp1 clock failed to initialize\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stm32mp1_rcc_init(struct device *dev)
|
||||
{
|
||||
void __iomem *base;
|
||||
int ret;
|
||||
|
||||
base = of_iomap(np, 0);
|
||||
base = of_iomap(dev_of_node(dev), 0);
|
||||
if (!base) {
|
||||
pr_err("%pOFn: unable to map resource", np);
|
||||
of_node_put(np);
|
||||
return;
|
||||
pr_err("%pOFn: unable to map resource", dev_of_node(dev));
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (stm32_rcc_init(np, base, stm32mp1_match_data)) {
|
||||
iounmap(base);
|
||||
of_node_put(np);
|
||||
ret = stm32_rcc_init(dev, base, stm32mp1_match_data);
|
||||
|
||||
out:
|
||||
if (ret) {
|
||||
if (base)
|
||||
iounmap(base);
|
||||
|
||||
of_node_put(dev_of_node(dev));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
CLK_OF_DECLARE_DRIVER(stm32mp1_rcc, "st,stm32mp1-rcc", stm32mp1_rcc_init);
|
||||
static int get_clock_deps(struct device *dev)
|
||||
{
|
||||
static const char * const clock_deps_name[] = {
|
||||
"hsi", "hse", "csi", "lsi", "lse",
|
||||
};
|
||||
size_t deps_size = sizeof(struct clk *) * ARRAY_SIZE(clock_deps_name);
|
||||
struct clk **clk_deps;
|
||||
int i;
|
||||
|
||||
clk_deps = devm_kzalloc(dev, deps_size, GFP_KERNEL);
|
||||
if (!clk_deps)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(clock_deps_name); i++) {
|
||||
struct clk *clk = of_clk_get_by_name(dev_of_node(dev),
|
||||
clock_deps_name[i]);
|
||||
|
||||
if (IS_ERR(clk)) {
|
||||
if (PTR_ERR(clk) != -EINVAL && PTR_ERR(clk) != -ENOENT)
|
||||
return PTR_ERR(clk);
|
||||
} else {
|
||||
/* Device gets a reference count on the clock */
|
||||
clk_deps[i] = devm_clk_get(dev, __clk_get_name(clk));
|
||||
clk_put(clk);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stm32mp1_rcc_clocks_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
int ret = get_clock_deps(dev);
|
||||
|
||||
if (!ret)
|
||||
ret = stm32mp1_rcc_init(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int stm32mp1_rcc_clocks_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *child, *np = dev_of_node(dev);
|
||||
|
||||
for_each_available_child_of_node(np, child)
|
||||
of_clk_del_provider(child);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver stm32mp1_rcc_clocks_driver = {
|
||||
.driver = {
|
||||
.name = "stm32mp1_rcc",
|
||||
.of_match_table = stm32mp1_match_data,
|
||||
},
|
||||
.probe = stm32mp1_rcc_clocks_probe,
|
||||
.remove = stm32mp1_rcc_clocks_remove,
|
||||
};
|
||||
|
||||
static int __init stm32mp1_clocks_init(void)
|
||||
{
|
||||
return platform_driver_register(&stm32mp1_rcc_clocks_driver);
|
||||
}
|
||||
core_initcall(stm32mp1_clocks_init);
|
||||
|
@ -25,6 +25,16 @@ config INGENIC_CGU_JZ4725B
|
||||
|
||||
If building for a JZ4725B SoC, you want to say Y here.
|
||||
|
||||
config INGENIC_CGU_JZ4760
|
||||
bool "Ingenic JZ4760 CGU driver"
|
||||
default MACH_JZ4760
|
||||
select INGENIC_CGU_COMMON
|
||||
help
|
||||
Support the clocks provided by the CGU hardware on Ingenic JZ4760
|
||||
and compatible SoCs.
|
||||
|
||||
If building for a JZ4760 SoC, you want to say Y here.
|
||||
|
||||
config INGENIC_CGU_JZ4770
|
||||
bool "Ingenic JZ4770 CGU driver"
|
||||
default MACH_JZ4770
|
||||
|
@ -2,6 +2,7 @@
|
||||
obj-$(CONFIG_INGENIC_CGU_COMMON) += cgu.o pm.o
|
||||
obj-$(CONFIG_INGENIC_CGU_JZ4740) += jz4740-cgu.o
|
||||
obj-$(CONFIG_INGENIC_CGU_JZ4725B) += jz4725b-cgu.o
|
||||
obj-$(CONFIG_INGENIC_CGU_JZ4760) += jz4760-cgu.o
|
||||
obj-$(CONFIG_INGENIC_CGU_JZ4770) += jz4770-cgu.o
|
||||
obj-$(CONFIG_INGENIC_CGU_JZ4780) += jz4780-cgu.o
|
||||
obj-$(CONFIG_INGENIC_CGU_X1000) += x1000-cgu.o
|
||||
|
@ -99,13 +99,14 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
|
||||
od_enc = ctl >> pll_info->od_shift;
|
||||
od_enc &= GENMASK(pll_info->od_bits - 1, 0);
|
||||
|
||||
ctl = readl(cgu->base + pll_info->bypass_reg);
|
||||
if (pll_info->bypass_bit >= 0) {
|
||||
ctl = readl(cgu->base + pll_info->bypass_reg);
|
||||
|
||||
bypass = !pll_info->no_bypass_bit &&
|
||||
!!(ctl & BIT(pll_info->bypass_bit));
|
||||
bypass = !!(ctl & BIT(pll_info->bypass_bit));
|
||||
|
||||
if (bypass)
|
||||
return parent_rate;
|
||||
if (bypass)
|
||||
return parent_rate;
|
||||
}
|
||||
|
||||
for (od = 0; od < pll_info->od_max; od++) {
|
||||
if (pll_info->od_encoding[od] == od_enc)
|
||||
@ -118,28 +119,42 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
|
||||
n * od);
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
ingenic_pll_calc(const struct ingenic_cgu_clk_info *clk_info,
|
||||
unsigned long rate, unsigned long parent_rate,
|
||||
unsigned *pm, unsigned *pn, unsigned *pod)
|
||||
static void
|
||||
ingenic_pll_calc_m_n_od(const struct ingenic_cgu_pll_info *pll_info,
|
||||
unsigned long rate, unsigned long parent_rate,
|
||||
unsigned int *pm, unsigned int *pn, unsigned int *pod)
|
||||
{
|
||||
const struct ingenic_cgu_pll_info *pll_info;
|
||||
unsigned m, n, od;
|
||||
|
||||
pll_info = &clk_info->pll;
|
||||
od = 1;
|
||||
unsigned int m, n, od = 1;
|
||||
|
||||
/*
|
||||
* The frequency after the input divider must be between 10 and 50 MHz.
|
||||
* The highest divider yields the best resolution.
|
||||
*/
|
||||
n = parent_rate / (10 * MHZ);
|
||||
n = min_t(unsigned, n, 1 << clk_info->pll.n_bits);
|
||||
n = max_t(unsigned, n, pll_info->n_offset);
|
||||
n = min_t(unsigned int, n, 1 << pll_info->n_bits);
|
||||
n = max_t(unsigned int, n, pll_info->n_offset);
|
||||
|
||||
m = (rate / MHZ) * od * n / (parent_rate / MHZ);
|
||||
m = min_t(unsigned, m, 1 << clk_info->pll.m_bits);
|
||||
m = max_t(unsigned, m, pll_info->m_offset);
|
||||
m = min_t(unsigned int, m, 1 << pll_info->m_bits);
|
||||
m = max_t(unsigned int, m, pll_info->m_offset);
|
||||
|
||||
*pm = m;
|
||||
*pn = n;
|
||||
*pod = od;
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
ingenic_pll_calc(const struct ingenic_cgu_clk_info *clk_info,
|
||||
unsigned long rate, unsigned long parent_rate,
|
||||
unsigned int *pm, unsigned int *pn, unsigned int *pod)
|
||||
{
|
||||
const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;
|
||||
unsigned int m, n, od;
|
||||
|
||||
if (pll_info->calc_m_n_od)
|
||||
(*pll_info->calc_m_n_od)(pll_info, rate, parent_rate, &m, &n, &od);
|
||||
else
|
||||
ingenic_pll_calc_m_n_od(pll_info, rate, parent_rate, &m, &n, &od);
|
||||
|
||||
if (pm)
|
||||
*pm = m;
|
||||
@ -225,11 +240,13 @@ static int ingenic_pll_enable(struct clk_hw *hw)
|
||||
u32 ctl;
|
||||
|
||||
spin_lock_irqsave(&cgu->lock, flags);
|
||||
ctl = readl(cgu->base + pll_info->bypass_reg);
|
||||
if (pll_info->bypass_bit >= 0) {
|
||||
ctl = readl(cgu->base + pll_info->bypass_reg);
|
||||
|
||||
ctl &= ~BIT(pll_info->bypass_bit);
|
||||
ctl &= ~BIT(pll_info->bypass_bit);
|
||||
|
||||
writel(ctl, cgu->base + pll_info->bypass_reg);
|
||||
writel(ctl, cgu->base + pll_info->bypass_reg);
|
||||
}
|
||||
|
||||
ctl = readl(cgu->base + pll_info->reg);
|
||||
|
||||
@ -369,18 +386,23 @@ ingenic_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
|
||||
struct ingenic_cgu *cgu = ingenic_clk->cgu;
|
||||
unsigned long rate = parent_rate;
|
||||
u32 div_reg, div;
|
||||
u8 parent;
|
||||
|
||||
if (clk_info->type & CGU_CLK_DIV) {
|
||||
div_reg = readl(cgu->base + clk_info->div.reg);
|
||||
div = (div_reg >> clk_info->div.shift) &
|
||||
GENMASK(clk_info->div.bits - 1, 0);
|
||||
parent = ingenic_clk_get_parent(hw);
|
||||
|
||||
if (clk_info->div.div_table)
|
||||
div = clk_info->div.div_table[div];
|
||||
else
|
||||
div = (div + 1) * clk_info->div.div;
|
||||
if (!(clk_info->div.bypass_mask & BIT(parent))) {
|
||||
div_reg = readl(cgu->base + clk_info->div.reg);
|
||||
div = (div_reg >> clk_info->div.shift) &
|
||||
GENMASK(clk_info->div.bits - 1, 0);
|
||||
|
||||
rate /= div;
|
||||
if (clk_info->div.div_table)
|
||||
div = clk_info->div.div_table[div];
|
||||
else
|
||||
div = (div + 1) * clk_info->div.div;
|
||||
|
||||
rate /= div;
|
||||
}
|
||||
} else if (clk_info->type & CGU_CLK_FIXDIV) {
|
||||
rate /= clk_info->fixdiv.div;
|
||||
}
|
||||
@ -410,10 +432,16 @@ ingenic_clk_calc_hw_div(const struct ingenic_cgu_clk_info *clk_info,
|
||||
}
|
||||
|
||||
static unsigned
|
||||
ingenic_clk_calc_div(const struct ingenic_cgu_clk_info *clk_info,
|
||||
ingenic_clk_calc_div(struct clk_hw *hw,
|
||||
const struct ingenic_cgu_clk_info *clk_info,
|
||||
unsigned long parent_rate, unsigned long req_rate)
|
||||
{
|
||||
unsigned int div, hw_div;
|
||||
u8 parent;
|
||||
|
||||
parent = ingenic_clk_get_parent(hw);
|
||||
if (clk_info->div.bypass_mask & BIT(parent))
|
||||
return 1;
|
||||
|
||||
/* calculate the divide */
|
||||
div = DIV_ROUND_UP(parent_rate, req_rate);
|
||||
@ -448,7 +476,7 @@ ingenic_clk_round_rate(struct clk_hw *hw, unsigned long req_rate,
|
||||
unsigned int div = 1;
|
||||
|
||||
if (clk_info->type & CGU_CLK_DIV)
|
||||
div = ingenic_clk_calc_div(clk_info, *parent_rate, req_rate);
|
||||
div = ingenic_clk_calc_div(hw, clk_info, *parent_rate, req_rate);
|
||||
else if (clk_info->type & CGU_CLK_FIXDIV)
|
||||
div = clk_info->fixdiv.div;
|
||||
else if (clk_hw_can_set_rate_parent(hw))
|
||||
@ -480,7 +508,7 @@ ingenic_clk_set_rate(struct clk_hw *hw, unsigned long req_rate,
|
||||
int ret = 0;
|
||||
|
||||
if (clk_info->type & CGU_CLK_DIV) {
|
||||
div = ingenic_clk_calc_div(clk_info, parent_rate, req_rate);
|
||||
div = ingenic_clk_calc_div(hw, clk_info, parent_rate, req_rate);
|
||||
rate = DIV_ROUND_UP(parent_rate, div);
|
||||
|
||||
if (rate != req_rate)
|
||||
|
@ -39,10 +39,10 @@
|
||||
* their encoded values in the PLL control register, or -1 for
|
||||
* unsupported values
|
||||
* @bypass_reg: the offset of the bypass control register within the CGU
|
||||
* @bypass_bit: the index of the bypass bit in the PLL control register
|
||||
* @bypass_bit: the index of the bypass bit in the PLL control register, or
|
||||
* -1 if there is no bypass bit
|
||||
* @enable_bit: the index of the enable bit in the PLL control register
|
||||
* @stable_bit: the index of the stable bit in the PLL control register
|
||||
* @no_bypass_bit: if set, the PLL has no bypass functionality
|
||||
*/
|
||||
struct ingenic_cgu_pll_info {
|
||||
unsigned reg;
|
||||
@ -52,10 +52,12 @@ struct ingenic_cgu_pll_info {
|
||||
u8 n_shift, n_bits, n_offset;
|
||||
u8 od_shift, od_bits, od_max;
|
||||
unsigned bypass_reg;
|
||||
u8 bypass_bit;
|
||||
s8 bypass_bit;
|
||||
u8 enable_bit;
|
||||
u8 stable_bit;
|
||||
bool no_bypass_bit;
|
||||
void (*calc_m_n_od)(const struct ingenic_cgu_pll_info *pll_info,
|
||||
unsigned long rate, unsigned long parent_rate,
|
||||
unsigned int *m, unsigned int *n, unsigned int *od);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -84,6 +86,7 @@ struct ingenic_cgu_mux_info {
|
||||
* isn't one
|
||||
* @busy_bit: the index of the busy bit within reg, or -1 if there isn't one
|
||||
* @stop_bit: the index of the stop bit within reg, or -1 if there isn't one
|
||||
* @bypass_mask: mask of parent clocks for which the divider does not apply
|
||||
* @div_table: optional table to map the value read from the register to the
|
||||
* actual divider value
|
||||
*/
|
||||
@ -95,6 +98,7 @@ struct ingenic_cgu_div_info {
|
||||
s8 ce_bit;
|
||||
s8 busy_bit;
|
||||
s8 stop_bit;
|
||||
u8 bypass_mask;
|
||||
const u8 *div_table;
|
||||
};
|
||||
|
||||
|
@ -80,7 +80,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
|
||||
"pll half", CGU_CLK_DIV,
|
||||
.parents = { JZ4725B_CLK_PLL, -1, -1, -1 },
|
||||
.div = {
|
||||
CGU_REG_CPCCR, 21, 1, 1, -1, -1, -1,
|
||||
CGU_REG_CPCCR, 21, 1, 1, -1, -1, -1, 0,
|
||||
jz4725b_cgu_pll_half_div_table,
|
||||
},
|
||||
},
|
||||
@ -89,7 +89,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
|
||||
"cclk", CGU_CLK_DIV,
|
||||
.parents = { JZ4725B_CLK_PLL, -1, -1, -1 },
|
||||
.div = {
|
||||
CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1,
|
||||
CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, 0,
|
||||
jz4725b_cgu_cpccr_div_table,
|
||||
},
|
||||
},
|
||||
@ -98,7 +98,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
|
||||
"hclk", CGU_CLK_DIV,
|
||||
.parents = { JZ4725B_CLK_PLL, -1, -1, -1 },
|
||||
.div = {
|
||||
CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1,
|
||||
CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1, 0,
|
||||
jz4725b_cgu_cpccr_div_table,
|
||||
},
|
||||
},
|
||||
@ -107,7 +107,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
|
||||
"pclk", CGU_CLK_DIV,
|
||||
.parents = { JZ4725B_CLK_PLL, -1, -1, -1 },
|
||||
.div = {
|
||||
CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1,
|
||||
CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1, 0,
|
||||
jz4725b_cgu_cpccr_div_table,
|
||||
},
|
||||
},
|
||||
@ -116,7 +116,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
|
||||
"mclk", CGU_CLK_DIV,
|
||||
.parents = { JZ4725B_CLK_PLL, -1, -1, -1 },
|
||||
.div = {
|
||||
CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1,
|
||||
CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, 0,
|
||||
jz4725b_cgu_cpccr_div_table,
|
||||
},
|
||||
},
|
||||
@ -125,7 +125,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
|
||||
"ipu", CGU_CLK_DIV | CGU_CLK_GATE,
|
||||
.parents = { JZ4725B_CLK_PLL, -1, -1, -1 },
|
||||
.div = {
|
||||
CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1,
|
||||
CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1, 0,
|
||||
jz4725b_cgu_cpccr_div_table,
|
||||
},
|
||||
.gate = { CGU_REG_CLKGR, 13 },
|
||||
|
@ -95,7 +95,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
|
||||
"pll half", CGU_CLK_DIV,
|
||||
.parents = { JZ4740_CLK_PLL, -1, -1, -1 },
|
||||
.div = {
|
||||
CGU_REG_CPCCR, 21, 1, 1, -1, -1, -1,
|
||||
CGU_REG_CPCCR, 21, 1, 1, -1, -1, -1, 0,
|
||||
jz4740_cgu_pll_half_div_table,
|
||||
},
|
||||
},
|
||||
@ -104,7 +104,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
|
||||
"cclk", CGU_CLK_DIV,
|
||||
.parents = { JZ4740_CLK_PLL, -1, -1, -1 },
|
||||
.div = {
|
||||
CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1,
|
||||
CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, 0,
|
||||
jz4740_cgu_cpccr_div_table,
|
||||
},
|
||||
},
|
||||
@ -113,7 +113,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
|
||||
"hclk", CGU_CLK_DIV,
|
||||
.parents = { JZ4740_CLK_PLL, -1, -1, -1 },
|
||||
.div = {
|
||||
CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1,
|
||||
CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1, 0,
|
||||
jz4740_cgu_cpccr_div_table,
|
||||
},
|
||||
},
|
||||
@ -122,7 +122,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
|
||||
"pclk", CGU_CLK_DIV,
|
||||
.parents = { JZ4740_CLK_PLL, -1, -1, -1 },
|
||||
.div = {
|
||||
CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1,
|
||||
CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1, 0,
|
||||
jz4740_cgu_cpccr_div_table,
|
||||
},
|
||||
},
|
||||
@ -131,7 +131,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
|
||||
"mclk", CGU_CLK_DIV,
|
||||
.parents = { JZ4740_CLK_PLL, -1, -1, -1 },
|
||||
.div = {
|
||||
CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1,
|
||||
CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, 0,
|
||||
jz4740_cgu_cpccr_div_table,
|
||||
},
|
||||
},
|
||||
@ -140,7 +140,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
|
||||
"lcd", CGU_CLK_DIV | CGU_CLK_GATE,
|
||||
.parents = { JZ4740_CLK_PLL_HALF, -1, -1, -1 },
|
||||
.div = {
|
||||
CGU_REG_CPCCR, 16, 1, 5, 22, -1, -1,
|
||||
CGU_REG_CPCCR, 16, 1, 5, 22, -1, -1, 0,
|
||||
jz4740_cgu_cpccr_div_table,
|
||||
},
|
||||
.gate = { CGU_REG_CLKGR, 10 },
|
||||
|
428
drivers/clk/ingenic/jz4760-cgu.c
Normal file
428
drivers/clk/ingenic/jz4760-cgu.c
Normal file
@ -0,0 +1,428 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* JZ4760 SoC CGU driver
|
||||
* Copyright 2018, Paul Cercueil <paul@crapouillou.net>
|
||||
*/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include <linux/clk.h>
|
||||
|
||||
#include <dt-bindings/clock/jz4760-cgu.h>
|
||||
|
||||
#include "cgu.h"
|
||||
#include "pm.h"
|
||||
|
||||
#define MHZ (1000 * 1000)
|
||||
|
||||
/*
|
||||
* CPM registers offset address definition
|
||||
*/
|
||||
#define CGU_REG_CPCCR 0x00
|
||||
#define CGU_REG_LCR 0x04
|
||||
#define CGU_REG_CPPCR0 0x10
|
||||
#define CGU_REG_CLKGR0 0x20
|
||||
#define CGU_REG_OPCR 0x24
|
||||
#define CGU_REG_CLKGR1 0x28
|
||||
#define CGU_REG_CPPCR1 0x30
|
||||
#define CGU_REG_USBPCR 0x3c
|
||||
#define CGU_REG_USBCDR 0x50
|
||||
#define CGU_REG_I2SCDR 0x60
|
||||
#define CGU_REG_LPCDR 0x64
|
||||
#define CGU_REG_MSCCDR 0x68
|
||||
#define CGU_REG_UHCCDR 0x6c
|
||||
#define CGU_REG_SSICDR 0x74
|
||||
#define CGU_REG_CIMCDR 0x7c
|
||||
#define CGU_REG_GPSCDR 0x80
|
||||
#define CGU_REG_PCMCDR 0x84
|
||||
#define CGU_REG_GPUCDR 0x88
|
||||
|
||||
static const s8 pll_od_encoding[8] = {
|
||||
0x0, 0x1, -1, 0x2, -1, -1, -1, 0x3,
|
||||
};
|
||||
|
||||
static const u8 jz4760_cgu_cpccr_div_table[] = {
|
||||
1, 2, 3, 4, 6, 8,
|
||||
};
|
||||
|
||||
static const u8 jz4760_cgu_pll_half_div_table[] = {
|
||||
2, 1,
|
||||
};
|
||||
|
||||
static void
|
||||
jz4760_cgu_calc_m_n_od(const struct ingenic_cgu_pll_info *pll_info,
|
||||
unsigned long rate, unsigned long parent_rate,
|
||||
unsigned int *pm, unsigned int *pn, unsigned int *pod)
|
||||
{
|
||||
unsigned int m, n, od, m_max = (1 << pll_info->m_bits) - 2;
|
||||
|
||||
/* The frequency after the N divider must be between 1 and 50 MHz. */
|
||||
n = parent_rate / (1 * MHZ);
|
||||
|
||||
/* The N divider must be >= 2. */
|
||||
n = clamp_val(n, 2, 1 << pll_info->n_bits);
|
||||
|
||||
for (;; n >>= 1) {
|
||||
od = (unsigned int)-1;
|
||||
|
||||
do {
|
||||
m = (rate / MHZ) * (1 << ++od) * n / (parent_rate / MHZ);
|
||||
} while ((m > m_max || m & 1) && (od < 4));
|
||||
|
||||
if (od < 4 && m >= 4 && m <= m_max)
|
||||
break;
|
||||
}
|
||||
|
||||
*pm = m;
|
||||
*pn = n;
|
||||
*pod = 1 << od;
|
||||
}
|
||||
|
||||
static const struct ingenic_cgu_clk_info jz4760_cgu_clocks[] = {
|
||||
|
||||
/* External clocks */
|
||||
|
||||
[JZ4760_CLK_EXT] = { "ext", CGU_CLK_EXT },
|
||||
[JZ4760_CLK_OSC32K] = { "osc32k", CGU_CLK_EXT },
|
||||
|
||||
/* PLLs */
|
||||
|
||||
[JZ4760_CLK_PLL0] = {
|
||||
"pll0", CGU_CLK_PLL,
|
||||
.parents = { JZ4760_CLK_EXT },
|
||||
.pll = {
|
||||
.reg = CGU_REG_CPPCR0,
|
||||
.rate_multiplier = 1,
|
||||
.m_shift = 23,
|
||||
.m_bits = 8,
|
||||
.m_offset = 0,
|
||||
.n_shift = 18,
|
||||
.n_bits = 4,
|
||||
.n_offset = 0,
|
||||
.od_shift = 16,
|
||||
.od_bits = 2,
|
||||
.od_max = 8,
|
||||
.od_encoding = pll_od_encoding,
|
||||
.bypass_reg = CGU_REG_CPPCR0,
|
||||
.bypass_bit = 9,
|
||||
.enable_bit = 8,
|
||||
.stable_bit = 10,
|
||||
.calc_m_n_od = jz4760_cgu_calc_m_n_od,
|
||||
},
|
||||
},
|
||||
|
||||
[JZ4760_CLK_PLL1] = {
|
||||
/* TODO: PLL1 can depend on PLL0 */
|
||||
"pll1", CGU_CLK_PLL,
|
||||
.parents = { JZ4760_CLK_EXT },
|
||||
.pll = {
|
||||
.reg = CGU_REG_CPPCR1,
|
||||
.rate_multiplier = 1,
|
||||
.m_shift = 23,
|
||||
.m_bits = 8,
|
||||
.m_offset = 0,
|
||||
.n_shift = 18,
|
||||
.n_bits = 4,
|
||||
.n_offset = 0,
|
||||
.od_shift = 16,
|
||||
.od_bits = 2,
|
||||
.od_max = 8,
|
||||
.od_encoding = pll_od_encoding,
|
||||
.bypass_bit = -1,
|
||||
.enable_bit = 7,
|
||||
.stable_bit = 6,
|
||||
.calc_m_n_od = jz4760_cgu_calc_m_n_od,
|
||||
},
|
||||
},
|
||||
|
||||
/* Main clocks */
|
||||
|
||||
[JZ4760_CLK_CCLK] = {
|
||||
"cclk", CGU_CLK_DIV,
|
||||
.parents = { JZ4760_CLK_PLL0, },
|
||||
.div = {
|
||||
CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, 0,
|
||||
jz4760_cgu_cpccr_div_table,
|
||||
},
|
||||
},
|
||||
[JZ4760_CLK_HCLK] = {
|
||||
"hclk", CGU_CLK_DIV,
|
||||
.parents = { JZ4760_CLK_PLL0, },
|
||||
.div = {
|
||||
CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1, 0,
|
||||
jz4760_cgu_cpccr_div_table,
|
||||
},
|
||||
},
|
||||
[JZ4760_CLK_SCLK] = {
|
||||
"sclk", CGU_CLK_DIV,
|
||||
.parents = { JZ4760_CLK_PLL0, },
|
||||
.div = {
|
||||
CGU_REG_CPCCR, 24, 1, 4, 22, -1, -1, 0,
|
||||
jz4760_cgu_cpccr_div_table,
|
||||
},
|
||||
},
|
||||
[JZ4760_CLK_H2CLK] = {
|
||||
"h2clk", CGU_CLK_DIV,
|
||||
.parents = { JZ4760_CLK_PLL0, },
|
||||
.div = {
|
||||
CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1, 0,
|
||||
jz4760_cgu_cpccr_div_table,
|
||||
},
|
||||
},
|
||||
[JZ4760_CLK_MCLK] = {
|
||||
"mclk", CGU_CLK_DIV,
|
||||
.parents = { JZ4760_CLK_PLL0, },
|
||||
.div = {
|
||||
CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, 0,
|
||||
jz4760_cgu_cpccr_div_table,
|
||||
},
|
||||
},
|
||||
[JZ4760_CLK_PCLK] = {
|
||||
"pclk", CGU_CLK_DIV,
|
||||
.parents = { JZ4760_CLK_PLL0, },
|
||||
.div = {
|
||||
CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1, 0,
|
||||
jz4760_cgu_cpccr_div_table,
|
||||
},
|
||||
},
|
||||
|
||||
/* Divided clocks */
|
||||
|
||||
[JZ4760_CLK_PLL0_HALF] = {
|
||||
"pll0_half", CGU_CLK_DIV,
|
||||
.parents = { JZ4760_CLK_PLL0 },
|
||||
.div = {
|
||||
CGU_REG_CPCCR, 21, 1, 1, 22, -1, -1, 0,
|
||||
jz4760_cgu_pll_half_div_table,
|
||||
},
|
||||
},
|
||||
|
||||
/* Those divided clocks can connect to PLL0 or PLL1 */
|
||||
|
||||
[JZ4760_CLK_UHC] = {
|
||||
"uhc", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
|
||||
.parents = { JZ4760_CLK_PLL0_HALF, JZ4760_CLK_PLL1, },
|
||||
.mux = { CGU_REG_UHCCDR, 31, 1 },
|
||||
.div = { CGU_REG_UHCCDR, 0, 1, 4, -1, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR0, 24 },
|
||||
},
|
||||
[JZ4760_CLK_GPU] = {
|
||||
"gpu", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
|
||||
.parents = { JZ4760_CLK_PLL0_HALF, JZ4760_CLK_PLL1, },
|
||||
.mux = { CGU_REG_GPUCDR, 31, 1 },
|
||||
.div = { CGU_REG_GPUCDR, 0, 1, 3, -1, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR1, 9 },
|
||||
},
|
||||
[JZ4760_CLK_LPCLK_DIV] = {
|
||||
"lpclk_div", CGU_CLK_DIV | CGU_CLK_MUX,
|
||||
.parents = { JZ4760_CLK_PLL0_HALF, JZ4760_CLK_PLL1, },
|
||||
.mux = { CGU_REG_LPCDR, 29, 1 },
|
||||
.div = { CGU_REG_LPCDR, 0, 1, 11, -1, -1, -1 },
|
||||
},
|
||||
[JZ4760_CLK_TVE] = {
|
||||
"tve", CGU_CLK_GATE | CGU_CLK_MUX,
|
||||
.parents = { JZ4760_CLK_LPCLK_DIV, JZ4760_CLK_EXT, },
|
||||
.mux = { CGU_REG_LPCDR, 31, 1 },
|
||||
.gate = { CGU_REG_CLKGR0, 27 },
|
||||
},
|
||||
[JZ4760_CLK_LPCLK] = {
|
||||
"lpclk", CGU_CLK_GATE | CGU_CLK_MUX,
|
||||
.parents = { JZ4760_CLK_LPCLK_DIV, JZ4760_CLK_TVE, },
|
||||
.mux = { CGU_REG_LPCDR, 30, 1 },
|
||||
.gate = { CGU_REG_CLKGR0, 28 },
|
||||
},
|
||||
[JZ4760_CLK_GPS] = {
|
||||
"gps", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
|
||||
.parents = { JZ4760_CLK_PLL0_HALF, JZ4760_CLK_PLL1, },
|
||||
.mux = { CGU_REG_GPSCDR, 31, 1 },
|
||||
.div = { CGU_REG_GPSCDR, 0, 1, 4, -1, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR0, 22 },
|
||||
},
|
||||
|
||||
/* Those divided clocks can connect to EXT, PLL0 or PLL1 */
|
||||
|
||||
[JZ4760_CLK_PCM] = {
|
||||
"pcm", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
|
||||
.parents = { JZ4760_CLK_EXT, -1,
|
||||
JZ4760_CLK_PLL0_HALF, JZ4760_CLK_PLL1 },
|
||||
.mux = { CGU_REG_PCMCDR, 30, 2 },
|
||||
.div = { CGU_REG_PCMCDR, 0, 1, 9, -1, -1, -1, BIT(0) },
|
||||
.gate = { CGU_REG_CLKGR1, 8 },
|
||||
},
|
||||
[JZ4760_CLK_I2S] = {
|
||||
"i2s", CGU_CLK_DIV | CGU_CLK_MUX,
|
||||
.parents = { JZ4760_CLK_EXT, -1,
|
||||
JZ4760_CLK_PLL0_HALF, JZ4760_CLK_PLL1 },
|
||||
.mux = { CGU_REG_I2SCDR, 30, 2 },
|
||||
.div = { CGU_REG_I2SCDR, 0, 1, 9, -1, -1, -1, BIT(0) },
|
||||
},
|
||||
[JZ4760_CLK_OTG] = {
|
||||
"usb", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
|
||||
.parents = { JZ4760_CLK_EXT, -1,
|
||||
JZ4760_CLK_PLL0_HALF, JZ4760_CLK_PLL1 },
|
||||
.mux = { CGU_REG_USBCDR, 30, 2 },
|
||||
.div = { CGU_REG_USBCDR, 0, 1, 8, -1, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR0, 2 },
|
||||
},
|
||||
|
||||
/* Those divided clocks can connect to EXT or PLL0 */
|
||||
[JZ4760_CLK_MMC_MUX] = {
|
||||
"mmc_mux", CGU_CLK_MUX | CGU_CLK_DIV,
|
||||
.parents = { JZ4760_CLK_EXT, JZ4760_CLK_PLL0_HALF, },
|
||||
.mux = { CGU_REG_MSCCDR, 31, 1 },
|
||||
.div = { CGU_REG_MSCCDR, 0, 1, 6, -1, -1, -1, BIT(0) },
|
||||
},
|
||||
[JZ4760_CLK_SSI_MUX] = {
|
||||
"ssi_mux", CGU_CLK_DIV | CGU_CLK_MUX,
|
||||
.parents = { JZ4760_CLK_EXT, JZ4760_CLK_PLL0_HALF, },
|
||||
.mux = { CGU_REG_SSICDR, 31, 1 },
|
||||
.div = { CGU_REG_SSICDR, 0, 1, 6, -1, -1, -1, BIT(0) },
|
||||
},
|
||||
|
||||
/* These divided clock can connect to PLL0 only */
|
||||
[JZ4760_CLK_CIM] = {
|
||||
"cim", CGU_CLK_DIV | CGU_CLK_GATE,
|
||||
.parents = { JZ4760_CLK_PLL0_HALF },
|
||||
.div = { CGU_REG_CIMCDR, 0, 1, 8, -1, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR0, 26 },
|
||||
},
|
||||
|
||||
/* Gate-only clocks */
|
||||
|
||||
[JZ4760_CLK_SSI0] = {
|
||||
"ssi0", CGU_CLK_GATE,
|
||||
.parents = { JZ4760_CLK_SSI_MUX, },
|
||||
.gate = { CGU_REG_CLKGR0, 4 },
|
||||
},
|
||||
[JZ4760_CLK_SSI1] = {
|
||||
"ssi1", CGU_CLK_GATE,
|
||||
.parents = { JZ4760_CLK_SSI_MUX, },
|
||||
.gate = { CGU_REG_CLKGR0, 19 },
|
||||
},
|
||||
[JZ4760_CLK_SSI2] = {
|
||||
"ssi2", CGU_CLK_GATE,
|
||||
.parents = { JZ4760_CLK_SSI_MUX, },
|
||||
.gate = { CGU_REG_CLKGR0, 20 },
|
||||
},
|
||||
[JZ4760_CLK_DMA] = {
|
||||
"dma", CGU_CLK_GATE,
|
||||
.parents = { JZ4760_CLK_H2CLK, },
|
||||
.gate = { CGU_REG_CLKGR0, 21 },
|
||||
},
|
||||
[JZ4760_CLK_I2C0] = {
|
||||
"i2c0", CGU_CLK_GATE,
|
||||
.parents = { JZ4760_CLK_EXT, },
|
||||
.gate = { CGU_REG_CLKGR0, 5 },
|
||||
},
|
||||
[JZ4760_CLK_I2C1] = {
|
||||
"i2c1", CGU_CLK_GATE,
|
||||
.parents = { JZ4760_CLK_EXT, },
|
||||
.gate = { CGU_REG_CLKGR0, 6 },
|
||||
},
|
||||
[JZ4760_CLK_UART0] = {
|
||||
"uart0", CGU_CLK_GATE,
|
||||
.parents = { JZ4760_CLK_EXT, },
|
||||
.gate = { CGU_REG_CLKGR0, 15 },
|
||||
},
|
||||
[JZ4760_CLK_UART1] = {
|
||||
"uart1", CGU_CLK_GATE,
|
||||
.parents = { JZ4760_CLK_EXT, },
|
||||
.gate = { CGU_REG_CLKGR0, 16 },
|
||||
},
|
||||
[JZ4760_CLK_UART2] = {
|
||||
"uart2", CGU_CLK_GATE,
|
||||
.parents = { JZ4760_CLK_EXT, },
|
||||
.gate = { CGU_REG_CLKGR0, 17 },
|
||||
},
|
||||
[JZ4760_CLK_UART3] = {
|
||||
"uart3", CGU_CLK_GATE,
|
||||
.parents = { JZ4760_CLK_EXT, },
|
||||
.gate = { CGU_REG_CLKGR0, 18 },
|
||||
},
|
||||
[JZ4760_CLK_IPU] = {
|
||||
"ipu", CGU_CLK_GATE,
|
||||
.parents = { JZ4760_CLK_HCLK, },
|
||||
.gate = { CGU_REG_CLKGR0, 29 },
|
||||
},
|
||||
[JZ4760_CLK_ADC] = {
|
||||
"adc", CGU_CLK_GATE,
|
||||
.parents = { JZ4760_CLK_EXT, },
|
||||
.gate = { CGU_REG_CLKGR0, 14 },
|
||||
},
|
||||
[JZ4760_CLK_AIC] = {
|
||||
"aic", CGU_CLK_GATE,
|
||||
.parents = { JZ4760_CLK_EXT, },
|
||||
.gate = { CGU_REG_CLKGR0, 8 },
|
||||
},
|
||||
[JZ4760_CLK_VPU] = {
|
||||
"vpu", CGU_CLK_GATE,
|
||||
.parents = { JZ4760_CLK_HCLK, },
|
||||
.gate = { CGU_REG_LCR, 30, false, 150 },
|
||||
},
|
||||
[JZ4760_CLK_MMC0] = {
|
||||
"mmc0", CGU_CLK_GATE,
|
||||
.parents = { JZ4760_CLK_MMC_MUX, },
|
||||
.gate = { CGU_REG_CLKGR0, 3 },
|
||||
},
|
||||
[JZ4760_CLK_MMC1] = {
|
||||
"mmc1", CGU_CLK_GATE,
|
||||
.parents = { JZ4760_CLK_MMC_MUX, },
|
||||
.gate = { CGU_REG_CLKGR0, 11 },
|
||||
},
|
||||
[JZ4760_CLK_MMC2] = {
|
||||
"mmc2", CGU_CLK_GATE,
|
||||
.parents = { JZ4760_CLK_MMC_MUX, },
|
||||
.gate = { CGU_REG_CLKGR0, 12 },
|
||||
},
|
||||
[JZ4760_CLK_UHC_PHY] = {
|
||||
"uhc_phy", CGU_CLK_GATE,
|
||||
.parents = { JZ4760_CLK_UHC, },
|
||||
.gate = { CGU_REG_OPCR, 5 },
|
||||
},
|
||||
[JZ4760_CLK_OTG_PHY] = {
|
||||
"usb_phy", CGU_CLK_GATE,
|
||||
.parents = { JZ4760_CLK_OTG },
|
||||
.gate = { CGU_REG_OPCR, 7, true, 50 },
|
||||
},
|
||||
|
||||
/* Custom clocks */
|
||||
[JZ4760_CLK_EXT512] = {
|
||||
"ext/512", CGU_CLK_FIXDIV,
|
||||
.parents = { JZ4760_CLK_EXT },
|
||||
.fixdiv = { 512 },
|
||||
},
|
||||
[JZ4760_CLK_RTC] = {
|
||||
"rtc", CGU_CLK_MUX,
|
||||
.parents = { JZ4760_CLK_EXT512, JZ4760_CLK_OSC32K, },
|
||||
.mux = { CGU_REG_OPCR, 2, 1},
|
||||
},
|
||||
};
|
||||
|
||||
static void __init jz4760_cgu_init(struct device_node *np)
|
||||
{
|
||||
struct ingenic_cgu *cgu;
|
||||
int retval;
|
||||
|
||||
cgu = ingenic_cgu_new(jz4760_cgu_clocks,
|
||||
ARRAY_SIZE(jz4760_cgu_clocks), np);
|
||||
if (!cgu) {
|
||||
pr_err("%s: failed to initialise CGU\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
retval = ingenic_cgu_register_clocks(cgu);
|
||||
if (retval)
|
||||
pr_err("%s: failed to register CGU Clocks\n", __func__);
|
||||
|
||||
ingenic_cgu_register_syscore_ops(cgu);
|
||||
}
|
||||
|
||||
/* We only probe via devicetree, no need for a platform driver */
|
||||
CLK_OF_DECLARE_DRIVER(jz4760_cgu, "ingenic,jz4760-cgu", jz4760_cgu_init);
|
||||
|
||||
/* JZ4760B has some small differences, but we don't implement them. */
|
||||
CLK_OF_DECLARE_DRIVER(jz4760b_cgu, "ingenic,jz4760b-cgu", jz4760_cgu_init);
|
@ -139,8 +139,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
|
||||
.od_bits = 2,
|
||||
.od_max = 8,
|
||||
.od_encoding = pll_od_encoding,
|
||||
.bypass_reg = CGU_REG_CPPCR1,
|
||||
.no_bypass_bit = true,
|
||||
.bypass_bit = -1,
|
||||
.enable_bit = 7,
|
||||
.stable_bit = 6,
|
||||
},
|
||||
@ -152,7 +151,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
|
||||
"cclk", CGU_CLK_DIV,
|
||||
.parents = { JZ4770_CLK_PLL0, },
|
||||
.div = {
|
||||
CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1,
|
||||
CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, 0,
|
||||
jz4770_cgu_cpccr_div_table,
|
||||
},
|
||||
},
|
||||
@ -160,7 +159,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
|
||||
"h0clk", CGU_CLK_DIV,
|
||||
.parents = { JZ4770_CLK_PLL0, },
|
||||
.div = {
|
||||
CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1,
|
||||
CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1, 0,
|
||||
jz4770_cgu_cpccr_div_table,
|
||||
},
|
||||
},
|
||||
@ -168,7 +167,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
|
||||
"h1clk", CGU_CLK_DIV | CGU_CLK_GATE,
|
||||
.parents = { JZ4770_CLK_PLL0, },
|
||||
.div = {
|
||||
CGU_REG_CPCCR, 24, 1, 4, 22, -1, -1,
|
||||
CGU_REG_CPCCR, 24, 1, 4, 22, -1, -1, 0,
|
||||
jz4770_cgu_cpccr_div_table,
|
||||
},
|
||||
.gate = { CGU_REG_CLKGR1, 7 },
|
||||
@ -177,7 +176,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
|
||||
"h2clk", CGU_CLK_DIV,
|
||||
.parents = { JZ4770_CLK_PLL0, },
|
||||
.div = {
|
||||
CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1,
|
||||
CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1, 0,
|
||||
jz4770_cgu_cpccr_div_table,
|
||||
},
|
||||
},
|
||||
@ -185,7 +184,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
|
||||
"c1clk", CGU_CLK_DIV | CGU_CLK_GATE,
|
||||
.parents = { JZ4770_CLK_PLL0, },
|
||||
.div = {
|
||||
CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1,
|
||||
CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, 0,
|
||||
jz4770_cgu_cpccr_div_table,
|
||||
},
|
||||
.gate = { CGU_REG_OPCR, 31, true }, // disable CCLK stop on idle
|
||||
@ -194,7 +193,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
|
||||
"pclk", CGU_CLK_DIV,
|
||||
.parents = { JZ4770_CLK_PLL0, },
|
||||
.div = {
|
||||
CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1,
|
||||
CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1, 0,
|
||||
jz4770_cgu_cpccr_div_table,
|
||||
},
|
||||
},
|
||||
|
@ -326,6 +326,7 @@ static const struct ingenic_soc_info x1000_soc_info = {
|
||||
static const struct of_device_id __maybe_unused ingenic_tcu_of_match[] __initconst = {
|
||||
{ .compatible = "ingenic,jz4740-tcu", .data = &jz4740_soc_info, },
|
||||
{ .compatible = "ingenic,jz4725b-tcu", .data = &jz4725b_soc_info, },
|
||||
{ .compatible = "ingenic,jz4760-tcu", .data = &jz4770_soc_info, },
|
||||
{ .compatible = "ingenic,jz4770-tcu", .data = &jz4770_soc_info, },
|
||||
{ .compatible = "ingenic,x1000-tcu", .data = &x1000_soc_info, },
|
||||
{ /* sentinel */ }
|
||||
@ -477,5 +478,6 @@ static void __init ingenic_tcu_init(struct device_node *np)
|
||||
|
||||
CLK_OF_DECLARE_DRIVER(jz4740_cgu, "ingenic,jz4740-tcu", ingenic_tcu_init);
|
||||
CLK_OF_DECLARE_DRIVER(jz4725b_cgu, "ingenic,jz4725b-tcu", ingenic_tcu_init);
|
||||
CLK_OF_DECLARE_DRIVER(jz4760_cgu, "ingenic,jz4760-tcu", ingenic_tcu_init);
|
||||
CLK_OF_DECLARE_DRIVER(jz4770_cgu, "ingenic,jz4770-tcu", ingenic_tcu_init);
|
||||
CLK_OF_DECLARE_DRIVER(x1000_cgu, "ingenic,x1000-tcu", ingenic_tcu_init);
|
||||
|
@ -199,12 +199,6 @@ config RESET_SIMPLE
|
||||
- ZTE's zx2967 family
|
||||
- SiFive FU740 SoCs
|
||||
|
||||
config RESET_STM32MP157
|
||||
bool "STM32MP157 Reset Driver" if COMPILE_TEST
|
||||
default MACH_STM32MP157
|
||||
help
|
||||
This enables the RCC reset controller driver for STM32 MPUs.
|
||||
|
||||
config RESET_SOCFPGA
|
||||
bool "SoCFPGA Reset Driver" if COMPILE_TEST && (!ARM || !ARCH_INTEL_SOCFPGA)
|
||||
default ARM && ARCH_INTEL_SOCFPGA
|
||||
|
@ -26,7 +26,6 @@ obj-$(CONFIG_RESET_QCOM_PDC) += reset-qcom-pdc.o
|
||||
obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o
|
||||
obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
|
||||
obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
|
||||
obj-$(CONFIG_RESET_STM32MP157) += reset-stm32mp1.o
|
||||
obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
|
||||
obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
|
||||
obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o
|
||||
|
@ -1,115 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) STMicroelectronics 2018 - All Rights Reserved
|
||||
* Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/reset-controller.h>
|
||||
|
||||
#define CLR_OFFSET 0x4
|
||||
|
||||
struct stm32_reset_data {
|
||||
struct reset_controller_dev rcdev;
|
||||
void __iomem *membase;
|
||||
};
|
||||
|
||||
static inline struct stm32_reset_data *
|
||||
to_stm32_reset_data(struct reset_controller_dev *rcdev)
|
||||
{
|
||||
return container_of(rcdev, struct stm32_reset_data, rcdev);
|
||||
}
|
||||
|
||||
static int stm32_reset_update(struct reset_controller_dev *rcdev,
|
||||
unsigned long id, bool assert)
|
||||
{
|
||||
struct stm32_reset_data *data = to_stm32_reset_data(rcdev);
|
||||
int reg_width = sizeof(u32);
|
||||
int bank = id / (reg_width * BITS_PER_BYTE);
|
||||
int offset = id % (reg_width * BITS_PER_BYTE);
|
||||
void __iomem *addr;
|
||||
|
||||
addr = data->membase + (bank * reg_width);
|
||||
if (!assert)
|
||||
addr += CLR_OFFSET;
|
||||
|
||||
writel(BIT(offset), addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stm32_reset_assert(struct reset_controller_dev *rcdev,
|
||||
unsigned long id)
|
||||
{
|
||||
return stm32_reset_update(rcdev, id, true);
|
||||
}
|
||||
|
||||
static int stm32_reset_deassert(struct reset_controller_dev *rcdev,
|
||||
unsigned long id)
|
||||
{
|
||||
return stm32_reset_update(rcdev, id, false);
|
||||
}
|
||||
|
||||
static int stm32_reset_status(struct reset_controller_dev *rcdev,
|
||||
unsigned long id)
|
||||
{
|
||||
struct stm32_reset_data *data = to_stm32_reset_data(rcdev);
|
||||
int reg_width = sizeof(u32);
|
||||
int bank = id / (reg_width * BITS_PER_BYTE);
|
||||
int offset = id % (reg_width * BITS_PER_BYTE);
|
||||
u32 reg;
|
||||
|
||||
reg = readl(data->membase + (bank * reg_width));
|
||||
|
||||
return !!(reg & BIT(offset));
|
||||
}
|
||||
|
||||
static const struct reset_control_ops stm32_reset_ops = {
|
||||
.assert = stm32_reset_assert,
|
||||
.deassert = stm32_reset_deassert,
|
||||
.status = stm32_reset_status,
|
||||
};
|
||||
|
||||
static const struct of_device_id stm32_reset_dt_ids[] = {
|
||||
{ .compatible = "st,stm32mp1-rcc"},
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
static int stm32_reset_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct stm32_reset_data *data;
|
||||
void __iomem *membase;
|
||||
struct resource *res;
|
||||
|
||||
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
membase = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(membase))
|
||||
return PTR_ERR(membase);
|
||||
|
||||
data->membase = membase;
|
||||
data->rcdev.owner = THIS_MODULE;
|
||||
data->rcdev.nr_resets = resource_size(res) * BITS_PER_BYTE;
|
||||
data->rcdev.ops = &stm32_reset_ops;
|
||||
data->rcdev.of_node = dev->of_node;
|
||||
|
||||
return devm_reset_controller_register(dev, &data->rcdev);
|
||||
}
|
||||
|
||||
static struct platform_driver stm32_reset_driver = {
|
||||
.probe = stm32_reset_probe,
|
||||
.driver = {
|
||||
.name = "stm32mp1-reset",
|
||||
.of_match_table = stm32_reset_dt_ids,
|
||||
},
|
||||
};
|
||||
|
||||
builtin_platform_driver(stm32_reset_driver);
|
@ -74,10 +74,12 @@
|
||||
#define CLK_RMII_REF 54
|
||||
#define CLK_GPIO 55
|
||||
|
||||
/* system clock (part 2) */
|
||||
/* additional clocks */
|
||||
#define CLK_APB 56
|
||||
#define CLK_DMAC 57
|
||||
#define CLK_NIC 58
|
||||
#define CLK_ETHERNET 59
|
||||
|
||||
#define CLK_NR_CLKS (CLK_DMAC + 1)
|
||||
#define CLK_NR_CLKS (CLK_ETHERNET + 1)
|
||||
|
||||
#endif /* __DT_BINDINGS_CLOCK_S500_CMU_H */
|
||||
|
54
include/dt-bindings/clock/jz4760-cgu.h
Normal file
54
include/dt-bindings/clock/jz4760-cgu.h
Normal file
@ -0,0 +1,54 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* This header provides clock numbers for the ingenic,jz4760-cgu DT binding.
|
||||
*/
|
||||
|
||||
#ifndef __DT_BINDINGS_CLOCK_JZ4760_CGU_H__
|
||||
#define __DT_BINDINGS_CLOCK_JZ4760_CGU_H__
|
||||
|
||||
#define JZ4760_CLK_EXT 0
|
||||
#define JZ4760_CLK_OSC32K 1
|
||||
#define JZ4760_CLK_PLL0 2
|
||||
#define JZ4760_CLK_PLL0_HALF 3
|
||||
#define JZ4760_CLK_PLL1 4
|
||||
#define JZ4760_CLK_CCLK 5
|
||||
#define JZ4760_CLK_HCLK 6
|
||||
#define JZ4760_CLK_SCLK 7
|
||||
#define JZ4760_CLK_H2CLK 8
|
||||
#define JZ4760_CLK_MCLK 9
|
||||
#define JZ4760_CLK_PCLK 10
|
||||
#define JZ4760_CLK_MMC_MUX 11
|
||||
#define JZ4760_CLK_MMC0 12
|
||||
#define JZ4760_CLK_MMC1 13
|
||||
#define JZ4760_CLK_MMC2 14
|
||||
#define JZ4760_CLK_CIM 15
|
||||
#define JZ4760_CLK_UHC 16
|
||||
#define JZ4760_CLK_GPU 17
|
||||
#define JZ4760_CLK_GPS 18
|
||||
#define JZ4760_CLK_SSI_MUX 19
|
||||
#define JZ4760_CLK_PCM 20
|
||||
#define JZ4760_CLK_I2S 21
|
||||
#define JZ4760_CLK_OTG 22
|
||||
#define JZ4760_CLK_SSI0 23
|
||||
#define JZ4760_CLK_SSI1 24
|
||||
#define JZ4760_CLK_SSI2 25
|
||||
#define JZ4760_CLK_DMA 26
|
||||
#define JZ4760_CLK_I2C0 27
|
||||
#define JZ4760_CLK_I2C1 28
|
||||
#define JZ4760_CLK_UART0 29
|
||||
#define JZ4760_CLK_UART1 30
|
||||
#define JZ4760_CLK_UART2 31
|
||||
#define JZ4760_CLK_UART3 32
|
||||
#define JZ4760_CLK_IPU 33
|
||||
#define JZ4760_CLK_ADC 34
|
||||
#define JZ4760_CLK_AIC 35
|
||||
#define JZ4760_CLK_VPU 36
|
||||
#define JZ4760_CLK_UHC_PHY 37
|
||||
#define JZ4760_CLK_OTG_PHY 38
|
||||
#define JZ4760_CLK_EXT512 39
|
||||
#define JZ4760_CLK_RTC 40
|
||||
#define JZ4760_CLK_LPCLK_DIV 41
|
||||
#define JZ4760_CLK_TVE 42
|
||||
#define JZ4760_CLK_LPCLK 43
|
||||
|
||||
#endif /* __DT_BINDINGS_CLOCK_JZ4760_CGU_H__ */
|
@ -248,4 +248,31 @@
|
||||
|
||||
#define STM32MP1_LAST_CLK 232
|
||||
|
||||
/* SCMI clock identifiers */
|
||||
#define CK_SCMI0_HSE 0
|
||||
#define CK_SCMI0_HSI 1
|
||||
#define CK_SCMI0_CSI 2
|
||||
#define CK_SCMI0_LSE 3
|
||||
#define CK_SCMI0_LSI 4
|
||||
#define CK_SCMI0_PLL2_Q 5
|
||||
#define CK_SCMI0_PLL2_R 6
|
||||
#define CK_SCMI0_MPU 7
|
||||
#define CK_SCMI0_AXI 8
|
||||
#define CK_SCMI0_BSEC 9
|
||||
#define CK_SCMI0_CRYP1 10
|
||||
#define CK_SCMI0_GPIOZ 11
|
||||
#define CK_SCMI0_HASH1 12
|
||||
#define CK_SCMI0_I2C4 13
|
||||
#define CK_SCMI0_I2C6 14
|
||||
#define CK_SCMI0_IWDG1 15
|
||||
#define CK_SCMI0_RNG1 16
|
||||
#define CK_SCMI0_RTC 17
|
||||
#define CK_SCMI0_RTCAPB 18
|
||||
#define CK_SCMI0_SPI6 19
|
||||
#define CK_SCMI0_USART1 20
|
||||
|
||||
#define CK_SCMI1_PLL3_Q 0
|
||||
#define CK_SCMI1_PLL3_R 1
|
||||
#define CK_SCMI1_MCU 2
|
||||
|
||||
#endif /* _DT_BINDINGS_STM32MP1_CLKS_H_ */
|
||||
|
@ -7,6 +7,7 @@
|
||||
#ifndef _DT_BINDINGS_STM32MP1_RESET_H_
|
||||
#define _DT_BINDINGS_STM32MP1_RESET_H_
|
||||
|
||||
#define MCU_HOLD_BOOT_R 2144
|
||||
#define LTDC_R 3072
|
||||
#define DSI_R 3076
|
||||
#define DDRPERFM_R 3080
|
||||
@ -105,4 +106,18 @@
|
||||
#define GPIOJ_R 19785
|
||||
#define GPIOK_R 19786
|
||||
|
||||
/* SCMI reset domain identifiers */
|
||||
#define RST_SCMI0_SPI6 0
|
||||
#define RST_SCMI0_I2C4 1
|
||||
#define RST_SCMI0_I2C6 2
|
||||
#define RST_SCMI0_USART1 3
|
||||
#define RST_SCMI0_STGEN 4
|
||||
#define RST_SCMI0_GPIOZ 5
|
||||
#define RST_SCMI0_CRYP1 6
|
||||
#define RST_SCMI0_HASH1 7
|
||||
#define RST_SCMI0_RNG1 8
|
||||
#define RST_SCMI0_MDMA 9
|
||||
#define RST_SCMI0_MCU 10
|
||||
#define RST_SCMI0_MCU_HOLD_BOOT 11
|
||||
|
||||
#endif /* _DT_BINDINGS_STM32MP1_RESET_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user