Commit 6f7478e3 authored by Stephen Boyd's avatar Stephen Boyd

Merge branches 'clk-mediatek', 'clk-sunplus', 'clk-loongson' and 'clk-socfpga' into clk-next

 - Frequency Hopping (FHCTL) on MediaTek MT6795, MT8173, MT8192 and
   MT8195 SoCs
 - Converted most Mediatek clock drivers to struct platform_driver
 - MediaTek clock drivers can be built as modules
 - Mediatek MT8188 SoC clk drivers
 - Clock driver for Sunplus SP7021 SoC
 - Reimplement Loongson-1 clk driver with DT support
 - Clk driver support for Loongson-2 SoCs
 - Migrate socfpga clk driver to of_clk_add_hw_provider()

* clk-mediatek: (84 commits)
  clk: mediatek: fhctl: Mark local variables static
  clk: mediatek: Use right match table, include mod_devicetable
  clk: mediatek: Add MT8188 adsp clock support
  clk: mediatek: Add MT8188 imp i2c wrapper clock support
  clk: mediatek: Add MT8188 wpesys clock support
  clk: mediatek: Add MT8188 vppsys1 clock support
  clk: mediatek: Add MT8188 vppsys0 clock support
  clk: mediatek: Add MT8188 vencsys clock support
  clk: mediatek: Add MT8188 vdosys1 clock support
  clk: mediatek: Add MT8188 vdosys0 clock support
  clk: mediatek: Add MT8188 vdecsys clock support
  clk: mediatek: Add MT8188 mfgcfg clock support
  clk: mediatek: Add MT8188 ipesys clock support
  clk: mediatek: Add MT8188 imgsys clock support
  clk: mediatek: Add MT8188 ccusys clock support
  clk: mediatek: Add MT8188 camsys clock support
  clk: mediatek: Add MT8188 infrastructure clock support
  clk: mediatek: Add MT8188 peripheral clock support
  clk: mediatek: Add MT8188 topckgen clock support
  clk: mediatek: Add MT8188 apmixedsys clock support
  ...

* clk-sunplus:
  clk: Add Sunplus SP7021 clock driver

* clk-loongson:
  clk: clk-loongson2: add clock controller driver support
  dt-bindings: clock: add loongson-2 boot clock index
  MAINTAINERS: remove obsolete file entry in MIPS/LOONGSON1 ARCHITECTURE
  MIPS: loongson32: Update the clock initialization
  clk: loongson1: Re-implement the clock driver
  clk: loongson1: Remove the outdated driver
  dt-bindings: clock: Add Loongson-1 clock

* clk-socfpga:
  clk: socfpga: arria10: use of_clk_add_hw_provider and improve error handling
  clk: socfpga: use of_clk_add_hw_provider and improve error handling
  clk: socfpga: arria10: use of_clk_add_hw_provider and improve error handling
  clk: socfpga: use of_clk_add_hw_provider and improve error handling
  clk: socfpga: arria10: use of_clk_add_hw_provider and improve error handling
  clk: socfpga: use of_clk_add_hw_provider and improve error handling
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/loongson,ls1x-clk.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Loongson-1 Clock Controller
maintainers:
- Keguang Zhang <keguang.zhang@gmail.com>
properties:
compatible:
enum:
- loongson,ls1b-clk
- loongson,ls1c-clk
reg:
maxItems: 1
clocks:
maxItems: 1
"#clock-cells":
const: 1
required:
- compatible
- reg
- clocks
- "#clock-cells"
additionalProperties: false
examples:
- |
clkc: clock-controller@1fe78030 {
compatible = "loongson,ls1b-clk";
reg = <0x1fe78030 0x8>;
clocks = <&xtal>;
#clock-cells = <1>;
};
...
......@@ -16,7 +16,12 @@ description: |
properties:
compatible:
const: mediatek,mt8186-fhctl
enum:
- mediatek,mt6795-fhctl
- mediatek,mt8173-fhctl
- mediatek,mt8186-fhctl
- mediatek,mt8192-fhctl
- mediatek,mt8195-fhctl
reg:
maxItems: 1
......
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/mediatek,mt8188-clock.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: MediaTek Functional Clock Controller for MT8188
maintainers:
- Garmin Chang <garmin.chang@mediatek.com>
description: |
The clock architecture in MediaTek like below
PLLs -->
dividers -->
muxes
-->
clock gate
The devices provide clock gate control in different IP blocks.
properties:
compatible:
enum:
- mediatek,mt8188-adsp-audio26m
- mediatek,mt8188-camsys
- mediatek,mt8188-camsys-rawa
- mediatek,mt8188-camsys-rawb
- mediatek,mt8188-camsys-yuva
- mediatek,mt8188-camsys-yuvb
- mediatek,mt8188-ccusys
- mediatek,mt8188-imgsys
- mediatek,mt8188-imgsys-wpe1
- mediatek,mt8188-imgsys-wpe2
- mediatek,mt8188-imgsys-wpe3
- mediatek,mt8188-imgsys1-dip-nr
- mediatek,mt8188-imgsys1-dip-top
- mediatek,mt8188-imp-iic-wrap-c
- mediatek,mt8188-imp-iic-wrap-en
- mediatek,mt8188-imp-iic-wrap-w
- mediatek,mt8188-ipesys
- mediatek,mt8188-mfgcfg
- mediatek,mt8188-vdecsys
- mediatek,mt8188-vdecsys-soc
- mediatek,mt8188-vencsys
- mediatek,mt8188-vppsys0
- mediatek,mt8188-vppsys1
- mediatek,mt8188-wpesys
- mediatek,mt8188-wpesys-vpp0
reg:
maxItems: 1
'#clock-cells':
const: 1
required:
- compatible
- reg
- '#clock-cells'
additionalProperties: false
examples:
- |
clock-controller@11283000 {
compatible = "mediatek,mt8188-imp-iic-wrap-c";
reg = <0x11283000 0x1000>;
#clock-cells = <1>;
};
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/mediatek,mt8188-sys-clock.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: MediaTek System Clock Controller for MT8188
maintainers:
- Garmin Chang <garmin.chang@mediatek.com>
description: |
The clock architecture in MediaTek like below
PLLs -->
dividers -->
muxes
-->
clock gate
The apmixedsys provides most of PLLs which generated from SoC 26m.
The topckgen provides dividers and muxes which provide the clock source to other IP blocks.
The infracfg_ao provides clock gate in peripheral and infrastructure IP blocks.
The mcusys provides mux control to select the clock source in AP MCU.
The device nodes also provide the system control capacity for configuration.
properties:
compatible:
items:
- enum:
- mediatek,mt8188-apmixedsys
- mediatek,mt8188-infracfg-ao
- mediatek,mt8188-pericfg-ao
- mediatek,mt8188-topckgen
- const: syscon
reg:
maxItems: 1
'#clock-cells':
const: 1
required:
- compatible
- reg
- '#clock-cells'
additionalProperties: false
examples:
- |
clock-controller@10000000 {
compatible = "mediatek,mt8188-topckgen", "syscon";
reg = <0x10000000 0x1000>;
#clock-cells = <1>;
};
......@@ -2849,6 +2849,7 @@ F: Documentation/devicetree/bindings/reset/sunplus,reset.yaml
F: arch/arm/boot/dts/sunplus-sp7021*.dts*
F: arch/arm/configs/sp7021_*defconfig
F: arch/arm/mach-sunplus/
F: drivers/clk/clk-sp7021.c
F: drivers/irqchip/irq-sp7021-intc.c
F: drivers/reset/reset-sunplus.c
F: include/dt-bindings/clock/sunplus,sp7021-clkc.h
......@@ -12121,6 +12122,7 @@ M: Yinbo Zhu <zhuyinbo@loongson.cn>
L: linux-clk@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/clock/loongson,ls2k-clk.yaml
F: drivers/clk/clk-loongson2.c
F: include/dt-bindings/clock/loongson,ls2k-clk.h
LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
......@@ -14000,7 +14002,6 @@ L: linux-mips@vger.kernel.org
S: Maintained
F: arch/mips/include/asm/mach-loongson32/
F: arch/mips/loongson32/
F: drivers/*/*/*loongson1*
F: drivers/*/*loongson1*
MIPS/LOONGSON2EF ARCHITECTURE
......
......@@ -20,7 +20,6 @@ extern struct platform_device ls1x_gpio1_pdev;
extern struct platform_device ls1x_rtc_pdev;
extern struct platform_device ls1x_wdt_pdev;
void __init ls1x_clk_init(void);
void __init ls1x_rtc_set_extclk(struct platform_device *pdev);
void __init ls1x_serial_set_uartclk(struct platform_device *pdev);
......
......@@ -4,6 +4,7 @@
*/
#include <linux/clk.h>
#include <linux/of_clk.h>
#include <linux/interrupt.h>
#include <linux/sizes.h>
#include <asm/time.h>
......@@ -211,7 +212,7 @@ void __init plat_time_init(void)
struct clk *clk = NULL;
/* initialize LS1X clocks */
ls1x_clk_init();
of_clk_init(NULL);
#ifdef CONFIG_CEVT_CSRC_LS1X
/* setup LS1X PWM timer */
......
......@@ -325,6 +325,15 @@ config COMMON_CLK_LOCHNAGAR
This driver supports the clocking features of the Cirrus Logic
Lochnagar audio development board.
config COMMON_CLK_LOONGSON2
bool "Clock driver for Loongson-2 SoC"
depends on LOONGARCH || COMPILE_TEST
help
This driver provides support for clock controller on Loongson-2 SoC.
The clock controller can generates and supplies clock to various
peripherals within the SoC.
Say Y here to support Loongson-2 SoC clock driver.
config COMMON_CLK_NXP
def_bool COMMON_CLK && (ARCH_LPC18XX || ARCH_LPC32XX)
select REGMAP_MMIO if ARCH_LPC32XX
......@@ -445,6 +454,16 @@ config COMMON_CLK_K210
help
Support for the Canaan Kendryte K210 RISC-V SoC clocks.
config COMMON_CLK_SP7021
tristate "Clock driver for Sunplus SP7021 SoC"
depends on SOC_SP7021 || COMPILE_TEST
default SOC_SP7021
help
This driver supports the Sunplus SP7021 SoC clocks.
It implements SP7021 PLLs/gate.
Not all features of the PLL are currently supported
by the driver.
source "drivers/clk/actions/Kconfig"
source "drivers/clk/analogbits/Kconfig"
source "drivers/clk/baikal-t1/Kconfig"
......
......@@ -43,6 +43,8 @@ obj-$(CONFIG_COMMON_CLK_K210) += clk-k210.o
obj-$(CONFIG_LMK04832) += clk-lmk04832.o
obj-$(CONFIG_COMMON_CLK_LAN966X) += clk-lan966x.o
obj-$(CONFIG_COMMON_CLK_LOCHNAGAR) += clk-lochnagar.o
obj-$(CONFIG_MACH_LOONGSON32) += clk-loongson1.o
obj-$(CONFIG_COMMON_CLK_LOONGSON2) += clk-loongson2.o
obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
obj-$(CONFIG_COMMON_CLK_MAX9485) += clk-max9485.o
obj-$(CONFIG_ARCH_MILBEAUT_M10V) += clk-milbeaut.o
......@@ -65,6 +67,7 @@ obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o
obj-$(CONFIG_COMMON_CLK_SI514) += clk-si514.o
obj-$(CONFIG_COMMON_CLK_SI544) += clk-si544.o
obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o
obj-$(CONFIG_COMMON_CLK_SP7021) += clk-sp7021.o
obj-$(CONFIG_COMMON_CLK_STM32F) += clk-stm32f4.o
obj-$(CONFIG_COMMON_CLK_STM32H7) += clk-stm32h7.o
obj-$(CONFIG_COMMON_CLK_STM32MP157) += clk-stm32mp1.o
......@@ -94,7 +97,6 @@ obj-y += imx/
obj-y += ingenic/
obj-$(CONFIG_ARCH_K3) += keystone/
obj-$(CONFIG_ARCH_KEYSTONE) += keystone/
obj-$(CONFIG_MACH_LOONGSON32) += loongson1/
obj-y += mediatek/
obj-$(CONFIG_ARCH_MESON) += meson/
obj-y += microchip/
......
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Clock driver for Loongson-1 SoC
*
* Copyright (C) 2012-2023 Keguang Zhang <keguang.zhang@gmail.com>
*/
#include <linux/bits.h>
#include <linux/clk-provider.h>
#include <linux/container_of.h>
#include <linux/io.h>
#include <linux/of_address.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/printk.h>
#include <dt-bindings/clock/loongson,ls1x-clk.h>
/* Loongson 1 Clock Register Definitions */
#define CLK_PLL_FREQ 0x0
#define CLK_PLL_DIV 0x4
static DEFINE_SPINLOCK(ls1x_clk_div_lock);
struct ls1x_clk_pll_data {
u32 fixed;
u8 shift;
u8 int_shift;
u8 int_width;
u8 frac_shift;
u8 frac_width;
};
struct ls1x_clk_div_data {
u8 shift;
u8 width;
unsigned long flags;
const struct clk_div_table *table;
u8 bypass_shift;
u8 bypass_inv;
spinlock_t *lock; /* protect access to DIV registers */
};
struct ls1x_clk {
void __iomem *reg;
unsigned int offset;
struct clk_hw hw;
const void *data;
};
#define to_ls1x_clk(_hw) container_of(_hw, struct ls1x_clk, hw)
static inline unsigned long ls1x_pll_rate_part(unsigned int val,
unsigned int shift,
unsigned int width)
{
return (val & GENMASK(shift + width, shift)) >> shift;
}
static unsigned long ls1x_pll_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct ls1x_clk *ls1x_clk = to_ls1x_clk(hw);
const struct ls1x_clk_pll_data *d = ls1x_clk->data;
u32 val, rate;
val = readl(ls1x_clk->reg);
rate = d->fixed;
rate += ls1x_pll_rate_part(val, d->int_shift, d->int_width);
if (d->frac_width)
rate += ls1x_pll_rate_part(val, d->frac_shift, d->frac_width);
rate *= parent_rate;
rate >>= d->shift;
return rate;
}
static const struct clk_ops ls1x_pll_clk_ops = {
.recalc_rate = ls1x_pll_recalc_rate,
};
static unsigned long ls1x_divider_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct ls1x_clk *ls1x_clk = to_ls1x_clk(hw);
const struct ls1x_clk_div_data *d = ls1x_clk->data;
unsigned int val;
val = readl(ls1x_clk->reg) >> d->shift;
val &= clk_div_mask(d->width);
return divider_recalc_rate(hw, parent_rate, val, d->table,
d->flags, d->width);
}
static long ls1x_divider_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
struct ls1x_clk *ls1x_clk = to_ls1x_clk(hw);
const struct ls1x_clk_div_data *d = ls1x_clk->data;
return divider_round_rate(hw, rate, prate, d->table,
d->width, d->flags);
}
static int ls1x_divider_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct ls1x_clk *ls1x_clk = to_ls1x_clk(hw);
const struct ls1x_clk_div_data *d = ls1x_clk->data;
int val, div_val;
unsigned long flags = 0;
div_val = divider_get_val(rate, parent_rate, d->table,
d->width, d->flags);
if (div_val < 0)
return div_val;
spin_lock_irqsave(d->lock, flags);
/* Bypass the clock */
val = readl(ls1x_clk->reg);
if (d->bypass_inv)
val &= ~BIT(d->bypass_shift);
else
val |= BIT(d->bypass_shift);
writel(val, ls1x_clk->reg);
val = readl(ls1x_clk->reg);
val &= ~(clk_div_mask(d->width) << d->shift);
val |= (u32)div_val << d->shift;
writel(val, ls1x_clk->reg);
/* Restore the clock */
val = readl(ls1x_clk->reg);
if (d->bypass_inv)
val |= BIT(d->bypass_shift);
else
val &= ~BIT(d->bypass_shift);
writel(val, ls1x_clk->reg);
spin_unlock_irqrestore(d->lock, flags);
return 0;
}
static const struct clk_ops ls1x_clk_divider_ops = {
.recalc_rate = ls1x_divider_recalc_rate,
.round_rate = ls1x_divider_round_rate,
.set_rate = ls1x_divider_set_rate,
};
#define LS1X_CLK_PLL(_name, _offset, _fixed, _shift, \
f_shift, f_width, i_shift, i_width) \
struct ls1x_clk _name = { \
.offset = (_offset), \
.data = &(const struct ls1x_clk_pll_data) { \
.fixed = (_fixed), \
.shift = (_shift), \
.int_shift = (i_shift), \
.int_width = (i_width), \
.frac_shift = (f_shift), \
.frac_width = (f_width), \
}, \
.hw.init = &(const struct clk_init_data) { \
.name = #_name, \
.ops = &ls1x_pll_clk_ops, \
.parent_data = &(const struct clk_parent_data) { \
.fw_name = "xtal", \
.name = "xtal", \
.index = -1, \
}, \
.num_parents = 1, \
}, \
}
#define LS1X_CLK_DIV(_name, _pname, _offset, _shift, _width, \
_table, _bypass_shift, _bypass_inv, _flags) \
struct ls1x_clk _name = { \
.offset = (_offset), \
.data = &(const struct ls1x_clk_div_data){ \
.shift = (_shift), \
.width = (_width), \
.table = (_table), \
.flags = (_flags), \
.bypass_shift = (_bypass_shift), \
.bypass_inv = (_bypass_inv), \
.lock = &ls1x_clk_div_lock, \
}, \
.hw.init = &(const struct clk_init_data) { \
.name = #_name, \
.ops = &ls1x_clk_divider_ops, \
.parent_hws = (const struct clk_hw *[]) { _pname }, \
.num_parents = 1, \
.flags = CLK_GET_RATE_NOCACHE, \
}, \
}
static LS1X_CLK_PLL(ls1b_clk_pll, CLK_PLL_FREQ, 12, 1, 0, 5, 0, 0);
static LS1X_CLK_DIV(ls1b_clk_cpu, &ls1b_clk_pll.hw, CLK_PLL_DIV,
20, 4, NULL, 8, 0,
CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ROUND_CLOSEST);
static LS1X_CLK_DIV(ls1b_clk_dc, &ls1b_clk_pll.hw, CLK_PLL_DIV,
26, 4, NULL, 12, 0, CLK_DIVIDER_ONE_BASED);
static LS1X_CLK_DIV(ls1b_clk_ahb, &ls1b_clk_pll.hw, CLK_PLL_DIV,
14, 4, NULL, 10, 0, CLK_DIVIDER_ONE_BASED);
static CLK_FIXED_FACTOR(ls1b_clk_apb, "ls1b_clk_apb", "ls1b_clk_ahb", 2, 1,
CLK_SET_RATE_PARENT);
static struct clk_hw_onecell_data ls1b_clk_hw_data = {
.hws = {
[LS1X_CLKID_PLL] = &ls1b_clk_pll.hw,
[LS1X_CLKID_CPU] = &ls1b_clk_cpu.hw,
[LS1X_CLKID_DC] = &ls1b_clk_dc.hw,
[LS1X_CLKID_AHB] = &ls1b_clk_ahb.hw,
[LS1X_CLKID_APB] = &ls1b_clk_apb.hw,
},
.num = CLK_NR_CLKS,
};
static const struct clk_div_table ls1c_ahb_div_table[] = {
[0] = { .val = 0, .div = 2 },
[1] = { .val = 1, .div = 4 },
[2] = { .val = 2, .div = 3 },
[3] = { .val = 3, .div = 3 },
[4] = { /* sentinel */ }
};
static LS1X_CLK_PLL(ls1c_clk_pll, CLK_PLL_FREQ, 0, 2, 8, 8, 16, 8);
static LS1X_CLK_DIV(ls1c_clk_cpu, &ls1c_clk_pll.hw, CLK_PLL_DIV,
8, 7, NULL, 0, 1,
CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ROUND_CLOSEST);
static LS1X_CLK_DIV(ls1c_clk_dc, &ls1c_clk_pll.hw, CLK_PLL_DIV,
24, 7, NULL, 4, 1, CLK_DIVIDER_ONE_BASED);
static LS1X_CLK_DIV(ls1c_clk_ahb, &ls1c_clk_cpu.hw, CLK_PLL_FREQ,
0, 2, ls1c_ahb_div_table, 0, 0, CLK_DIVIDER_ALLOW_ZERO);
static CLK_FIXED_FACTOR(ls1c_clk_apb, "ls1c_clk_apb", "ls1c_clk_ahb", 1, 1,
CLK_SET_RATE_PARENT);
static struct clk_hw_onecell_data ls1c_clk_hw_data = {
.hws = {
[LS1X_CLKID_PLL] = &ls1c_clk_pll.hw,
[LS1X_CLKID_CPU] = &ls1c_clk_cpu.hw,
[LS1X_CLKID_DC] = &ls1c_clk_dc.hw,
[LS1X_CLKID_AHB] = &ls1c_clk_ahb.hw,
[LS1X_CLKID_APB] = &ls1c_clk_apb.hw,
},
.num = CLK_NR_CLKS,
};
static void __init ls1x_clk_init(struct device_node *np,
struct clk_hw_onecell_data *hw_data)
{
struct ls1x_clk *ls1x_clk;
void __iomem *reg;
int i, ret;
reg = of_iomap(np, 0);
if (!reg) {
pr_err("Unable to map base for %pOF\n", np);
return;
}
for (i = 0; i < hw_data->num; i++) {
/* array might be sparse */
if (!hw_data->hws[i])
continue;
if (i != LS1X_CLKID_APB) {
ls1x_clk = to_ls1x_clk(hw_data->hws[i]);
ls1x_clk->reg = reg + ls1x_clk->offset;
}
ret = of_clk_hw_register(np, hw_data->hws[i]);
if (ret)
goto err;
}
ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, hw_data);
if (!ret)
return;
err:
pr_err("Failed to register %pOF\n", np);
while (--i >= 0)
clk_hw_unregister(hw_data->hws[i]);
iounmap(reg);
}
static void __init ls1b_clk_init(struct device_node *np)
{
return ls1x_clk_init(np, &ls1b_clk_hw_data);
}
static void __init ls1c_clk_init(struct device_node *np)
{
return ls1x_clk_init(np, &ls1c_clk_hw_data);
}
CLK_OF_DECLARE(ls1b_clk, "loongson,ls1b-clk", ls1b_clk_init);
CLK_OF_DECLARE(ls1c_clk, "loongson,ls1c-clk", ls1c_clk_init);
// SPDX-License-Identifier: GPL-2.0+
/*
* Author: Yinbo Zhu <zhuyinbo@loongson.cn>
* Copyright (C) 2022-2023 Loongson Technology Corporation Limited
*/
#include <linux/err.h>
#include <linux/init.h>
#include <linux/clk-provider.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include <dt-bindings/clock/loongson,ls2k-clk.h>
#define LOONGSON2_PLL_MULT_SHIFT 32
#define LOONGSON2_PLL_MULT_WIDTH 10
#define LOONGSON2_PLL_DIV_SHIFT 26
#define LOONGSON2_PLL_DIV_WIDTH 6
#define LOONGSON2_APB_FREQSCALE_SHIFT 20
#define LOONGSON2_APB_FREQSCALE_WIDTH 3
#define LOONGSON2_USB_FREQSCALE_SHIFT 16
#define LOONGSON2_USB_FREQSCALE_WIDTH 3
#define LOONGSON2_SATA_FREQSCALE_SHIFT 12
#define LOONGSON2_SATA_FREQSCALE_WIDTH 3
#define LOONGSON2_BOOT_FREQSCALE_SHIFT 8
#define LOONGSON2_BOOT_FREQSCALE_WIDTH 3
static void __iomem *loongson2_pll_base;
static const struct clk_parent_data pdata[] = {
{ .fw_name = "ref_100m",},
};
static struct clk_hw *loongson2_clk_register(struct device *dev,
const char *name,
const char *parent_name,
const struct clk_ops *ops,
unsigned long flags)
{
int ret;
struct clk_hw *hw;
struct clk_init_data init;
hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
if (!hw)
return ERR_PTR(-ENOMEM);
init.name = name;
init.ops = ops;
init.flags = flags;
init.num_parents = 1;
if (!parent_name)
init.parent_data = pdata;
else
init.parent_names = &parent_name;
hw->init = &init;
ret = devm_clk_hw_register(dev, hw);
if (ret)
hw = ERR_PTR(ret);
return hw;
}
static unsigned long loongson2_calc_pll_rate(int offset, unsigned long rate)
{
u64 val;
u32 mult, div;
val = readq(loongson2_pll_base + offset);
mult = (val >> LOONGSON2_PLL_MULT_SHIFT) &
clk_div_mask(LOONGSON2_PLL_MULT_WIDTH);
div = (val >> LOONGSON2_PLL_DIV_SHIFT) &
clk_div_mask(LOONGSON2_PLL_DIV_WIDTH);
return div_u64((u64)rate * mult, div);
}
static unsigned long loongson2_node_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
return loongson2_calc_pll_rate(0x0, parent_rate);
}
static const struct clk_ops loongson2_node_clk_ops = {
.recalc_rate = loongson2_node_recalc_rate,
};
static unsigned long loongson2_ddr_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
return loongson2_calc_pll_rate(0x10, parent_rate);
}
static const struct clk_ops loongson2_ddr_clk_ops = {
.recalc_rate = loongson2_ddr_recalc_rate,
};
static unsigned long loongson2_dc_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
return loongson2_calc_pll_rate(0x20, parent_rate);
}
static const struct clk_ops loongson2_dc_clk_ops = {
.recalc_rate = loongson2_dc_recalc_rate,
};
static unsigned long loongson2_pix0_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
return loongson2_calc_pll_rate(0x30, parent_rate);
}
static const struct clk_ops loongson2_pix0_clk_ops = {
.recalc_rate = loongson2_pix0_recalc_rate,
};
static unsigned long loongson2_pix1_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
return loongson2_calc_pll_rate(0x40, parent_rate);
}
static const struct clk_ops loongson2_pix1_clk_ops = {
.recalc_rate = loongson2_pix1_recalc_rate,
};
static unsigned long loongson2_calc_rate(unsigned long rate,
int shift, int width)
{
u64 val;
u32 mult;
val = readq(loongson2_pll_base + 0x50);
mult = (val >> shift) & clk_div_mask(width);
return div_u64((u64)rate * (mult + 1), 8);
}
static unsigned long loongson2_boot_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
return loongson2_calc_rate(parent_rate,
LOONGSON2_BOOT_FREQSCALE_SHIFT,
LOONGSON2_BOOT_FREQSCALE_WIDTH);
}
static const struct clk_ops loongson2_boot_clk_ops = {
.recalc_rate = loongson2_boot_recalc_rate,
};
static unsigned long loongson2_apb_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
return loongson2_calc_rate(parent_rate,
LOONGSON2_APB_FREQSCALE_SHIFT,
LOONGSON2_APB_FREQSCALE_WIDTH);
}
static const struct clk_ops loongson2_apb_clk_ops = {
.recalc_rate = loongson2_apb_recalc_rate,
};
static unsigned long loongson2_usb_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
return loongson2_calc_rate(parent_rate,
LOONGSON2_USB_FREQSCALE_SHIFT,
LOONGSON2_USB_FREQSCALE_WIDTH);
}
static const struct clk_ops loongson2_usb_clk_ops = {
.recalc_rate = loongson2_usb_recalc_rate,
};
static unsigned long loongson2_sata_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
return loongson2_calc_rate(parent_rate,
LOONGSON2_SATA_FREQSCALE_SHIFT,
LOONGSON2_SATA_FREQSCALE_WIDTH);
}
static const struct clk_ops loongson2_sata_clk_ops = {
.recalc_rate = loongson2_sata_recalc_rate,
};
static inline int loongson2_check_clk_hws(struct clk_hw *clks[], unsigned int count)
{
unsigned int i;
for (i = 0; i < count; i++)
if (IS_ERR(clks[i])) {
pr_err("Loongson2 clk %u: register failed with %ld\n",
i, PTR_ERR(clks[i]));
return PTR_ERR(clks[i]);
}
return 0;
}
static int loongson2_clk_probe(struct platform_device *pdev)
{
int ret;
struct clk_hw **hws;
struct clk_hw_onecell_data *clk_hw_data;
spinlock_t loongson2_clk_lock;
struct device *dev = &pdev->dev;
loongson2_pll_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(loongson2_pll_base))
return PTR_ERR(loongson2_pll_base);
clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, LOONGSON2_CLK_END),
GFP_KERNEL);
if (WARN_ON(!clk_hw_data))
return -ENOMEM;
clk_hw_data->num = LOONGSON2_CLK_END;
hws = clk_hw_data->hws;
hws[LOONGSON2_NODE_PLL] = loongson2_clk_register(dev, "node_pll",
NULL,
&loongson2_node_clk_ops, 0);
hws[LOONGSON2_DDR_PLL] = loongson2_clk_register(dev, "ddr_pll",
NULL,
&loongson2_ddr_clk_ops, 0);
hws[LOONGSON2_DC_PLL] = loongson2_clk_register(dev, "dc_pll",
NULL,
&loongson2_dc_clk_ops, 0);
hws[LOONGSON2_PIX0_PLL] = loongson2_clk_register(dev, "pix0_pll",
NULL,
&loongson2_pix0_clk_ops, 0);
hws[LOONGSON2_PIX1_PLL] = loongson2_clk_register(dev, "pix1_pll",
NULL,
&loongson2_pix1_clk_ops, 0);
hws[LOONGSON2_BOOT_CLK] = loongson2_clk_register(dev, "boot",
NULL,
&loongson2_boot_clk_ops, 0);
hws[LOONGSON2_NODE_CLK] = devm_clk_hw_register_divider(dev, "node",
"node_pll", 0,
loongson2_pll_base + 0x8, 0,
6, CLK_DIVIDER_ONE_BASED,
&loongson2_clk_lock);
/*
* The hda clk divisor in the upper 32bits and the clk-prodiver
* layer code doesn't support 64bit io operation thus a conversion
* is required that subtract shift by 32 and add 4byte to the hda
* address
*/
hws[LOONGSON2_HDA_CLK] = devm_clk_hw_register_divider(dev, "hda",
"ddr_pll", 0,
loongson2_pll_base + 0x22, 12,
7, CLK_DIVIDER_ONE_BASED,
&loongson2_clk_lock);
hws[LOONGSON2_GPU_CLK] = devm_clk_hw_register_divider(dev, "gpu",
"ddr_pll", 0,
loongson2_pll_base + 0x18, 22,
6, CLK_DIVIDER_ONE_BASED,
&loongson2_clk_lock);
hws[LOONGSON2_DDR_CLK] = devm_clk_hw_register_divider(dev, "ddr",
"ddr_pll", 0,
loongson2_pll_base + 0x18, 0,
6, CLK_DIVIDER_ONE_BASED,
&loongson2_clk_lock);
hws[LOONGSON2_GMAC_CLK] = devm_clk_hw_register_divider(dev, "gmac",
"dc_pll", 0,
loongson2_pll_base + 0x28, 22,
6, CLK_DIVIDER_ONE_BASED,
&loongson2_clk_lock);
hws[LOONGSON2_DC_CLK] = devm_clk_hw_register_divider(dev, "dc",
"dc_pll", 0,
loongson2_pll_base + 0x28, 0,
6, CLK_DIVIDER_ONE_BASED,
&loongson2_clk_lock);
hws[LOONGSON2_APB_CLK] = loongson2_clk_register(dev, "apb",
"gmac",
&loongson2_apb_clk_ops, 0);
hws[LOONGSON2_USB_CLK] = loongson2_clk_register(dev, "usb",
"gmac",
&loongson2_usb_clk_ops, 0);
hws[LOONGSON2_SATA_CLK] = loongson2_clk_register(dev, "sata",
"gmac",
&loongson2_sata_clk_ops, 0);
hws[LOONGSON2_PIX0_CLK] = clk_hw_register_divider(NULL, "pix0",
"pix0_pll", 0,
loongson2_pll_base + 0x38, 0, 6,
CLK_DIVIDER_ONE_BASED,
&loongson2_clk_lock);
hws[LOONGSON2_PIX1_CLK] = clk_hw_register_divider(NULL, "pix1",
"pix1_pll", 0,
loongson2_pll_base + 0x48, 0, 6,
CLK_DIVIDER_ONE_BASED,
&loongson2_clk_lock);
ret = loongson2_check_clk_hws(hws, LOONGSON2_CLK_END);
if (ret)
return ret;
return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_hw_data);
}
static const struct of_device_id loongson2_clk_match_table[] = {
{ .compatible = "loongson,ls2k-clk" },
{ }
};
MODULE_DEVICE_TABLE(of, loongson2_clk_match_table);
static struct platform_driver loongson2_clk_driver = {
.probe = loongson2_clk_probe,
.driver = {
.name = "loongson2-clk",
.of_match_table = loongson2_clk_match_table,
},
};
module_platform_driver(loongson2_clk_driver);
MODULE_DESCRIPTION("Loongson2 clock driver");
MODULE_LICENSE("GPL");
This diff is collapsed.
# SPDX-License-Identifier: GPL-2.0-only
obj-y += clk.o
obj-$(CONFIG_LOONGSON1_LS1B) += clk-loongson1b.o
obj-$(CONFIG_LOONGSON1_LS1C) += clk-loongson1c.o
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2012-2016 Zhang, Keguang <keguang.zhang@gmail.com>
*/
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/err.h>
#include <loongson1.h>
#include "clk.h"
#define OSC (33 * 1000000)
#define DIV_APB 2
static DEFINE_SPINLOCK(_lock);
static unsigned long ls1x_pll_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
u32 pll, rate;
pll = __raw_readl(LS1X_CLK_PLL_FREQ);
rate = 12 + (pll & GENMASK(5, 0));
rate *= OSC;
rate >>= 1;
return rate;
}
static const struct clk_ops ls1x_pll_clk_ops = {
.recalc_rate = ls1x_pll_recalc_rate,
};
static const char *const cpu_parents[] = { "cpu_clk_div", "osc_clk", };
static const char *const ahb_parents[] = { "ahb_clk_div", "osc_clk", };
static const char *const dc_parents[] = { "dc_clk_div", "osc_clk", };
void __init ls1x_clk_init(void)
{
struct clk_hw *hw;
hw = clk_hw_register_fixed_rate(NULL, "osc_clk", NULL, 0, OSC);
clk_hw_register_clkdev(hw, "osc_clk", NULL);
/* clock derived from 33 MHz OSC clk */
hw = clk_hw_register_pll(NULL, "pll_clk", "osc_clk",
&ls1x_pll_clk_ops, 0);
clk_hw_register_clkdev(hw, "pll_clk", NULL);
/* clock derived from PLL clk */
/* _____
* _______________________| |
* OSC ___/ | MUX |___ CPU CLK
* \___ PLL ___ CPU DIV ___| |
* |_____|
*/
hw = clk_hw_register_divider(NULL, "cpu_clk_div", "pll_clk",
CLK_GET_RATE_NOCACHE, LS1X_CLK_PLL_DIV,
DIV_CPU_SHIFT, DIV_CPU_WIDTH,
CLK_DIVIDER_ONE_BASED |
CLK_DIVIDER_ROUND_CLOSEST, &_lock);
clk_hw_register_clkdev(hw, "cpu_clk_div", NULL);
hw = clk_hw_register_mux(NULL, "cpu_clk", cpu_parents,
ARRAY_SIZE(cpu_parents),
CLK_SET_RATE_NO_REPARENT, LS1X_CLK_PLL_DIV,
BYPASS_CPU_SHIFT, BYPASS_CPU_WIDTH, 0, &_lock);
clk_hw_register_clkdev(hw, "cpu_clk", NULL);
/* _____
* _______________________| |
* OSC ___/ | MUX |___ DC CLK
* \___ PLL ___ DC DIV ___| |
* |_____|
*/
hw = clk_hw_register_divider(NULL, "dc_clk_div", "pll_clk",
0, LS1X_CLK_PLL_DIV, DIV_DC_SHIFT,
DIV_DC_WIDTH, CLK_DIVIDER_ONE_BASED, &_lock);
clk_hw_register_clkdev(hw, "dc_clk_div", NULL);
hw = clk_hw_register_mux(NULL, "dc_clk", dc_parents,
ARRAY_SIZE(dc_parents),
CLK_SET_RATE_NO_REPARENT, LS1X_CLK_PLL_DIV,
BYPASS_DC_SHIFT, BYPASS_DC_WIDTH, 0, &_lock);
clk_hw_register_clkdev(hw, "dc_clk", NULL);
/* _____
* _______________________| |
* OSC ___/ | MUX |___ DDR CLK
* \___ PLL ___ DDR DIV ___| |
* |_____|
*/
hw = clk_hw_register_divider(NULL, "ahb_clk_div", "pll_clk",
0, LS1X_CLK_PLL_DIV, DIV_DDR_SHIFT,
DIV_DDR_WIDTH, CLK_DIVIDER_ONE_BASED,
&_lock);
clk_hw_register_clkdev(hw, "ahb_clk_div", NULL);
hw = clk_hw_register_mux(NULL, "ahb_clk", ahb_parents,
ARRAY_SIZE(ahb_parents),
CLK_SET_RATE_NO_REPARENT, LS1X_CLK_PLL_DIV,
BYPASS_DDR_SHIFT, BYPASS_DDR_WIDTH, 0, &_lock);
clk_hw_register_clkdev(hw, "ahb_clk", NULL);
clk_hw_register_clkdev(hw, "ls1x-dma", NULL);
clk_hw_register_clkdev(hw, "stmmaceth", NULL);
/* clock derived from AHB clk */
/* APB clk is always half of the AHB clk */
hw = clk_hw_register_fixed_factor(NULL, "apb_clk", "ahb_clk", 0, 1,
DIV_APB);
clk_hw_register_clkdev(hw, "apb_clk", NULL);
clk_hw_register_clkdev(hw, "ls1x-ac97", NULL);
clk_hw_register_clkdev(hw, "ls1x-i2c", NULL);
clk_hw_register_clkdev(hw, "ls1x-nand", NULL);
clk_hw_register_clkdev(hw, "ls1x-pwmtimer", NULL);
clk_hw_register_clkdev(hw, "ls1x-spi", NULL);
clk_hw_register_clkdev(hw, "ls1x-wdt", NULL);
clk_hw_register_clkdev(hw, "serial8250", NULL);
}
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2016 Yang Ling <gnaygnil@gmail.com>
*/
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <loongson1.h>
#include "clk.h"
#define OSC (24 * 1000000)
#define DIV_APB 1
static DEFINE_SPINLOCK(_lock);
static unsigned long ls1x_pll_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
u32 pll, rate;
pll = __raw_readl(LS1X_CLK_PLL_FREQ);
rate = ((pll >> 8) & 0xff) + ((pll >> 16) & 0xff);
rate *= OSC;
rate >>= 2;
return rate;
}
static const struct clk_ops ls1x_pll_clk_ops = {
.recalc_rate = ls1x_pll_recalc_rate,
};
static const struct clk_div_table ahb_div_table[] = {
[0] = { .val = 0, .div = 2 },
[1] = { .val = 1, .div = 4 },
[2] = { .val = 2, .div = 3 },
[3] = { .val = 3, .div = 3 },
[4] = { /* sentinel */ }
};
void __init ls1x_clk_init(void)
{
struct clk_hw *hw;
hw = clk_hw_register_fixed_rate(NULL, "osc_clk", NULL, 0, OSC);
clk_hw_register_clkdev(hw, "osc_clk", NULL);
/* clock derived from 24 MHz OSC clk */
hw = clk_hw_register_pll(NULL, "pll_clk", "osc_clk",
&ls1x_pll_clk_ops, 0);
clk_hw_register_clkdev(hw, "pll_clk", NULL);
hw = clk_hw_register_divider(NULL, "cpu_clk_div", "pll_clk",
CLK_GET_RATE_NOCACHE, LS1X_CLK_PLL_DIV,
DIV_CPU_SHIFT, DIV_CPU_WIDTH,
CLK_DIVIDER_ONE_BASED |
CLK_DIVIDER_ROUND_CLOSEST, &_lock);
clk_hw_register_clkdev(hw, "cpu_clk_div", NULL);
hw = clk_hw_register_fixed_factor(NULL, "cpu_clk", "cpu_clk_div",
0, 1, 1);
clk_hw_register_clkdev(hw, "cpu_clk", NULL);
hw = clk_hw_register_divider(NULL, "dc_clk_div", "pll_clk",
0, LS1X_CLK_PLL_DIV, DIV_DC_SHIFT,
DIV_DC_WIDTH, CLK_DIVIDER_ONE_BASED, &_lock);
clk_hw_register_clkdev(hw, "dc_clk_div", NULL);
hw = clk_hw_register_fixed_factor(NULL, "dc_clk", "dc_clk_div",
0, 1, 1);
clk_hw_register_clkdev(hw, "dc_clk", NULL);
hw = clk_hw_register_divider_table(NULL, "ahb_clk_div", "cpu_clk_div",
0, LS1X_CLK_PLL_FREQ, DIV_DDR_SHIFT,
DIV_DDR_WIDTH, CLK_DIVIDER_ALLOW_ZERO,
ahb_div_table, &_lock);
clk_hw_register_clkdev(hw, "ahb_clk_div", NULL);
hw = clk_hw_register_fixed_factor(NULL, "ahb_clk", "ahb_clk_div",
0, 1, 1);
clk_hw_register_clkdev(hw, "ahb_clk", NULL);
clk_hw_register_clkdev(hw, "ls1x-dma", NULL);
clk_hw_register_clkdev(hw, "stmmaceth", NULL);
/* clock derived from AHB clk */
hw = clk_hw_register_fixed_factor(NULL, "apb_clk", "ahb_clk", 0, 1,
DIV_APB);
clk_hw_register_clkdev(hw, "apb_clk", NULL);
clk_hw_register_clkdev(hw, "ls1x-ac97", NULL);
clk_hw_register_clkdev(hw, "ls1x-i2c", NULL);
clk_hw_register_clkdev(hw, "ls1x-nand", NULL);
clk_hw_register_clkdev(hw, "ls1x-pwmtimer", NULL);
clk_hw_register_clkdev(hw, "ls1x-spi", NULL);
clk_hw_register_clkdev(hw, "ls1x-wdt", NULL);
clk_hw_register_clkdev(hw, "serial8250", NULL);
}
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2012-2016 Zhang, Keguang <keguang.zhang@gmail.com>
*/
#include <linux/clk-provider.h>
#include <linux/slab.h>
#include "clk.h"
struct clk_hw *__init clk_hw_register_pll(struct device *dev,
const char *name,
const char *parent_name,
const struct clk_ops *ops,
unsigned long flags)
{
int ret;
struct clk_hw *hw;
struct clk_init_data init;
/* allocate the divider */
hw = kzalloc(sizeof(*hw), GFP_KERNEL);
if (!hw)
return ERR_PTR(-ENOMEM);
init.name = name;
init.ops = ops;
init.flags = flags;
init.parent_names = parent_name ? &parent_name : NULL;
init.num_parents = parent_name ? 1 : 0;
hw->init = &init;
/* register the clock */
ret = clk_hw_register(dev, hw);
if (ret) {
kfree(hw);
hw = ERR_PTR(ret);
}
return hw;
}
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (c) 2012-2016 Zhang, Keguang <keguang.zhang@gmail.com>
*/
#ifndef __LOONGSON1_CLK_H
#define __LOONGSON1_CLK_H
struct clk_hw *clk_hw_register_pll(struct device *dev,
const char *name,
const char *parent_name,
const struct clk_ops *ops,
unsigned long flags);
#endif /* __LOONGSON1_CLK_H */
This diff is collapsed.
......@@ -38,7 +38,7 @@ obj-$(CONFIG_COMMON_CLK_MT2701_HIFSYS) += clk-mt2701-hif.o
obj-$(CONFIG_COMMON_CLK_MT2701_IMGSYS) += clk-mt2701-img.o
obj-$(CONFIG_COMMON_CLK_MT2701_MMSYS) += clk-mt2701-mm.o
obj-$(CONFIG_COMMON_CLK_MT2701_VDECSYS) += clk-mt2701-vdec.o
obj-$(CONFIG_COMMON_CLK_MT2712) += clk-mt2712.o
obj-$(CONFIG_COMMON_CLK_MT2712) += clk-mt2712-apmixedsys.o clk-mt2712.o
obj-$(CONFIG_COMMON_CLK_MT2712_BDPSYS) += clk-mt2712-bdp.o
obj-$(CONFIG_COMMON_CLK_MT2712_IMGSYS) += clk-mt2712-img.o
obj-$(CONFIG_COMMON_CLK_MT2712_JPGDECSYS) += clk-mt2712-jpgdec.o
......@@ -46,7 +46,8 @@ obj-$(CONFIG_COMMON_CLK_MT2712_MFGCFG) += clk-mt2712-mfg.o
obj-$(CONFIG_COMMON_CLK_MT2712_MMSYS) += clk-mt2712-mm.o
obj-$(CONFIG_COMMON_CLK_MT2712_VDECSYS) += clk-mt2712-vdec.o
obj-$(CONFIG_COMMON_CLK_MT2712_VENCSYS) += clk-mt2712-venc.o
obj-$(CONFIG_COMMON_CLK_MT7622) += clk-mt7622.o
obj-$(CONFIG_COMMON_CLK_MT7622) += clk-mt7622-apmixedsys.o clk-mt7622.o \
clk-mt7622-infracfg.o
obj-$(CONFIG_COMMON_CLK_MT7622_ETHSYS) += clk-mt7622-eth.o
obj-$(CONFIG_COMMON_CLK_MT7622_HIFSYS) += clk-mt7622-hif.o
obj-$(CONFIG_COMMON_CLK_MT7622_AUDSYS) += clk-mt7622-aud.o
......@@ -61,8 +62,8 @@ obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-apmixed.o
obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-topckgen.o
obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-infracfg.o
obj-$(CONFIG_COMMON_CLK_MT7986_ETHSYS) += clk-mt7986-eth.o
obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o
obj-$(CONFIG_COMMON_CLK_MT8167) += clk-mt8167.o
obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135-apmixedsys.o clk-mt8135.o
obj-$(CONFIG_COMMON_CLK_MT8167) += clk-mt8167-apmixedsys.o clk-mt8167.o
obj-$(CONFIG_COMMON_CLK_MT8167_AUDSYS) += clk-mt8167-aud.o
obj-$(CONFIG_COMMON_CLK_MT8167_IMGSYS) += clk-mt8167-img.o
obj-$(CONFIG_COMMON_CLK_MT8167_MFGCFG) += clk-mt8167-mfgcfg.o
......@@ -74,7 +75,7 @@ obj-$(CONFIG_COMMON_CLK_MT8173_IMGSYS) += clk-mt8173-img.o
obj-$(CONFIG_COMMON_CLK_MT8173_MMSYS) += clk-mt8173-mm.o
obj-$(CONFIG_COMMON_CLK_MT8173_VDECSYS) += clk-mt8173-vdecsys.o
obj-$(CONFIG_COMMON_CLK_MT8173_VENCSYS) += clk-mt8173-vencsys.o
obj-$(CONFIG_COMMON_CLK_MT8183) += clk-mt8183.o
obj-$(CONFIG_COMMON_CLK_MT8183) += clk-mt8183-apmixedsys.o clk-mt8183.o
obj-$(CONFIG_COMMON_CLK_MT8183_AUDIOSYS) += clk-mt8183-audio.o
obj-$(CONFIG_COMMON_CLK_MT8183_CAMSYS) += clk-mt8183-cam.o
obj-$(CONFIG_COMMON_CLK_MT8183_IMGSYS) += clk-mt8183-img.o
......@@ -86,12 +87,33 @@ obj-$(CONFIG_COMMON_CLK_MT8183_MFGCFG) += clk-mt8183-mfgcfg.o
obj-$(CONFIG_COMMON_CLK_MT8183_MMSYS) += clk-mt8183-mm.o
obj-$(CONFIG_COMMON_CLK_MT8183_VDECSYS) += clk-mt8183-vdec.o
obj-$(CONFIG_COMMON_CLK_MT8183_VENCSYS) += clk-mt8183-venc.o
obj-$(CONFIG_COMMON_CLK_MT8186) += clk-mt8186-mcu.o clk-mt8186-topckgen.o clk-mt8186-infra_ao.o \
clk-mt8186-apmixedsys.o clk-mt8186-imp_iic_wrap.o \
clk-mt8186-mfg.o clk-mt8186-mm.o clk-mt8186-wpe.o \
clk-mt8186-img.o clk-mt8186-vdec.o clk-mt8186-venc.o \
clk-mt8186-cam.o clk-mt8186-mdp.o clk-mt8186-ipe.o
obj-$(CONFIG_COMMON_CLK_MT8192) += clk-mt8192.o
obj-$(CONFIG_COMMON_CLK_MT8186) += clk-mt8186-apmixedsys.o clk-mt8186-topckgen.o \
clk-mt8186-infra_ao.o
obj-$(CONFIG_COMMON_CLK_MT8186_CAMSYS) += clk-mt8186-cam.o
obj-$(CONFIG_COMMON_CLK_MT8186_IMGSYS) += clk-mt8186-img.o
obj-$(CONFIG_COMMON_CLK_MT8186_IMP_IIC_WRAP) += clk-mt8186-imp_iic_wrap.o
obj-$(CONFIG_COMMON_CLK_MT8186_IPESYS) += clk-mt8186-ipe.o
obj-$(CONFIG_COMMON_CLK_MT8186_MCUSYS) += clk-mt8186-mcu.o
obj-$(CONFIG_COMMON_CLK_MT8186_MDPSYS) += clk-mt8186-mdp.o
obj-$(CONFIG_COMMON_CLK_MT8186_MFGCFG) += clk-mt8186-mfg.o
obj-$(CONFIG_COMMON_CLK_MT8186_MMSYS) += clk-mt8186-mm.o
obj-$(CONFIG_COMMON_CLK_MT8186_VDECSYS) += clk-mt8186-vdec.o
obj-$(CONFIG_COMMON_CLK_MT8186_VENCSYS) += clk-mt8186-venc.o
obj-$(CONFIG_COMMON_CLK_MT8186_WPESYS) += clk-mt8186-wpe.o
obj-$(CONFIG_COMMON_CLK_MT8188) += clk-mt8188-apmixedsys.o clk-mt8188-topckgen.o \
clk-mt8188-peri_ao.o clk-mt8188-infra_ao.o
obj-$(CONFIG_COMMON_CLK_MT8188_ADSP_AUDIO26M) += clk-mt8188-adsp_audio26m.o
obj-$(CONFIG_COMMON_CLK_MT8188_CAMSYS) += clk-mt8188-cam.o clk-mt8188-ccu.o
obj-$(CONFIG_COMMON_CLK_MT8188_IMGSYS) += clk-mt8188-img.o
obj-$(CONFIG_COMMON_CLK_MT8188_IMP_IIC_WRAP) += clk-mt8188-imp_iic_wrap.o
obj-$(CONFIG_COMMON_CLK_MT8188_IPESYS) += clk-mt8188-ipe.o
obj-$(CONFIG_COMMON_CLK_MT8188_MFGCFG) += clk-mt8188-mfg.o
obj-$(CONFIG_COMMON_CLK_MT8188_VDECSYS) += clk-mt8188-vdec.o
obj-$(CONFIG_COMMON_CLK_MT8188_VDOSYS) += clk-mt8188-vdo0.o clk-mt8188-vdo1.o
obj-$(CONFIG_COMMON_CLK_MT8188_VENCSYS) += clk-mt8188-venc.o
obj-$(CONFIG_COMMON_CLK_MT8188_VPPSYS) += clk-mt8188-vpp0.o clk-mt8188-vpp1.o
obj-$(CONFIG_COMMON_CLK_MT8188_WPESYS) += clk-mt8188-wpe.o
obj-$(CONFIG_COMMON_CLK_MT8192) += clk-mt8192-apmixedsys.o clk-mt8192.o
obj-$(CONFIG_COMMON_CLK_MT8192_AUDSYS) += clk-mt8192-aud.o
obj-$(CONFIG_COMMON_CLK_MT8192_CAMSYS) += clk-mt8192-cam.o
obj-$(CONFIG_COMMON_CLK_MT8192_IMGSYS) += clk-mt8192-img.o
......@@ -105,19 +127,25 @@ obj-$(CONFIG_COMMON_CLK_MT8192_SCP_ADSP) += clk-mt8192-scp_adsp.o
obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o \
clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o \
clk-mt8195-cam.o clk-mt8195-ccu.o clk-mt8195-img.o \
clk-mt8195-ipe.o clk-mt8195-mfg.o clk-mt8195-scp_adsp.o \
clk-mt8195-vdec.o clk-mt8195-vdo0.o clk-mt8195-vdo1.o \
clk-mt8195-venc.o clk-mt8195-vpp0.o clk-mt8195-vpp1.o \
clk-mt8195-wpe.o clk-mt8195-imp_iic_wrap.o \
clk-mt8195-apusys_pll.o
obj-$(CONFIG_COMMON_CLK_MT8365) += clk-mt8365.o
clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o
obj-$(CONFIG_COMMON_CLK_MT8195_APUSYS) += clk-mt8195-apusys_pll.o
obj-$(CONFIG_COMMON_CLK_MT8195_CAMSYS) += clk-mt8195-cam.o clk-mt8195-ccu.o
obj-$(CONFIG_COMMON_CLK_MT8195_IMGSYS) += clk-mt8195-img.o
obj-$(CONFIG_COMMON_CLK_MT8195_IMP_IIC_WRAP) += clk-mt8195-imp_iic_wrap.o
obj-$(CONFIG_COMMON_CLK_MT8195_IPESYS) += clk-mt8195-ipe.o
obj-$(CONFIG_COMMON_CLK_MT8195_MFGCFG) += clk-mt8195-mfg.o
obj-$(CONFIG_COMMON_CLK_MT8195_SCP_ADSP) += clk-mt8195-scp_adsp.o
obj-$(CONFIG_COMMON_CLK_MT8195_VDECSYS) += clk-mt8195-vdec.o
obj-$(CONFIG_COMMON_CLK_MT8195_VDOSYS) += clk-mt8195-vdo0.o clk-mt8195-vdo1.o
obj-$(CONFIG_COMMON_CLK_MT8195_VENCSYS) += clk-mt8195-venc.o
obj-$(CONFIG_COMMON_CLK_MT8195_VPPSYS) += clk-mt8195-vpp0.o clk-mt8195-vpp1.o
obj-$(CONFIG_COMMON_CLK_MT8195_WPESYS) += clk-mt8195-wpe.o
obj-$(CONFIG_COMMON_CLK_MT8365) += clk-mt8365-apmixedsys.o clk-mt8365.o
obj-$(CONFIG_COMMON_CLK_MT8365_APU) += clk-mt8365-apu.o
obj-$(CONFIG_COMMON_CLK_MT8365_CAM) += clk-mt8365-cam.o
obj-$(CONFIG_COMMON_CLK_MT8365_MFG) += clk-mt8365-mfg.o
obj-$(CONFIG_COMMON_CLK_MT8365_MMSYS) += clk-mt8365-mm.o
obj-$(CONFIG_COMMON_CLK_MT8365_VDEC) += clk-mt8365-vdec.o
obj-$(CONFIG_COMMON_CLK_MT8365_VENC) += clk-mt8365-venc.o
obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516-apmixedsys.o clk-mt8516.o
obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
......@@ -14,7 +14,20 @@
#define PERCENT_TO_DDSLMT(dds, percent_m10) \
((((dds) * (percent_m10)) >> 5) / 100)
static const struct fhctl_offset fhctl_offset = {
static const struct fhctl_offset fhctl_offset_v1 = {
.offset_hp_en = 0x0,
.offset_clk_con = 0x4,
.offset_rst_con = 0x8,
.offset_slope0 = 0xc,
.offset_slope1 = 0x10,
.offset_cfg = 0x0,
.offset_updnlmt = 0x4,
.offset_dds = 0x8,
.offset_dvfs = 0xc,
.offset_mon = 0x10,
};
static const struct fhctl_offset fhctl_offset_v2 = {
.offset_hp_en = 0x0,
.offset_clk_con = 0x8,
.offset_rst_con = 0xc,
......@@ -27,9 +40,16 @@ static const struct fhctl_offset fhctl_offset = {
.offset_mon = 0x10,
};
const struct fhctl_offset *fhctl_get_offset_table(void)
const struct fhctl_offset *fhctl_get_offset_table(enum fhctl_variant v)
{
return &fhctl_offset;
switch (v) {
case FHCTL_PLLFH_V1:
return &fhctl_offset_v1;
case FHCTL_PLLFH_V2:
return &fhctl_offset_v2;
default:
return ERR_PTR(-EINVAL);
};
}
static void dump_hw(struct mtk_clk_pll *pll, struct fh_pll_regs *regs,
......
......@@ -7,6 +7,13 @@
#ifndef __CLK_FHCTL_H
#define __CLK_FHCTL_H
#include "clk-pllfh.h"
enum fhctl_variant {
FHCTL_PLLFH_V1,
FHCTL_PLLFH_V2,
};
struct fhctl_offset {
u32 offset_hp_en;
u32 offset_clk_con;
......@@ -19,7 +26,7 @@ struct fhctl_offset {
u32 offset_dvfs;
u32 offset_mon;
};
const struct fhctl_offset *fhctl_get_offset_table(void);
const struct fhctl_offset *fhctl_get_offset_table(enum fhctl_variant v);
const struct fh_operation *fhctl_get_ops(void);
void fhctl_hw_init(struct mtk_fh *fh);
......
......@@ -15,41 +15,17 @@
#include <dt-bindings/clock/mt2701-clk.h>
#define GATE_AUDIO0(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &audio0_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_no_setclr, \
}
#define GATE_AUDIO0(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &audio0_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
#define GATE_AUDIO1(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &audio1_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_no_setclr, \
}
#define GATE_AUDIO1(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &audio1_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
#define GATE_AUDIO2(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &audio2_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_no_setclr, \
}
#define GATE_AUDIO2(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &audio2_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
#define GATE_AUDIO3(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &audio3_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_no_setclr, \
}
#define GATE_AUDIO3(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &audio3_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
static const struct mtk_gate_regs audio0_cg_regs = {
.set_ofs = 0x0,
......@@ -148,6 +124,7 @@ static const struct of_device_id of_match_clk_mt2701_aud[] = {
{ .compatible = "mediatek,mt2701-audsys", .data = &audio_desc },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, of_match_clk_mt2701_aud);
static int clk_mt2701_aud_probe(struct platform_device *pdev)
{
......@@ -187,5 +164,5 @@ static struct platform_driver clk_mt2701_aud_drv = {
.of_match_table = of_match_clk_mt2701_aud,
},
};
builtin_platform_driver(clk_mt2701_aud_drv);
module_platform_driver(clk_mt2701_aud_drv);
MODULE_LICENSE("GPL");
......@@ -24,23 +24,11 @@ static const struct mtk_gate_regs bdp1_cg_regs = {
.sta_ofs = 0x0110,
};
#define GATE_BDP0(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &bdp0_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_setclr_inv, \
}
#define GATE_BDP0(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &bdp0_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
#define GATE_BDP1(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &bdp1_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_setclr_inv, \
}
#define GATE_BDP1(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &bdp1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
static const struct mtk_gate bdp_clks[] = {
GATE_BDP0(CLK_BDP_BRG_BA, "brg_baclk", "mm_sel", 0),
......@@ -107,6 +95,7 @@ static const struct of_device_id of_match_clk_mt2701_bdp[] = {
/* sentinel */
}
};
MODULE_DEVICE_TABLE(of, of_match_clk_mt2701_bdp);
static struct platform_driver clk_mt2701_bdp_drv = {
.probe = mtk_clk_simple_probe,
......@@ -116,5 +105,5 @@ static struct platform_driver clk_mt2701_bdp_drv = {
.of_match_table = of_match_clk_mt2701_bdp,
},
};
builtin_platform_driver(clk_mt2701_bdp_drv);
module_platform_driver(clk_mt2701_bdp_drv);
MODULE_LICENSE("GPL");
......@@ -16,14 +16,8 @@ static const struct mtk_gate_regs eth_cg_regs = {
.sta_ofs = 0x0030,
};
#define GATE_ETH(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &eth_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_no_setclr_inv, \
}
#define GATE_ETH(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &eth_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
static const struct mtk_gate eth_clks[] = {
GATE_DUMMY(CLK_DUMMY, "eth_dummy"),
......@@ -55,6 +49,7 @@ static const struct of_device_id of_match_clk_mt2701_eth[] = {
{ .compatible = "mediatek,mt2701-ethsys", .data = &eth_desc },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, of_match_clk_mt2701_eth);
static struct platform_driver clk_mt2701_eth_drv = {
.probe = mtk_clk_simple_probe,
......@@ -64,5 +59,5 @@ static struct platform_driver clk_mt2701_eth_drv = {
.of_match_table = of_match_clk_mt2701_eth,
},
};
builtin_platform_driver(clk_mt2701_eth_drv);
module_platform_driver(clk_mt2701_eth_drv);
MODULE_LICENSE("GPL");
......@@ -16,14 +16,8 @@
#include <dt-bindings/clock/mt2701-clk.h>
#define GATE_G3D(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &g3d_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_setclr, \
}
#define GATE_G3D(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &g3d_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
static const struct mtk_gate_regs g3d_cg_regs = {
.sta_ofs = 0x0,
......@@ -54,6 +48,7 @@ static const struct of_device_id of_match_clk_mt2701_g3d[] = {
{ .compatible = "mediatek,mt2701-g3dsys", .data = &g3d_desc },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, of_match_clk_mt2701_g3d);
static struct platform_driver clk_mt2701_g3d_drv = {
.probe = mtk_clk_simple_probe,
......@@ -63,5 +58,5 @@ static struct platform_driver clk_mt2701_g3d_drv = {
.of_match_table = of_match_clk_mt2701_g3d,
},
};
builtin_platform_driver(clk_mt2701_g3d_drv);
module_platform_driver(clk_mt2701_g3d_drv);
MODULE_LICENSE("GPL");
......@@ -16,14 +16,8 @@ static const struct mtk_gate_regs hif_cg_regs = {
.sta_ofs = 0x0030,
};
#define GATE_HIF(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &hif_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_no_setclr_inv, \
}
#define GATE_HIF(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &hif_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
static const struct mtk_gate hif_clks[] = {
GATE_DUMMY(CLK_DUMMY, "hif_dummy"),
......@@ -52,6 +46,7 @@ static const struct of_device_id of_match_clk_mt2701_hif[] = {
{ .compatible = "mediatek,mt2701-hifsys", .data = &hif_desc },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, of_match_clk_mt2701_hif);
static struct platform_driver clk_mt2701_hif_drv = {
.probe = mtk_clk_simple_probe,
......@@ -61,5 +56,5 @@ static struct platform_driver clk_mt2701_hif_drv = {
.of_match_table = of_match_clk_mt2701_hif,
},
};
builtin_platform_driver(clk_mt2701_hif_drv);
module_platform_driver(clk_mt2701_hif_drv);
MODULE_LICENSE("GPL");
......@@ -18,14 +18,8 @@ static const struct mtk_gate_regs img_cg_regs = {
.sta_ofs = 0x0000,
};
#define GATE_IMG(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &img_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_setclr, \
}
#define GATE_IMG(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &img_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
static const struct mtk_gate img_clks[] = {
GATE_IMG(CLK_IMG_SMI_COMM, "img_smi_comm", "mm_sel", 0),
......@@ -49,6 +43,7 @@ static const struct of_device_id of_match_clk_mt2701_img[] = {
/* sentinel */
}
};
MODULE_DEVICE_TABLE(of, of_match_clk_mt2701_img);
static struct platform_driver clk_mt2701_img_drv = {
.probe = mtk_clk_simple_probe,
......@@ -58,5 +53,5 @@ static struct platform_driver clk_mt2701_img_drv = {
.of_match_table = of_match_clk_mt2701_img,
},
};
builtin_platform_driver(clk_mt2701_img_drv);
module_platform_driver(clk_mt2701_img_drv);
MODULE_LICENSE("GPL");
......@@ -24,23 +24,11 @@ static const struct mtk_gate_regs disp1_cg_regs = {
.sta_ofs = 0x0110,
};
#define GATE_DISP0(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &disp0_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_setclr, \
}
#define GATE_DISP0(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &disp0_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
#define GATE_DISP1(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &disp1_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_setclr, \
}
#define GATE_DISP1(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &disp1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
static const struct mtk_gate mm_clks[] = {
GATE_DISP0(CLK_MM_SMI_COMMON, "mm_smi_comm", "mm_sel", 0),
......@@ -79,32 +67,24 @@ static const struct mtk_gate mm_clks[] = {
GATE_DISP1(CLK_MM_TVE_FMM, "mm_tve_fmm", "mm_sel", 14),
};
static int clk_mt2701_mm_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *node = dev->parent->of_node;
struct clk_hw_onecell_data *clk_data;
int r;
clk_data = mtk_alloc_clk_data(CLK_MM_NR);
mtk_clk_register_gates(&pdev->dev, node, mm_clks,
ARRAY_SIZE(mm_clks), clk_data);
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
if (r)
dev_err(&pdev->dev,
"could not register clock provider: %s: %d\n",
pdev->name, r);
static const struct mtk_clk_desc mm_desc = {
.clks = mm_clks,
.num_clks = ARRAY_SIZE(mm_clks),
};
return r;
}
static const struct platform_device_id clk_mt2701_mm_id_table[] = {
{ .name = "clk-mt2701-mm", .driver_data = (kernel_ulong_t)&mm_desc },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, clk_mt2701_mm_id_table);
static struct platform_driver clk_mt2701_mm_drv = {
.probe = clk_mt2701_mm_probe,
.probe = mtk_clk_pdev_probe,
.remove = mtk_clk_pdev_remove,
.driver = {
.name = "clk-mt2701-mm",
},
.id_table = clk_mt2701_mm_id_table,
};
builtin_platform_driver(clk_mt2701_mm_drv);
module_platform_driver(clk_mt2701_mm_drv);
MODULE_LICENSE("GPL");
......@@ -24,23 +24,11 @@ static const struct mtk_gate_regs vdec1_cg_regs = {
.sta_ofs = 0x0008,
};
#define GATE_VDEC0(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &vdec0_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_setclr_inv, \
}
#define GATE_VDEC0(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &vdec0_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
#define GATE_VDEC1(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &vdec1_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_setclr_inv, \
}
#define GATE_VDEC1(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &vdec1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
static const struct mtk_gate vdec_clks[] = {
GATE_VDEC0(CLK_VDEC_CKGEN, "vdec_cken", "vdec_sel", 0),
......@@ -60,6 +48,7 @@ static const struct of_device_id of_match_clk_mt2701_vdec[] = {
/* sentinel */
}
};
MODULE_DEVICE_TABLE(of, of_match_clk_mt2701_vdec);
static struct platform_driver clk_mt2701_vdec_drv = {
.probe = mtk_clk_simple_probe,
......@@ -69,5 +58,5 @@ static struct platform_driver clk_mt2701_vdec_drv = {
.of_match_table = of_match_clk_mt2701_vdec,
},
};
builtin_platform_driver(clk_mt2701_vdec_drv);
module_platform_driver(clk_mt2701_vdec_drv);
MODULE_LICENSE("GPL");
......@@ -636,14 +636,8 @@ static const struct mtk_gate_regs top_aud_cg_regs = {
.sta_ofs = 0x012C,
};
#define GATE_TOP_AUD(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &top_aud_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_no_setclr, \
}
#define GATE_TOP_AUD(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &top_aud_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
static const struct mtk_gate top_clks[] = {
GATE_TOP_AUD(CLK_TOP_AUD_48K_TIMING, "a1sys_hp_ck", "aud_mux1_div",
......@@ -687,7 +681,7 @@ static int mtk_topckgen_init(struct platform_device *pdev)
ARRAY_SIZE(top_muxes), base,
&mt2701_clk_lock, clk_data);
mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs),
mtk_clk_register_dividers(&pdev->dev, top_adj_divs, ARRAY_SIZE(top_adj_divs),
base, &mt2701_clk_lock, clk_data);
mtk_clk_register_gates(&pdev->dev, node, top_clks,
......@@ -702,14 +696,8 @@ static const struct mtk_gate_regs infra_cg_regs = {
.sta_ofs = 0x0048,
};
#define GATE_ICG(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &infra_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_setclr, \
}
#define GATE_ICG(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &infra_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
static const struct mtk_gate infra_clks[] = {
GATE_ICG(CLK_INFRA_DBG, "dbgclk", "axi_sel", 0),
......@@ -823,23 +811,11 @@ static const struct mtk_gate_regs peri1_cg_regs = {
.sta_ofs = 0x001c,
};
#define GATE_PERI0(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &peri0_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_setclr, \
}
#define GATE_PERI0(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &peri0_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
#define GATE_PERI1(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &peri1_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_setclr, \
}
#define GATE_PERI1(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &peri1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
static const struct mtk_gate peri_clks[] = {
GATE_PERI0(CLK_PERI_USB0_MCU, "usb0_mcu_ck", "axi_sel", 31),
......@@ -1023,6 +999,7 @@ static const struct of_device_id of_match_clk_mt2701[] = {
/* sentinel */
}
};
MODULE_DEVICE_TABLE(of, of_match_clk_mt2701);
static int clk_mt2701_probe(struct platform_device *pdev)
{
......@@ -1056,3 +1033,4 @@ static int __init clk_mt2701_init(void)
}
arch_initcall(clk_mt2701_init);
MODULE_LICENSE("GPL");
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017 MediaTek Inc.
* Weiyi Lu <weiyi.lu@mediatek.com>
* Copyright (c) 2023 Collabora Ltd.
* AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
*/
#include <linux/clk.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include "clk-pll.h"
#include "clk-mtk.h"
#include <dt-bindings/clock/mt2712-clk.h>
#define MT2712_PLL_FMAX (3000UL * MHZ)
#define CON0_MT2712_RST_BAR BIT(24)
#define PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \
_pd_reg, _pd_shift, _tuner_reg, _tuner_en_reg, \
_tuner_en_bit, _pcw_reg, _pcw_shift, \
_div_table) { \
.id = _id, \
.name = _name, \
.reg = _reg, \
.pwr_reg = _pwr_reg, \
.en_mask = _en_mask, \
.flags = _flags, \
.rst_bar_mask = CON0_MT2712_RST_BAR, \
.fmax = MT2712_PLL_FMAX, \
.pcwbits = _pcwbits, \
.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_shift = _pcw_shift, \
.div_table = _div_table, \
}
#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \
_pd_reg, _pd_shift, _tuner_reg, _tuner_en_reg, \
_tuner_en_bit, _pcw_reg, _pcw_shift) \
PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, \
_pcwbits, _pd_reg, _pd_shift, _tuner_reg, \
_tuner_en_reg, _tuner_en_bit, _pcw_reg, \
_pcw_shift, NULL)
static const struct mtk_pll_div_table armca35pll_div_table[] = {
{ .div = 0, .freq = MT2712_PLL_FMAX },
{ .div = 1, .freq = 1202500000 },
{ .div = 2, .freq = 500500000 },
{ .div = 3, .freq = 315250000 },
{ .div = 4, .freq = 157625000 },
{ /* sentinel */ }
};
static const struct mtk_pll_div_table armca72pll_div_table[] = {
{ .div = 0, .freq = MT2712_PLL_FMAX },
{ .div = 1, .freq = 994500000 },
{ .div = 2, .freq = 520000000 },
{ .div = 3, .freq = 315250000 },
{ .div = 4, .freq = 157625000 },
{ /* sentinel */ }
};
static const struct mtk_pll_div_table mmpll_div_table[] = {
{ .div = 0, .freq = MT2712_PLL_FMAX },
{ .div = 1, .freq = 1001000000 },
{ .div = 2, .freq = 601250000 },
{ .div = 3, .freq = 250250000 },
{ .div = 4, .freq = 125125000 },
{ /* sentinel */ }
};
static const struct mtk_pll_data plls[] = {
PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x0230, 0x023C, 0xf0000100,
HAVE_RST_BAR, 31, 0x0230, 4, 0, 0, 0, 0x0234, 0),
PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x0240, 0x024C, 0xfe000100,
HAVE_RST_BAR, 31, 0x0240, 4, 0, 0, 0, 0x0244, 0),
PLL(CLK_APMIXED_VCODECPLL, "vcodecpll", 0x0320, 0x032C, 0xc0000100,
0, 31, 0x0320, 4, 0, 0, 0, 0x0324, 0),
PLL(CLK_APMIXED_VENCPLL, "vencpll", 0x0280, 0x028C, 0x00000100,
0, 31, 0x0280, 4, 0, 0, 0, 0x0284, 0),
PLL(CLK_APMIXED_APLL1, "apll1", 0x0330, 0x0340, 0x00000100,
0, 31, 0x0330, 4, 0x0338, 0x0014, 0, 0x0334, 0),
PLL(CLK_APMIXED_APLL2, "apll2", 0x0350, 0x0360, 0x00000100,
0, 31, 0x0350, 4, 0x0358, 0x0014, 1, 0x0354, 0),
PLL(CLK_APMIXED_LVDSPLL, "lvdspll", 0x0370, 0x037c, 0x00000100,
0, 31, 0x0370, 4, 0, 0, 0, 0x0374, 0),
PLL(CLK_APMIXED_LVDSPLL2, "lvdspll2", 0x0390, 0x039C, 0x00000100,
0, 31, 0x0390, 4, 0, 0, 0, 0x0394, 0),
PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x0270, 0x027C, 0x00000100,
0, 31, 0x0270, 4, 0, 0, 0, 0x0274, 0),
PLL(CLK_APMIXED_MSDCPLL2, "msdcpll2", 0x0410, 0x041C, 0x00000100,
0, 31, 0x0410, 4, 0, 0, 0, 0x0414, 0),
PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x0290, 0x029C, 0xc0000100,
0, 31, 0x0290, 4, 0, 0, 0, 0x0294, 0),
PLL_B(CLK_APMIXED_MMPLL, "mmpll", 0x0250, 0x0260, 0x00000100,
0, 31, 0x0250, 4, 0, 0, 0, 0x0254, 0, mmpll_div_table),
PLL_B(CLK_APMIXED_ARMCA35PLL, "armca35pll", 0x0100, 0x0110, 0xf0000100,
HAVE_RST_BAR, 31, 0x0100, 4, 0, 0, 0, 0x0104, 0, armca35pll_div_table),
PLL_B(CLK_APMIXED_ARMCA72PLL, "armca72pll", 0x0210, 0x0220, 0x00000100,
0, 31, 0x0210, 4, 0, 0, 0, 0x0214, 0, armca72pll_div_table),
PLL(CLK_APMIXED_ETHERPLL, "etherpll", 0x0300, 0x030C, 0xc0000100,
0, 31, 0x0300, 4, 0, 0, 0, 0x0304, 0),
};
static int clk_mt2712_apmixed_probe(struct platform_device *pdev)
{
struct clk_hw_onecell_data *clk_data;
int r;
struct device_node *node = pdev->dev.of_node;
clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
if (!clk_data)
return -ENOMEM;
r = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
if (r)
goto free_clk_data;
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
if (r) {
dev_err(&pdev->dev, "Cannot register clock provider: %d\n", r);
goto unregister_plls;
}
return 0;
unregister_plls:
mtk_clk_unregister_plls(plls, ARRAY_SIZE(plls), clk_data);
free_clk_data:
mtk_free_clk_data(clk_data);
return r;
}
static int clk_mt2712_apmixed_remove(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
struct clk_hw_onecell_data *clk_data = platform_get_drvdata(pdev);
of_clk_del_provider(node);
mtk_clk_unregister_plls(plls, ARRAY_SIZE(plls), clk_data);
mtk_free_clk_data(clk_data);
return 0;
}
static const struct of_device_id of_match_clk_mt2712_apmixed[] = {
{ .compatible = "mediatek,mt2712-apmixedsys" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, of_match_clk_mt2712_apmixed);
static struct platform_driver clk_mt2712_apmixed_drv = {
.probe = clk_mt2712_apmixed_probe,
.remove = clk_mt2712_apmixed_remove,
.driver = {
.name = "clk-mt2712-apmixed",
.of_match_table = of_match_clk_mt2712_apmixed,
},
};
module_platform_driver(clk_mt2712_apmixed_drv)
MODULE_LICENSE("GPL");
......@@ -18,14 +18,8 @@ static const struct mtk_gate_regs bdp_cg_regs = {
.sta_ofs = 0x100,
};
#define GATE_BDP(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &bdp_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_no_setclr, \
}
#define GATE_BDP(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &bdp_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
static const struct mtk_gate bdp_clks[] = {
GATE_BDP(CLK_BDP_BRIDGE_B, "bdp_bridge_b", "mm_sel", 0),
......@@ -71,6 +65,7 @@ static const struct of_device_id of_match_clk_mt2712_bdp[] = {
/* sentinel */
}
};
MODULE_DEVICE_TABLE(of, of_match_clk_mt2712_bdp);
static struct platform_driver clk_mt2712_bdp_drv = {
.probe = mtk_clk_simple_probe,
......@@ -80,5 +75,5 @@ static struct platform_driver clk_mt2712_bdp_drv = {
.of_match_table = of_match_clk_mt2712_bdp,
},
};
builtin_platform_driver(clk_mt2712_bdp_drv);
module_platform_driver(clk_mt2712_bdp_drv);
MODULE_LICENSE("GPL");
......@@ -18,14 +18,8 @@ static const struct mtk_gate_regs img_cg_regs = {
.sta_ofs = 0x0,
};
#define GATE_IMG(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &img_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_no_setclr, \
}
#define GATE_IMG(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &img_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
static const struct mtk_gate img_clks[] = {
GATE_IMG(CLK_IMG_SMI_LARB2, "img_smi_larb2", "mm_sel", 0),
......@@ -49,6 +43,7 @@ static const struct of_device_id of_match_clk_mt2712_img[] = {
/* sentinel */
}
};
MODULE_DEVICE_TABLE(of, of_match_clk_mt2712_img);
static struct platform_driver clk_mt2712_img_drv = {
.probe = mtk_clk_simple_probe,
......@@ -58,5 +53,5 @@ static struct platform_driver clk_mt2712_img_drv = {
.of_match_table = of_match_clk_mt2712_img,
},
};
builtin_platform_driver(clk_mt2712_img_drv);
module_platform_driver(clk_mt2712_img_drv);
MODULE_LICENSE("GPL");
......@@ -18,14 +18,8 @@ static const struct mtk_gate_regs jpgdec_cg_regs = {
.sta_ofs = 0x0,
};
#define GATE_JPGDEC(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &jpgdec_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_setclr_inv, \
}
#define GATE_JPGDEC(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &jpgdec_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
static const struct mtk_gate jpgdec_clks[] = {
GATE_JPGDEC(CLK_JPGDEC_JPGDEC1, "jpgdec_jpgdec1", "jpgdec_sel", 0),
......@@ -45,6 +39,7 @@ static const struct of_device_id of_match_clk_mt2712_jpgdec[] = {
/* sentinel */
}
};
MODULE_DEVICE_TABLE(of, of_match_clk_mt2712_jpgdec);
static struct platform_driver clk_mt2712_jpgdec_drv = {
.probe = mtk_clk_simple_probe,
......@@ -54,5 +49,5 @@ static struct platform_driver clk_mt2712_jpgdec_drv = {
.of_match_table = of_match_clk_mt2712_jpgdec,
},
};
builtin_platform_driver(clk_mt2712_jpgdec_drv);
module_platform_driver(clk_mt2712_jpgdec_drv);
MODULE_LICENSE("GPL");
......@@ -18,14 +18,8 @@ static const struct mtk_gate_regs mfg_cg_regs = {
.sta_ofs = 0x0,
};
#define GATE_MFG(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &mfg_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_setclr, \
}
#define GATE_MFG(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &mfg_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
static const struct mtk_gate mfg_clks[] = {
GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "mfg_sel", 0),
......@@ -44,6 +38,7 @@ static const struct of_device_id of_match_clk_mt2712_mfg[] = {
/* sentinel */
}
};
MODULE_DEVICE_TABLE(of, of_match_clk_mt2712_mfg);
static struct platform_driver clk_mt2712_mfg_drv = {
.probe = mtk_clk_simple_probe,
......@@ -53,5 +48,5 @@ static struct platform_driver clk_mt2712_mfg_drv = {
.of_match_table = of_match_clk_mt2712_mfg,
},
};
builtin_platform_driver(clk_mt2712_mfg_drv);
module_platform_driver(clk_mt2712_mfg_drv);
MODULE_LICENSE("GPL");
......@@ -30,32 +30,14 @@ static const struct mtk_gate_regs mm2_cg_regs = {
.sta_ofs = 0x220,
};
#define GATE_MM0(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &mm0_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_setclr, \
}
#define GATE_MM0(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &mm0_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
#define GATE_MM1(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &mm1_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_setclr, \
}
#define GATE_MM1(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &mm1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
#define GATE_MM2(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &mm2_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_setclr, \
}
#define GATE_MM2(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &mm2_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
static const struct mtk_gate mm_clks[] = {
/* MM0 */
......@@ -126,32 +108,24 @@ static const struct mtk_gate mm_clks[] = {
GATE_MM2(CLK_MM_DSI3_DIGITAL, "mm_dsi3_digital", "dsi1_lntc", 6),
};
static int clk_mt2712_mm_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *node = dev->parent->of_node;
struct clk_hw_onecell_data *clk_data;
int r;
clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK);
mtk_clk_register_gates(&pdev->dev, node, mm_clks,
ARRAY_SIZE(mm_clks), clk_data);
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
if (r != 0)
pr_err("%s(): could not register clock provider: %d\n",
__func__, r);
static const struct mtk_clk_desc mm_desc = {
.clks = mm_clks,
.num_clks = ARRAY_SIZE(mm_clks),
};
return r;
}
static const struct platform_device_id clk_mt2712_mm_id_table[] = {
{ .name = "clk-mt2712-mm", .driver_data = (kernel_ulong_t)&mm_desc },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, clk_mt2712_mm_id_table);
static struct platform_driver clk_mt2712_mm_drv = {
.probe = clk_mt2712_mm_probe,
.probe = mtk_clk_pdev_probe,
.remove = mtk_clk_pdev_remove,
.driver = {
.name = "clk-mt2712-mm",
},
.id_table = clk_mt2712_mm_id_table,
};
builtin_platform_driver(clk_mt2712_mm_drv);
module_platform_driver(clk_mt2712_mm_drv);
MODULE_LICENSE("GPL");
......@@ -24,23 +24,11 @@ static const struct mtk_gate_regs vdec1_cg_regs = {
.sta_ofs = 0x8,
};
#define GATE_VDEC0(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &vdec0_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_setclr_inv, \
}
#define GATE_VDEC0(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &vdec0_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
#define GATE_VDEC1(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &vdec1_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_setclr_inv, \
}
#define GATE_VDEC1(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &vdec1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
static const struct mtk_gate vdec_clks[] = {
/* VDEC0 */
......@@ -63,6 +51,7 @@ static const struct of_device_id of_match_clk_mt2712_vdec[] = {
/* sentinel */
}
};
MODULE_DEVICE_TABLE(of, of_match_clk_mt2712_vdec);
static struct platform_driver clk_mt2712_vdec_drv = {
.probe = mtk_clk_simple_probe,
......@@ -72,5 +61,5 @@ static struct platform_driver clk_mt2712_vdec_drv = {
.of_match_table = of_match_clk_mt2712_vdec,
},
};
builtin_platform_driver(clk_mt2712_vdec_drv);
module_platform_driver(clk_mt2712_vdec_drv);
MODULE_LICENSE("GPL");
......@@ -18,14 +18,8 @@ static const struct mtk_gate_regs venc_cg_regs = {
.sta_ofs = 0x0,
};
#define GATE_VENC(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &venc_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_setclr_inv, \
}
#define GATE_VENC(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &venc_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
static const struct mtk_gate venc_clks[] = {
GATE_VENC(CLK_VENC_SMI_COMMON_CON, "venc_smi", "mm_sel", 0),
......@@ -46,6 +40,7 @@ static const struct of_device_id of_match_clk_mt2712_venc[] = {
/* sentinel */
}
};
MODULE_DEVICE_TABLE(of, of_match_clk_mt2712_venc);
static struct platform_driver clk_mt2712_venc_drv = {
.probe = mtk_clk_simple_probe,
......@@ -55,5 +50,5 @@ static struct platform_driver clk_mt2712_venc_drv = {
.of_match_table = of_match_clk_mt2712_venc,
},
};
builtin_platform_driver(clk_mt2712_venc_drv);
module_platform_driver(clk_mt2712_venc_drv);
MODULE_LICENSE("GPL");
This diff is collapsed.
......@@ -24,23 +24,11 @@ static const struct mtk_gate_regs audio1_cg_regs = {
.sta_ofs = 0x4,
};
#define GATE_AUDIO0(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &audio0_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_no_setclr, \
}
#define GATE_AUDIO0(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &audio0_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
#define GATE_AUDIO1(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &audio1_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_no_setclr, \
}
#define GATE_AUDIO1(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &audio1_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
static const struct mtk_gate audio_clks[] = {
/* AUDIO0 */
......@@ -77,6 +65,7 @@ static const struct of_device_id of_match_clk_mt6765_audio[] = {
/* sentinel */
}
};
MODULE_DEVICE_TABLE(of, of_match_clk_mt6765_audio);
static struct platform_driver clk_mt6765_audio_drv = {
.probe = mtk_clk_simple_probe,
......@@ -86,5 +75,5 @@ static struct platform_driver clk_mt6765_audio_drv = {
.of_match_table = of_match_clk_mt6765_audio,
},
};
builtin_platform_driver(clk_mt6765_audio_drv);
module_platform_driver(clk_mt6765_audio_drv);
MODULE_LICENSE("GPL");
......@@ -18,14 +18,8 @@ static const struct mtk_gate_regs cam_cg_regs = {
.sta_ofs = 0x0,
};
#define GATE_CAM(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &cam_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_setclr, \
}
#define GATE_CAM(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &cam_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
static const struct mtk_gate cam_clks[] = {
GATE_CAM(CLK_CAM_LARB3, "cam_larb3", "mm_ck", 0),
......@@ -52,6 +46,7 @@ static const struct of_device_id of_match_clk_mt6765_cam[] = {
/* sentinel */
}
};
MODULE_DEVICE_TABLE(of, of_match_clk_mt6765_cam);
static struct platform_driver clk_mt6765_cam_drv = {
.probe = mtk_clk_simple_probe,
......@@ -61,5 +56,5 @@ static struct platform_driver clk_mt6765_cam_drv = {
.of_match_table = of_match_clk_mt6765_cam,
},
};
builtin_platform_driver(clk_mt6765_cam_drv);
module_platform_driver(clk_mt6765_cam_drv);
MODULE_LICENSE("GPL");
......@@ -18,14 +18,8 @@ static const struct mtk_gate_regs img_cg_regs = {
.sta_ofs = 0x0,
};
#define GATE_IMG(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &img_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_setclr, \
}
#define GATE_IMG(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &img_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
static const struct mtk_gate img_clks[] = {
GATE_IMG(CLK_IMG_LARB2, "img_larb2", "mm_ck", 0),
......@@ -48,6 +42,7 @@ static const struct of_device_id of_match_clk_mt6765_img[] = {
/* sentinel */
}
};
MODULE_DEVICE_TABLE(of, of_match_clk_mt6765_img);
static struct platform_driver clk_mt6765_img_drv = {
.probe = mtk_clk_simple_probe,
......@@ -57,5 +52,5 @@ static struct platform_driver clk_mt6765_img_drv = {
.of_match_table = of_match_clk_mt6765_img,
},
};
builtin_platform_driver(clk_mt6765_img_drv);
module_platform_driver(clk_mt6765_img_drv);
MODULE_LICENSE("GPL");
......@@ -18,14 +18,8 @@ static const struct mtk_gate_regs mipi0a_cg_regs = {
.sta_ofs = 0x80,
};
#define GATE_MIPI0A(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &mipi0a_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_no_setclr_inv, \
}
#define GATE_MIPI0A(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &mipi0a_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
static const struct mtk_gate mipi0a_clks[] = {
GATE_MIPI0A(CLK_MIPI0A_CSR_CSI_EN_0A,
......@@ -45,6 +39,7 @@ static const struct of_device_id of_match_clk_mt6765_mipi0a[] = {
/* sentinel */
}
};
MODULE_DEVICE_TABLE(of, of_match_clk_mt6765_mipi0a);
static struct platform_driver clk_mt6765_mipi0a_drv = {
.probe = mtk_clk_simple_probe,
......@@ -54,5 +49,5 @@ static struct platform_driver clk_mt6765_mipi0a_drv = {
.of_match_table = of_match_clk_mt6765_mipi0a,
},
};
builtin_platform_driver(clk_mt6765_mipi0a_drv);
module_platform_driver(clk_mt6765_mipi0a_drv);
MODULE_LICENSE("GPL");
......@@ -18,14 +18,8 @@ static const struct mtk_gate_regs mm_cg_regs = {
.sta_ofs = 0x100,
};
#define GATE_MM(_id, _name, _parent, _shift) { \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &mm_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_setclr, \
}
#define GATE_MM(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &mm_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
static const struct mtk_gate mm_clks[] = {
/* MM */
......@@ -74,6 +68,7 @@ static const struct of_device_id of_match_clk_mt6765_mm[] = {
/* sentinel */
}
};
MODULE_DEVICE_TABLE(of, of_match_clk_mt6765_mm);
static struct platform_driver clk_mt6765_mm_drv = {
.probe = mtk_clk_simple_probe,
......@@ -83,5 +78,5 @@ static struct platform_driver clk_mt6765_mm_drv = {
.of_match_table = of_match_clk_mt6765_mm,
},
};
builtin_platform_driver(clk_mt6765_mm_drv);
module_platform_driver(clk_mt6765_mm_drv);
MODULE_LICENSE("GPL");
This diff is collapsed.
This diff is collapsed.
......@@ -102,6 +102,7 @@ static const struct of_device_id of_match_clk_mt6779_aud[] = {
/* sentinel */
}
};
MODULE_DEVICE_TABLE(of, of_match_clk_mt6779_aud);
static struct platform_driver clk_mt6779_aud_drv = {
.probe = mtk_clk_simple_probe,
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment