mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-04 04:06:26 +00:00
Merge branches 'clk-cleanup', 'clk-mediatek', 'clk-kunit', 'clk-xilinx' and 'clk-fixed-gate' into clk-next
- Various clk driver cleanups - MediaTek MT6735 SoC clks - MediaTek MT7620, MT7628 and MT7688 MMC clks - KUnit tests for clk-assigned-rates{,-u64} - Add a driver for gated fixed rate clocks * clk-cleanup: clk: clk-loongson2: Fix potential buffer overflow in flexible-array member access clk: Fix invalid execution of clk_set_rate clk: clk-loongson2: Fix memory corruption bug in struct loongson2_clk_provider clk: lan966x: make it selectable for ARCH_LAN969X clk: clk-apple-nco: Add NULL check in applnco_probe clk: starfive: jh7110-pll: Mark the probe function as __init clk: sophgo: avoid integer overflow in sg2042_pll_recalc_rate() clk: tegra: use clamp() in tegra_bpmp_clk_determine_rate() clk: cdce925: make regmap_cdce925_bus constant clk: Drop explicit initialization of struct i2c_device_id::driver_data to 0 clk: clk-qoriq: Replace of_node_put() with __free() clk: Remove unused clk_hw_rate_is_protected * clk-mediatek: clk: en7523: map io region in a single block clk: en7523: move en7581_reset_register() in en7581_clk_hw_init() clk: en7523: fix estimation of fixed rate for EN7581 clk: en7523: introduce chip_scu regmap clk: en7523: move clock_register in hw_init callback clk: en7523: remove REG_PCIE*_{MEM,MEM_MASK} configuration dt-bindings: clock: airoha: Update reg mapping for EN7581 SoC. clk: mediatek: Add drivers for MT6735 syscon clock and reset controllers dt-bindings: clock: mediatek: Add bindings for MT6735 syscon clock and reset controllers clk: mediatek: mt6735-apmixedsys: Fix an error handling path in clk_mt6735_apmixed_probe() clk: ralink: mtmips: add mmc related clocks for SoCs MT7620, MT7628 and MT7688 clk: ralink: mtmips: fix clocks probe order in oldest ralink SoCs clk: ralink: mtmips: fix clock plan for Ralink SoC RT3883 clk: mediatek: clk-mt8188-topckgen: Remove univpll from parents of mfg_core_tmp clk: mediatek: Add drivers for MediaTek MT6735 main clock and reset drivers dt-bindings: clock: Add MediaTek MT6735 clock and reset bindings clk: mediatek: drop two dead config options * clk-kunit: clk: Allow kunit tests to run without OF_OVERLAY enabled clk: test: Add KUnit tests for clock-assigned-rates{-u64} DT properties of: kunit: Extract some overlay boiler plate into macros clk: test: Add test managed of_clk_add_hw_provider() * clk-xilinx: clk: clocking-wizard: move dynamic reconfig setup behind flag dt-bindings: clock: xilinx: describe whether dynamic reconfig is enabled clk: clocking-wizard: move clock registration to separate function clk: clocking-wizard: use devres versions of clk_hw API clk: clocking-wizard: use newer clk_hw API clk: clocking-wizard: simplify probe/remove with devres helpers * clk-fixed-gate: clk: clk-gpio: add driver for gated-fixed-clocks clk: clk-gpio: use dev_err_probe for gpio-get failure clk: clk-gpio: update documentation for gpio-gate clock dt-bindings: clocks: add binding for gated-fixed-clocks
This commit is contained in:
commit
6af88ccfcb
@ -34,8 +34,10 @@ properties:
|
||||
- airoha,en7581-scu
|
||||
|
||||
reg:
|
||||
minItems: 2
|
||||
maxItems: 4
|
||||
items:
|
||||
- description: scu base address
|
||||
- description: misc scu base address
|
||||
minItems: 1
|
||||
|
||||
"#clock-cells":
|
||||
description:
|
||||
@ -60,9 +62,7 @@ allOf:
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
items:
|
||||
- description: scu base address
|
||||
- description: misc scu base address
|
||||
minItems: 2
|
||||
|
||||
'#reset-cells': false
|
||||
|
||||
@ -73,11 +73,7 @@ allOf:
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
items:
|
||||
- description: scu base address
|
||||
- description: misc scu base address
|
||||
- description: reset base address
|
||||
- description: pb scu base address
|
||||
maxItems: 1
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
@ -96,12 +92,9 @@ examples:
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
scuclk: clock-controller@1fa20000 {
|
||||
scuclk: clock-controller@1fb00000 {
|
||||
compatible = "airoha,en7581-scu";
|
||||
reg = <0x0 0x1fa20000 0x0 0x400>,
|
||||
<0x0 0x1fb00000 0x0 0x90>,
|
||||
<0x0 0x1fb00830 0x0 0x8>,
|
||||
<0x0 0x1fbe3400 0x0 0xfc>;
|
||||
reg = <0x0 0x1fb00000 0x0 0x970>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
@ -0,0 +1,49 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/gated-fixed-clock.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Gated Fixed clock
|
||||
|
||||
maintainers:
|
||||
- Heiko Stuebner <heiko@sntech.de>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: gated-fixed-clock
|
||||
|
||||
"#clock-cells":
|
||||
const: 0
|
||||
|
||||
clock-frequency: true
|
||||
|
||||
clock-output-names:
|
||||
maxItems: 1
|
||||
|
||||
enable-gpios:
|
||||
description:
|
||||
Contains a single GPIO specifier for the GPIO that enables and disables
|
||||
the oscillator.
|
||||
maxItems: 1
|
||||
|
||||
vdd-supply:
|
||||
description: handle of the regulator that provides the supply voltage
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- "#clock-cells"
|
||||
- clock-frequency
|
||||
- vdd-supply
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
clock-1000000000 {
|
||||
compatible = "gated-fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <1000000000>;
|
||||
vdd-supply = <®_vdd>;
|
||||
};
|
||||
...
|
@ -12,7 +12,8 @@ maintainers:
|
||||
|
||||
description:
|
||||
The Mediatek apmixedsys controller provides PLLs to the system.
|
||||
The clock values can be found in <dt-bindings/clock/mt*-clk.h>.
|
||||
The clock values can be found in <dt-bindings/clock/mt*-clk.h>
|
||||
and <dt-bindings/clock/mediatek,mt*-apmixedsys.h>.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
@ -34,6 +35,7 @@ properties:
|
||||
- enum:
|
||||
- mediatek,mt2701-apmixedsys
|
||||
- mediatek,mt2712-apmixedsys
|
||||
- mediatek,mt6735-apmixedsys
|
||||
- mediatek,mt6765-apmixedsys
|
||||
- mediatek,mt6779-apmixed
|
||||
- mediatek,mt6795-apmixedsys
|
||||
|
@ -11,9 +11,10 @@ maintainers:
|
||||
|
||||
description:
|
||||
The Mediatek infracfg controller provides various clocks and reset outputs
|
||||
to the system. The clock values can be found in <dt-bindings/clock/mt*-clk.h>,
|
||||
and reset values in <dt-bindings/reset/mt*-reset.h> and
|
||||
<dt-bindings/reset/mt*-resets.h>.
|
||||
to the system. The clock values can be found in <dt-bindings/clock/mt*-clk.h>
|
||||
and <dt-bindings/clock/mediatek,mt*-infracfg.h>, and reset values in
|
||||
<dt-bindings/reset/mt*-reset.h>, <dt-bindings/reset/mt*-resets.h> and
|
||||
<dt-bindings/reset/mediatek,mt*-infracfg.h>.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
@ -22,6 +23,7 @@ properties:
|
||||
- enum:
|
||||
- mediatek,mt2701-infracfg
|
||||
- mediatek,mt2712-infracfg
|
||||
- mediatek,mt6735-infracfg
|
||||
- mediatek,mt6765-infracfg
|
||||
- mediatek,mt6795-infracfg
|
||||
- mediatek,mt6779-infracfg_ao
|
||||
|
@ -20,6 +20,7 @@ properties:
|
||||
- enum:
|
||||
- mediatek,mt2701-pericfg
|
||||
- mediatek,mt2712-pericfg
|
||||
- mediatek,mt6735-pericfg
|
||||
- mediatek,mt6765-pericfg
|
||||
- mediatek,mt6795-pericfg
|
||||
- mediatek,mt7622-pericfg
|
||||
|
@ -28,6 +28,10 @@ properties:
|
||||
- mediatek,mt2712-mfgcfg
|
||||
- mediatek,mt2712-vdecsys
|
||||
- mediatek,mt2712-vencsys
|
||||
- mediatek,mt6735-imgsys
|
||||
- mediatek,mt6735-mfgcfg
|
||||
- mediatek,mt6735-vdecsys
|
||||
- mediatek,mt6735-vencsys
|
||||
- mediatek,mt6765-camsys
|
||||
- mediatek,mt6765-imgsys
|
||||
- mediatek,mt6765-mipi0a
|
||||
|
@ -12,7 +12,8 @@ maintainers:
|
||||
|
||||
description:
|
||||
The Mediatek topckgen controller provides various clocks to the system.
|
||||
The clock values can be found in <dt-bindings/clock/mt*-clk.h>.
|
||||
The clock values can be found in <dt-bindings/clock/mt*-clk.h> and
|
||||
<dt-bindings/clock/mediatek,mt*-topckgen.h>.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
@ -31,6 +32,7 @@ properties:
|
||||
- enum:
|
||||
- mediatek,mt2701-topckgen
|
||||
- mediatek,mt2712-topckgen
|
||||
- mediatek,mt6735-topckgen
|
||||
- mediatek,mt6765-topckgen
|
||||
- mediatek,mt6779-topckgen
|
||||
- mediatek,mt6795-topckgen
|
||||
|
@ -39,6 +39,11 @@ properties:
|
||||
- const: clk_in1
|
||||
- const: s_axi_aclk
|
||||
|
||||
xlnx,static-config:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description:
|
||||
Indicate whether the core has been configured without support for dynamic
|
||||
runtime reconfguration of the clocking primitive MMCM/PLL.
|
||||
|
||||
xlnx,speed-grade:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
@ -70,6 +75,7 @@ examples:
|
||||
compatible = "xlnx,clocking-wizard";
|
||||
reg = <0xb0000000 0x10000>;
|
||||
#clock-cells = <1>;
|
||||
xlnx,static-config;
|
||||
xlnx,speed-grade = <1>;
|
||||
xlnx,nr-outputs = <6>;
|
||||
clock-names = "clk_in1", "s_axi_aclk";
|
||||
|
26
MAINTAINERS
26
MAINTAINERS
@ -14528,6 +14528,32 @@ S: Maintained
|
||||
F: Documentation/devicetree/bindings/mmc/mtk-sd.yaml
|
||||
F: drivers/mmc/host/mtk-sd.c
|
||||
|
||||
MEDIATEK MT6735 CLOCK & RESET DRIVERS
|
||||
M: Yassine Oudjana <y.oudjana@protonmail.com>
|
||||
L: linux-clk@vger.kernel.org
|
||||
L: linux-mediatek@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: drivers/clk/mediatek/clk-mt6735-apmixedsys.c
|
||||
F: drivers/clk/mediatek/clk-mt6735-imgsys.c
|
||||
F: drivers/clk/mediatek/clk-mt6735-infracfg.c
|
||||
F: drivers/clk/mediatek/clk-mt6735-mfgcfg.c
|
||||
F: drivers/clk/mediatek/clk-mt6735-pericfg.c
|
||||
F: drivers/clk/mediatek/clk-mt6735-topckgen.c
|
||||
F: drivers/clk/mediatek/clk-mt6735-vdecsys.c
|
||||
F: drivers/clk/mediatek/clk-mt6735-vencsys.c
|
||||
F: include/dt-bindings/clock/mediatek,mt6735-apmixedsys.h
|
||||
F: include/dt-bindings/clock/mediatek,mt6735-imgsys.h
|
||||
F: include/dt-bindings/clock/mediatek,mt6735-infracfg.h
|
||||
F: include/dt-bindings/clock/mediatek,mt6735-mfgcfg.h
|
||||
F: include/dt-bindings/clock/mediatek,mt6735-pericfg.h
|
||||
F: include/dt-bindings/clock/mediatek,mt6735-topckgen.h
|
||||
F: include/dt-bindings/clock/mediatek,mt6735-vdecsys.h
|
||||
F: include/dt-bindings/clock/mediatek,mt6735-vencsys.h
|
||||
F: include/dt-bindings/reset/mediatek,mt6735-infracfg.h
|
||||
F: include/dt-bindings/reset/mediatek,mt6735-mfgcfg.h
|
||||
F: include/dt-bindings/reset/mediatek,mt6735-pericfg.h
|
||||
F: include/dt-bindings/reset/mediatek,mt6735-vdecsys.h
|
||||
|
||||
MEDIATEK MT76 WIRELESS LAN DRIVER
|
||||
M: Felix Fietkau <nbd@nbd.name>
|
||||
M: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
@ -1,5 +1,6 @@
|
||||
CONFIG_KUNIT=y
|
||||
CONFIG_OF=y
|
||||
CONFIG_OF_OVERLAY=y
|
||||
CONFIG_COMMON_CLK=y
|
||||
CONFIG_CLK_KUNIT_TEST=y
|
||||
CONFIG_CLK_FIXED_RATE_KUNIT_TEST=y
|
||||
|
@ -517,7 +517,6 @@ config CLK_KUNIT_TEST
|
||||
tristate "Basic Clock Framework Kunit Tests" if !KUNIT_ALL_TESTS
|
||||
depends on KUNIT
|
||||
default KUNIT_ALL_TESTS
|
||||
select OF_OVERLAY if OF
|
||||
select DTC
|
||||
help
|
||||
Kunit tests for the common clock framework.
|
||||
@ -526,7 +525,6 @@ config CLK_FIXED_RATE_KUNIT_TEST
|
||||
tristate "Basic fixed rate clk type KUnit test" if !KUNIT_ALL_TESTS
|
||||
depends on KUNIT
|
||||
default KUNIT_ALL_TESTS
|
||||
select OF_OVERLAY if OF
|
||||
select DTC
|
||||
help
|
||||
KUnit tests for the basic fixed rate clk type.
|
||||
|
@ -4,6 +4,20 @@ obj-$(CONFIG_HAVE_CLK) += clk-devres.o clk-bulk.o clkdev.o
|
||||
obj-$(CONFIG_COMMON_CLK) += clk.o
|
||||
obj-$(CONFIG_CLK_KUNIT_TEST) += clk-test.o
|
||||
clk-test-y := clk_test.o \
|
||||
kunit_clk_assigned_rates_u64_one.dtbo.o \
|
||||
kunit_clk_assigned_rates_u64_one_consumer.dtbo.o \
|
||||
kunit_clk_assigned_rates_u64_multiple.dtbo.o \
|
||||
kunit_clk_assigned_rates_u64_multiple_consumer.dtbo.o \
|
||||
kunit_clk_assigned_rates_multiple.dtbo.o \
|
||||
kunit_clk_assigned_rates_multiple_consumer.dtbo.o \
|
||||
kunit_clk_assigned_rates_null.dtbo.o \
|
||||
kunit_clk_assigned_rates_null_consumer.dtbo.o \
|
||||
kunit_clk_assigned_rates_one.dtbo.o \
|
||||
kunit_clk_assigned_rates_one_consumer.dtbo.o \
|
||||
kunit_clk_assigned_rates_without.dtbo.o \
|
||||
kunit_clk_assigned_rates_without_consumer.dtbo.o \
|
||||
kunit_clk_assigned_rates_zero.dtbo.o \
|
||||
kunit_clk_assigned_rates_zero_consumer.dtbo.o \
|
||||
kunit_clk_parent_data_test.dtbo.o
|
||||
obj-$(CONFIG_COMMON_CLK) += clk-divider.o
|
||||
obj-$(CONFIG_COMMON_CLK) += clk-fixed-factor.o
|
||||
|
@ -3,8 +3,10 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/reset-controller.h>
|
||||
#include <dt-bindings/clock/en7523-clk.h>
|
||||
#include <dt-bindings/reset/airoha,en7581-reset.h>
|
||||
@ -31,19 +33,14 @@
|
||||
#define REG_RESET_CONTROL_PCIE1 BIT(27)
|
||||
#define REG_RESET_CONTROL_PCIE2 BIT(26)
|
||||
/* EN7581 */
|
||||
#define REG_PCIE0_MEM 0x00
|
||||
#define REG_PCIE0_MEM_MASK 0x04
|
||||
#define REG_PCIE1_MEM 0x08
|
||||
#define REG_PCIE1_MEM_MASK 0x0c
|
||||
#define REG_PCIE2_MEM 0x10
|
||||
#define REG_PCIE2_MEM_MASK 0x14
|
||||
#define REG_NP_SCU_PCIC 0x88
|
||||
#define REG_NP_SCU_SSTR 0x9c
|
||||
#define REG_PCIE_XSI0_SEL_MASK GENMASK(14, 13)
|
||||
#define REG_PCIE_XSI1_SEL_MASK GENMASK(12, 11)
|
||||
#define REG_CRYPTO_CLKSRC2 0x20c
|
||||
|
||||
#define REG_RST_CTRL2 0x00
|
||||
#define REG_RST_CTRL1 0x04
|
||||
#define REG_RST_CTRL2 0x830
|
||||
#define REG_RST_CTRL1 0x834
|
||||
|
||||
struct en_clk_desc {
|
||||
int id;
|
||||
@ -79,12 +76,8 @@ struct en_rst_data {
|
||||
|
||||
struct en_clk_soc_data {
|
||||
const struct clk_ops pcie_ops;
|
||||
struct {
|
||||
const u16 *bank_ofs;
|
||||
const u16 *idx_map;
|
||||
u16 idx_map_nr;
|
||||
} reset;
|
||||
int (*hw_init)(struct platform_device *pdev, void __iomem *np_base);
|
||||
int (*hw_init)(struct platform_device *pdev,
|
||||
struct clk_hw_onecell_data *clk_data);
|
||||
};
|
||||
|
||||
static const u32 gsw_base[] = { 400000000, 500000000 };
|
||||
@ -92,6 +85,10 @@ static const u32 emi_base[] = { 333000000, 400000000 };
|
||||
static const u32 bus_base[] = { 500000000, 540000000 };
|
||||
static const u32 slic_base[] = { 100000000, 3125000 };
|
||||
static const u32 npu_base[] = { 333000000, 400000000, 500000000 };
|
||||
/* EN7581 */
|
||||
static const u32 emi7581_base[] = { 540000000, 480000000, 400000000, 300000000 };
|
||||
static const u32 npu7581_base[] = { 800000000, 750000000, 720000000, 600000000 };
|
||||
static const u32 crypto_base[] = { 540000000, 480000000 };
|
||||
|
||||
static const struct en_clk_desc en7523_base_clks[] = {
|
||||
{
|
||||
@ -189,6 +186,102 @@ static const struct en_clk_desc en7523_base_clks[] = {
|
||||
}
|
||||
};
|
||||
|
||||
static const struct en_clk_desc en7581_base_clks[] = {
|
||||
{
|
||||
.id = EN7523_CLK_GSW,
|
||||
.name = "gsw",
|
||||
|
||||
.base_reg = REG_GSW_CLK_DIV_SEL,
|
||||
.base_bits = 1,
|
||||
.base_shift = 8,
|
||||
.base_values = gsw_base,
|
||||
.n_base_values = ARRAY_SIZE(gsw_base),
|
||||
|
||||
.div_bits = 3,
|
||||
.div_shift = 0,
|
||||
.div_step = 1,
|
||||
.div_offset = 1,
|
||||
}, {
|
||||
.id = EN7523_CLK_EMI,
|
||||
.name = "emi",
|
||||
|
||||
.base_reg = REG_EMI_CLK_DIV_SEL,
|
||||
.base_bits = 2,
|
||||
.base_shift = 8,
|
||||
.base_values = emi7581_base,
|
||||
.n_base_values = ARRAY_SIZE(emi7581_base),
|
||||
|
||||
.div_bits = 3,
|
||||
.div_shift = 0,
|
||||
.div_step = 1,
|
||||
.div_offset = 1,
|
||||
}, {
|
||||
.id = EN7523_CLK_BUS,
|
||||
.name = "bus",
|
||||
|
||||
.base_reg = REG_BUS_CLK_DIV_SEL,
|
||||
.base_bits = 1,
|
||||
.base_shift = 8,
|
||||
.base_values = bus_base,
|
||||
.n_base_values = ARRAY_SIZE(bus_base),
|
||||
|
||||
.div_bits = 3,
|
||||
.div_shift = 0,
|
||||
.div_step = 1,
|
||||
.div_offset = 1,
|
||||
}, {
|
||||
.id = EN7523_CLK_SLIC,
|
||||
.name = "slic",
|
||||
|
||||
.base_reg = REG_SPI_CLK_FREQ_SEL,
|
||||
.base_bits = 1,
|
||||
.base_shift = 0,
|
||||
.base_values = slic_base,
|
||||
.n_base_values = ARRAY_SIZE(slic_base),
|
||||
|
||||
.div_reg = REG_SPI_CLK_DIV_SEL,
|
||||
.div_bits = 5,
|
||||
.div_shift = 24,
|
||||
.div_val0 = 20,
|
||||
.div_step = 2,
|
||||
}, {
|
||||
.id = EN7523_CLK_SPI,
|
||||
.name = "spi",
|
||||
|
||||
.base_reg = REG_SPI_CLK_DIV_SEL,
|
||||
|
||||
.base_value = 400000000,
|
||||
|
||||
.div_bits = 5,
|
||||
.div_shift = 8,
|
||||
.div_val0 = 40,
|
||||
.div_step = 2,
|
||||
}, {
|
||||
.id = EN7523_CLK_NPU,
|
||||
.name = "npu",
|
||||
|
||||
.base_reg = REG_NPU_CLK_DIV_SEL,
|
||||
.base_bits = 2,
|
||||
.base_shift = 8,
|
||||
.base_values = npu7581_base,
|
||||
.n_base_values = ARRAY_SIZE(npu7581_base),
|
||||
|
||||
.div_bits = 3,
|
||||
.div_shift = 0,
|
||||
.div_step = 1,
|
||||
.div_offset = 1,
|
||||
}, {
|
||||
.id = EN7523_CLK_CRYPTO,
|
||||
.name = "crypto",
|
||||
|
||||
.base_reg = REG_CRYPTO_CLKSRC2,
|
||||
.base_bits = 1,
|
||||
.base_shift = 0,
|
||||
.base_values = crypto_base,
|
||||
.n_base_values = ARRAY_SIZE(crypto_base),
|
||||
}
|
||||
};
|
||||
|
||||
static const u16 en7581_rst_ofs[] = {
|
||||
REG_RST_CTRL2,
|
||||
REG_RST_CTRL1,
|
||||
@ -252,15 +345,11 @@ static const u16 en7581_rst_map[] = {
|
||||
[EN7581_XPON_MAC_RST] = RST_NR_PER_BANK + 31,
|
||||
};
|
||||
|
||||
static unsigned int en7523_get_base_rate(void __iomem *base, unsigned int i)
|
||||
static u32 en7523_get_base_rate(const struct en_clk_desc *desc, u32 val)
|
||||
{
|
||||
const struct en_clk_desc *desc = &en7523_base_clks[i];
|
||||
u32 val;
|
||||
|
||||
if (!desc->base_bits)
|
||||
return desc->base_value;
|
||||
|
||||
val = readl(base + desc->base_reg);
|
||||
val >>= desc->base_shift;
|
||||
val &= (1 << desc->base_bits) - 1;
|
||||
|
||||
@ -270,16 +359,11 @@ static unsigned int en7523_get_base_rate(void __iomem *base, unsigned int i)
|
||||
return desc->base_values[val];
|
||||
}
|
||||
|
||||
static u32 en7523_get_div(void __iomem *base, int i)
|
||||
static u32 en7523_get_div(const struct en_clk_desc *desc, u32 val)
|
||||
{
|
||||
const struct en_clk_desc *desc = &en7523_base_clks[i];
|
||||
u32 reg, val;
|
||||
|
||||
if (!desc->div_bits)
|
||||
return 1;
|
||||
|
||||
reg = desc->div_reg ? desc->div_reg : desc->base_reg;
|
||||
val = readl(base + reg);
|
||||
val >>= desc->div_shift;
|
||||
val &= (1 << desc->div_bits) - 1;
|
||||
|
||||
@ -412,32 +496,6 @@ static void en7581_pci_disable(struct clk_hw *hw)
|
||||
usleep_range(1000, 2000);
|
||||
}
|
||||
|
||||
static int en7581_clk_hw_init(struct platform_device *pdev,
|
||||
void __iomem *np_base)
|
||||
{
|
||||
void __iomem *pb_base;
|
||||
u32 val;
|
||||
|
||||
pb_base = devm_platform_ioremap_resource(pdev, 3);
|
||||
if (IS_ERR(pb_base))
|
||||
return PTR_ERR(pb_base);
|
||||
|
||||
val = readl(np_base + REG_NP_SCU_SSTR);
|
||||
val &= ~(REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK);
|
||||
writel(val, np_base + REG_NP_SCU_SSTR);
|
||||
val = readl(np_base + REG_NP_SCU_PCIC);
|
||||
writel(val | 3, np_base + REG_NP_SCU_PCIC);
|
||||
|
||||
writel(0x20000000, pb_base + REG_PCIE0_MEM);
|
||||
writel(0xfc000000, pb_base + REG_PCIE0_MEM_MASK);
|
||||
writel(0x24000000, pb_base + REG_PCIE1_MEM);
|
||||
writel(0xfc000000, pb_base + REG_PCIE1_MEM_MASK);
|
||||
writel(0x28000000, pb_base + REG_PCIE2_MEM);
|
||||
writel(0xfc000000, pb_base + REG_PCIE2_MEM_MASK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data,
|
||||
void __iomem *base, void __iomem *np_base)
|
||||
{
|
||||
@ -447,9 +505,12 @@ static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_dat
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(en7523_base_clks); i++) {
|
||||
const struct en_clk_desc *desc = &en7523_base_clks[i];
|
||||
u32 reg = desc->div_reg ? desc->div_reg : desc->base_reg;
|
||||
u32 val = readl(base + desc->base_reg);
|
||||
|
||||
rate = en7523_get_base_rate(base, i);
|
||||
rate /= en7523_get_div(base, i);
|
||||
rate = en7523_get_base_rate(desc, val);
|
||||
val = readl(base + reg);
|
||||
rate /= en7523_get_div(desc, val);
|
||||
|
||||
hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate);
|
||||
if (IS_ERR(hw)) {
|
||||
@ -467,6 +528,68 @@ static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_dat
|
||||
clk_data->num = EN7523_NUM_CLOCKS;
|
||||
}
|
||||
|
||||
static int en7523_clk_hw_init(struct platform_device *pdev,
|
||||
struct clk_hw_onecell_data *clk_data)
|
||||
{
|
||||
void __iomem *base, *np_base;
|
||||
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
np_base = devm_platform_ioremap_resource(pdev, 1);
|
||||
if (IS_ERR(np_base))
|
||||
return PTR_ERR(np_base);
|
||||
|
||||
en7523_register_clocks(&pdev->dev, clk_data, base, np_base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data,
|
||||
struct regmap *map, void __iomem *base)
|
||||
{
|
||||
struct clk_hw *hw;
|
||||
u32 rate;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(en7581_base_clks); i++) {
|
||||
const struct en_clk_desc *desc = &en7581_base_clks[i];
|
||||
u32 val, reg = desc->div_reg ? desc->div_reg : desc->base_reg;
|
||||
int err;
|
||||
|
||||
err = regmap_read(map, desc->base_reg, &val);
|
||||
if (err) {
|
||||
pr_err("Failed reading fixed clk rate %s: %d\n",
|
||||
desc->name, err);
|
||||
continue;
|
||||
}
|
||||
rate = en7523_get_base_rate(desc, val);
|
||||
|
||||
err = regmap_read(map, reg, &val);
|
||||
if (err) {
|
||||
pr_err("Failed reading fixed clk div %s: %d\n",
|
||||
desc->name, err);
|
||||
continue;
|
||||
}
|
||||
rate /= en7523_get_div(desc, val);
|
||||
|
||||
hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate);
|
||||
if (IS_ERR(hw)) {
|
||||
pr_err("Failed to register clk %s: %ld\n",
|
||||
desc->name, PTR_ERR(hw));
|
||||
continue;
|
||||
}
|
||||
|
||||
clk_data->hws[desc->id] = hw;
|
||||
}
|
||||
|
||||
hw = en7523_register_pcie_clk(dev, base);
|
||||
clk_data->hws[EN7523_CLK_PCIE] = hw;
|
||||
|
||||
clk_data->num = EN7523_NUM_CLOCKS;
|
||||
}
|
||||
|
||||
static int en7523_reset_update(struct reset_controller_dev *rcdev,
|
||||
unsigned long id, bool assert)
|
||||
{
|
||||
@ -516,38 +639,27 @@ static int en7523_reset_xlate(struct reset_controller_dev *rcdev,
|
||||
return rst_data->idx_map[reset_spec->args[0]];
|
||||
}
|
||||
|
||||
static const struct reset_control_ops en7523_reset_ops = {
|
||||
static const struct reset_control_ops en7581_reset_ops = {
|
||||
.assert = en7523_reset_assert,
|
||||
.deassert = en7523_reset_deassert,
|
||||
.status = en7523_reset_status,
|
||||
};
|
||||
|
||||
static int en7523_reset_register(struct platform_device *pdev,
|
||||
const struct en_clk_soc_data *soc_data)
|
||||
static int en7581_reset_register(struct device *dev, void __iomem *base)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct en_rst_data *rst_data;
|
||||
void __iomem *base;
|
||||
|
||||
/* no reset lines available */
|
||||
if (!soc_data->reset.idx_map_nr)
|
||||
return 0;
|
||||
|
||||
base = devm_platform_ioremap_resource(pdev, 2);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
rst_data = devm_kzalloc(dev, sizeof(*rst_data), GFP_KERNEL);
|
||||
if (!rst_data)
|
||||
return -ENOMEM;
|
||||
|
||||
rst_data->bank_ofs = soc_data->reset.bank_ofs;
|
||||
rst_data->idx_map = soc_data->reset.idx_map;
|
||||
rst_data->bank_ofs = en7581_rst_ofs;
|
||||
rst_data->idx_map = en7581_rst_map;
|
||||
rst_data->base = base;
|
||||
|
||||
rst_data->rcdev.nr_resets = soc_data->reset.idx_map_nr;
|
||||
rst_data->rcdev.nr_resets = ARRAY_SIZE(en7581_rst_map);
|
||||
rst_data->rcdev.of_xlate = en7523_reset_xlate;
|
||||
rst_data->rcdev.ops = &en7523_reset_ops;
|
||||
rst_data->rcdev.ops = &en7581_reset_ops;
|
||||
rst_data->rcdev.of_node = dev->of_node;
|
||||
rst_data->rcdev.of_reset_n_cells = 1;
|
||||
rst_data->rcdev.owner = THIS_MODULE;
|
||||
@ -556,28 +668,38 @@ static int en7523_reset_register(struct platform_device *pdev,
|
||||
return devm_reset_controller_register(dev, &rst_data->rcdev);
|
||||
}
|
||||
|
||||
static int en7523_clk_probe(struct platform_device *pdev)
|
||||
static int en7581_clk_hw_init(struct platform_device *pdev,
|
||||
struct clk_hw_onecell_data *clk_data)
|
||||
{
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
const struct en_clk_soc_data *soc_data;
|
||||
struct clk_hw_onecell_data *clk_data;
|
||||
void __iomem *base, *np_base;
|
||||
int r;
|
||||
struct regmap *map;
|
||||
void __iomem *base;
|
||||
u32 val;
|
||||
|
||||
map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu");
|
||||
if (IS_ERR(map))
|
||||
return PTR_ERR(map);
|
||||
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
np_base = devm_platform_ioremap_resource(pdev, 1);
|
||||
if (IS_ERR(np_base))
|
||||
return PTR_ERR(np_base);
|
||||
en7581_register_clocks(&pdev->dev, clk_data, map, base);
|
||||
|
||||
soc_data = device_get_match_data(&pdev->dev);
|
||||
if (soc_data->hw_init) {
|
||||
r = soc_data->hw_init(pdev, np_base);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
val = readl(base + REG_NP_SCU_SSTR);
|
||||
val &= ~(REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK);
|
||||
writel(val, base + REG_NP_SCU_SSTR);
|
||||
val = readl(base + REG_NP_SCU_PCIC);
|
||||
writel(val | 3, base + REG_NP_SCU_PCIC);
|
||||
|
||||
return en7581_reset_register(&pdev->dev, base);
|
||||
}
|
||||
|
||||
static int en7523_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
const struct en_clk_soc_data *soc_data;
|
||||
struct clk_hw_onecell_data *clk_data;
|
||||
int r;
|
||||
|
||||
clk_data = devm_kzalloc(&pdev->dev,
|
||||
struct_size(clk_data, hws, EN7523_NUM_CLOCKS),
|
||||
@ -585,21 +707,12 @@ static int en7523_clk_probe(struct platform_device *pdev)
|
||||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
en7523_register_clocks(&pdev->dev, clk_data, base, np_base);
|
||||
|
||||
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||
soc_data = device_get_match_data(&pdev->dev);
|
||||
r = soc_data->hw_init(pdev, clk_data);
|
||||
if (r)
|
||||
return dev_err_probe(&pdev->dev, r, "Could not register clock provider: %s\n",
|
||||
pdev->name);
|
||||
return r;
|
||||
|
||||
r = en7523_reset_register(pdev, soc_data);
|
||||
if (r) {
|
||||
of_clk_del_provider(node);
|
||||
return dev_err_probe(&pdev->dev, r, "Could not register reset controller: %s\n",
|
||||
pdev->name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||
}
|
||||
|
||||
static const struct en_clk_soc_data en7523_data = {
|
||||
@ -608,6 +721,7 @@ static const struct en_clk_soc_data en7523_data = {
|
||||
.prepare = en7523_pci_prepare,
|
||||
.unprepare = en7523_pci_unprepare,
|
||||
},
|
||||
.hw_init = en7523_clk_hw_init,
|
||||
};
|
||||
|
||||
static const struct en_clk_soc_data en7581_data = {
|
||||
@ -616,11 +730,6 @@ static const struct en_clk_soc_data en7581_data = {
|
||||
.enable = en7581_pci_enable,
|
||||
.disable = en7581_pci_disable,
|
||||
},
|
||||
.reset = {
|
||||
.bank_ofs = en7581_rst_ofs,
|
||||
.idx_map = en7581_rst_map,
|
||||
.idx_map_nr = ARRAY_SIZE(en7581_rst_map),
|
||||
},
|
||||
.hw_init = en7581_clk_hw_init,
|
||||
};
|
||||
|
||||
|
@ -17,13 +17,15 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
/**
|
||||
* DOC: basic gpio gated clock which can be enabled and disabled
|
||||
* with gpio output
|
||||
* Traits of this clock:
|
||||
* prepare - clk_(un)prepare only ensures parent is (un)prepared
|
||||
* enable - clk_enable and clk_disable are functional & control gpio
|
||||
* prepare - clk_(un)prepare are functional and control a gpio that can sleep
|
||||
* enable - clk_enable and clk_disable are functional & control
|
||||
* non-sleeping gpio
|
||||
* rate - inherits rate from parent. No clk_set_rate support
|
||||
* parent - fixed parent. No clk_set_parent support
|
||||
*/
|
||||
@ -199,7 +201,6 @@ static int gpio_clk_driver_probe(struct platform_device *pdev)
|
||||
struct gpio_desc *gpiod;
|
||||
struct clk_hw *hw;
|
||||
bool is_mux;
|
||||
int ret;
|
||||
|
||||
is_mux = of_device_is_compatible(node, "gpio-mux-clock");
|
||||
|
||||
@ -211,17 +212,9 @@ static int gpio_clk_driver_probe(struct platform_device *pdev)
|
||||
|
||||
gpio_name = is_mux ? "select" : "enable";
|
||||
gpiod = devm_gpiod_get(dev, gpio_name, GPIOD_OUT_LOW);
|
||||
if (IS_ERR(gpiod)) {
|
||||
ret = PTR_ERR(gpiod);
|
||||
if (ret == -EPROBE_DEFER)
|
||||
pr_debug("%pOFn: %s: GPIOs not yet available, retry later\n",
|
||||
node, __func__);
|
||||
else
|
||||
pr_err("%pOFn: %s: Can't get '%s' named GPIO property\n",
|
||||
node, __func__,
|
||||
gpio_name);
|
||||
return ret;
|
||||
}
|
||||
if (IS_ERR(gpiod))
|
||||
return dev_err_probe(dev, PTR_ERR(gpiod),
|
||||
"Can't get '%s' named GPIO property\n", gpio_name);
|
||||
|
||||
if (is_mux)
|
||||
hw = clk_hw_register_gpio_mux(dev, gpiod);
|
||||
@ -247,3 +240,187 @@ static struct platform_driver gpio_clk_driver = {
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(gpio_clk_driver);
|
||||
|
||||
/**
|
||||
* DOC: gated fixed clock, controlled with a gpio output and a regulator
|
||||
* Traits of this clock:
|
||||
* prepare - clk_prepare and clk_unprepare are function & control regulator
|
||||
* optionally a gpio that can sleep
|
||||
* enable - clk_enable and clk_disable are functional & control gpio
|
||||
* rate - rate is fixed and set on clock registration
|
||||
* parent - fixed clock is a root clock and has no parent
|
||||
*/
|
||||
|
||||
/**
|
||||
* struct clk_gated_fixed - Gateable fixed rate clock
|
||||
* @clk_gpio: instance of clk_gpio for gate-gpio
|
||||
* @supply: supply regulator
|
||||
* @rate: fixed rate
|
||||
*/
|
||||
struct clk_gated_fixed {
|
||||
struct clk_gpio clk_gpio;
|
||||
struct regulator *supply;
|
||||
unsigned long rate;
|
||||
};
|
||||
|
||||
#define to_clk_gated_fixed(_clk_gpio) container_of(_clk_gpio, struct clk_gated_fixed, clk_gpio)
|
||||
|
||||
static unsigned long clk_gated_fixed_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
return to_clk_gated_fixed(to_clk_gpio(hw))->rate;
|
||||
}
|
||||
|
||||
static int clk_gated_fixed_prepare(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_gated_fixed *clk = to_clk_gated_fixed(to_clk_gpio(hw));
|
||||
|
||||
if (!clk->supply)
|
||||
return 0;
|
||||
|
||||
return regulator_enable(clk->supply);
|
||||
}
|
||||
|
||||
static void clk_gated_fixed_unprepare(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_gated_fixed *clk = to_clk_gated_fixed(to_clk_gpio(hw));
|
||||
|
||||
if (!clk->supply)
|
||||
return;
|
||||
|
||||
regulator_disable(clk->supply);
|
||||
}
|
||||
|
||||
static int clk_gated_fixed_is_prepared(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_gated_fixed *clk = to_clk_gated_fixed(to_clk_gpio(hw));
|
||||
|
||||
if (!clk->supply)
|
||||
return true;
|
||||
|
||||
return regulator_is_enabled(clk->supply);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fixed gated clock with non-sleeping gpio.
|
||||
*
|
||||
* Prepare operation turns on the supply regulator
|
||||
* and the enable operation switches the enable-gpio.
|
||||
*/
|
||||
static const struct clk_ops clk_gated_fixed_ops = {
|
||||
.prepare = clk_gated_fixed_prepare,
|
||||
.unprepare = clk_gated_fixed_unprepare,
|
||||
.is_prepared = clk_gated_fixed_is_prepared,
|
||||
.enable = clk_gpio_gate_enable,
|
||||
.disable = clk_gpio_gate_disable,
|
||||
.is_enabled = clk_gpio_gate_is_enabled,
|
||||
.recalc_rate = clk_gated_fixed_recalc_rate,
|
||||
};
|
||||
|
||||
static int clk_sleeping_gated_fixed_prepare(struct clk_hw *hw)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = clk_gated_fixed_prepare(hw);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_sleeping_gpio_gate_prepare(hw);
|
||||
if (ret)
|
||||
clk_gated_fixed_unprepare(hw);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void clk_sleeping_gated_fixed_unprepare(struct clk_hw *hw)
|
||||
{
|
||||
clk_gated_fixed_unprepare(hw);
|
||||
clk_sleeping_gpio_gate_unprepare(hw);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fixed gated clock with non-sleeping gpio.
|
||||
*
|
||||
* Enabling the supply regulator and switching the enable-gpio happens
|
||||
* both in the prepare step.
|
||||
* is_prepared only needs to check the gpio state, as toggling the
|
||||
* gpio is the last step when preparing.
|
||||
*/
|
||||
static const struct clk_ops clk_sleeping_gated_fixed_ops = {
|
||||
.prepare = clk_sleeping_gated_fixed_prepare,
|
||||
.unprepare = clk_sleeping_gated_fixed_unprepare,
|
||||
.is_prepared = clk_sleeping_gpio_gate_is_prepared,
|
||||
.recalc_rate = clk_gated_fixed_recalc_rate,
|
||||
};
|
||||
|
||||
static int clk_gated_fixed_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct clk_gated_fixed *clk;
|
||||
const struct clk_ops *ops;
|
||||
const char *clk_name;
|
||||
u32 rate;
|
||||
int ret;
|
||||
|
||||
clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL);
|
||||
if (!clk)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = device_property_read_u32(dev, "clock-frequency", &rate);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to get clock-frequency\n");
|
||||
clk->rate = rate;
|
||||
|
||||
ret = device_property_read_string(dev, "clock-output-names", &clk_name);
|
||||
if (ret)
|
||||
clk_name = fwnode_get_name(dev->fwnode);
|
||||
|
||||
clk->supply = devm_regulator_get_optional(dev, "vdd");
|
||||
if (IS_ERR(clk->supply)) {
|
||||
if (PTR_ERR(clk->supply) != -ENODEV)
|
||||
return dev_err_probe(dev, PTR_ERR(clk->supply),
|
||||
"Failed to get regulator\n");
|
||||
clk->supply = NULL;
|
||||
}
|
||||
|
||||
clk->clk_gpio.gpiod = devm_gpiod_get_optional(dev, "enable",
|
||||
GPIOD_OUT_LOW);
|
||||
if (IS_ERR(clk->clk_gpio.gpiod))
|
||||
return dev_err_probe(dev, PTR_ERR(clk->clk_gpio.gpiod),
|
||||
"Failed to get gpio\n");
|
||||
|
||||
if (gpiod_cansleep(clk->clk_gpio.gpiod))
|
||||
ops = &clk_sleeping_gated_fixed_ops;
|
||||
else
|
||||
ops = &clk_gated_fixed_ops;
|
||||
|
||||
clk->clk_gpio.hw.init = CLK_HW_INIT_NO_PARENT(clk_name, ops, 0);
|
||||
|
||||
/* register the clock */
|
||||
ret = devm_clk_hw_register(dev, &clk->clk_gpio.hw);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"Failed to register clock\n");
|
||||
|
||||
ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get,
|
||||
&clk->clk_gpio.hw);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"Failed to register clock provider\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id gated_fixed_clk_match_table[] = {
|
||||
{ .compatible = "gated-fixed-clock" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct platform_driver gated_fixed_clk_driver = {
|
||||
.probe = clk_gated_fixed_probe,
|
||||
.driver = {
|
||||
.name = "gated-fixed-clk",
|
||||
.of_match_table = gated_fixed_clk_match_table,
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(gated_fixed_clk_driver);
|
||||
|
@ -203,5 +203,35 @@ int of_clk_hw_register_kunit(struct kunit *test, struct device_node *node, struc
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_clk_hw_register_kunit);
|
||||
|
||||
KUNIT_DEFINE_ACTION_WRAPPER(of_clk_del_provider_wrapper,
|
||||
of_clk_del_provider, struct device_node *);
|
||||
|
||||
/**
|
||||
* of_clk_add_hw_provider_kunit() - Test managed of_clk_add_hw_provider()
|
||||
* @test: The test context
|
||||
* @np: Device node pointer associated with clock provider
|
||||
* @get: Callback for decoding clk_hw
|
||||
* @data: Context pointer for @get callback.
|
||||
*
|
||||
* Just like of_clk_add_hw_provider(), except the clk_hw provider is managed by
|
||||
* the test case and is automatically unregistered after the test case
|
||||
* concludes.
|
||||
*
|
||||
* Return: 0 on success or a negative errno value on failure.
|
||||
*/
|
||||
int of_clk_add_hw_provider_kunit(struct kunit *test, struct device_node *np,
|
||||
struct clk_hw *(*get)(struct of_phandle_args *clkspec, void *data),
|
||||
void *data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = of_clk_add_hw_provider(np, get, data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return kunit_add_action_or_reset(test, of_clk_del_provider_wrapper, np);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_clk_add_hw_provider_kunit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("KUnit helpers for clk providers and consumers");
|
||||
|
@ -4,6 +4,7 @@
|
||||
*/
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clk/clk-conf.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
@ -15,6 +16,7 @@
|
||||
#include <kunit/platform_device.h>
|
||||
#include <kunit/test.h>
|
||||
|
||||
#include "kunit_clk_assigned_rates.h"
|
||||
#include "clk_parent_data_test.h"
|
||||
|
||||
static const struct clk_ops empty_clk_ops = { };
|
||||
@ -3108,7 +3110,326 @@ static struct kunit_suite clk_register_clk_parent_data_device_suite = {
|
||||
.test_cases = clk_register_clk_parent_data_device_test_cases,
|
||||
};
|
||||
|
||||
struct clk_assigned_rates_context {
|
||||
struct clk_dummy_context clk0;
|
||||
struct clk_dummy_context clk1;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct clk_assigned_rates_test_param - Test parameters for clk_assigned_rates test
|
||||
* @desc: Test description
|
||||
* @overlay_begin: Pointer to start of DT overlay to apply for test
|
||||
* @overlay_end: Pointer to end of DT overlay to apply for test
|
||||
* @rate0: Initial rate of first clk
|
||||
* @rate1: Initial rate of second clk
|
||||
* @consumer_test: true if a consumer is being tested
|
||||
*/
|
||||
struct clk_assigned_rates_test_param {
|
||||
const char *desc;
|
||||
u8 *overlay_begin;
|
||||
u8 *overlay_end;
|
||||
unsigned long rate0;
|
||||
unsigned long rate1;
|
||||
bool consumer_test;
|
||||
};
|
||||
|
||||
#define TEST_PARAM_OVERLAY(overlay_name) \
|
||||
.overlay_begin = of_overlay_begin(overlay_name), \
|
||||
.overlay_end = of_overlay_end(overlay_name)
|
||||
|
||||
static void
|
||||
clk_assigned_rates_register_clk(struct kunit *test,
|
||||
struct clk_dummy_context *ctx,
|
||||
struct device_node *np, const char *name,
|
||||
unsigned long rate)
|
||||
{
|
||||
struct clk_init_data init = { };
|
||||
|
||||
init.name = name;
|
||||
init.ops = &clk_dummy_rate_ops;
|
||||
ctx->hw.init = &init;
|
||||
ctx->rate = rate;
|
||||
|
||||
KUNIT_ASSERT_EQ(test, 0, of_clk_hw_register_kunit(test, np, &ctx->hw));
|
||||
KUNIT_ASSERT_EQ(test, ctx->rate, rate);
|
||||
}
|
||||
|
||||
/*
|
||||
* Does most of the work of the test:
|
||||
*
|
||||
* 1. Apply the overlay to test
|
||||
* 2. Register the clk or clks to test
|
||||
* 3. Register the clk provider
|
||||
* 4. Apply clk defaults to the consumer device if this is a consumer test
|
||||
*
|
||||
* The tests will set different test_param values to test different scenarios
|
||||
* and validate that in their test functions.
|
||||
*/
|
||||
static int clk_assigned_rates_test_init(struct kunit *test)
|
||||
{
|
||||
struct device_node *np, *consumer;
|
||||
struct clk_hw_onecell_data *data;
|
||||
struct clk_assigned_rates_context *ctx;
|
||||
u32 clk_cells;
|
||||
const struct clk_assigned_rates_test_param *test_param;
|
||||
|
||||
test_param = test->param_value;
|
||||
|
||||
KUNIT_ASSERT_EQ(test, 0, __of_overlay_apply_kunit(test,
|
||||
test_param->overlay_begin,
|
||||
test_param->overlay_end));
|
||||
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test,
|
||||
ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL));
|
||||
test->priv = ctx;
|
||||
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test,
|
||||
np = of_find_compatible_node(NULL, NULL, "test,clk-assigned-rates"));
|
||||
of_node_put_kunit(test, np);
|
||||
|
||||
KUNIT_ASSERT_EQ(test, 0, of_property_read_u32(np, "#clock-cells", &clk_cells));
|
||||
/* Only support #clock-cells = <0> or <1> */
|
||||
KUNIT_ASSERT_LT(test, clk_cells, 2);
|
||||
|
||||
clk_assigned_rates_register_clk(test, &ctx->clk0, np,
|
||||
"test_assigned_rate0", test_param->rate0);
|
||||
if (clk_cells == 0) {
|
||||
KUNIT_ASSERT_EQ(test, 0,
|
||||
of_clk_add_hw_provider_kunit(test, np, of_clk_hw_simple_get,
|
||||
&ctx->clk0.hw));
|
||||
} else if (clk_cells == 1) {
|
||||
clk_assigned_rates_register_clk(test, &ctx->clk1, np,
|
||||
"test_assigned_rate1", test_param->rate1);
|
||||
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test,
|
||||
data = kunit_kzalloc(test, struct_size(data, hws, 2), GFP_KERNEL));
|
||||
data->num = 2;
|
||||
data->hws[0] = &ctx->clk0.hw;
|
||||
data->hws[1] = &ctx->clk1.hw;
|
||||
|
||||
KUNIT_ASSERT_EQ(test, 0,
|
||||
of_clk_add_hw_provider_kunit(test, np, of_clk_hw_onecell_get, data));
|
||||
}
|
||||
|
||||
/* Consumers are optional */
|
||||
if (test_param->consumer_test) {
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test,
|
||||
consumer = of_find_compatible_node(NULL, NULL, "test,clk-consumer"));
|
||||
of_node_put_kunit(test, consumer);
|
||||
|
||||
KUNIT_ASSERT_EQ(test, 0, of_clk_set_defaults(consumer, false));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void clk_assigned_rates_assigns_one(struct kunit *test)
|
||||
{
|
||||
struct clk_assigned_rates_context *ctx = test->priv;
|
||||
|
||||
KUNIT_EXPECT_EQ(test, ctx->clk0.rate, ASSIGNED_RATES_0_RATE);
|
||||
}
|
||||
|
||||
static void clk_assigned_rates_assigns_multiple(struct kunit *test)
|
||||
{
|
||||
struct clk_assigned_rates_context *ctx = test->priv;
|
||||
|
||||
KUNIT_EXPECT_EQ(test, ctx->clk0.rate, ASSIGNED_RATES_0_RATE);
|
||||
KUNIT_EXPECT_EQ(test, ctx->clk1.rate, ASSIGNED_RATES_1_RATE);
|
||||
}
|
||||
|
||||
static void clk_assigned_rates_skips(struct kunit *test)
|
||||
{
|
||||
struct clk_assigned_rates_context *ctx = test->priv;
|
||||
const struct clk_assigned_rates_test_param *test_param = test->param_value;
|
||||
|
||||
KUNIT_EXPECT_NE(test, ctx->clk0.rate, ASSIGNED_RATES_0_RATE);
|
||||
KUNIT_EXPECT_EQ(test, ctx->clk0.rate, test_param->rate0);
|
||||
}
|
||||
|
||||
OF_OVERLAY_DECLARE(kunit_clk_assigned_rates_one);
|
||||
OF_OVERLAY_DECLARE(kunit_clk_assigned_rates_one_consumer);
|
||||
OF_OVERLAY_DECLARE(kunit_clk_assigned_rates_u64_one);
|
||||
OF_OVERLAY_DECLARE(kunit_clk_assigned_rates_u64_one_consumer);
|
||||
|
||||
/* Test cases that assign one rate */
|
||||
static const struct clk_assigned_rates_test_param clk_assigned_rates_assigns_one_test_params[] = {
|
||||
{
|
||||
/*
|
||||
* Test that a single cell assigned-clock-rates property
|
||||
* assigns the rate when the property is in the provider.
|
||||
*/
|
||||
.desc = "provider assigns",
|
||||
TEST_PARAM_OVERLAY(kunit_clk_assigned_rates_one),
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Test that a single cell assigned-clock-rates property
|
||||
* assigns the rate when the property is in the consumer.
|
||||
*/
|
||||
.desc = "consumer assigns",
|
||||
TEST_PARAM_OVERLAY(kunit_clk_assigned_rates_one_consumer),
|
||||
.consumer_test = true,
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Test that a single cell assigned-clock-rates-u64 property
|
||||
* assigns the rate when the property is in the provider.
|
||||
*/
|
||||
.desc = "provider assigns u64",
|
||||
TEST_PARAM_OVERLAY(kunit_clk_assigned_rates_u64_one),
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Test that a single cell assigned-clock-rates-u64 property
|
||||
* assigns the rate when the property is in the consumer.
|
||||
*/
|
||||
.desc = "consumer assigns u64",
|
||||
TEST_PARAM_OVERLAY(kunit_clk_assigned_rates_u64_one_consumer),
|
||||
.consumer_test = true,
|
||||
},
|
||||
};
|
||||
KUNIT_ARRAY_PARAM_DESC(clk_assigned_rates_assigns_one,
|
||||
clk_assigned_rates_assigns_one_test_params, desc)
|
||||
|
||||
OF_OVERLAY_DECLARE(kunit_clk_assigned_rates_multiple);
|
||||
OF_OVERLAY_DECLARE(kunit_clk_assigned_rates_multiple_consumer);
|
||||
OF_OVERLAY_DECLARE(kunit_clk_assigned_rates_u64_multiple);
|
||||
OF_OVERLAY_DECLARE(kunit_clk_assigned_rates_u64_multiple_consumer);
|
||||
|
||||
/* Test cases that assign multiple rates */
|
||||
static const struct clk_assigned_rates_test_param clk_assigned_rates_assigns_multiple_test_params[] = {
|
||||
{
|
||||
/*
|
||||
* Test that a multiple cell assigned-clock-rates property
|
||||
* assigns the rates when the property is in the provider.
|
||||
*/
|
||||
.desc = "provider assigns",
|
||||
TEST_PARAM_OVERLAY(kunit_clk_assigned_rates_multiple),
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Test that a multiple cell assigned-clock-rates property
|
||||
* assigns the rates when the property is in the consumer.
|
||||
*/
|
||||
.desc = "consumer assigns",
|
||||
TEST_PARAM_OVERLAY(kunit_clk_assigned_rates_multiple_consumer),
|
||||
.consumer_test = true,
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Test that a single cell assigned-clock-rates-u64 property
|
||||
* assigns the rate when the property is in the provider.
|
||||
*/
|
||||
.desc = "provider assigns u64",
|
||||
TEST_PARAM_OVERLAY(kunit_clk_assigned_rates_u64_multiple),
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Test that a multiple cell assigned-clock-rates-u64 property
|
||||
* assigns the rates when the property is in the consumer.
|
||||
*/
|
||||
.desc = "consumer assigns u64",
|
||||
TEST_PARAM_OVERLAY(kunit_clk_assigned_rates_u64_multiple_consumer),
|
||||
.consumer_test = true,
|
||||
},
|
||||
};
|
||||
KUNIT_ARRAY_PARAM_DESC(clk_assigned_rates_assigns_multiple,
|
||||
clk_assigned_rates_assigns_multiple_test_params,
|
||||
desc)
|
||||
|
||||
OF_OVERLAY_DECLARE(kunit_clk_assigned_rates_without);
|
||||
OF_OVERLAY_DECLARE(kunit_clk_assigned_rates_without_consumer);
|
||||
OF_OVERLAY_DECLARE(kunit_clk_assigned_rates_zero);
|
||||
OF_OVERLAY_DECLARE(kunit_clk_assigned_rates_zero_consumer);
|
||||
OF_OVERLAY_DECLARE(kunit_clk_assigned_rates_null);
|
||||
OF_OVERLAY_DECLARE(kunit_clk_assigned_rates_null_consumer);
|
||||
|
||||
/* Test cases that skip changing the rate due to malformed DT */
|
||||
static const struct clk_assigned_rates_test_param clk_assigned_rates_skips_test_params[] = {
|
||||
{
|
||||
/*
|
||||
* Test that an assigned-clock-rates property without an assigned-clocks
|
||||
* property fails when the property is in the provider.
|
||||
*/
|
||||
.desc = "provider missing assigned-clocks",
|
||||
TEST_PARAM_OVERLAY(kunit_clk_assigned_rates_without),
|
||||
.rate0 = 3000,
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Test that an assigned-clock-rates property without an assigned-clocks
|
||||
* property fails when the property is in the consumer.
|
||||
*/
|
||||
.desc = "consumer missing assigned-clocks",
|
||||
TEST_PARAM_OVERLAY(kunit_clk_assigned_rates_without_consumer),
|
||||
.rate0 = 3000,
|
||||
.consumer_test = true,
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Test that an assigned-clock-rates property of zero doesn't
|
||||
* set a rate when the property is in the provider.
|
||||
*/
|
||||
.desc = "provider assigned-clock-rates of zero",
|
||||
TEST_PARAM_OVERLAY(kunit_clk_assigned_rates_zero),
|
||||
.rate0 = 3000,
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Test that an assigned-clock-rates property of zero doesn't
|
||||
* set a rate when the property is in the consumer.
|
||||
*/
|
||||
.desc = "consumer assigned-clock-rates of zero",
|
||||
TEST_PARAM_OVERLAY(kunit_clk_assigned_rates_zero_consumer),
|
||||
.rate0 = 3000,
|
||||
.consumer_test = true,
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Test that an assigned-clocks property with a null phandle
|
||||
* doesn't set a rate when the property is in the provider.
|
||||
*/
|
||||
.desc = "provider assigned-clocks null phandle",
|
||||
TEST_PARAM_OVERLAY(kunit_clk_assigned_rates_null),
|
||||
.rate0 = 3000,
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Test that an assigned-clocks property with a null phandle
|
||||
* doesn't set a rate when the property is in the consumer.
|
||||
*/
|
||||
.desc = "provider assigned-clocks null phandle",
|
||||
TEST_PARAM_OVERLAY(kunit_clk_assigned_rates_null_consumer),
|
||||
.rate0 = 3000,
|
||||
.consumer_test = true,
|
||||
},
|
||||
};
|
||||
KUNIT_ARRAY_PARAM_DESC(clk_assigned_rates_skips,
|
||||
clk_assigned_rates_skips_test_params,
|
||||
desc)
|
||||
|
||||
static struct kunit_case clk_assigned_rates_test_cases[] = {
|
||||
KUNIT_CASE_PARAM(clk_assigned_rates_assigns_one,
|
||||
clk_assigned_rates_assigns_one_gen_params),
|
||||
KUNIT_CASE_PARAM(clk_assigned_rates_assigns_multiple,
|
||||
clk_assigned_rates_assigns_multiple_gen_params),
|
||||
KUNIT_CASE_PARAM(clk_assigned_rates_skips,
|
||||
clk_assigned_rates_skips_gen_params),
|
||||
{}
|
||||
};
|
||||
|
||||
/*
|
||||
* Test suite for assigned-clock-rates{-u64} DT property.
|
||||
*/
|
||||
static struct kunit_suite clk_assigned_rates_suite = {
|
||||
.name = "clk_assigned_rates",
|
||||
.test_cases = clk_assigned_rates_test_cases,
|
||||
.init = clk_assigned_rates_test_init,
|
||||
};
|
||||
|
||||
kunit_test_suites(
|
||||
&clk_assigned_rates_suite,
|
||||
&clk_leaf_mux_set_rate_parent_test_suite,
|
||||
&clk_test_suite,
|
||||
&clk_multiple_parents_mux_test_suite,
|
||||
|
8
drivers/clk/kunit_clk_assigned_rates.h
Normal file
8
drivers/clk/kunit_clk_assigned_rates.h
Normal file
@ -0,0 +1,8 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _KUNIT_CLK_ASSIGNED_RATES_H
|
||||
#define _KUNIT_CLK_ASSIGNED_RATES_H
|
||||
|
||||
#define ASSIGNED_RATES_0_RATE 1600000
|
||||
#define ASSIGNED_RATES_1_RATE 9700000
|
||||
|
||||
#endif
|
16
drivers/clk/kunit_clk_assigned_rates_multiple.dtso
Normal file
16
drivers/clk/kunit_clk_assigned_rates_multiple.dtso
Normal file
@ -0,0 +1,16 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "kunit_clk_assigned_rates.h"
|
||||
|
||||
&{/} {
|
||||
clk: kunit-clock {
|
||||
compatible = "test,clk-assigned-rates";
|
||||
#clock-cells = <1>;
|
||||
assigned-clocks = <&clk 0>,
|
||||
<&clk 1>;
|
||||
assigned-clock-rates = <ASSIGNED_RATES_0_RATE>,
|
||||
<ASSIGNED_RATES_1_RATE>;
|
||||
};
|
||||
};
|
20
drivers/clk/kunit_clk_assigned_rates_multiple_consumer.dtso
Normal file
20
drivers/clk/kunit_clk_assigned_rates_multiple_consumer.dtso
Normal file
@ -0,0 +1,20 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "kunit_clk_assigned_rates.h"
|
||||
|
||||
&{/} {
|
||||
clk: kunit-clock {
|
||||
compatible = "test,clk-assigned-rates";
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
kunit-clock-consumer {
|
||||
compatible = "test,clk-consumer";
|
||||
assigned-clocks = <&clk 0>,
|
||||
<&clk 1>;
|
||||
assigned-clock-rates = <ASSIGNED_RATES_0_RATE>,
|
||||
<ASSIGNED_RATES_1_RATE>;
|
||||
};
|
||||
};
|
14
drivers/clk/kunit_clk_assigned_rates_null.dtso
Normal file
14
drivers/clk/kunit_clk_assigned_rates_null.dtso
Normal file
@ -0,0 +1,14 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "kunit_clk_assigned_rates.h"
|
||||
|
||||
&{/} {
|
||||
clk: kunit-clock {
|
||||
compatible = "test,clk-assigned-rates";
|
||||
#clock-cells = <0>;
|
||||
assigned-clocks = <0>;
|
||||
assigned-clock-rates = <ASSIGNED_RATES_0_RATE>;
|
||||
};
|
||||
};
|
18
drivers/clk/kunit_clk_assigned_rates_null_consumer.dtso
Normal file
18
drivers/clk/kunit_clk_assigned_rates_null_consumer.dtso
Normal file
@ -0,0 +1,18 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "kunit_clk_assigned_rates.h"
|
||||
|
||||
&{/} {
|
||||
clk: kunit-clock {
|
||||
compatible = "test,clk-assigned-rates";
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
|
||||
kunit-clock-consumer {
|
||||
compatible = "test,clk-consumer";
|
||||
assigned-clocks = <0>;
|
||||
assigned-clock-rates = <ASSIGNED_RATES_0_RATE>;
|
||||
};
|
||||
};
|
14
drivers/clk/kunit_clk_assigned_rates_one.dtso
Normal file
14
drivers/clk/kunit_clk_assigned_rates_one.dtso
Normal file
@ -0,0 +1,14 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "kunit_clk_assigned_rates.h"
|
||||
|
||||
&{/} {
|
||||
clk: kunit-clock {
|
||||
compatible = "test,clk-assigned-rates";
|
||||
#clock-cells = <0>;
|
||||
assigned-clocks = <&clk>;
|
||||
assigned-clock-rates = <ASSIGNED_RATES_0_RATE>;
|
||||
};
|
||||
};
|
18
drivers/clk/kunit_clk_assigned_rates_one_consumer.dtso
Normal file
18
drivers/clk/kunit_clk_assigned_rates_one_consumer.dtso
Normal file
@ -0,0 +1,18 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "kunit_clk_assigned_rates.h"
|
||||
|
||||
&{/} {
|
||||
clk: kunit-clock {
|
||||
compatible = "test,clk-assigned-rates";
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
|
||||
kunit-clock-consumer {
|
||||
compatible = "test,clk-consumer";
|
||||
assigned-clocks = <&clk>;
|
||||
assigned-clock-rates = <ASSIGNED_RATES_0_RATE>;
|
||||
};
|
||||
};
|
16
drivers/clk/kunit_clk_assigned_rates_u64_multiple.dtso
Normal file
16
drivers/clk/kunit_clk_assigned_rates_u64_multiple.dtso
Normal file
@ -0,0 +1,16 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "kunit_clk_assigned_rates.h"
|
||||
|
||||
&{/} {
|
||||
clk: kunit-clock {
|
||||
compatible = "test,clk-assigned-rates";
|
||||
#clock-cells = <1>;
|
||||
assigned-clocks = <&clk 0>,
|
||||
<&clk 1>;
|
||||
assigned-clock-rates-u64 = /bits/ 64 <ASSIGNED_RATES_0_RATE>,
|
||||
/bits/ 64 <ASSIGNED_RATES_1_RATE>;
|
||||
};
|
||||
};
|
@ -0,0 +1,20 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "kunit_clk_assigned_rates.h"
|
||||
|
||||
&{/} {
|
||||
clk: kunit-clock {
|
||||
compatible = "test,clk-assigned-rates";
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
kunit-clock-consumer {
|
||||
compatible = "test,clk-consumer";
|
||||
assigned-clocks = <&clk 0>,
|
||||
<&clk 1>;
|
||||
assigned-clock-rates-u64 = /bits/ 64 <ASSIGNED_RATES_0_RATE>,
|
||||
/bits/ 64 <ASSIGNED_RATES_1_RATE>;
|
||||
};
|
||||
};
|
14
drivers/clk/kunit_clk_assigned_rates_u64_one.dtso
Normal file
14
drivers/clk/kunit_clk_assigned_rates_u64_one.dtso
Normal file
@ -0,0 +1,14 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "kunit_clk_assigned_rates.h"
|
||||
|
||||
&{/} {
|
||||
clk: kunit-clock {
|
||||
compatible = "test,clk-assigned-rates";
|
||||
#clock-cells = <0>;
|
||||
assigned-clocks = <&clk>;
|
||||
assigned-clock-rates-u64 = /bits/ 64 <ASSIGNED_RATES_0_RATE>;
|
||||
};
|
||||
};
|
18
drivers/clk/kunit_clk_assigned_rates_u64_one_consumer.dtso
Normal file
18
drivers/clk/kunit_clk_assigned_rates_u64_one_consumer.dtso
Normal file
@ -0,0 +1,18 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "kunit_clk_assigned_rates.h"
|
||||
|
||||
&{/} {
|
||||
clk: kunit-clock {
|
||||
compatible = "test,clk-assigned-rates";
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
|
||||
kunit-clock-consumer {
|
||||
compatible = "test,clk-consumer";
|
||||
assigned-clocks = <&clk>;
|
||||
assigned-clock-rates-u64 = /bits/ 64 <ASSIGNED_RATES_0_RATE>;
|
||||
};
|
||||
};
|
13
drivers/clk/kunit_clk_assigned_rates_without.dtso
Normal file
13
drivers/clk/kunit_clk_assigned_rates_without.dtso
Normal file
@ -0,0 +1,13 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "kunit_clk_assigned_rates.h"
|
||||
|
||||
&{/} {
|
||||
clk: kunit-clock {
|
||||
compatible = "test,clk-assigned-rates";
|
||||
#clock-cells = <0>;
|
||||
assigned-clock-rates = <ASSIGNED_RATES_0_RATE>;
|
||||
};
|
||||
};
|
17
drivers/clk/kunit_clk_assigned_rates_without_consumer.dtso
Normal file
17
drivers/clk/kunit_clk_assigned_rates_without_consumer.dtso
Normal file
@ -0,0 +1,17 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "kunit_clk_assigned_rates.h"
|
||||
|
||||
&{/} {
|
||||
clk: kunit-clock {
|
||||
compatible = "test,clk-assigned-rates";
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
|
||||
kunit-clock-consumer {
|
||||
compatible = "test,clk-consumer";
|
||||
assigned-clock-rates = <ASSIGNED_RATES_0_RATE>;
|
||||
};
|
||||
};
|
12
drivers/clk/kunit_clk_assigned_rates_zero.dtso
Normal file
12
drivers/clk/kunit_clk_assigned_rates_zero.dtso
Normal file
@ -0,0 +1,12 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
&{/} {
|
||||
clk: kunit-clock {
|
||||
compatible = "test,clk-assigned-rates";
|
||||
#clock-cells = <0>;
|
||||
assigned-clocks = <&clk>;
|
||||
assigned-clock-rates = <0>;
|
||||
};
|
||||
};
|
16
drivers/clk/kunit_clk_assigned_rates_zero_consumer.dtso
Normal file
16
drivers/clk/kunit_clk_assigned_rates_zero_consumer.dtso
Normal file
@ -0,0 +1,16 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
&{/} {
|
||||
clk: kunit-clock {
|
||||
compatible = "test,clk-assigned-rates";
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
|
||||
kunit-clock-consumer {
|
||||
compatible = "test,clk-consumer";
|
||||
assigned-clocks = <&clk>;
|
||||
assigned-clock-rates = <0>;
|
||||
};
|
||||
};
|
@ -124,6 +124,43 @@ config COMMON_CLK_MT2712_VENCSYS
|
||||
help
|
||||
This driver supports MediaTek MT2712 vencsys clocks.
|
||||
|
||||
config COMMON_CLK_MT6735
|
||||
tristate "Main clock drivers for MediaTek MT6735"
|
||||
depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||
select COMMON_CLK_MEDIATEK
|
||||
help
|
||||
This enables drivers for clocks and resets provided
|
||||
by apmixedsys, topckgen, infracfg and pericfg on the
|
||||
MediaTek MT6735 SoC.
|
||||
|
||||
config COMMON_CLK_MT6735_IMGSYS
|
||||
tristate "Clock driver for MediaTek MT6735 imgsys"
|
||||
depends on COMMON_CLK_MT6735
|
||||
help
|
||||
This enables a driver for clocks provided by imgsys
|
||||
on the MediaTek MT6735 SoC.
|
||||
|
||||
config COMMON_CLK_MT6735_MFGCFG
|
||||
tristate "Clock driver for MediaTek MT6735 mfgcfg"
|
||||
depends on COMMON_CLK_MT6735
|
||||
help
|
||||
This enables a driver for clocks and resets provided
|
||||
by mfgcfg on the MediaTek MT6735 SoC.
|
||||
|
||||
config COMMON_CLK_MT6735_VDECSYS
|
||||
tristate "Clock driver for MediaTek MT6735 vdecsys"
|
||||
depends on COMMON_CLK_MT6735
|
||||
help
|
||||
This enables a driver for clocks and resets provided
|
||||
by vdecsys on the MediaTek MT6735 SoC.
|
||||
|
||||
config COMMON_CLK_MT6735_VENCSYS
|
||||
tristate "Clock driver for MediaTek MT6735 vencsys"
|
||||
depends on COMMON_CLK_MT6735
|
||||
help
|
||||
This enables a driver for clocks provided by vencsys
|
||||
on the MediaTek MT6735 SoC.
|
||||
|
||||
config COMMON_CLK_MT6765
|
||||
bool "Clock driver for MediaTek MT6765"
|
||||
depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
|
||||
@ -887,13 +924,6 @@ config COMMON_CLK_MT8195_APUSYS
|
||||
help
|
||||
This driver supports MediaTek MT8195 AI Processor Unit System clocks.
|
||||
|
||||
config COMMON_CLK_MT8195_AUDSYS
|
||||
tristate "Clock driver for MediaTek MT8195 audsys"
|
||||
depends on COMMON_CLK_MT8195
|
||||
default COMMON_CLK_MT8195
|
||||
help
|
||||
This driver supports MediaTek MT8195 audsys clocks.
|
||||
|
||||
config COMMON_CLK_MT8195_IMP_IIC_WRAP
|
||||
tristate "Clock driver for MediaTek MT8195 imp_iic_wrap"
|
||||
depends on COMMON_CLK_MT8195
|
||||
@ -908,14 +938,6 @@ config COMMON_CLK_MT8195_MFGCFG
|
||||
help
|
||||
This driver supports MediaTek MT8195 mfgcfg clocks.
|
||||
|
||||
config COMMON_CLK_MT8195_MSDC
|
||||
tristate "Clock driver for MediaTek MT8195 msdc"
|
||||
depends on COMMON_CLK_MT8195
|
||||
default COMMON_CLK_MT8195
|
||||
help
|
||||
This driver supports MediaTek MT8195 MMC and SD Controller's
|
||||
msdc and msdc_top clocks.
|
||||
|
||||
config COMMON_CLK_MT8195_SCP_ADSP
|
||||
tristate "Clock driver for MediaTek MT8195 scp_adsp"
|
||||
depends on COMMON_CLK_MT8195
|
||||
|
@ -2,6 +2,11 @@
|
||||
obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o clk-cpumux.o reset.o clk-mux.o
|
||||
obj-$(CONFIG_COMMON_CLK_MEDIATEK_FHCTL) += clk-fhctl.o clk-pllfh.o
|
||||
|
||||
obj-$(CONFIG_COMMON_CLK_MT6735) += clk-mt6735-apmixedsys.o clk-mt6735-infracfg.o clk-mt6735-pericfg.o clk-mt6735-topckgen.o
|
||||
obj-$(CONFIG_COMMON_CLK_MT6735_IMGSYS) += clk-mt6735-imgsys.o
|
||||
obj-$(CONFIG_COMMON_CLK_MT6735_MFGCFG) += clk-mt6735-mfgcfg.o
|
||||
obj-$(CONFIG_COMMON_CLK_MT6735_VDECSYS) += clk-mt6735-vdecsys.o
|
||||
obj-$(CONFIG_COMMON_CLK_MT6735_VENCSYS) += clk-mt6735-vencsys.o
|
||||
obj-$(CONFIG_COMMON_CLK_MT6765) += clk-mt6765.o
|
||||
obj-$(CONFIG_COMMON_CLK_MT6765_AUDIOSYS) += clk-mt6765-audio.o
|
||||
obj-$(CONFIG_COMMON_CLK_MT6765_CAMSYS) += clk-mt6765-cam.o
|
||||
|
137
drivers/clk/mediatek/clk-mt6735-apmixedsys.c
Normal file
137
drivers/clk/mediatek/clk-mt6735-apmixedsys.c
Normal file
@ -0,0 +1,137 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2022 Yassine Oudjana <y.oudjana@protonmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "clk-mtk.h"
|
||||
#include "clk-pll.h"
|
||||
|
||||
#include <dt-bindings/clock/mediatek,mt6735-apmixedsys.h>
|
||||
|
||||
#define AP_PLL_CON_5 0x014
|
||||
#define ARMPLL_CON0 0x200
|
||||
#define ARMPLL_CON1 0x204
|
||||
#define ARMPLL_PWR_CON0 0x20c
|
||||
#define MAINPLL_CON0 0x210
|
||||
#define MAINPLL_CON1 0x214
|
||||
#define MAINPLL_PWR_CON0 0x21c
|
||||
#define UNIVPLL_CON0 0x220
|
||||
#define UNIVPLL_CON1 0x224
|
||||
#define UNIVPLL_PWR_CON0 0x22c
|
||||
#define MMPLL_CON0 0x230
|
||||
#define MMPLL_CON1 0x234
|
||||
#define MMPLL_PWR_CON0 0x23c
|
||||
#define MSDCPLL_CON0 0x240
|
||||
#define MSDCPLL_CON1 0x244
|
||||
#define MSDCPLL_PWR_CON0 0x24c
|
||||
#define VENCPLL_CON0 0x250
|
||||
#define VENCPLL_CON1 0x254
|
||||
#define VENCPLL_PWR_CON0 0x25c
|
||||
#define TVDPLL_CON0 0x260
|
||||
#define TVDPLL_CON1 0x264
|
||||
#define TVDPLL_PWR_CON0 0x26c
|
||||
#define APLL1_CON0 0x270
|
||||
#define APLL1_CON1 0x274
|
||||
#define APLL1_CON2 0x278
|
||||
#define APLL1_PWR_CON0 0x280
|
||||
#define APLL2_CON0 0x284
|
||||
#define APLL2_CON1 0x288
|
||||
#define APLL2_CON2 0x28c
|
||||
#define APLL2_PWR_CON0 0x294
|
||||
|
||||
#define CON0_RST_BAR BIT(24)
|
||||
|
||||
#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _rst_bar_mask, \
|
||||
_pd_reg, _pd_shift, _tuner_reg, _tuner_en_reg, \
|
||||
_tuner_en_bit, _pcw_reg, _pcwbits, _flags) { \
|
||||
.id = _id, \
|
||||
.name = _name, \
|
||||
.parent_name = "clk26m", \
|
||||
.reg = _reg, \
|
||||
.pwr_reg = _pwr_reg, \
|
||||
.en_mask = _en_mask, \
|
||||
.rst_bar_mask = _rst_bar_mask, \
|
||||
.pd_reg = _pd_reg, \
|
||||
.pd_shift = _pd_shift, \
|
||||
.tuner_reg = _tuner_reg, \
|
||||
.tuner_en_reg = _tuner_en_reg, \
|
||||
.tuner_en_bit = _tuner_en_bit, \
|
||||
.pcw_reg = _pcw_reg, \
|
||||
.pcw_chg_reg = _pcw_reg, \
|
||||
.pcwbits = _pcwbits, \
|
||||
.flags = _flags, \
|
||||
}
|
||||
|
||||
static const struct mtk_pll_data apmixedsys_plls[] = {
|
||||
PLL(CLK_APMIXED_ARMPLL, "armpll", ARMPLL_CON0, ARMPLL_PWR_CON0, 0x00000001, 0, ARMPLL_CON1, 24, 0, 0, 0, ARMPLL_CON1, 21, PLL_AO),
|
||||
PLL(CLK_APMIXED_MAINPLL, "mainpll", MAINPLL_CON0, MAINPLL_PWR_CON0, 0xf0000101, CON0_RST_BAR, MAINPLL_CON1, 24, 0, 0, 0, MAINPLL_CON1, 21, HAVE_RST_BAR),
|
||||
PLL(CLK_APMIXED_UNIVPLL, "univpll", UNIVPLL_CON0, UNIVPLL_PWR_CON0, 0xfc000001, CON0_RST_BAR, UNIVPLL_CON1, 24, 0, 0, 0, UNIVPLL_CON1, 21, HAVE_RST_BAR),
|
||||
PLL(CLK_APMIXED_MMPLL, "mmpll", MMPLL_CON0, MMPLL_PWR_CON0, 0x00000001, 0, MMPLL_CON1, 24, 0, 0, 0, MMPLL_CON1, 21, 0),
|
||||
PLL(CLK_APMIXED_MSDCPLL, "msdcpll", MSDCPLL_CON0, MSDCPLL_PWR_CON0, 0x00000001, 0, MSDCPLL_CON1, 24, 0, 0, 0, MSDCPLL_CON1, 21, 0),
|
||||
PLL(CLK_APMIXED_VENCPLL, "vencpll", VENCPLL_CON0, VENCPLL_PWR_CON0, 0x00000001, CON0_RST_BAR, VENCPLL_CON1, 24, 0, 0, 0, VENCPLL_CON1, 21, HAVE_RST_BAR),
|
||||
PLL(CLK_APMIXED_TVDPLL, "tvdpll", TVDPLL_CON0, TVDPLL_PWR_CON0, 0x00000001, 0, TVDPLL_CON1, 24, 0, 0, 0, TVDPLL_CON1, 21, 0),
|
||||
PLL(CLK_APMIXED_APLL1, "apll1", APLL1_CON0, APLL1_PWR_CON0, 0x00000001, 0, APLL1_CON0, 4, APLL1_CON2, AP_PLL_CON_5, 0, APLL1_CON1, 31, 0),
|
||||
PLL(CLK_APMIXED_APLL2, "apll2", APLL2_CON0, APLL2_PWR_CON0, 0x00000001, 0, APLL2_CON0, 4, APLL2_CON2, AP_PLL_CON_5, 1, APLL2_CON1, 31, 0)
|
||||
};
|
||||
|
||||
static int clk_mt6735_apmixed_probe(struct platform_device *pdev)
|
||||
{
|
||||
void __iomem *base;
|
||||
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
struct clk_hw_onecell_data *clk_data;
|
||||
int ret;
|
||||
|
||||
base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
clk_data = mtk_devm_alloc_clk_data(&pdev->dev, ARRAY_SIZE(apmixedsys_plls));
|
||||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
platform_set_drvdata(pdev, clk_data);
|
||||
|
||||
ret = mtk_clk_register_plls(pdev->dev.of_node, apmixedsys_plls,
|
||||
ARRAY_SIZE(apmixedsys_plls), clk_data);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to register PLLs: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_onecell_get,
|
||||
clk_data);
|
||||
if (ret)
|
||||
dev_err(&pdev->dev,
|
||||
"Failed to register clock provider: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void clk_mt6735_apmixed_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct clk_hw_onecell_data *clk_data = platform_get_drvdata(pdev);
|
||||
|
||||
mtk_clk_unregister_plls(apmixedsys_plls, ARRAY_SIZE(apmixedsys_plls), clk_data);
|
||||
}
|
||||
|
||||
static const struct of_device_id of_match_mt6735_apmixedsys[] = {
|
||||
{ .compatible = "mediatek,mt6735-apmixedsys" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, of_match_mt6735_apmixedsys);
|
||||
|
||||
static struct platform_driver clk_mt6735_apmixedsys = {
|
||||
.probe = clk_mt6735_apmixed_probe,
|
||||
.remove = clk_mt6735_apmixed_remove,
|
||||
.driver = {
|
||||
.name = "clk-mt6735-apmixedsys",
|
||||
.of_match_table = of_match_mt6735_apmixedsys,
|
||||
},
|
||||
};
|
||||
module_platform_driver(clk_mt6735_apmixedsys);
|
||||
|
||||
MODULE_AUTHOR("Yassine Oudjana <y.oudjana@protonmail.com>");
|
||||
MODULE_DESCRIPTION("MediaTek MT6735 apmixedsys clock driver");
|
||||
MODULE_LICENSE("GPL");
|
57
drivers/clk/mediatek/clk-mt6735-imgsys.c
Normal file
57
drivers/clk/mediatek/clk-mt6735-imgsys.c
Normal file
@ -0,0 +1,57 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2022 Yassine Oudjana <y.oudjana@protonmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "clk-gate.h"
|
||||
#include "clk-mtk.h"
|
||||
|
||||
#include <dt-bindings/clock/mediatek,mt6735-imgsys.h>
|
||||
|
||||
#define IMG_CG_CON 0x00
|
||||
#define IMG_CG_SET 0x04
|
||||
#define IMG_CG_CLR 0x08
|
||||
|
||||
static struct mtk_gate_regs imgsys_cg_regs = {
|
||||
.set_ofs = IMG_CG_SET,
|
||||
.clr_ofs = IMG_CG_CLR,
|
||||
.sta_ofs = IMG_CG_CON,
|
||||
};
|
||||
|
||||
static const struct mtk_gate imgsys_gates[] = {
|
||||
GATE_MTK(CLK_IMG_SMI_LARB2, "smi_larb2", "mm_sel", &imgsys_cg_regs, 0, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_IMG_CAM_SMI, "cam_smi", "mm_sel", &imgsys_cg_regs, 5, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_IMG_CAM_CAM, "cam_cam", "mm_sel", &imgsys_cg_regs, 6, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_IMG_SEN_TG, "sen_tg", "mm_sel", &imgsys_cg_regs, 7, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_IMG_SEN_CAM, "sen_cam", "mm_sel", &imgsys_cg_regs, 8, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_IMG_CAM_SV, "cam_sv", "mm_sel", &imgsys_cg_regs, 9, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_IMG_SUFOD, "sufod", "mm_sel", &imgsys_cg_regs, 10, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_IMG_FD, "fd", "mm_sel", &imgsys_cg_regs, 11, &mtk_clk_gate_ops_setclr),
|
||||
};
|
||||
|
||||
static const struct mtk_clk_desc imgsys_clks = {
|
||||
.clks = imgsys_gates,
|
||||
.num_clks = ARRAY_SIZE(imgsys_gates),
|
||||
};
|
||||
|
||||
static const struct of_device_id of_match_mt6735_imgsys[] = {
|
||||
{ .compatible = "mediatek,mt6735-imgsys", .data = &imgsys_clks },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct platform_driver clk_mt6735_imgsys = {
|
||||
.probe = mtk_clk_simple_probe,
|
||||
.remove = mtk_clk_simple_remove,
|
||||
.driver = {
|
||||
.name = "clk-mt6735-imgsys",
|
||||
.of_match_table = of_match_mt6735_imgsys,
|
||||
},
|
||||
};
|
||||
module_platform_driver(clk_mt6735_imgsys);
|
||||
|
||||
MODULE_AUTHOR("Yassine Oudjana <y.oudjana@protonmail.com>");
|
||||
MODULE_DESCRIPTION("MediaTek MT6735 imgsys clock driver");
|
||||
MODULE_LICENSE("GPL");
|
107
drivers/clk/mediatek/clk-mt6735-infracfg.c
Normal file
107
drivers/clk/mediatek/clk-mt6735-infracfg.c
Normal file
@ -0,0 +1,107 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2022 Yassine Oudjana <y.oudjana@protonmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "clk-gate.h"
|
||||
#include "clk-mtk.h"
|
||||
|
||||
#include <dt-bindings/clock/mediatek,mt6735-infracfg.h>
|
||||
#include <dt-bindings/reset/mediatek,mt6735-infracfg.h>
|
||||
|
||||
#define INFRA_RST0 0x30
|
||||
#define INFRA_GLOBALCON_PDN0 0x40
|
||||
#define INFRA_PDN1 0x44
|
||||
#define INFRA_PDN_STA 0x48
|
||||
|
||||
#define RST_NR_PER_BANK 32
|
||||
|
||||
static struct mtk_gate_regs infra_cg_regs = {
|
||||
.set_ofs = INFRA_GLOBALCON_PDN0,
|
||||
.clr_ofs = INFRA_PDN1,
|
||||
.sta_ofs = INFRA_PDN_STA,
|
||||
};
|
||||
|
||||
static const struct mtk_gate infracfg_gates[] = {
|
||||
GATE_MTK(CLK_INFRA_DBG, "dbg", "axi_sel", &infra_cg_regs, 0, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_INFRA_GCE, "gce", "axi_sel", &infra_cg_regs, 1, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_INFRA_TRBG, "trbg", "axi_sel", &infra_cg_regs, 2, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_INFRA_CPUM, "cpum", "axi_sel", &infra_cg_regs, 3, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_INFRA_DEVAPC, "devapc", "axi_sel", &infra_cg_regs, 4, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_INFRA_AUDIO, "audio", "aud_intbus_sel", &infra_cg_regs, 5, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_INFRA_GCPU, "gcpu", "axi_sel", &infra_cg_regs, 6, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_INFRA_L2C_SRAM, "l2csram", "axi_sel", &infra_cg_regs, 7, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_INFRA_M4U, "m4u", "axi_sel", &infra_cg_regs, 8, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_INFRA_CLDMA, "cldma", "axi_sel", &infra_cg_regs, 12, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_INFRA_CONNMCU_BUS, "connmcu_bus", "axi_sel", &infra_cg_regs, 15, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_INFRA_KP, "kp", "axi_sel", &infra_cg_regs, 16, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK_FLAGS(CLK_INFRA_APXGPT, "apxgpt", "axi_sel", &infra_cg_regs, 18, &mtk_clk_gate_ops_setclr, CLK_IS_CRITICAL),
|
||||
GATE_MTK(CLK_INFRA_SEJ, "sej", "axi_sel", &infra_cg_regs, 19, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_INFRA_CCIF0_AP, "ccif0ap", "axi_sel", &infra_cg_regs, 20, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_INFRA_CCIF1_AP, "ccif1ap", "axi_sel", &infra_cg_regs, 21, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_INFRA_PMIC_SPI, "pmicspi", "pmicspi_sel", &infra_cg_regs, 22, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_INFRA_PMIC_WRAP, "pmicwrap", "axi_sel", &infra_cg_regs, 23, &mtk_clk_gate_ops_setclr)
|
||||
};
|
||||
|
||||
static u16 infracfg_rst_bank_ofs[] = { INFRA_RST0 };
|
||||
|
||||
static u16 infracfg_rst_idx_map[] = {
|
||||
[MT6735_INFRA_RST0_EMI_REG] = 0 * RST_NR_PER_BANK + 0,
|
||||
[MT6735_INFRA_RST0_DRAMC0_AO] = 0 * RST_NR_PER_BANK + 1,
|
||||
[MT6735_INFRA_RST0_AP_CIRQ_EINT] = 0 * RST_NR_PER_BANK + 3,
|
||||
[MT6735_INFRA_RST0_APXGPT] = 0 * RST_NR_PER_BANK + 4,
|
||||
[MT6735_INFRA_RST0_SCPSYS] = 0 * RST_NR_PER_BANK + 5,
|
||||
[MT6735_INFRA_RST0_KP] = 0 * RST_NR_PER_BANK + 6,
|
||||
[MT6735_INFRA_RST0_PMIC_WRAP] = 0 * RST_NR_PER_BANK + 7,
|
||||
[MT6735_INFRA_RST0_CLDMA_AO_TOP] = 0 * RST_NR_PER_BANK + 8,
|
||||
[MT6735_INFRA_RST0_USBSIF_TOP] = 0 * RST_NR_PER_BANK + 9,
|
||||
[MT6735_INFRA_RST0_EMI] = 0 * RST_NR_PER_BANK + 16,
|
||||
[MT6735_INFRA_RST0_CCIF] = 0 * RST_NR_PER_BANK + 17,
|
||||
[MT6735_INFRA_RST0_DRAMC0] = 0 * RST_NR_PER_BANK + 18,
|
||||
[MT6735_INFRA_RST0_EMI_AO_REG] = 0 * RST_NR_PER_BANK + 19,
|
||||
[MT6735_INFRA_RST0_CCIF_AO] = 0 * RST_NR_PER_BANK + 20,
|
||||
[MT6735_INFRA_RST0_TRNG] = 0 * RST_NR_PER_BANK + 21,
|
||||
[MT6735_INFRA_RST0_SYS_CIRQ] = 0 * RST_NR_PER_BANK + 22,
|
||||
[MT6735_INFRA_RST0_GCE] = 0 * RST_NR_PER_BANK + 23,
|
||||
[MT6735_INFRA_RST0_M4U] = 0 * RST_NR_PER_BANK + 24,
|
||||
[MT6735_INFRA_RST0_CCIF1] = 0 * RST_NR_PER_BANK + 25,
|
||||
[MT6735_INFRA_RST0_CLDMA_TOP_PD] = 0 * RST_NR_PER_BANK + 26
|
||||
};
|
||||
|
||||
static const struct mtk_clk_rst_desc infracfg_resets = {
|
||||
.version = MTK_RST_SIMPLE,
|
||||
.rst_bank_ofs = infracfg_rst_bank_ofs,
|
||||
.rst_bank_nr = ARRAY_SIZE(infracfg_rst_bank_ofs),
|
||||
.rst_idx_map = infracfg_rst_idx_map,
|
||||
.rst_idx_map_nr = ARRAY_SIZE(infracfg_rst_idx_map)
|
||||
};
|
||||
|
||||
static const struct mtk_clk_desc infracfg_clks = {
|
||||
.clks = infracfg_gates,
|
||||
.num_clks = ARRAY_SIZE(infracfg_gates),
|
||||
|
||||
.rst_desc = &infracfg_resets
|
||||
};
|
||||
|
||||
static const struct of_device_id of_match_mt6735_infracfg[] = {
|
||||
{ .compatible = "mediatek,mt6735-infracfg", .data = &infracfg_clks },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, of_match_mt6735_infracfg);
|
||||
|
||||
static struct platform_driver clk_mt6735_infracfg = {
|
||||
.probe = mtk_clk_simple_probe,
|
||||
.remove = mtk_clk_simple_remove,
|
||||
.driver = {
|
||||
.name = "clk-mt6735-infracfg",
|
||||
.of_match_table = of_match_mt6735_infracfg,
|
||||
},
|
||||
};
|
||||
module_platform_driver(clk_mt6735_infracfg);
|
||||
|
||||
MODULE_AUTHOR("Yassine Oudjana <y.oudjana@protonmail.com>");
|
||||
MODULE_DESCRIPTION("MediaTek MT6735 infracfg clock and reset driver");
|
||||
MODULE_LICENSE("GPL");
|
61
drivers/clk/mediatek/clk-mt6735-mfgcfg.c
Normal file
61
drivers/clk/mediatek/clk-mt6735-mfgcfg.c
Normal file
@ -0,0 +1,61 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2022 Yassine Oudjana <y.oudjana@protonmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "clk-gate.h"
|
||||
#include "clk-mtk.h"
|
||||
|
||||
#include <dt-bindings/clock/mediatek,mt6735-mfgcfg.h>
|
||||
|
||||
#define MFG_CG_CON 0x00
|
||||
#define MFG_CG_SET 0x04
|
||||
#define MFG_CG_CLR 0x08
|
||||
#define MFG_RESET 0x0c
|
||||
|
||||
static struct mtk_gate_regs mfgcfg_cg_regs = {
|
||||
.set_ofs = MFG_CG_SET,
|
||||
.clr_ofs = MFG_CG_CLR,
|
||||
.sta_ofs = MFG_CG_CON,
|
||||
};
|
||||
|
||||
static const struct mtk_gate mfgcfg_gates[] = {
|
||||
GATE_MTK(CLK_MFG_BG3D, "bg3d", "mfg_sel", &mfgcfg_cg_regs, 0, &mtk_clk_gate_ops_setclr),
|
||||
};
|
||||
|
||||
static u16 mfgcfg_rst_ofs[] = { MFG_RESET };
|
||||
|
||||
static const struct mtk_clk_rst_desc mfgcfg_resets = {
|
||||
.version = MTK_RST_SIMPLE,
|
||||
.rst_bank_ofs = mfgcfg_rst_ofs,
|
||||
.rst_bank_nr = ARRAY_SIZE(mfgcfg_rst_ofs)
|
||||
};
|
||||
|
||||
static const struct mtk_clk_desc mfgcfg_clks = {
|
||||
.clks = mfgcfg_gates,
|
||||
.num_clks = ARRAY_SIZE(mfgcfg_gates),
|
||||
|
||||
.rst_desc = &mfgcfg_resets
|
||||
};
|
||||
|
||||
static const struct of_device_id of_match_mt6735_mfgcfg[] = {
|
||||
{ .compatible = "mediatek,mt6735-mfgcfg", .data = &mfgcfg_clks },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct platform_driver clk_mt6735_mfgcfg = {
|
||||
.probe = mtk_clk_simple_probe,
|
||||
.remove = mtk_clk_simple_remove,
|
||||
.driver = {
|
||||
.name = "clk-mt6735-mfgcfg",
|
||||
.of_match_table = of_match_mt6735_mfgcfg,
|
||||
},
|
||||
};
|
||||
module_platform_driver(clk_mt6735_mfgcfg);
|
||||
|
||||
MODULE_AUTHOR("Yassine Oudjana <y.oudjana@protonmail.com>");
|
||||
MODULE_DESCRIPTION("Mediatek MT6735 mfgcfg clock and reset driver");
|
||||
MODULE_LICENSE("GPL");
|
124
drivers/clk/mediatek/clk-mt6735-pericfg.c
Normal file
124
drivers/clk/mediatek/clk-mt6735-pericfg.c
Normal file
@ -0,0 +1,124 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2022 Yassine Oudjana <y.oudjana@protonmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "clk-gate.h"
|
||||
#include "clk-mtk.h"
|
||||
|
||||
#include <dt-bindings/clock/mediatek,mt6735-pericfg.h>
|
||||
#include <dt-bindings/reset/mediatek,mt6735-pericfg.h>
|
||||
|
||||
#define PERI_GLOBALCON_RST0 0x00
|
||||
#define PERI_GLOBALCON_RST1 0x04
|
||||
#define PERI_GLOBALCON_PDN0_SET 0x08
|
||||
#define PERI_GLOBALCON_PDN0_CLR 0x10
|
||||
#define PERI_GLOBALCON_PDN0_STA 0x18
|
||||
|
||||
#define RST_NR_PER_BANK 32
|
||||
|
||||
static struct mtk_gate_regs peri_cg_regs = {
|
||||
.set_ofs = PERI_GLOBALCON_PDN0_SET,
|
||||
.clr_ofs = PERI_GLOBALCON_PDN0_CLR,
|
||||
.sta_ofs = PERI_GLOBALCON_PDN0_STA,
|
||||
};
|
||||
|
||||
static const struct mtk_gate pericfg_gates[] = {
|
||||
GATE_MTK(CLK_PERI_DISP_PWM, "disp_pwm", "disppwm_sel", &peri_cg_regs, 0, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_THERM, "therm", "axi_sel", &peri_cg_regs, 1, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_PWM1, "pwm1", "axi_sel", &peri_cg_regs, 2, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_PWM2, "pwm2", "axi_sel", &peri_cg_regs, 3, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_PWM3, "pwm3", "axi_sel", &peri_cg_regs, 4, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_PWM4, "pwm4", "axi_sel", &peri_cg_regs, 5, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_PWM5, "pwm5", "axi_sel", &peri_cg_regs, 6, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_PWM6, "pwm6", "axi_sel", &peri_cg_regs, 7, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_PWM7, "pwm7", "axi_sel", &peri_cg_regs, 8, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_PWM, "pwm", "axi_sel", &peri_cg_regs, 9, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_USB0, "usb0", "usb20_sel", &peri_cg_regs, 10, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_IRDA, "irda", "irda_sel", &peri_cg_regs, 11, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_APDMA, "apdma", "axi_sel", &peri_cg_regs, 12, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_MSDC30_0, "msdc30_0", "msdc30_0_sel", &peri_cg_regs, 13, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_MSDC30_1, "msdc30_1", "msdc30_1_sel", &peri_cg_regs, 14, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_MSDC30_2, "msdc30_2", "msdc30_2_sel", &peri_cg_regs, 15, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_MSDC30_3, "msdc30_3", "msdc30_3_sel", &peri_cg_regs, 16, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_UART0, "uart0", "uart_sel", &peri_cg_regs, 17, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_UART1, "uart1", "uart_sel", &peri_cg_regs, 18, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_UART2, "uart2", "uart_sel", &peri_cg_regs, 19, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_UART3, "uart3", "uart_sel", &peri_cg_regs, 20, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_UART4, "uart4", "uart_sel", &peri_cg_regs, 21, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_BTIF, "btif", "axi_sel", &peri_cg_regs, 22, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_I2C0, "i2c0", "axi_sel", &peri_cg_regs, 23, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_I2C1, "i2c1", "axi_sel", &peri_cg_regs, 24, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_I2C2, "i2c2", "axi_sel", &peri_cg_regs, 25, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_I2C3, "i2c3", "axi_sel", &peri_cg_regs, 26, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_AUXADC, "auxadc", "axi_sel", &peri_cg_regs, 27, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_SPI0, "spi0", "spi_sel", &peri_cg_regs, 28, &mtk_clk_gate_ops_setclr),
|
||||
GATE_MTK(CLK_PERI_IRTX, "irtx", "irtx_sel", &peri_cg_regs, 29, &mtk_clk_gate_ops_setclr)
|
||||
};
|
||||
|
||||
static u16 pericfg_rst_bank_ofs[] = { PERI_GLOBALCON_RST0, PERI_GLOBALCON_RST1 };
|
||||
|
||||
static u16 pericfg_rst_idx_map[] = {
|
||||
[MT6735_PERI_RST0_UART0] = 0 * RST_NR_PER_BANK + 0,
|
||||
[MT6735_PERI_RST0_UART1] = 0 * RST_NR_PER_BANK + 1,
|
||||
[MT6735_PERI_RST0_UART2] = 0 * RST_NR_PER_BANK + 2,
|
||||
[MT6735_PERI_RST0_UART3] = 0 * RST_NR_PER_BANK + 3,
|
||||
[MT6735_PERI_RST0_UART4] = 0 * RST_NR_PER_BANK + 4,
|
||||
[MT6735_PERI_RST0_BTIF] = 0 * RST_NR_PER_BANK + 6,
|
||||
[MT6735_PERI_RST0_DISP_PWM_PERI] = 0 * RST_NR_PER_BANK + 7,
|
||||
[MT6735_PERI_RST0_PWM] = 0 * RST_NR_PER_BANK + 8,
|
||||
[MT6735_PERI_RST0_AUXADC] = 0 * RST_NR_PER_BANK + 10,
|
||||
[MT6735_PERI_RST0_DMA] = 0 * RST_NR_PER_BANK + 11,
|
||||
[MT6735_PERI_RST0_IRDA] = 0 * RST_NR_PER_BANK + 12,
|
||||
[MT6735_PERI_RST0_IRTX] = 0 * RST_NR_PER_BANK + 13,
|
||||
[MT6735_PERI_RST0_THERM] = 0 * RST_NR_PER_BANK + 16,
|
||||
[MT6735_PERI_RST0_MSDC2] = 0 * RST_NR_PER_BANK + 17,
|
||||
[MT6735_PERI_RST0_MSDC3] = 0 * RST_NR_PER_BANK + 18,
|
||||
[MT6735_PERI_RST0_MSDC0] = 0 * RST_NR_PER_BANK + 19,
|
||||
[MT6735_PERI_RST0_MSDC1] = 0 * RST_NR_PER_BANK + 20,
|
||||
[MT6735_PERI_RST0_I2C0] = 0 * RST_NR_PER_BANK + 22,
|
||||
[MT6735_PERI_RST0_I2C1] = 0 * RST_NR_PER_BANK + 23,
|
||||
[MT6735_PERI_RST0_I2C2] = 0 * RST_NR_PER_BANK + 24,
|
||||
[MT6735_PERI_RST0_I2C3] = 0 * RST_NR_PER_BANK + 25,
|
||||
[MT6735_PERI_RST0_USB] = 0 * RST_NR_PER_BANK + 28,
|
||||
|
||||
[MT6735_PERI_RST1_SPI0] = 1 * RST_NR_PER_BANK + 1,
|
||||
};
|
||||
|
||||
static const struct mtk_clk_rst_desc pericfg_resets = {
|
||||
.version = MTK_RST_SIMPLE,
|
||||
.rst_bank_ofs = pericfg_rst_bank_ofs,
|
||||
.rst_bank_nr = ARRAY_SIZE(pericfg_rst_bank_ofs),
|
||||
.rst_idx_map = pericfg_rst_idx_map,
|
||||
.rst_idx_map_nr = ARRAY_SIZE(pericfg_rst_idx_map)
|
||||
};
|
||||
|
||||
static const struct mtk_clk_desc pericfg_clks = {
|
||||
.clks = pericfg_gates,
|
||||
.num_clks = ARRAY_SIZE(pericfg_gates),
|
||||
|
||||
.rst_desc = &pericfg_resets
|
||||
};
|
||||
|
||||
static const struct of_device_id of_match_mt6735_pericfg[] = {
|
||||
{ .compatible = "mediatek,mt6735-pericfg", .data = &pericfg_clks },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, of_match_mt6735_pericfg);
|
||||
|
||||
static struct platform_driver clk_mt6735_pericfg = {
|
||||
.probe = mtk_clk_simple_probe,
|
||||
.remove = mtk_clk_simple_remove,
|
||||
.driver = {
|
||||
.name = "clk-mt6735-pericfg",
|
||||
.of_match_table = of_match_mt6735_pericfg,
|
||||
},
|
||||
};
|
||||
module_platform_driver(clk_mt6735_pericfg);
|
||||
|
||||
MODULE_AUTHOR("Yassine Oudjana <y.oudjana@protonmail.com>");
|
||||
MODULE_DESCRIPTION("MediaTek MT6735 pericfg clock driver");
|
||||
MODULE_LICENSE("GPL");
|
394
drivers/clk/mediatek/clk-mt6735-topckgen.c
Normal file
394
drivers/clk/mediatek/clk-mt6735-topckgen.c
Normal file
@ -0,0 +1,394 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2022 Yassine Oudjana <y.oudjana@protonmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "clk-mtk.h"
|
||||
#include "clk-mux.h"
|
||||
|
||||
#include <dt-bindings/clock/mediatek,mt6735-topckgen.h>
|
||||
|
||||
#define CLK_CFG_0 0x40
|
||||
#define CLK_CFG_0_SET 0x44
|
||||
#define CLK_CFG_0_CLR 0x48
|
||||
#define CLK_CFG_1 0x50
|
||||
#define CLK_CFG_1_SET 0x54
|
||||
#define CLK_CFG_1_CLR 0x58
|
||||
#define CLK_CFG_2 0x60
|
||||
#define CLK_CFG_2_SET 0x64
|
||||
#define CLK_CFG_2_CLR 0x68
|
||||
#define CLK_CFG_3 0x70
|
||||
#define CLK_CFG_3_SET 0x74
|
||||
#define CLK_CFG_3_CLR 0x78
|
||||
#define CLK_CFG_4 0x80
|
||||
#define CLK_CFG_4_SET 0x84
|
||||
#define CLK_CFG_4_CLR 0x88
|
||||
#define CLK_CFG_5 0x90
|
||||
#define CLK_CFG_5_SET 0x94
|
||||
#define CLK_CFG_5_CLR 0x98
|
||||
#define CLK_CFG_6 0xa0
|
||||
#define CLK_CFG_6_SET 0xa4
|
||||
#define CLK_CFG_6_CLR 0xa8
|
||||
#define CLK_CFG_7 0xb0
|
||||
#define CLK_CFG_7_SET 0xb4
|
||||
#define CLK_CFG_7_CLR 0xb8
|
||||
|
||||
static DEFINE_SPINLOCK(mt6735_topckgen_lock);
|
||||
|
||||
/* Some clocks with unknown details are modeled as fixed clocks */
|
||||
static const struct mtk_fixed_clk topckgen_fixed_clks[] = {
|
||||
/*
|
||||
* This clock is available as a parent option for multiple
|
||||
* muxes and seems like an alternative name for clk26m at first,
|
||||
* but it appears alongside it in several muxes which should
|
||||
* mean it is a separate clock.
|
||||
*/
|
||||
FIXED_CLK(CLK_TOP_AD_SYS_26M_CK, "ad_sys_26m_ck", "clk26m", 26 * MHZ),
|
||||
/*
|
||||
* This clock is the parent of DMPLL divisors. It might be MEMPLL
|
||||
* or its parent, as DMPLL appears to be an alternative name for
|
||||
* MEMPLL.
|
||||
*/
|
||||
FIXED_CLK(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", NULL, 0),
|
||||
/*
|
||||
* DMPLL clock (dmpll_ck), controlled by DDRPHY.
|
||||
*/
|
||||
FIXED_CLK(CLK_TOP_DMPLL, "dmpll", "clkph_mck_o", 0),
|
||||
/*
|
||||
* MIPI DPI clock. Parent option for dpi0_sel. Unknown parent.
|
||||
*/
|
||||
FIXED_CLK(CLK_TOP_DPI_CK, "dpi_ck", NULL, 0),
|
||||
/*
|
||||
* This clock is a child of WHPLL which is controlled by
|
||||
* the modem.
|
||||
*/
|
||||
FIXED_CLK(CLK_TOP_WHPLL_AUDIO_CK, "whpll_audio_ck", NULL, 0)
|
||||
};
|
||||
|
||||
static const struct mtk_fixed_factor topckgen_factors[] = {
|
||||
FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "mainpll", 1, 2),
|
||||
FACTOR(CLK_TOP_SYSPLL_D3, "syspll_d3", "mainpll", 1, 3),
|
||||
FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "mainpll", 1, 5),
|
||||
FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "mainpll", 1, 2),
|
||||
FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4", "mainpll", 1, 4),
|
||||
FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8", "mainpll", 1, 8),
|
||||
FACTOR(CLK_TOP_SYSPLL1_D16, "syspll1_d16", "mainpll", 1, 16),
|
||||
FACTOR(CLK_TOP_SYSPLL2_D2, "syspll2_d2", "mainpll", 1, 2),
|
||||
FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4", "mainpll", 1, 4),
|
||||
FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2", "mainpll", 1, 2),
|
||||
FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4", "mainpll", 1, 4),
|
||||
FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2", "mainpll", 1, 2),
|
||||
FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4", "mainpll", 1, 4),
|
||||
FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll", 1, 2),
|
||||
FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll", 1, 3),
|
||||
FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5),
|
||||
FACTOR(CLK_TOP_UNIVPLL_D26, "univpll_d26", "univpll", 1, 26),
|
||||
FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll", 1, 2),
|
||||
FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll", 1, 4),
|
||||
FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll", 1, 8),
|
||||
FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll", 1, 2),
|
||||
FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll", 1, 4),
|
||||
FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll", 1, 8),
|
||||
FACTOR(CLK_TOP_UNIVPLL3_D2, "univpll3_d2", "univpll", 1, 2),
|
||||
FACTOR(CLK_TOP_UNIVPLL3_D4, "univpll3_d4", "univpll", 1, 4),
|
||||
FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll", 1, 2),
|
||||
FACTOR(CLK_TOP_MSDCPLL_D4, "msdcpll_d4", "msdcpll", 1, 4),
|
||||
FACTOR(CLK_TOP_MSDCPLL_D8, "msdcpll_d8", "msdcpll", 1, 8),
|
||||
FACTOR(CLK_TOP_MSDCPLL_D16, "msdcpll_d16", "msdcpll", 1, 16),
|
||||
FACTOR(CLK_TOP_VENCPLL_D3, "vencpll_d3", "vencpll", 1, 3),
|
||||
FACTOR(CLK_TOP_TVDPLL_D2, "tvdpll_d2", "tvdpll", 1, 2),
|
||||
FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll", 1, 4),
|
||||
FACTOR(CLK_TOP_DMPLL_D2, "dmpll_d2", "clkph_mck_o", 1, 2),
|
||||
FACTOR(CLK_TOP_DMPLL_D4, "dmpll_d4", "clkph_mck_o", 1, 4),
|
||||
FACTOR(CLK_TOP_DMPLL_D8, "dmpll_d8", "clkph_mck_o", 1, 8),
|
||||
FACTOR(CLK_TOP_AD_SYS_26M_D2, "ad_sys_26m_d2", "clk26m", 1, 2)
|
||||
};
|
||||
|
||||
static const char * const axi_sel_parents[] = {
|
||||
"clk26m",
|
||||
"syspll1_d2",
|
||||
"syspll_d5",
|
||||
"syspll1_d4",
|
||||
"univpll_d5",
|
||||
"univpll2_d2",
|
||||
"dmpll",
|
||||
"dmpll_d2"
|
||||
};
|
||||
|
||||
static const char * const mem_sel_parents[] = {
|
||||
"clk26m",
|
||||
"dmpll"
|
||||
};
|
||||
|
||||
static const char * const ddrphycfg_parents[] = {
|
||||
"clk26m",
|
||||
"syspll1_d8"
|
||||
};
|
||||
|
||||
static const char * const mm_sel_parents[] = {
|
||||
"clk26m",
|
||||
"vencpll",
|
||||
"syspll1_d2",
|
||||
"syspll_d5",
|
||||
"syspll1_d4",
|
||||
"univpll_d5",
|
||||
"univpll2_d2",
|
||||
"dmpll"
|
||||
};
|
||||
|
||||
static const char * const pwm_sel_parents[] = {
|
||||
"clk26m",
|
||||
"univpll2_d4",
|
||||
"univpll3_d2",
|
||||
"univpll1_d4"
|
||||
};
|
||||
|
||||
static const char * const vdec_sel_parents[] = {
|
||||
"clk26m",
|
||||
"syspll1_d2",
|
||||
"syspll_d5",
|
||||
"syspll1_d4",
|
||||
"univpll_d5",
|
||||
"syspll_d2",
|
||||
"syspll2_d2",
|
||||
"msdcpll_d2"
|
||||
};
|
||||
|
||||
static const char * const mfg_sel_parents[] = {
|
||||
"clk26m",
|
||||
"mmpll",
|
||||
"clk26m",
|
||||
"clk26m",
|
||||
"clk26m",
|
||||
"clk26m",
|
||||
"clk26m",
|
||||
"clk26m",
|
||||
"clk26m",
|
||||
"syspll_d3",
|
||||
"syspll1_d2",
|
||||
"syspll_d5",
|
||||
"univpll_d3",
|
||||
"univpll1_d2"
|
||||
};
|
||||
|
||||
static const char * const camtg_sel_parents[] = {
|
||||
"clk26m",
|
||||
"univpll_d26",
|
||||
"univpll2_d2",
|
||||
"syspll3_d2",
|
||||
"syspll3_d4",
|
||||
"msdcpll_d4"
|
||||
};
|
||||
|
||||
static const char * const uart_sel_parents[] = {
|
||||
"clk26m",
|
||||
"univpll2_d8"
|
||||
};
|
||||
|
||||
static const char * const spi_sel_parents[] = {
|
||||
"clk26m",
|
||||
"syspll3_d2",
|
||||
"msdcpll_d8",
|
||||
"syspll2_d4",
|
||||
"syspll4_d2",
|
||||
"univpll2_d4",
|
||||
"univpll1_d8"
|
||||
};
|
||||
|
||||
static const char * const usb20_sel_parents[] = {
|
||||
"clk26m",
|
||||
"univpll1_d8",
|
||||
"univpll3_d4"
|
||||
};
|
||||
|
||||
static const char * const msdc50_0_sel_parents[] = {
|
||||
"clk26m",
|
||||
"syspll1_d2",
|
||||
"syspll2_d2",
|
||||
"syspll4_d2",
|
||||
"univpll_d5",
|
||||
"univpll1_d4"
|
||||
};
|
||||
|
||||
static const char * const msdc30_0_sel_parents[] = {
|
||||
"clk26m",
|
||||
"msdcpll",
|
||||
"msdcpll_d2",
|
||||
"msdcpll_d4",
|
||||
"syspll2_d2",
|
||||
"syspll1_d4",
|
||||
"univpll1_d4",
|
||||
"univpll_d3",
|
||||
"univpll_d26",
|
||||
"syspll2_d4",
|
||||
"univpll_d2"
|
||||
};
|
||||
|
||||
static const char * const msdc30_1_2_sel_parents[] = {
|
||||
"clk26m",
|
||||
"univpll2_d2",
|
||||
"msdcpll_d4",
|
||||
"syspll2_d2",
|
||||
"syspll1_d4",
|
||||
"univpll1_d4",
|
||||
"univpll_d26",
|
||||
"syspll2_d4"
|
||||
};
|
||||
|
||||
static const char * const msdc30_3_sel_parents[] = {
|
||||
"clk26m",
|
||||
"univpll2_d2",
|
||||
"msdcpll_d4",
|
||||
"syspll2_d2",
|
||||
"syspll1_d4",
|
||||
"univpll1_d4",
|
||||
"univpll_d26",
|
||||
"msdcpll_d16",
|
||||
"syspll2_d4"
|
||||
};
|
||||
|
||||
static const char * const audio_sel_parents[] = {
|
||||
"clk26m",
|
||||
"syspll3_d4",
|
||||
"syspll4_d4",
|
||||
"syspll1_d16"
|
||||
};
|
||||
|
||||
static const char * const aud_intbus_sel_parents[] = {
|
||||
"clk26m",
|
||||
"syspll1_d4",
|
||||
"syspll4_d2",
|
||||
"dmpll_d4"
|
||||
};
|
||||
|
||||
static const char * const pmicspi_sel_parents[] = {
|
||||
"clk26m",
|
||||
"syspll1_d8",
|
||||
"syspll3_d4",
|
||||
"syspll1_d16",
|
||||
"univpll3_d4",
|
||||
"univpll_d26",
|
||||
"dmpll_d4",
|
||||
"dmpll_d8"
|
||||
};
|
||||
|
||||
static const char * const scp_sel_parents[] = {
|
||||
"clk26m",
|
||||
"syspll1_d8",
|
||||
"dmpll_d2",
|
||||
"dmpll_d4"
|
||||
};
|
||||
|
||||
static const char * const atb_sel_parents[] = {
|
||||
"clk26m",
|
||||
"syspll1_d2",
|
||||
"syspll_d5",
|
||||
"dmpll"
|
||||
};
|
||||
|
||||
static const char * const dpi0_sel_parents[] = {
|
||||
"clk26m",
|
||||
"tvdpll",
|
||||
"tvdpll_d2",
|
||||
"tvdpll_d4",
|
||||
"dpi_ck"
|
||||
};
|
||||
|
||||
static const char * const scam_sel_parents[] = {
|
||||
"clk26m",
|
||||
"syspll3_d2",
|
||||
"univpll2_d4",
|
||||
"vencpll_d3"
|
||||
};
|
||||
|
||||
static const char * const mfg13m_sel_parents[] = {
|
||||
"clk26m",
|
||||
"ad_sys_26m_d2"
|
||||
};
|
||||
|
||||
static const char * const aud_1_2_sel_parents[] = {
|
||||
"clk26m",
|
||||
"apll1"
|
||||
};
|
||||
|
||||
static const char * const irda_sel_parents[] = {
|
||||
"clk26m",
|
||||
"univpll2_d4"
|
||||
};
|
||||
|
||||
static const char * const irtx_sel_parents[] = {
|
||||
"clk26m",
|
||||
"ad_sys_26m_ck"
|
||||
};
|
||||
|
||||
static const char * const disppwm_sel_parents[] = {
|
||||
"clk26m",
|
||||
"univpll2_d4",
|
||||
"syspll4_d2_d8",
|
||||
"ad_sys_26m_ck"
|
||||
};
|
||||
|
||||
static const struct mtk_mux topckgen_muxes[] = {
|
||||
MUX_CLR_SET_UPD(CLK_TOP_AXI_SEL, "axi_sel", axi_sel_parents, CLK_CFG_0, CLK_CFG_0_SET, CLK_CFG_0_CLR, 0, 3, 0, 0),
|
||||
MUX_CLR_SET_UPD(CLK_TOP_MEM_SEL, "mem_sel", mem_sel_parents, CLK_CFG_0, CLK_CFG_0_SET, CLK_CFG_0_CLR, 8, 1, 0, 0),
|
||||
MUX_CLR_SET_UPD(CLK_TOP_DDRPHY_SEL, "ddrphycfg_sel", ddrphycfg_parents, CLK_CFG_0, CLK_CFG_0_SET, CLK_CFG_0_CLR, 16, 1, 0, 0),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_MM_SEL, "mm_sel", mm_sel_parents, CLK_CFG_0, CLK_CFG_0_SET, CLK_CFG_0_CLR, 24, 3, 31, 0, 0),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_PWM_SEL, "pwm_sel", pwm_sel_parents, CLK_CFG_1, CLK_CFG_1_SET, CLK_CFG_1_CLR, 0, 2, 7, 0, 0),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_VDEC_SEL, "vdec_sel", vdec_sel_parents, CLK_CFG_1, CLK_CFG_1_SET, CLK_CFG_1_CLR, 8, 3, 15, 0, 0),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_MFG_SEL, "mfg_sel", mfg_sel_parents, CLK_CFG_1, CLK_CFG_1_SET, CLK_CFG_1_CLR, 16, 4, 23, 0, 0),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG_SEL, "camtg_sel", camtg_sel_parents, CLK_CFG_1, CLK_CFG_1_SET, CLK_CFG_1_CLR, 24, 3, 31, 0, 0),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_UART_SEL, "uart_sel", uart_sel_parents, CLK_CFG_2, CLK_CFG_2_SET, CLK_CFG_2_CLR, 0, 1, 7, 0, 0),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_SPI_SEL, "spi_sel", spi_sel_parents, CLK_CFG_2, CLK_CFG_2_SET, CLK_CFG_2_CLR, 8, 3, 15, 0, 0),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_USB20_SEL, "usb20_sel", usb20_sel_parents, CLK_CFG_2, CLK_CFG_2_SET, CLK_CFG_2_CLR, 16, 2, 23, 0, 0),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC50_0_SEL, "msdc50_0_sel", msdc50_0_sel_parents, CLK_CFG_2, CLK_CFG_2_SET, CLK_CFG_2_CLR, 24, 3, 31, 0, 0),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC30_0_SEL, "msdc30_0_sel", msdc30_0_sel_parents, CLK_CFG_3, CLK_CFG_3_SET, CLK_CFG_3_CLR, 0, 4, 7, 0, 0),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel", msdc30_1_2_sel_parents, CLK_CFG_3, CLK_CFG_3_SET, CLK_CFG_3_CLR, 8, 3, 15, 0, 0),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC30_2_SEL, "msdc30_2_sel", msdc30_1_2_sel_parents, CLK_CFG_3, CLK_CFG_3_SET, CLK_CFG_3_CLR, 16, 3, 23, 0, 0),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC30_3_SEL, "msdc30_3_sel", msdc30_3_sel_parents, CLK_CFG_3, CLK_CFG_3_SET, CLK_CFG_3_CLR, 24, 4, 31, 0, 0),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_AUDIO_SEL, "audio_sel", audio_sel_parents, CLK_CFG_4, CLK_CFG_4_SET, CLK_CFG_4_CLR, 0, 2, 7, 0, 0),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_AUDINTBUS_SEL, "aud_intbus_sel", aud_intbus_sel_parents, CLK_CFG_4, CLK_CFG_4_SET, CLK_CFG_4_CLR, 8, 2, 15, 0, 0),
|
||||
MUX_CLR_SET_UPD(CLK_TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_sel_parents, CLK_CFG_4, CLK_CFG_4_SET, CLK_CFG_4_CLR, 16, 3, 0, 0),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_SCP_SEL, "scp_sel", scp_sel_parents, CLK_CFG_4, CLK_CFG_4_SET, CLK_CFG_4_CLR, 24, 2, 31, 0, 0),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_ATB_SEL, "atb_sel", atb_sel_parents, CLK_CFG_5, CLK_CFG_5_SET, CLK_CFG_5_CLR, 0, 2, 7, 0, 0),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_DPI0_SEL, "dpi0_sel", dpi0_sel_parents, CLK_CFG_5, CLK_CFG_5_SET, CLK_CFG_5_CLR, 8, 3, 15, 0, 0),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_SCAM_SEL, "scam_sel", scam_sel_parents, CLK_CFG_5, CLK_CFG_5_SET, CLK_CFG_5_CLR, 16, 2, 23, 0, 0),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_MFG13M_SEL, "mfg13m_sel", mfg13m_sel_parents, CLK_CFG_5, CLK_CFG_5_SET, CLK_CFG_5_CLR, 24, 1, 31, 0, 0),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD1_SEL, "aud_1_sel", aud_1_2_sel_parents, CLK_CFG_6, CLK_CFG_6_SET, CLK_CFG_6_CLR, 0, 1, 7, 0, 0),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD2_SEL, "aud_2_sel", aud_1_2_sel_parents, CLK_CFG_6, CLK_CFG_6_SET, CLK_CFG_6_CLR, 8, 1, 15, 0, 0),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_IRDA_SEL, "irda_sel", irda_sel_parents, CLK_CFG_6, CLK_CFG_6_SET, CLK_CFG_6_CLR, 16, 1, 23, 0, 0),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_IRTX_SEL, "irtx_sel", irtx_sel_parents, CLK_CFG_6, CLK_CFG_6_SET, CLK_CFG_6_CLR, 24, 1, 31, 0, 0),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_DISPPWM_SEL, "disppwm_sel", disppwm_sel_parents, CLK_CFG_7, CLK_CFG_7_SET, CLK_CFG_7_CLR, 0, 2, 7, 0, 0),
|
||||
};
|
||||
|
||||
static const struct mtk_clk_desc topckgen_desc = {
|
||||
.fixed_clks = topckgen_fixed_clks,
|
||||
.num_fixed_clks = ARRAY_SIZE(topckgen_fixed_clks),
|
||||
.factor_clks = topckgen_factors,
|
||||
.num_factor_clks = ARRAY_SIZE(topckgen_factors),
|
||||
.mux_clks = topckgen_muxes,
|
||||
.num_mux_clks = ARRAY_SIZE(topckgen_muxes),
|
||||
.clk_lock = &mt6735_topckgen_lock,
|
||||
};
|
||||
|
||||
static const struct of_device_id of_match_mt6735_topckgen[] = {
|
||||
{ .compatible = "mediatek,mt6735-topckgen", .data = &topckgen_desc},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, of_match_mt6735_topckgen);
|
||||
|
||||
static struct platform_driver clk_mt6735_topckgen = {
|
||||
.probe = mtk_clk_simple_probe,
|
||||
.remove = mtk_clk_simple_remove,
|
||||
.driver = {
|
||||
.name = "clk-mt6735-topckgen",
|
||||
.of_match_table = of_match_mt6735_topckgen,
|
||||
},
|
||||
};
|
||||
module_platform_driver(clk_mt6735_topckgen);
|
||||
|
||||
MODULE_AUTHOR("Yassine Oudjana <y.oudjana@protonmail.com>");
|
||||
MODULE_DESCRIPTION("MediaTek MT6735 topckgen clock driver");
|
||||
MODULE_LICENSE("GPL");
|
79
drivers/clk/mediatek/clk-mt6735-vdecsys.c
Normal file
79
drivers/clk/mediatek/clk-mt6735-vdecsys.c
Normal file
@ -0,0 +1,79 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2022 Yassine Oudjana <y.oudjana@protonmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "clk-gate.h"
|
||||
#include "clk-mtk.h"
|
||||
|
||||
#include <dt-bindings/clock/mediatek,mt6735-vdecsys.h>
|
||||
#include <dt-bindings/reset/mediatek,mt6735-vdecsys.h>
|
||||
|
||||
#define VDEC_CKEN_SET 0x00
|
||||
#define VDEC_CKEN_CLR 0x04
|
||||
#define SMI_LARB1_CKEN_SET 0x08
|
||||
#define SMI_LARB1_CKEN_CLR 0x0c
|
||||
#define VDEC_RESETB_CON 0x10
|
||||
#define SMI_LARB1_RESETB_CON 0x14
|
||||
|
||||
#define RST_NR_PER_BANK 32
|
||||
|
||||
static struct mtk_gate_regs vdec_cg_regs = {
|
||||
.set_ofs = VDEC_CKEN_SET,
|
||||
.clr_ofs = VDEC_CKEN_CLR,
|
||||
.sta_ofs = VDEC_CKEN_SET,
|
||||
};
|
||||
|
||||
static struct mtk_gate_regs smi_larb1_cg_regs = {
|
||||
.set_ofs = SMI_LARB1_CKEN_SET,
|
||||
.clr_ofs = SMI_LARB1_CKEN_CLR,
|
||||
.sta_ofs = SMI_LARB1_CKEN_SET,
|
||||
};
|
||||
|
||||
static const struct mtk_gate vdecsys_gates[] = {
|
||||
GATE_MTK(CLK_VDEC_VDEC, "vdec", "vdec_sel", &vdec_cg_regs, 0, &mtk_clk_gate_ops_setclr_inv),
|
||||
GATE_MTK(CLK_VDEC_SMI_LARB1, "smi_larb1", "vdec_sel", &smi_larb1_cg_regs, 0, &mtk_clk_gate_ops_setclr_inv),
|
||||
};
|
||||
|
||||
static u16 vdecsys_rst_bank_ofs[] = { VDEC_RESETB_CON, SMI_LARB1_RESETB_CON };
|
||||
|
||||
static u16 vdecsys_rst_idx_map[] = {
|
||||
[MT6735_VDEC_RST0_VDEC] = 0 * RST_NR_PER_BANK + 0,
|
||||
[MT6735_VDEC_RST1_SMI_LARB1] = 1 * RST_NR_PER_BANK + 0,
|
||||
};
|
||||
|
||||
static const struct mtk_clk_rst_desc vdecsys_resets = {
|
||||
.version = MTK_RST_SIMPLE,
|
||||
.rst_bank_ofs = vdecsys_rst_bank_ofs,
|
||||
.rst_bank_nr = ARRAY_SIZE(vdecsys_rst_bank_ofs),
|
||||
.rst_idx_map = vdecsys_rst_idx_map,
|
||||
.rst_idx_map_nr = ARRAY_SIZE(vdecsys_rst_idx_map)
|
||||
};
|
||||
|
||||
static const struct mtk_clk_desc vdecsys_clks = {
|
||||
.clks = vdecsys_gates,
|
||||
.num_clks = ARRAY_SIZE(vdecsys_gates),
|
||||
.rst_desc = &vdecsys_resets
|
||||
};
|
||||
|
||||
static const struct of_device_id of_match_mt6735_vdecsys[] = {
|
||||
{ .compatible = "mediatek,mt6735-vdecsys", .data = &vdecsys_clks },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct platform_driver clk_mt6735_vdecsys = {
|
||||
.probe = mtk_clk_simple_probe,
|
||||
.remove = mtk_clk_simple_remove,
|
||||
.driver = {
|
||||
.name = "clk-mt6735-vdecsys",
|
||||
.of_match_table = of_match_mt6735_vdecsys,
|
||||
},
|
||||
};
|
||||
module_platform_driver(clk_mt6735_vdecsys);
|
||||
|
||||
MODULE_AUTHOR("Yassine Oudjana <y.oudjana@protonmail.com>");
|
||||
MODULE_DESCRIPTION("MediaTek MT6735 vdecsys clock and reset driver");
|
||||
MODULE_LICENSE("GPL");
|
53
drivers/clk/mediatek/clk-mt6735-vencsys.c
Normal file
53
drivers/clk/mediatek/clk-mt6735-vencsys.c
Normal file
@ -0,0 +1,53 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2022 Yassine Oudjana <y.oudjana@protonmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "clk-gate.h"
|
||||
#include "clk-mtk.h"
|
||||
|
||||
#include <dt-bindings/clock/mediatek,mt6735-vencsys.h>
|
||||
|
||||
#define VENC_CG_CON 0x00
|
||||
#define VENC_CG_SET 0x04
|
||||
#define VENC_CG_CLR 0x08
|
||||
|
||||
static struct mtk_gate_regs venc_cg_regs = {
|
||||
.set_ofs = VENC_CG_SET,
|
||||
.clr_ofs = VENC_CG_CLR,
|
||||
.sta_ofs = VENC_CG_CON,
|
||||
};
|
||||
|
||||
static const struct mtk_gate vencsys_gates[] = {
|
||||
GATE_MTK(CLK_VENC_SMI_LARB3, "smi_larb3", "mm_sel", &venc_cg_regs, 0, &mtk_clk_gate_ops_setclr_inv),
|
||||
GATE_MTK(CLK_VENC_VENC, "venc", "mm_sel", &venc_cg_regs, 4, &mtk_clk_gate_ops_setclr_inv),
|
||||
GATE_MTK(CLK_VENC_JPGENC, "jpgenc", "mm_sel", &venc_cg_regs, 8, &mtk_clk_gate_ops_setclr_inv),
|
||||
GATE_MTK(CLK_VENC_JPGDEC, "jpgdec", "mm_sel", &venc_cg_regs, 12, &mtk_clk_gate_ops_setclr_inv),
|
||||
};
|
||||
|
||||
static const struct mtk_clk_desc vencsys_clks = {
|
||||
.clks = vencsys_gates,
|
||||
.num_clks = ARRAY_SIZE(vencsys_gates),
|
||||
};
|
||||
|
||||
static const struct of_device_id of_match_mt6735_vencsys[] = {
|
||||
{ .compatible = "mediatek,mt6735-vencsys", .data = &vencsys_clks },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct platform_driver clk_mt6735_vencsys = {
|
||||
.probe = mtk_clk_simple_probe,
|
||||
.remove = mtk_clk_simple_remove,
|
||||
.driver = {
|
||||
.name = "clk-mt6735-vencsys",
|
||||
.of_match_table = of_match_mt6735_vencsys,
|
||||
},
|
||||
};
|
||||
module_platform_driver(clk_mt6735_vencsys);
|
||||
|
||||
MODULE_AUTHOR("Yassine Oudjana <y.oudjana@protonmail.com>");
|
||||
MODULE_DESCRIPTION("Mediatek MT6735 vencsys clock driver");
|
||||
MODULE_LICENSE("GPL");
|
@ -342,11 +342,14 @@ static const char * const dsp7_parents[] = {
|
||||
"univpll_d3"
|
||||
};
|
||||
|
||||
/*
|
||||
* MFG can be also parented to "univpll_d6" and "univpll_d7":
|
||||
* these have been removed from the parents list to let us
|
||||
* achieve GPU DVFS without any special clock handlers.
|
||||
*/
|
||||
static const char * const mfg_core_tmp_parents[] = {
|
||||
"clk26m",
|
||||
"mainpll_d5_d2",
|
||||
"univpll_d6",
|
||||
"univpll_d7"
|
||||
"mainpll_d5_d2"
|
||||
};
|
||||
|
||||
static const char * const camtg_parents[] = {
|
||||
|
@ -207,6 +207,7 @@ static struct mtmips_clk mt7620_pherip_clks[] = {
|
||||
{ CLK_PERIPH("10000b00.spi", "bus") },
|
||||
{ CLK_PERIPH("10000b40.spi", "bus") },
|
||||
{ CLK_PERIPH("10000c00.uartlite", "periph") },
|
||||
{ CLK_PERIPH("10130000.mmc", "sdhc") },
|
||||
{ CLK_PERIPH("10180000.wmac", "xtal") }
|
||||
};
|
||||
|
||||
@ -220,6 +221,7 @@ static struct mtmips_clk mt76x8_pherip_clks[] = {
|
||||
{ CLK_PERIPH("10000c00.uart0", "periph") },
|
||||
{ CLK_PERIPH("10000d00.uart1", "periph") },
|
||||
{ CLK_PERIPH("10000e00.uart2", "periph") },
|
||||
{ CLK_PERIPH("10130000.mmc", "sdhc") },
|
||||
{ CLK_PERIPH("10300000.wmac", "xtal") }
|
||||
};
|
||||
|
||||
@ -263,16 +265,22 @@ static int mtmips_register_pherip_clocks(struct device_node *np,
|
||||
.rate = _rate \
|
||||
}
|
||||
|
||||
static struct mtmips_clk_fixed rt305x_fixed_clocks[] = {
|
||||
CLK_FIXED("xtal", NULL, 40000000)
|
||||
static struct mtmips_clk_fixed rt3883_fixed_clocks[] = {
|
||||
CLK_FIXED("xtal", NULL, 40000000),
|
||||
CLK_FIXED("periph", "xtal", 40000000)
|
||||
};
|
||||
|
||||
static struct mtmips_clk_fixed rt3352_fixed_clocks[] = {
|
||||
CLK_FIXED("periph", "xtal", 40000000)
|
||||
};
|
||||
|
||||
static struct mtmips_clk_fixed mt7620_fixed_clocks[] = {
|
||||
CLK_FIXED("bbppll", "xtal", 480000000)
|
||||
};
|
||||
|
||||
static struct mtmips_clk_fixed mt76x8_fixed_clocks[] = {
|
||||
CLK_FIXED("pcmi2s", "xtal", 480000000),
|
||||
CLK_FIXED("bbppll", "xtal", 480000000),
|
||||
CLK_FIXED("pcmi2s", "bbppll", 480000000),
|
||||
CLK_FIXED("periph", "xtal", 40000000)
|
||||
};
|
||||
|
||||
@ -327,6 +335,15 @@ static struct mtmips_clk_factor rt305x_factor_clocks[] = {
|
||||
CLK_FACTOR("bus", "cpu", 1, 3)
|
||||
};
|
||||
|
||||
static struct mtmips_clk_factor mt7620_factor_clocks[] = {
|
||||
CLK_FACTOR("sdhc", "bbppll", 1, 10)
|
||||
};
|
||||
|
||||
static struct mtmips_clk_factor mt76x8_factor_clocks[] = {
|
||||
CLK_FACTOR("bus", "cpu", 1, 3),
|
||||
CLK_FACTOR("sdhc", "bbppll", 1, 10)
|
||||
};
|
||||
|
||||
static int mtmips_register_factor_clocks(struct clk_hw_onecell_data *clk_data,
|
||||
struct mtmips_clk_priv *priv)
|
||||
{
|
||||
@ -366,6 +383,12 @@ static inline struct mtmips_clk *to_mtmips_clk(struct clk_hw *hw)
|
||||
return container_of(hw, struct mtmips_clk, hw);
|
||||
}
|
||||
|
||||
static unsigned long rt2880_xtal_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
return 40000000;
|
||||
}
|
||||
|
||||
static unsigned long rt5350_xtal_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
@ -677,10 +700,12 @@ static unsigned long mt76x8_cpu_recalc_rate(struct clk_hw *hw,
|
||||
}
|
||||
|
||||
static struct mtmips_clk rt2880_clks_base[] = {
|
||||
{ CLK_BASE("xtal", NULL, rt2880_xtal_recalc_rate) },
|
||||
{ CLK_BASE("cpu", "xtal", rt2880_cpu_recalc_rate) }
|
||||
};
|
||||
|
||||
static struct mtmips_clk rt305x_clks_base[] = {
|
||||
{ CLK_BASE("xtal", NULL, rt2880_xtal_recalc_rate) },
|
||||
{ CLK_BASE("cpu", "xtal", rt305x_cpu_recalc_rate) }
|
||||
};
|
||||
|
||||
@ -690,6 +715,7 @@ static struct mtmips_clk rt3352_clks_base[] = {
|
||||
};
|
||||
|
||||
static struct mtmips_clk rt3883_clks_base[] = {
|
||||
{ CLK_BASE("xtal", NULL, rt2880_xtal_recalc_rate) },
|
||||
{ CLK_BASE("cpu", "xtal", rt3883_cpu_recalc_rate) },
|
||||
{ CLK_BASE("bus", "cpu", rt3883_bus_recalc_rate) }
|
||||
};
|
||||
@ -746,8 +772,8 @@ static int mtmips_register_clocks(struct device_node *np,
|
||||
static const struct mtmips_clk_data rt2880_clk_data = {
|
||||
.clk_base = rt2880_clks_base,
|
||||
.num_clk_base = ARRAY_SIZE(rt2880_clks_base),
|
||||
.clk_fixed = rt305x_fixed_clocks,
|
||||
.num_clk_fixed = ARRAY_SIZE(rt305x_fixed_clocks),
|
||||
.clk_fixed = NULL,
|
||||
.num_clk_fixed = 0,
|
||||
.clk_factor = rt2880_factor_clocks,
|
||||
.num_clk_factor = ARRAY_SIZE(rt2880_factor_clocks),
|
||||
.clk_periph = rt2880_pherip_clks,
|
||||
@ -757,8 +783,8 @@ static const struct mtmips_clk_data rt2880_clk_data = {
|
||||
static const struct mtmips_clk_data rt305x_clk_data = {
|
||||
.clk_base = rt305x_clks_base,
|
||||
.num_clk_base = ARRAY_SIZE(rt305x_clks_base),
|
||||
.clk_fixed = rt305x_fixed_clocks,
|
||||
.num_clk_fixed = ARRAY_SIZE(rt305x_fixed_clocks),
|
||||
.clk_fixed = NULL,
|
||||
.num_clk_fixed = 0,
|
||||
.clk_factor = rt305x_factor_clocks,
|
||||
.num_clk_factor = ARRAY_SIZE(rt305x_factor_clocks),
|
||||
.clk_periph = rt305x_pherip_clks,
|
||||
@ -779,8 +805,8 @@ static const struct mtmips_clk_data rt3352_clk_data = {
|
||||
static const struct mtmips_clk_data rt3883_clk_data = {
|
||||
.clk_base = rt3883_clks_base,
|
||||
.num_clk_base = ARRAY_SIZE(rt3883_clks_base),
|
||||
.clk_fixed = rt305x_fixed_clocks,
|
||||
.num_clk_fixed = ARRAY_SIZE(rt305x_fixed_clocks),
|
||||
.clk_fixed = rt3883_fixed_clocks,
|
||||
.num_clk_fixed = ARRAY_SIZE(rt3883_fixed_clocks),
|
||||
.clk_factor = NULL,
|
||||
.num_clk_factor = 0,
|
||||
.clk_periph = rt5350_pherip_clks,
|
||||
@ -801,10 +827,10 @@ static const struct mtmips_clk_data rt5350_clk_data = {
|
||||
static const struct mtmips_clk_data mt7620_clk_data = {
|
||||
.clk_base = mt7620_clks_base,
|
||||
.num_clk_base = ARRAY_SIZE(mt7620_clks_base),
|
||||
.clk_fixed = NULL,
|
||||
.num_clk_fixed = 0,
|
||||
.clk_factor = NULL,
|
||||
.num_clk_factor = 0,
|
||||
.clk_fixed = mt7620_fixed_clocks,
|
||||
.num_clk_fixed = ARRAY_SIZE(mt7620_fixed_clocks),
|
||||
.clk_factor = mt7620_factor_clocks,
|
||||
.num_clk_factor = ARRAY_SIZE(mt7620_factor_clocks),
|
||||
.clk_periph = mt7620_pherip_clks,
|
||||
.num_clk_periph = ARRAY_SIZE(mt7620_pherip_clks),
|
||||
};
|
||||
@ -814,8 +840,8 @@ static const struct mtmips_clk_data mt76x8_clk_data = {
|
||||
.num_clk_base = ARRAY_SIZE(mt76x8_clks_base),
|
||||
.clk_fixed = mt76x8_fixed_clocks,
|
||||
.num_clk_fixed = ARRAY_SIZE(mt76x8_fixed_clocks),
|
||||
.clk_factor = rt305x_factor_clocks,
|
||||
.num_clk_factor = ARRAY_SIZE(rt305x_factor_clocks),
|
||||
.clk_factor = mt76x8_factor_clocks,
|
||||
.num_clk_factor = ARRAY_SIZE(mt76x8_factor_clocks),
|
||||
.clk_periph = mt76x8_pherip_clks,
|
||||
.num_clk_periph = ARRAY_SIZE(mt76x8_pherip_clks),
|
||||
};
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/math64.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/overflow.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/iopoll.h>
|
||||
|
||||
@ -121,26 +122,24 @@ enum clk_wzrd_int_clks {
|
||||
/**
|
||||
* struct clk_wzrd - Clock wizard private data structure
|
||||
*
|
||||
* @clk_data: Clock data
|
||||
* @nb: Notifier block
|
||||
* @base: Memory base
|
||||
* @clk_in1: Handle to input clock 'clk_in1'
|
||||
* @axi_clk: Handle to input clock 's_axi_aclk'
|
||||
* @clks_internal: Internal clocks
|
||||
* @clkout: Output clocks
|
||||
* @speed_grade: Speed grade of the device
|
||||
* @suspended: Flag indicating power state of the device
|
||||
* @clk_data: Output clock data
|
||||
*/
|
||||
struct clk_wzrd {
|
||||
struct clk_onecell_data clk_data;
|
||||
struct notifier_block nb;
|
||||
void __iomem *base;
|
||||
struct clk *clk_in1;
|
||||
struct clk *axi_clk;
|
||||
struct clk *clks_internal[wzrd_clk_int_max];
|
||||
struct clk *clkout[WZRD_NUM_OUTPUTS];
|
||||
struct clk_hw *clks_internal[wzrd_clk_int_max];
|
||||
unsigned int speed_grade;
|
||||
bool suspended;
|
||||
struct clk_hw_onecell_data clk_data;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -765,7 +764,7 @@ static const struct clk_ops clk_wzrd_clk_divider_ops_f = {
|
||||
.recalc_rate = clk_wzrd_recalc_ratef,
|
||||
};
|
||||
|
||||
static struct clk *clk_wzrd_register_divf(struct device *dev,
|
||||
static struct clk_hw *clk_wzrd_register_divf(struct device *dev,
|
||||
const char *name,
|
||||
const char *parent_name,
|
||||
unsigned long flags,
|
||||
@ -805,10 +804,10 @@ static struct clk *clk_wzrd_register_divf(struct device *dev,
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
return hw->clk;
|
||||
return hw;
|
||||
}
|
||||
|
||||
static struct clk *clk_wzrd_ver_register_divider(struct device *dev,
|
||||
static struct clk_hw *clk_wzrd_ver_register_divider(struct device *dev,
|
||||
const char *name,
|
||||
const char *parent_name,
|
||||
unsigned long flags,
|
||||
@ -852,10 +851,10 @@ static struct clk *clk_wzrd_ver_register_divider(struct device *dev,
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
return hw->clk;
|
||||
return hw;
|
||||
}
|
||||
|
||||
static struct clk *clk_wzrd_register_divider(struct device *dev,
|
||||
static struct clk_hw *clk_wzrd_register_divider(struct device *dev,
|
||||
const char *name,
|
||||
const char *parent_name,
|
||||
unsigned long flags,
|
||||
@ -898,7 +897,7 @@ static struct clk *clk_wzrd_register_divider(struct device *dev,
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
return hw->clk;
|
||||
return hw;
|
||||
}
|
||||
|
||||
static int clk_wzrd_clk_notifier(struct notifier_block *nb, unsigned long event,
|
||||
@ -963,81 +962,30 @@ static const struct versal_clk_data versal_data = {
|
||||
.is_versal = true,
|
||||
};
|
||||
|
||||
static int clk_wzrd_probe(struct platform_device *pdev)
|
||||
static int clk_wzrd_register_output_clocks(struct device *dev, int nr_outputs)
|
||||
{
|
||||
const char *clkout_name, *clk_name, *clk_mul_name;
|
||||
struct clk_wzrd *clk_wzrd = dev_get_drvdata(dev);
|
||||
u32 regl, regh, edge, regld, reghd, edged, div;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
const struct versal_clk_data *data;
|
||||
struct clk_wzrd *clk_wzrd;
|
||||
unsigned long flags = 0;
|
||||
bool is_versal = false;
|
||||
void __iomem *ctrl_reg;
|
||||
u32 reg, reg_f, mult;
|
||||
bool is_versal = false;
|
||||
unsigned long rate;
|
||||
int nr_outputs;
|
||||
int i, ret;
|
||||
int i;
|
||||
|
||||
clk_wzrd = devm_kzalloc(&pdev->dev, sizeof(*clk_wzrd), GFP_KERNEL);
|
||||
if (!clk_wzrd)
|
||||
return -ENOMEM;
|
||||
platform_set_drvdata(pdev, clk_wzrd);
|
||||
|
||||
clk_wzrd->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(clk_wzrd->base))
|
||||
return PTR_ERR(clk_wzrd->base);
|
||||
|
||||
ret = of_property_read_u32(np, "xlnx,speed-grade", &clk_wzrd->speed_grade);
|
||||
if (!ret) {
|
||||
if (clk_wzrd->speed_grade < 1 || clk_wzrd->speed_grade > 3) {
|
||||
dev_warn(&pdev->dev, "invalid speed grade '%d'\n",
|
||||
clk_wzrd->speed_grade);
|
||||
clk_wzrd->speed_grade = 0;
|
||||
}
|
||||
}
|
||||
|
||||
clk_wzrd->clk_in1 = devm_clk_get(&pdev->dev, "clk_in1");
|
||||
if (IS_ERR(clk_wzrd->clk_in1))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->clk_in1),
|
||||
"clk_in1 not found\n");
|
||||
|
||||
clk_wzrd->axi_clk = devm_clk_get(&pdev->dev, "s_axi_aclk");
|
||||
if (IS_ERR(clk_wzrd->axi_clk))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->axi_clk),
|
||||
"s_axi_aclk not found\n");
|
||||
ret = clk_prepare_enable(clk_wzrd->axi_clk);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "enabling s_axi_aclk failed\n");
|
||||
return ret;
|
||||
}
|
||||
rate = clk_get_rate(clk_wzrd->axi_clk);
|
||||
if (rate > WZRD_ACLK_MAX_FREQ) {
|
||||
dev_err(&pdev->dev, "s_axi_aclk frequency (%lu) too high\n",
|
||||
rate);
|
||||
ret = -EINVAL;
|
||||
goto err_disable_clk;
|
||||
}
|
||||
|
||||
data = device_get_match_data(&pdev->dev);
|
||||
data = device_get_match_data(dev);
|
||||
if (data)
|
||||
is_versal = data->is_versal;
|
||||
|
||||
ret = of_property_read_u32(np, "xlnx,nr-outputs", &nr_outputs);
|
||||
if (ret || nr_outputs > WZRD_NUM_OUTPUTS) {
|
||||
ret = -EINVAL;
|
||||
goto err_disable_clk;
|
||||
}
|
||||
|
||||
clkout_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_out0", dev_name(&pdev->dev));
|
||||
if (!clkout_name) {
|
||||
ret = -ENOMEM;
|
||||
goto err_disable_clk;
|
||||
}
|
||||
clkout_name = devm_kasprintf(dev, GFP_KERNEL, "%s_out0", dev_name(dev));
|
||||
if (!clkout_name)
|
||||
return -ENOMEM;
|
||||
|
||||
if (is_versal) {
|
||||
if (nr_outputs == 1) {
|
||||
clk_wzrd->clkout[0] = clk_wzrd_ver_register_divider
|
||||
(&pdev->dev, clkout_name,
|
||||
clk_wzrd->clk_data.hws[0] = clk_wzrd_ver_register_divider
|
||||
(dev, clkout_name,
|
||||
__clk_get_name(clk_wzrd->clk_in1), 0,
|
||||
clk_wzrd->base, WZRD_CLK_CFG_REG(is_versal, 3),
|
||||
WZRD_CLKOUT_DIVIDE_SHIFT,
|
||||
@ -1045,7 +993,7 @@ static int clk_wzrd_probe(struct platform_device *pdev)
|
||||
CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
|
||||
DIV_ALL, &clkwzrd_lock);
|
||||
|
||||
goto out;
|
||||
return 0;
|
||||
}
|
||||
/* register multiplier */
|
||||
edge = !!(readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 0)) &
|
||||
@ -1069,8 +1017,8 @@ static int clk_wzrd_probe(struct platform_device *pdev)
|
||||
div = 64;
|
||||
} else {
|
||||
if (nr_outputs == 1) {
|
||||
clk_wzrd->clkout[0] = clk_wzrd_register_divider
|
||||
(&pdev->dev, clkout_name,
|
||||
clk_wzrd->clk_data.hws[0] = clk_wzrd_register_divider
|
||||
(dev, clkout_name,
|
||||
__clk_get_name(clk_wzrd->clk_in1), 0,
|
||||
clk_wzrd->base, WZRD_CLK_CFG_REG(is_versal, 3),
|
||||
WZRD_CLKOUT_DIVIDE_SHIFT,
|
||||
@ -1078,7 +1026,7 @@ static int clk_wzrd_probe(struct platform_device *pdev)
|
||||
CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
|
||||
DIV_ALL, &clkwzrd_lock);
|
||||
|
||||
goto out;
|
||||
return 0;
|
||||
}
|
||||
reg = readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 0));
|
||||
reg_f = reg & WZRD_CLKFBOUT_FRAC_MASK;
|
||||
@ -1089,26 +1037,21 @@ static int clk_wzrd_probe(struct platform_device *pdev)
|
||||
mult = (reg * 1000) + reg_f;
|
||||
div = 1000;
|
||||
}
|
||||
clk_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_mul", dev_name(&pdev->dev));
|
||||
if (!clk_name) {
|
||||
ret = -ENOMEM;
|
||||
goto err_disable_clk;
|
||||
}
|
||||
clk_wzrd->clks_internal[wzrd_clk_mul] = clk_register_fixed_factor
|
||||
(&pdev->dev, clk_name,
|
||||
clk_name = devm_kasprintf(dev, GFP_KERNEL, "%s_mul", dev_name(dev));
|
||||
if (!clk_name)
|
||||
return -ENOMEM;
|
||||
clk_wzrd->clks_internal[wzrd_clk_mul] = devm_clk_hw_register_fixed_factor
|
||||
(dev, clk_name,
|
||||
__clk_get_name(clk_wzrd->clk_in1),
|
||||
0, mult, div);
|
||||
if (IS_ERR(clk_wzrd->clks_internal[wzrd_clk_mul])) {
|
||||
dev_err(&pdev->dev, "unable to register fixed-factor clock\n");
|
||||
ret = PTR_ERR(clk_wzrd->clks_internal[wzrd_clk_mul]);
|
||||
goto err_disable_clk;
|
||||
dev_err(dev, "unable to register fixed-factor clock\n");
|
||||
return PTR_ERR(clk_wzrd->clks_internal[wzrd_clk_mul]);
|
||||
}
|
||||
|
||||
clk_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_mul_div", dev_name(&pdev->dev));
|
||||
if (!clk_name) {
|
||||
ret = -ENOMEM;
|
||||
goto err_rm_int_clk;
|
||||
}
|
||||
clk_name = devm_kasprintf(dev, GFP_KERNEL, "%s_mul_div", dev_name(dev));
|
||||
if (!clk_name)
|
||||
return -ENOMEM;
|
||||
|
||||
if (is_versal) {
|
||||
edged = !!(readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 20)) &
|
||||
@ -1121,36 +1064,31 @@ static int clk_wzrd_probe(struct platform_device *pdev)
|
||||
if (!div)
|
||||
div = 1;
|
||||
|
||||
clk_mul_name = __clk_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]);
|
||||
clk_mul_name = clk_hw_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]);
|
||||
clk_wzrd->clks_internal[wzrd_clk_mul_div] =
|
||||
clk_register_fixed_factor(&pdev->dev, clk_name,
|
||||
clk_mul_name, 0, 1, div);
|
||||
devm_clk_hw_register_fixed_factor(dev, clk_name, clk_mul_name, 0, 1, div);
|
||||
} else {
|
||||
ctrl_reg = clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 0);
|
||||
clk_wzrd->clks_internal[wzrd_clk_mul_div] = clk_register_divider
|
||||
(&pdev->dev, clk_name,
|
||||
__clk_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]),
|
||||
clk_wzrd->clks_internal[wzrd_clk_mul_div] = devm_clk_hw_register_divider
|
||||
(dev, clk_name,
|
||||
clk_hw_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]),
|
||||
flags, ctrl_reg, 0, 8, CLK_DIVIDER_ONE_BASED |
|
||||
CLK_DIVIDER_ALLOW_ZERO, &clkwzrd_lock);
|
||||
}
|
||||
if (IS_ERR(clk_wzrd->clks_internal[wzrd_clk_mul_div])) {
|
||||
dev_err(&pdev->dev, "unable to register divider clock\n");
|
||||
ret = PTR_ERR(clk_wzrd->clks_internal[wzrd_clk_mul_div]);
|
||||
goto err_rm_int_clk;
|
||||
dev_err(dev, "unable to register divider clock\n");
|
||||
return PTR_ERR(clk_wzrd->clks_internal[wzrd_clk_mul_div]);
|
||||
}
|
||||
|
||||
/* register div per output */
|
||||
for (i = nr_outputs - 1; i >= 0 ; i--) {
|
||||
clkout_name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
|
||||
"%s_out%d", dev_name(&pdev->dev), i);
|
||||
if (!clkout_name) {
|
||||
ret = -ENOMEM;
|
||||
goto err_rm_int_clk;
|
||||
}
|
||||
clkout_name = devm_kasprintf(dev, GFP_KERNEL, "%s_out%d", dev_name(dev), i);
|
||||
if (!clkout_name)
|
||||
return -ENOMEM;
|
||||
|
||||
if (is_versal) {
|
||||
clk_wzrd->clkout[i] = clk_wzrd_ver_register_divider
|
||||
(&pdev->dev,
|
||||
clk_wzrd->clk_data.hws[i] = clk_wzrd_ver_register_divider
|
||||
(dev,
|
||||
clkout_name, clk_name, 0,
|
||||
clk_wzrd->base,
|
||||
(WZRD_CLK_CFG_REG(is_versal, 3) + i * 8),
|
||||
@ -1161,84 +1099,108 @@ static int clk_wzrd_probe(struct platform_device *pdev)
|
||||
DIV_O, &clkwzrd_lock);
|
||||
} else {
|
||||
if (!i)
|
||||
clk_wzrd->clkout[i] = clk_wzrd_register_divf
|
||||
(&pdev->dev, clkout_name, clk_name, flags, clk_wzrd->base,
|
||||
clk_wzrd->clk_data.hws[i] = clk_wzrd_register_divf
|
||||
(dev, clkout_name, clk_name, flags, clk_wzrd->base,
|
||||
(WZRD_CLK_CFG_REG(is_versal, 2) + i * 12),
|
||||
WZRD_CLKOUT_DIVIDE_SHIFT,
|
||||
WZRD_CLKOUT_DIVIDE_WIDTH,
|
||||
CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
|
||||
DIV_O, &clkwzrd_lock);
|
||||
else
|
||||
clk_wzrd->clkout[i] = clk_wzrd_register_divider
|
||||
(&pdev->dev, clkout_name, clk_name, 0, clk_wzrd->base,
|
||||
clk_wzrd->clk_data.hws[i] = clk_wzrd_register_divider
|
||||
(dev, clkout_name, clk_name, 0, clk_wzrd->base,
|
||||
(WZRD_CLK_CFG_REG(is_versal, 2) + i * 12),
|
||||
WZRD_CLKOUT_DIVIDE_SHIFT,
|
||||
WZRD_CLKOUT_DIVIDE_WIDTH,
|
||||
CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
|
||||
DIV_O, &clkwzrd_lock);
|
||||
}
|
||||
if (IS_ERR(clk_wzrd->clkout[i])) {
|
||||
int j;
|
||||
|
||||
for (j = i + 1; j < nr_outputs; j++)
|
||||
clk_unregister(clk_wzrd->clkout[j]);
|
||||
dev_err(&pdev->dev,
|
||||
"unable to register divider clock\n");
|
||||
ret = PTR_ERR(clk_wzrd->clkout[i]);
|
||||
goto err_rm_int_clks;
|
||||
if (IS_ERR(clk_wzrd->clk_data.hws[i])) {
|
||||
dev_err(dev, "unable to register divider clock\n");
|
||||
return PTR_ERR(clk_wzrd->clk_data.hws[i]);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
clk_wzrd->clk_data.clks = clk_wzrd->clkout;
|
||||
clk_wzrd->clk_data.clk_num = ARRAY_SIZE(clk_wzrd->clkout);
|
||||
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_wzrd->clk_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (clk_wzrd->speed_grade) {
|
||||
clk_wzrd->nb.notifier_call = clk_wzrd_clk_notifier;
|
||||
static int clk_wzrd_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct clk_wzrd *clk_wzrd;
|
||||
unsigned long rate;
|
||||
int nr_outputs;
|
||||
int ret;
|
||||
|
||||
ret = clk_notifier_register(clk_wzrd->clk_in1,
|
||||
&clk_wzrd->nb);
|
||||
ret = of_property_read_u32(np, "xlnx,nr-outputs", &nr_outputs);
|
||||
if (ret || nr_outputs > WZRD_NUM_OUTPUTS)
|
||||
return -EINVAL;
|
||||
|
||||
clk_wzrd = devm_kzalloc(&pdev->dev, struct_size(clk_wzrd, clk_data.hws, nr_outputs),
|
||||
GFP_KERNEL);
|
||||
if (!clk_wzrd)
|
||||
return -ENOMEM;
|
||||
platform_set_drvdata(pdev, clk_wzrd);
|
||||
|
||||
clk_wzrd->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(clk_wzrd->base))
|
||||
return PTR_ERR(clk_wzrd->base);
|
||||
|
||||
clk_wzrd->axi_clk = devm_clk_get_enabled(&pdev->dev, "s_axi_aclk");
|
||||
if (IS_ERR(clk_wzrd->axi_clk))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->axi_clk),
|
||||
"s_axi_aclk not found\n");
|
||||
rate = clk_get_rate(clk_wzrd->axi_clk);
|
||||
if (rate > WZRD_ACLK_MAX_FREQ) {
|
||||
dev_err(&pdev->dev, "s_axi_aclk frequency (%lu) too high\n", rate);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!of_property_present(np, "xlnx,static-config")) {
|
||||
ret = of_property_read_u32(np, "xlnx,speed-grade", &clk_wzrd->speed_grade);
|
||||
if (!ret) {
|
||||
if (clk_wzrd->speed_grade < 1 || clk_wzrd->speed_grade > 3) {
|
||||
dev_warn(&pdev->dev, "invalid speed grade '%d'\n",
|
||||
clk_wzrd->speed_grade);
|
||||
clk_wzrd->speed_grade = 0;
|
||||
}
|
||||
}
|
||||
|
||||
clk_wzrd->clk_in1 = devm_clk_get(&pdev->dev, "clk_in1");
|
||||
if (IS_ERR(clk_wzrd->clk_in1))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->clk_in1),
|
||||
"clk_in1 not found\n");
|
||||
|
||||
ret = clk_wzrd_register_output_clocks(&pdev->dev, nr_outputs);
|
||||
if (ret)
|
||||
dev_warn(&pdev->dev,
|
||||
"unable to register clock notifier\n");
|
||||
return ret;
|
||||
|
||||
ret = clk_notifier_register(clk_wzrd->axi_clk, &clk_wzrd->nb);
|
||||
if (ret)
|
||||
dev_warn(&pdev->dev,
|
||||
"unable to register clock notifier\n");
|
||||
clk_wzrd->clk_data.num = nr_outputs;
|
||||
ret = devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_onecell_get,
|
||||
&clk_wzrd->clk_data);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "unable to register clock provider\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (clk_wzrd->speed_grade) {
|
||||
clk_wzrd->nb.notifier_call = clk_wzrd_clk_notifier;
|
||||
|
||||
ret = devm_clk_notifier_register(&pdev->dev, clk_wzrd->clk_in1,
|
||||
&clk_wzrd->nb);
|
||||
if (ret)
|
||||
dev_warn(&pdev->dev,
|
||||
"unable to register clock notifier\n");
|
||||
|
||||
ret = devm_clk_notifier_register(&pdev->dev, clk_wzrd->axi_clk,
|
||||
&clk_wzrd->nb);
|
||||
if (ret)
|
||||
dev_warn(&pdev->dev,
|
||||
"unable to register clock notifier\n");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_rm_int_clks:
|
||||
clk_unregister(clk_wzrd->clks_internal[1]);
|
||||
err_rm_int_clk:
|
||||
clk_unregister(clk_wzrd->clks_internal[0]);
|
||||
err_disable_clk:
|
||||
clk_disable_unprepare(clk_wzrd->axi_clk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void clk_wzrd_remove(struct platform_device *pdev)
|
||||
{
|
||||
int i;
|
||||
struct clk_wzrd *clk_wzrd = platform_get_drvdata(pdev);
|
||||
|
||||
of_clk_del_provider(pdev->dev.of_node);
|
||||
|
||||
for (i = 0; i < WZRD_NUM_OUTPUTS; i++)
|
||||
clk_unregister(clk_wzrd->clkout[i]);
|
||||
for (i = 0; i < wzrd_clk_int_max; i++)
|
||||
clk_unregister(clk_wzrd->clks_internal[i]);
|
||||
|
||||
if (clk_wzrd->speed_grade) {
|
||||
clk_notifier_unregister(clk_wzrd->axi_clk, &clk_wzrd->nb);
|
||||
clk_notifier_unregister(clk_wzrd->clk_in1, &clk_wzrd->nb);
|
||||
}
|
||||
|
||||
clk_disable_unprepare(clk_wzrd->axi_clk);
|
||||
}
|
||||
|
||||
static const struct of_device_id clk_wzrd_ids[] = {
|
||||
@ -1257,7 +1219,6 @@ static struct platform_driver clk_wzrd_driver = {
|
||||
.pm = &clk_wzrd_dev_pm_ops,
|
||||
},
|
||||
.probe = clk_wzrd_probe,
|
||||
.remove = clk_wzrd_remove,
|
||||
};
|
||||
module_platform_driver(clk_wzrd_driver);
|
||||
|
||||
|
16
include/dt-bindings/clock/mediatek,mt6735-apmixedsys.h
Normal file
16
include/dt-bindings/clock/mediatek,mt6735-apmixedsys.h
Normal file
@ -0,0 +1,16 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_MT6735_APMIXEDSYS_H
|
||||
#define _DT_BINDINGS_CLK_MT6735_APMIXEDSYS_H
|
||||
|
||||
#define CLK_APMIXED_ARMPLL 0
|
||||
#define CLK_APMIXED_MAINPLL 1
|
||||
#define CLK_APMIXED_UNIVPLL 2
|
||||
#define CLK_APMIXED_MMPLL 3
|
||||
#define CLK_APMIXED_MSDCPLL 4
|
||||
#define CLK_APMIXED_VENCPLL 5
|
||||
#define CLK_APMIXED_TVDPLL 6
|
||||
#define CLK_APMIXED_APLL1 7
|
||||
#define CLK_APMIXED_APLL2 8
|
||||
|
||||
#endif
|
15
include/dt-bindings/clock/mediatek,mt6735-imgsys.h
Normal file
15
include/dt-bindings/clock/mediatek,mt6735-imgsys.h
Normal file
@ -0,0 +1,15 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_MT6735_IMGSYS_H
|
||||
#define _DT_BINDINGS_CLK_MT6735_IMGSYS_H
|
||||
|
||||
#define CLK_IMG_SMI_LARB2 0
|
||||
#define CLK_IMG_CAM_SMI 1
|
||||
#define CLK_IMG_CAM_CAM 2
|
||||
#define CLK_IMG_SEN_TG 3
|
||||
#define CLK_IMG_SEN_CAM 4
|
||||
#define CLK_IMG_CAM_SV 5
|
||||
#define CLK_IMG_SUFOD 6
|
||||
#define CLK_IMG_FD 7
|
||||
|
||||
#endif /* _DT_BINDINGS_CLK_MT6735_IMGSYS_H */
|
25
include/dt-bindings/clock/mediatek,mt6735-infracfg.h
Normal file
25
include/dt-bindings/clock/mediatek,mt6735-infracfg.h
Normal file
@ -0,0 +1,25 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_MT6735_INFRACFG_H
|
||||
#define _DT_BINDINGS_CLK_MT6735_INFRACFG_H
|
||||
|
||||
#define CLK_INFRA_DBG 0
|
||||
#define CLK_INFRA_GCE 1
|
||||
#define CLK_INFRA_TRBG 2
|
||||
#define CLK_INFRA_CPUM 3
|
||||
#define CLK_INFRA_DEVAPC 4
|
||||
#define CLK_INFRA_AUDIO 5
|
||||
#define CLK_INFRA_GCPU 6
|
||||
#define CLK_INFRA_L2C_SRAM 7
|
||||
#define CLK_INFRA_M4U 8
|
||||
#define CLK_INFRA_CLDMA 9
|
||||
#define CLK_INFRA_CONNMCU_BUS 10
|
||||
#define CLK_INFRA_KP 11
|
||||
#define CLK_INFRA_APXGPT 12
|
||||
#define CLK_INFRA_SEJ 13
|
||||
#define CLK_INFRA_CCIF0_AP 14
|
||||
#define CLK_INFRA_CCIF1_AP 15
|
||||
#define CLK_INFRA_PMIC_SPI 16
|
||||
#define CLK_INFRA_PMIC_WRAP 17
|
||||
|
||||
#endif
|
8
include/dt-bindings/clock/mediatek,mt6735-mfgcfg.h
Normal file
8
include/dt-bindings/clock/mediatek,mt6735-mfgcfg.h
Normal file
@ -0,0 +1,8 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_MT6735_MFGCFG_H
|
||||
#define _DT_BINDINGS_CLK_MT6735_MFGCFG_H
|
||||
|
||||
#define CLK_MFG_BG3D 0
|
||||
|
||||
#endif /* _DT_BINDINGS_CLK_MT6735_MFGCFG_H */
|
37
include/dt-bindings/clock/mediatek,mt6735-pericfg.h
Normal file
37
include/dt-bindings/clock/mediatek,mt6735-pericfg.h
Normal file
@ -0,0 +1,37 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_MT6735_PERICFG_H
|
||||
#define _DT_BINDINGS_CLK_MT6735_PERICFG_H
|
||||
|
||||
#define CLK_PERI_DISP_PWM 0
|
||||
#define CLK_PERI_THERM 1
|
||||
#define CLK_PERI_PWM1 2
|
||||
#define CLK_PERI_PWM2 3
|
||||
#define CLK_PERI_PWM3 4
|
||||
#define CLK_PERI_PWM4 5
|
||||
#define CLK_PERI_PWM5 6
|
||||
#define CLK_PERI_PWM6 7
|
||||
#define CLK_PERI_PWM7 8
|
||||
#define CLK_PERI_PWM 9
|
||||
#define CLK_PERI_USB0 10
|
||||
#define CLK_PERI_IRDA 11
|
||||
#define CLK_PERI_APDMA 12
|
||||
#define CLK_PERI_MSDC30_0 13
|
||||
#define CLK_PERI_MSDC30_1 14
|
||||
#define CLK_PERI_MSDC30_2 15
|
||||
#define CLK_PERI_MSDC30_3 16
|
||||
#define CLK_PERI_UART0 17
|
||||
#define CLK_PERI_UART1 18
|
||||
#define CLK_PERI_UART2 19
|
||||
#define CLK_PERI_UART3 20
|
||||
#define CLK_PERI_UART4 21
|
||||
#define CLK_PERI_BTIF 22
|
||||
#define CLK_PERI_I2C0 23
|
||||
#define CLK_PERI_I2C1 24
|
||||
#define CLK_PERI_I2C2 25
|
||||
#define CLK_PERI_I2C3 26
|
||||
#define CLK_PERI_AUXADC 27
|
||||
#define CLK_PERI_SPI0 28
|
||||
#define CLK_PERI_IRTX 29
|
||||
|
||||
#endif
|
79
include/dt-bindings/clock/mediatek,mt6735-topckgen.h
Normal file
79
include/dt-bindings/clock/mediatek,mt6735-topckgen.h
Normal file
@ -0,0 +1,79 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_MT6735_TOPCKGEN_H
|
||||
#define _DT_BINDINGS_CLK_MT6735_TOPCKGEN_H
|
||||
|
||||
#define CLK_TOP_AD_SYS_26M_CK 0
|
||||
#define CLK_TOP_CLKPH_MCK_O 1
|
||||
#define CLK_TOP_DMPLL 2
|
||||
#define CLK_TOP_DPI_CK 3
|
||||
#define CLK_TOP_WHPLL_AUDIO_CK 4
|
||||
|
||||
#define CLK_TOP_SYSPLL_D2 5
|
||||
#define CLK_TOP_SYSPLL_D3 6
|
||||
#define CLK_TOP_SYSPLL_D5 7
|
||||
#define CLK_TOP_SYSPLL1_D2 8
|
||||
#define CLK_TOP_SYSPLL1_D4 9
|
||||
#define CLK_TOP_SYSPLL1_D8 10
|
||||
#define CLK_TOP_SYSPLL1_D16 11
|
||||
#define CLK_TOP_SYSPLL2_D2 12
|
||||
#define CLK_TOP_SYSPLL2_D4 13
|
||||
#define CLK_TOP_SYSPLL3_D2 14
|
||||
#define CLK_TOP_SYSPLL3_D4 15
|
||||
#define CLK_TOP_SYSPLL4_D2 16
|
||||
#define CLK_TOP_SYSPLL4_D4 17
|
||||
#define CLK_TOP_UNIVPLL_D2 18
|
||||
#define CLK_TOP_UNIVPLL_D3 19
|
||||
#define CLK_TOP_UNIVPLL_D5 20
|
||||
#define CLK_TOP_UNIVPLL_D26 21
|
||||
#define CLK_TOP_UNIVPLL1_D2 22
|
||||
#define CLK_TOP_UNIVPLL1_D4 23
|
||||
#define CLK_TOP_UNIVPLL1_D8 24
|
||||
#define CLK_TOP_UNIVPLL2_D2 25
|
||||
#define CLK_TOP_UNIVPLL2_D4 26
|
||||
#define CLK_TOP_UNIVPLL2_D8 27
|
||||
#define CLK_TOP_UNIVPLL3_D2 28
|
||||
#define CLK_TOP_UNIVPLL3_D4 29
|
||||
#define CLK_TOP_MSDCPLL_D2 30
|
||||
#define CLK_TOP_MSDCPLL_D4 31
|
||||
#define CLK_TOP_MSDCPLL_D8 32
|
||||
#define CLK_TOP_MSDCPLL_D16 33
|
||||
#define CLK_TOP_VENCPLL_D3 34
|
||||
#define CLK_TOP_TVDPLL_D2 35
|
||||
#define CLK_TOP_TVDPLL_D4 36
|
||||
#define CLK_TOP_DMPLL_D2 37
|
||||
#define CLK_TOP_DMPLL_D4 38
|
||||
#define CLK_TOP_DMPLL_D8 39
|
||||
#define CLK_TOP_AD_SYS_26M_D2 40
|
||||
|
||||
#define CLK_TOP_AXI_SEL 41
|
||||
#define CLK_TOP_MEM_SEL 42
|
||||
#define CLK_TOP_DDRPHY_SEL 43
|
||||
#define CLK_TOP_MM_SEL 44
|
||||
#define CLK_TOP_PWM_SEL 45
|
||||
#define CLK_TOP_VDEC_SEL 46
|
||||
#define CLK_TOP_MFG_SEL 47
|
||||
#define CLK_TOP_CAMTG_SEL 48
|
||||
#define CLK_TOP_UART_SEL 49
|
||||
#define CLK_TOP_SPI_SEL 50
|
||||
#define CLK_TOP_USB20_SEL 51
|
||||
#define CLK_TOP_MSDC50_0_SEL 52
|
||||
#define CLK_TOP_MSDC30_0_SEL 53
|
||||
#define CLK_TOP_MSDC30_1_SEL 54
|
||||
#define CLK_TOP_MSDC30_2_SEL 55
|
||||
#define CLK_TOP_MSDC30_3_SEL 56
|
||||
#define CLK_TOP_AUDIO_SEL 57
|
||||
#define CLK_TOP_AUDINTBUS_SEL 58
|
||||
#define CLK_TOP_PMICSPI_SEL 59
|
||||
#define CLK_TOP_SCP_SEL 60
|
||||
#define CLK_TOP_ATB_SEL 61
|
||||
#define CLK_TOP_DPI0_SEL 62
|
||||
#define CLK_TOP_SCAM_SEL 63
|
||||
#define CLK_TOP_MFG13M_SEL 64
|
||||
#define CLK_TOP_AUD1_SEL 65
|
||||
#define CLK_TOP_AUD2_SEL 66
|
||||
#define CLK_TOP_IRDA_SEL 67
|
||||
#define CLK_TOP_IRTX_SEL 68
|
||||
#define CLK_TOP_DISPPWM_SEL 69
|
||||
|
||||
#endif
|
9
include/dt-bindings/clock/mediatek,mt6735-vdecsys.h
Normal file
9
include/dt-bindings/clock/mediatek,mt6735-vdecsys.h
Normal file
@ -0,0 +1,9 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_MT6735_VDECSYS_H
|
||||
#define _DT_BINDINGS_CLK_MT6735_VDECSYS_H
|
||||
|
||||
#define CLK_VDEC_VDEC 0
|
||||
#define CLK_VDEC_SMI_LARB1 1
|
||||
|
||||
#endif /* _DT_BINDINGS_CLK_MT6735_VDECSYS_H */
|
11
include/dt-bindings/clock/mediatek,mt6735-vencsys.h
Normal file
11
include/dt-bindings/clock/mediatek,mt6735-vencsys.h
Normal file
@ -0,0 +1,11 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_MT6735_VENCSYS_H
|
||||
#define _DT_BINDINGS_CLK_MT6735_VENCSYS_H
|
||||
|
||||
#define CLK_VENC_SMI_LARB3 0
|
||||
#define CLK_VENC_VENC 1
|
||||
#define CLK_VENC_JPGENC 2
|
||||
#define CLK_VENC_JPGDEC 3
|
||||
|
||||
#endif /* _DT_BINDINGS_CLK_MT6735_VENCSYS_H */
|
27
include/dt-bindings/reset/mediatek,mt6735-infracfg.h
Normal file
27
include/dt-bindings/reset/mediatek,mt6735-infracfg.h
Normal file
@ -0,0 +1,27 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
|
||||
#ifndef _DT_BINDINGS_RESET_MT6735_INFRACFG_H
|
||||
#define _DT_BINDINGS_RESET_MT6735_INFRACFG_H
|
||||
|
||||
#define MT6735_INFRA_RST0_EMI_REG 0
|
||||
#define MT6735_INFRA_RST0_DRAMC0_AO 1
|
||||
#define MT6735_INFRA_RST0_AP_CIRQ_EINT 2
|
||||
#define MT6735_INFRA_RST0_APXGPT 3
|
||||
#define MT6735_INFRA_RST0_SCPSYS 4
|
||||
#define MT6735_INFRA_RST0_KP 5
|
||||
#define MT6735_INFRA_RST0_PMIC_WRAP 6
|
||||
#define MT6735_INFRA_RST0_CLDMA_AO_TOP 7
|
||||
#define MT6735_INFRA_RST0_USBSIF_TOP 8
|
||||
#define MT6735_INFRA_RST0_EMI 9
|
||||
#define MT6735_INFRA_RST0_CCIF 10
|
||||
#define MT6735_INFRA_RST0_DRAMC0 11
|
||||
#define MT6735_INFRA_RST0_EMI_AO_REG 12
|
||||
#define MT6735_INFRA_RST0_CCIF_AO 13
|
||||
#define MT6735_INFRA_RST0_TRNG 14
|
||||
#define MT6735_INFRA_RST0_SYS_CIRQ 15
|
||||
#define MT6735_INFRA_RST0_GCE 16
|
||||
#define MT6735_INFRA_RST0_M4U 17
|
||||
#define MT6735_INFRA_RST0_CCIF1 18
|
||||
#define MT6735_INFRA_RST0_CLDMA_TOP_PD 19
|
||||
|
||||
#endif
|
9
include/dt-bindings/reset/mediatek,mt6735-mfgcfg.h
Normal file
9
include/dt-bindings/reset/mediatek,mt6735-mfgcfg.h
Normal file
@ -0,0 +1,9 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
|
||||
#ifndef _DT_BINDINGS_RESET_MT6735_MFGCFG_H
|
||||
#define _DT_BINDINGS_RESET_MT6735_MFGCFG_H
|
||||
|
||||
#define MT6735_MFG_RST0_AXI 0
|
||||
#define MT6735_MFG_RST0_G3D 1
|
||||
|
||||
#endif /* _DT_BINDINGS_RESET_MT6735_MFGCFG_H */
|
31
include/dt-bindings/reset/mediatek,mt6735-pericfg.h
Normal file
31
include/dt-bindings/reset/mediatek,mt6735-pericfg.h
Normal file
@ -0,0 +1,31 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
|
||||
#ifndef _DT_BINDINGS_RESET_MT6735_PERICFG_H
|
||||
#define _DT_BINDINGS_RESET_MT6735_PERICFG_H
|
||||
|
||||
#define MT6735_PERI_RST0_UART0 0
|
||||
#define MT6735_PERI_RST0_UART1 1
|
||||
#define MT6735_PERI_RST0_UART2 2
|
||||
#define MT6735_PERI_RST0_UART3 3
|
||||
#define MT6735_PERI_RST0_UART4 4
|
||||
#define MT6735_PERI_RST0_BTIF 5
|
||||
#define MT6735_PERI_RST0_DISP_PWM_PERI 6
|
||||
#define MT6735_PERI_RST0_PWM 7
|
||||
#define MT6735_PERI_RST0_AUXADC 8
|
||||
#define MT6735_PERI_RST0_DMA 9
|
||||
#define MT6735_PERI_RST0_IRDA 10
|
||||
#define MT6735_PERI_RST0_IRTX 11
|
||||
#define MT6735_PERI_RST0_THERM 12
|
||||
#define MT6735_PERI_RST0_MSDC2 13
|
||||
#define MT6735_PERI_RST0_MSDC3 14
|
||||
#define MT6735_PERI_RST0_MSDC0 15
|
||||
#define MT6735_PERI_RST0_MSDC1 16
|
||||
#define MT6735_PERI_RST0_I2C0 17
|
||||
#define MT6735_PERI_RST0_I2C1 18
|
||||
#define MT6735_PERI_RST0_I2C2 19
|
||||
#define MT6735_PERI_RST0_I2C3 20
|
||||
#define MT6735_PERI_RST0_USB 21
|
||||
|
||||
#define MT6735_PERI_RST1_SPI0 22
|
||||
|
||||
#endif
|
9
include/dt-bindings/reset/mediatek,mt6735-vdecsys.h
Normal file
9
include/dt-bindings/reset/mediatek,mt6735-vdecsys.h
Normal file
@ -0,0 +1,9 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
|
||||
#ifndef _DT_BINDINGS_RESET_MT6735_VDECSYS_H
|
||||
#define _DT_BINDINGS_RESET_MT6735_VDECSYS_H
|
||||
|
||||
#define MT6735_VDEC_RST0_VDEC 0
|
||||
#define MT6735_VDEC_RST1_SMI_LARB1 1
|
||||
|
||||
#endif /* _DT_BINDINGS_RESET_MT6735_VDECSYS_H */
|
@ -25,4 +25,8 @@ int clk_hw_register_kunit(struct kunit *test, struct device *dev, struct clk_hw
|
||||
int of_clk_hw_register_kunit(struct kunit *test, struct device_node *node,
|
||||
struct clk_hw *hw);
|
||||
|
||||
int of_clk_add_hw_provider_kunit(struct kunit *test, struct device_node *np,
|
||||
struct clk_hw *(*get)(struct of_phandle_args *clkspec, void *data),
|
||||
void *data);
|
||||
|
||||
#endif
|
||||
|
@ -62,6 +62,13 @@ static inline int __of_overlay_apply_kunit(struct kunit *test,
|
||||
&unused);
|
||||
}
|
||||
|
||||
#define of_overlay_begin(overlay_name) __dtbo_##overlay_name##_begin
|
||||
#define of_overlay_end(overlay_name) __dtbo_##overlay_name##_end
|
||||
|
||||
#define OF_OVERLAY_DECLARE(overlay_name) \
|
||||
extern uint8_t of_overlay_begin(overlay_name)[]; \
|
||||
extern uint8_t of_overlay_end(overlay_name)[] \
|
||||
|
||||
/**
|
||||
* of_overlay_apply_kunit() - Test managed of_overlay_fdt_apply() for built-in overlays
|
||||
* @test: test context
|
||||
@ -104,12 +111,11 @@ static inline int __of_overlay_apply_kunit(struct kunit *test,
|
||||
*/
|
||||
#define of_overlay_apply_kunit(test, overlay_name) \
|
||||
({ \
|
||||
extern uint8_t __dtbo_##overlay_name##_begin[]; \
|
||||
extern uint8_t __dtbo_##overlay_name##_end[]; \
|
||||
OF_OVERLAY_DECLARE(overlay_name); \
|
||||
\
|
||||
__of_overlay_apply_kunit((test), \
|
||||
__dtbo_##overlay_name##_begin, \
|
||||
__dtbo_##overlay_name##_end); \
|
||||
of_overlay_begin(overlay_name), \
|
||||
of_overlay_end(overlay_name)); \
|
||||
})
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user