Merge tag 'riscv-sg2042-clk-for-v6.11' of https://github.com/sophgo/linux into clk-sophgo

Pull RISC-V SG2042 clock driver changes from Chen Wang:

 - Add sg2042 clk driver

* tag 'riscv-sg2042-clk-for-v6.11' of https://github.com/sophgo/linux:
  clk: sophgo: Add SG2042 clock driver
  dt-bindings: clock: sophgo: add clkgen for SG2042
  dt-bindings: clock: sophgo: add RP gate clocks for SG2042
  dt-bindings: clock: sophgo: add pll clocks for SG2042
This commit is contained in:
Stephen Boyd
2024-07-08 11:46:31 -07:00
12 changed files with 2409 additions and 0 deletions

View File

@@ -0,0 +1,61 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/sophgo,sg2042-clkgen.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Sophgo SG2042 Clock Generator for divider/mux/gate
maintainers:
- Chen Wang <unicorn_wang@outlook.com>
properties:
compatible:
const: sophgo,sg2042-clkgen
reg:
maxItems: 1
clocks:
items:
- description: Main PLL
- description: Fixed PLL
- description: DDR PLL 0
- description: DDR PLL 1
clock-names:
items:
- const: mpll
- const: fpll
- const: dpll0
- const: dpll1
'#clock-cells':
const: 1
description:
See <dt-bindings/clock/sophgo,sg2042-clkgen.h> for valid indices.
required:
- compatible
- reg
- clocks
- clock-names
- '#clock-cells'
additionalProperties: false
examples:
- |
clock-controller@30012000 {
compatible = "sophgo,sg2042-clkgen";
reg = <0x30012000 0x1000>;
clocks = <&pllclk 0>,
<&pllclk 1>,
<&pllclk 2>,
<&pllclk 3>;
clock-names = "mpll",
"fpll",
"dpll0",
"dpll1";
#clock-cells = <1>;
};

View File

@@ -0,0 +1,53 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/sophgo,sg2042-pll.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Sophgo SG2042 PLL Clock Generator
maintainers:
- Chen Wang <unicorn_wang@outlook.com>
properties:
compatible:
const: sophgo,sg2042-pll
reg:
maxItems: 1
clocks:
items:
- description: Oscillator(Clock Generation IC) for Main/Fixed PLL (25 MHz)
- description: Oscillator(Clock Generation IC) for DDR PLL 0 (25 MHz)
- description: Oscillator(Clock Generation IC) for DDR PLL 1 (25 MHz)
clock-names:
items:
- const: cgi_main
- const: cgi_dpll0
- const: cgi_dpll1
'#clock-cells':
const: 1
description:
See <dt-bindings/clock/sophgo,sg2042-pll.h> for valid indices.
required:
- compatible
- reg
- clocks
- clock-names
- '#clock-cells'
additionalProperties: false
examples:
- |
clock-controller@10000000 {
compatible = "sophgo,sg2042-pll";
reg = <0x10000000 0x10000>;
clocks = <&cgi_main>, <&cgi_dpll0>, <&cgi_dpll1>;
clock-names = "cgi_main", "cgi_dpll0", "cgi_dpll1";
#clock-cells = <1>;
};

View File

@@ -0,0 +1,49 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/sophgo,sg2042-rpgate.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Sophgo SG2042 Gate Clock Generator for RP(riscv processors) subsystem
maintainers:
- Chen Wang <unicorn_wang@outlook.com>
properties:
compatible:
const: sophgo,sg2042-rpgate
reg:
maxItems: 1
clocks:
items:
- description: Gate clock for RP subsystem
clock-names:
items:
- const: rpgate
'#clock-cells':
const: 1
description:
See <dt-bindings/clock/sophgo,sg2042-rpgate.h> for valid indices.
required:
- compatible
- reg
- clocks
- clock-names
- '#clock-cells'
additionalProperties: false
examples:
- |
clock-controller@20000000 {
compatible = "sophgo,sg2042-rpgate";
reg = <0x20000000 0x10000>;
clocks = <&clkgen 85>;
clock-names = "rpgate";
#clock-cells = <1>;
};

View File

@@ -9,3 +9,31 @@ config CLK_SOPHGO_CV1800
The driver require a 25MHz Oscillator to function generate clock.
It includes PLLs, common clock function and some vendor clock for
IPs of CV18XX series SoC
config CLK_SOPHGO_SG2042_PLL
tristate "Sophgo SG2042 PLL clock support"
depends on ARCH_SOPHGO || COMPILE_TEST
help
This driver supports the PLL clock controller on the
Sophgo SG2042 SoC. This clock IP uses three oscillators with
frequency of 25 MHz as input, which are used for Main/Fixed
PLL, DDR PLL 0 and DDR PLL 1 respectively.
config CLK_SOPHGO_SG2042_CLKGEN
tristate "Sophgo SG2042 Clock Generator support"
depends on CLK_SOPHGO_SG2042_PLL
help
This driver supports the Clock Generator on the
Sophgo SG2042 SoC. This clock IP depends on SG2042 PLL clock
because it uses PLL clocks as input.
This driver provides clock function such as DIV/Mux/Gate.
config CLK_SOPHGO_SG2042_RPGATE
tristate "Sophgo SG2042 RP subsystem clock controller support"
depends on CLK_SOPHGO_SG2042_CLKGEN
help
This driver supports the RP((Riscv Processors)) subsystem clock
controller on the Sophgo SG2042 SoC.
This clock IP depends on SG2042 Clock Generator because it uses
clock from Clock Generator IP as input.
This driver provides Gate function for RP.

View File

@@ -5,3 +5,7 @@ clk-sophgo-cv1800-y += clk-cv1800.o
clk-sophgo-cv1800-y += clk-cv18xx-common.o
clk-sophgo-cv1800-y += clk-cv18xx-ip.o
clk-sophgo-cv1800-y += clk-cv18xx-pll.o
obj-$(CONFIG_CLK_SOPHGO_SG2042_CLKGEN) += clk-sg2042-clkgen.o
obj-$(CONFIG_CLK_SOPHGO_SG2042_PLL) += clk-sg2042-pll.o
obj-$(CONFIG_CLK_SOPHGO_SG2042_RPGATE) += clk-sg2042-rpgate.o

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,570 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Sophgo SG2042 PLL clock Driver
*
* Copyright (C) 2024 Sophgo Technology Inc.
* Copyright (C) 2024 Chen Wang <unicorn_wang@outlook.com>
*/
#include <linux/array_size.h>
#include <linux/bitfield.h>
#include <linux/bits.h>
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/platform_device.h>
#include <asm/div64.h>
#include <dt-bindings/clock/sophgo,sg2042-pll.h>
#include "clk-sg2042.h"
/* Registers defined in SYS_CTRL */
#define R_PLL_BEGIN 0xC0
#define R_PLL_STAT (0xC0 - R_PLL_BEGIN)
#define R_PLL_CLKEN_CONTROL (0xC4 - R_PLL_BEGIN)
#define R_MPLL_CONTROL (0xE8 - R_PLL_BEGIN)
#define R_FPLL_CONTROL (0xF4 - R_PLL_BEGIN)
#define R_DPLL0_CONTROL (0xF8 - R_PLL_BEGIN)
#define R_DPLL1_CONTROL (0xFC - R_PLL_BEGIN)
/**
* struct sg2042_pll_clock - PLL clock
* @hw: clk_hw for initialization
* @id: used to map clk_onecell_data
* @base: used for readl/writel.
* **NOTE**: PLL registers are all in SYS_CTRL!
* @lock: spinlock to protect register access, modification
* of frequency can only be served one at the time.
* @offset_ctrl: offset of pll control registers
* @shift_status_lock: shift of XXX_LOCK in pll status register
* @shift_status_updating: shift of UPDATING_XXX in pll status register
* @shift_enable: shift of XXX_CLK_EN in pll enable register
*/
struct sg2042_pll_clock {
struct clk_hw hw;
unsigned int id;
void __iomem *base;
/* protect register access */
spinlock_t *lock;
u32 offset_ctrl;
u8 shift_status_lock;
u8 shift_status_updating;
u8 shift_enable;
};
#define to_sg2042_pll_clk(_hw) container_of(_hw, struct sg2042_pll_clock, hw)
#define KHZ 1000UL
#define MHZ (KHZ * KHZ)
#define REFDIV_MIN 1
#define REFDIV_MAX 63
#define FBDIV_MIN 16
#define FBDIV_MAX 320
#define PLL_FREF_SG2042 (25 * MHZ)
#define PLL_FOUTPOSTDIV_MIN (16 * MHZ)
#define PLL_FOUTPOSTDIV_MAX (3200 * MHZ)
#define PLL_FOUTVCO_MIN (800 * MHZ)
#define PLL_FOUTVCO_MAX (3200 * MHZ)
struct sg2042_pll_ctrl {
unsigned long freq;
unsigned int fbdiv;
unsigned int postdiv1;
unsigned int postdiv2;
unsigned int refdiv;
};
#define PLLCTRL_FBDIV_MASK GENMASK(27, 16)
#define PLLCTRL_POSTDIV2_MASK GENMASK(14, 12)
#define PLLCTRL_POSTDIV1_MASK GENMASK(10, 8)
#define PLLCTRL_REFDIV_MASK GENMASK(5, 0)
static inline u32 sg2042_pll_ctrl_encode(struct sg2042_pll_ctrl *ctrl)
{
return FIELD_PREP(PLLCTRL_FBDIV_MASK, ctrl->fbdiv) |
FIELD_PREP(PLLCTRL_POSTDIV2_MASK, ctrl->postdiv2) |
FIELD_PREP(PLLCTRL_POSTDIV1_MASK, ctrl->postdiv1) |
FIELD_PREP(PLLCTRL_REFDIV_MASK, ctrl->refdiv);
}
static inline void sg2042_pll_ctrl_decode(unsigned int reg_value,
struct sg2042_pll_ctrl *ctrl)
{
ctrl->fbdiv = FIELD_GET(PLLCTRL_FBDIV_MASK, reg_value);
ctrl->refdiv = FIELD_GET(PLLCTRL_REFDIV_MASK, reg_value);
ctrl->postdiv1 = FIELD_GET(PLLCTRL_POSTDIV1_MASK, reg_value);
ctrl->postdiv2 = FIELD_GET(PLLCTRL_POSTDIV2_MASK, reg_value);
}
static inline int sg2042_pll_enable(struct sg2042_pll_clock *pll, bool en)
{
u32 value;
if (en) {
/* wait pll lock */
if (readl_poll_timeout_atomic(pll->base + R_PLL_STAT,
value,
((value >> pll->shift_status_lock) & 0x1),
0,
100000))
pr_warn("%s not locked\n", pll->hw.init->name);
/* wait pll updating */
if (readl_poll_timeout_atomic(pll->base + R_PLL_STAT,
value,
!((value >> pll->shift_status_updating) & 0x1),
0,
100000))
pr_warn("%s still updating\n", pll->hw.init->name);
/* enable pll */
value = readl(pll->base + R_PLL_CLKEN_CONTROL);
writel(value | (1 << pll->shift_enable), pll->base + R_PLL_CLKEN_CONTROL);
} else {
/* disable pll */
value = readl(pll->base + R_PLL_CLKEN_CONTROL);
writel(value & (~(1 << pll->shift_enable)), pll->base + R_PLL_CLKEN_CONTROL);
}
return 0;
}
/**
* sg2042_pll_recalc_rate() - Calculate rate for plls
* @reg_value: current register value
* @parent_rate: parent frequency
*
* This function is used to calculate below "rate" in equation
* rate = (parent_rate/REFDIV) x FBDIV/POSTDIV1/POSTDIV2
* = (parent_rate x FBDIV) / (REFDIV x POSTDIV1 x POSTDIV2)
*
* Return: The rate calculated.
*/
static unsigned long sg2042_pll_recalc_rate(unsigned int reg_value,
unsigned long parent_rate)
{
struct sg2042_pll_ctrl ctrl_table;
u64 numerator, denominator;
sg2042_pll_ctrl_decode(reg_value, &ctrl_table);
numerator = parent_rate * ctrl_table.fbdiv;
denominator = ctrl_table.refdiv * ctrl_table.postdiv1 * ctrl_table.postdiv2;
do_div(numerator, denominator);
return numerator;
}
/**
* sg2042_pll_get_postdiv_1_2() - Based on input rate/prate/fbdiv/refdiv,
* look up the postdiv1_2 table to get the closest postdiiv combination.
* @rate: FOUTPOSTDIV
* @prate: parent rate, i.e. FREF
* @fbdiv: FBDIV
* @refdiv: REFDIV
* @postdiv1: POSTDIV1, output
* @postdiv2: POSTDIV2, output
*
* postdiv1_2 contains all the possible combination lists of POSTDIV1 and POSTDIV2
* for example:
* postdiv1_2[0] = {2, 4, 8}, where div1 = 2, div2 = 4 , div1 * div2 = 8
*
* See TRM:
* FOUTPOSTDIV = FREF * FBDIV / REFDIV / (POSTDIV1 * POSTDIV2)
* So we get following formula to get POSTDIV1 and POSTDIV2:
* POSTDIV = (prate/REFDIV) x FBDIV/rate
* above POSTDIV = POSTDIV1*POSTDIV2
*
* Return:
* %0 - OK
* %-EINVAL - invalid argument, which means Failed to get the postdivs.
*/
static int sg2042_pll_get_postdiv_1_2(unsigned long rate,
unsigned long prate,
unsigned int fbdiv,
unsigned int refdiv,
unsigned int *postdiv1,
unsigned int *postdiv2)
{
int index;
u64 tmp0;
/* POSTDIV_RESULT_INDEX point to 3rd element in the array postdiv1_2 */
#define POSTDIV_RESULT_INDEX 2
static const int postdiv1_2[][3] = {
{2, 4, 8}, {3, 3, 9}, {2, 5, 10}, {2, 6, 12},
{2, 7, 14}, {3, 5, 15}, {4, 4, 16}, {3, 6, 18},
{4, 5, 20}, {3, 7, 21}, {4, 6, 24}, {5, 5, 25},
{4, 7, 28}, {5, 6, 30}, {5, 7, 35}, {6, 6, 36},
{6, 7, 42}, {7, 7, 49}
};
/* prate/REFDIV and result save to tmp0 */
tmp0 = prate;
do_div(tmp0, refdiv);
/* ((prate/REFDIV) x FBDIV) and result save to tmp0 */
tmp0 *= fbdiv;
/* ((prate/REFDIV) x FBDIV)/rate and result save to tmp0 */
do_div(tmp0, rate);
/* tmp0 is POSTDIV1*POSTDIV2, now we calculate div1 and div2 value */
if (tmp0 <= 7) {
/* (div1 * div2) <= 7, no need to use array search */
*postdiv1 = tmp0;
*postdiv2 = 1;
return 0;
}
/* (div1 * div2) > 7, use array search */
for (index = 0; index < ARRAY_SIZE(postdiv1_2); index++) {
if (tmp0 > postdiv1_2[index][POSTDIV_RESULT_INDEX]) {
continue;
} else {
/* found it */
*postdiv1 = postdiv1_2[index][1];
*postdiv2 = postdiv1_2[index][0];
return 0;
}
}
pr_warn("%s can not find in postdiv array!\n", __func__);
return -EINVAL;
}
/**
* sg2042_get_pll_ctl_setting() - Based on the given FOUTPISTDIV and the input
* FREF to calculate the REFDIV/FBDIV/PSTDIV1/POSTDIV2 combination for pllctrl
* register.
* @req_rate: expected output clock rate, i.e. FOUTPISTDIV
* @parent_rate: input parent clock rate, i.e. FREF
* @best: output to hold calculated combination of REFDIV/FBDIV/PSTDIV1/POSTDIV2
*
* Return:
* %0 - OK
* %-EINVAL - invalid argument
*/
static int sg2042_get_pll_ctl_setting(struct sg2042_pll_ctrl *best,
unsigned long req_rate,
unsigned long parent_rate)
{
unsigned int fbdiv, refdiv, postdiv1, postdiv2;
unsigned long foutpostdiv;
u64 foutvco;
int ret;
u64 tmp;
if (parent_rate != PLL_FREF_SG2042) {
pr_err("INVALID FREF: %ld\n", parent_rate);
return -EINVAL;
}
if (req_rate < PLL_FOUTPOSTDIV_MIN || req_rate > PLL_FOUTPOSTDIV_MAX) {
pr_alert("INVALID FOUTPOSTDIV: %ld\n", req_rate);
return -EINVAL;
}
memset(best, 0, sizeof(struct sg2042_pll_ctrl));
for (refdiv = REFDIV_MIN; refdiv < REFDIV_MAX + 1; refdiv++) {
/* required by hardware: FREF/REFDIV must > 10 */
tmp = parent_rate;
do_div(tmp, refdiv);
if (tmp <= 10)
continue;
for (fbdiv = FBDIV_MIN; fbdiv < FBDIV_MAX + 1; fbdiv++) {
/*
* FOUTVCO = FREF*FBDIV/REFDIV validation
* required by hardware, FOUTVCO must [800MHz, 3200MHz]
*/
foutvco = parent_rate * fbdiv;
do_div(foutvco, refdiv);
if (foutvco < PLL_FOUTVCO_MIN || foutvco > PLL_FOUTVCO_MAX)
continue;
ret = sg2042_pll_get_postdiv_1_2(req_rate, parent_rate,
fbdiv, refdiv,
&postdiv1, &postdiv2);
if (ret)
continue;
/*
* FOUTPOSTDIV = FREF*FBDIV/REFDIV/(POSTDIV1*POSTDIV2)
* = FOUTVCO/(POSTDIV1*POSTDIV2)
*/
tmp = foutvco;
do_div(tmp, (postdiv1 * postdiv2));
foutpostdiv = (unsigned long)tmp;
/* Iterative to approach the expected value */
if (abs_diff(foutpostdiv, req_rate) < abs_diff(best->freq, req_rate)) {
best->freq = foutpostdiv;
best->refdiv = refdiv;
best->fbdiv = fbdiv;
best->postdiv1 = postdiv1;
best->postdiv2 = postdiv2;
if (foutpostdiv == req_rate)
return 0;
}
continue;
}
}
if (best->freq == 0)
return -EINVAL;
else
return 0;
}
/**
* sg2042_clk_pll_recalc_rate() - recalc_rate callback for pll clks
* @hw: ccf use to hook get sg2042_pll_clock
* @parent_rate: parent rate
*
* The is function will be called through clk_get_rate
* and return current rate after decoding reg value
*
* Return: Current rate recalculated.
*/
static unsigned long sg2042_clk_pll_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct sg2042_pll_clock *pll = to_sg2042_pll_clk(hw);
unsigned long rate;
u32 value;
value = readl(pll->base + pll->offset_ctrl);
rate = sg2042_pll_recalc_rate(value, parent_rate);
pr_debug("--> %s: pll_recalc_rate: val = %ld\n",
clk_hw_get_name(hw), rate);
return rate;
}
static long sg2042_clk_pll_round_rate(struct clk_hw *hw,
unsigned long req_rate,
unsigned long *prate)
{
struct sg2042_pll_ctrl pctrl_table;
unsigned int value;
long proper_rate;
int ret;
ret = sg2042_get_pll_ctl_setting(&pctrl_table, req_rate, *prate);
if (ret) {
proper_rate = 0;
goto out;
}
value = sg2042_pll_ctrl_encode(&pctrl_table);
proper_rate = (long)sg2042_pll_recalc_rate(value, *prate);
out:
pr_debug("--> %s: pll_round_rate: val = %ld\n",
clk_hw_get_name(hw), proper_rate);
return proper_rate;
}
static int sg2042_clk_pll_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
req->rate = sg2042_clk_pll_round_rate(hw, min(req->rate, req->max_rate),
&req->best_parent_rate);
pr_debug("--> %s: pll_determine_rate: val = %ld\n",
clk_hw_get_name(hw), req->rate);
return 0;
}
static int sg2042_clk_pll_set_rate(struct clk_hw *hw,
unsigned long rate,
unsigned long parent_rate)
{
struct sg2042_pll_clock *pll = to_sg2042_pll_clk(hw);
struct sg2042_pll_ctrl pctrl_table;
unsigned long flags;
u32 value;
int ret;
spin_lock_irqsave(pll->lock, flags);
if (sg2042_pll_enable(pll, 0)) {
pr_warn("Can't disable pll(%s), status error\n", pll->hw.init->name);
goto out;
}
ret = sg2042_get_pll_ctl_setting(&pctrl_table, rate, parent_rate);
if (ret) {
pr_warn("%s: Can't find a proper pll setting\n", pll->hw.init->name);
goto out2;
}
value = sg2042_pll_ctrl_encode(&pctrl_table);
/* write the value to top register */
writel(value, pll->base + pll->offset_ctrl);
out2:
sg2042_pll_enable(pll, 1);
out:
spin_unlock_irqrestore(pll->lock, flags);
pr_debug("--> %s: pll_set_rate: val = 0x%x\n",
clk_hw_get_name(hw), value);
return ret;
}
static const struct clk_ops sg2042_clk_pll_ops = {
.recalc_rate = sg2042_clk_pll_recalc_rate,
.round_rate = sg2042_clk_pll_round_rate,
.determine_rate = sg2042_clk_pll_determine_rate,
.set_rate = sg2042_clk_pll_set_rate,
};
static const struct clk_ops sg2042_clk_pll_ro_ops = {
.recalc_rate = sg2042_clk_pll_recalc_rate,
.round_rate = sg2042_clk_pll_round_rate,
};
/*
* Clock initialization macro naming rules:
* FW: use CLK_HW_INIT_FW_NAME
* RO: means Read-Only
*/
#define SG2042_PLL_FW(_id, _name, _parent, _r_ctrl, _shift) \
{ \
.id = _id, \
.hw.init = CLK_HW_INIT_FW_NAME( \
_name, \
_parent, \
&sg2042_clk_pll_ops, \
CLK_GET_RATE_NOCACHE | CLK_GET_ACCURACY_NOCACHE),\
.offset_ctrl = _r_ctrl, \
.shift_status_lock = 8 + (_shift), \
.shift_status_updating = _shift, \
.shift_enable = _shift, \
}
#define SG2042_PLL_FW_RO(_id, _name, _parent, _r_ctrl, _shift) \
{ \
.id = _id, \
.hw.init = CLK_HW_INIT_FW_NAME( \
_name, \
_parent, \
&sg2042_clk_pll_ro_ops, \
CLK_GET_RATE_NOCACHE | CLK_GET_ACCURACY_NOCACHE),\
.offset_ctrl = _r_ctrl, \
.shift_status_lock = 8 + (_shift), \
.shift_status_updating = _shift, \
.shift_enable = _shift, \
}
static struct sg2042_pll_clock sg2042_pll_clks[] = {
SG2042_PLL_FW(MPLL_CLK, "mpll_clock", "cgi_main", R_MPLL_CONTROL, 0),
SG2042_PLL_FW_RO(FPLL_CLK, "fpll_clock", "cgi_main", R_FPLL_CONTROL, 3),
SG2042_PLL_FW_RO(DPLL0_CLK, "dpll0_clock", "cgi_dpll0", R_DPLL0_CONTROL, 4),
SG2042_PLL_FW_RO(DPLL1_CLK, "dpll1_clock", "cgi_dpll1", R_DPLL1_CONTROL, 5),
};
static DEFINE_SPINLOCK(sg2042_clk_lock);
static int sg2042_clk_register_plls(struct device *dev,
struct sg2042_clk_data *clk_data,
struct sg2042_pll_clock pll_clks[],
int num_pll_clks)
{
struct sg2042_pll_clock *pll;
struct clk_hw *hw;
int i, ret = 0;
for (i = 0; i < num_pll_clks; i++) {
pll = &pll_clks[i];
/* assign these for ops usage during registration */
pll->base = clk_data->iobase;
pll->lock = &sg2042_clk_lock;
hw = &pll->hw;
ret = devm_clk_hw_register(dev, hw);
if (ret) {
pr_err("failed to register clock %s\n", pll->hw.init->name);
break;
}
clk_data->onecell_data.hws[pll->id] = hw;
}
return ret;
}
static int sg2042_init_clkdata(struct platform_device *pdev,
int num_clks,
struct sg2042_clk_data **pp_clk_data)
{
struct sg2042_clk_data *clk_data;
clk_data = devm_kzalloc(&pdev->dev,
struct_size(clk_data, onecell_data.hws, num_clks),
GFP_KERNEL);
if (!clk_data)
return -ENOMEM;
clk_data->iobase = devm_platform_ioremap_resource(pdev, 0);
if (WARN_ON(IS_ERR(clk_data->iobase)))
return PTR_ERR(clk_data->iobase);
clk_data->onecell_data.num = num_clks;
*pp_clk_data = clk_data;
return 0;
}
static int sg2042_pll_probe(struct platform_device *pdev)
{
struct sg2042_clk_data *clk_data = NULL;
int num_clks;
int ret;
num_clks = ARRAY_SIZE(sg2042_pll_clks);
ret = sg2042_init_clkdata(pdev, num_clks, &clk_data);
if (ret)
goto error_out;
ret = sg2042_clk_register_plls(&pdev->dev, clk_data, sg2042_pll_clks,
num_clks);
if (ret)
goto error_out;
return devm_of_clk_add_hw_provider(&pdev->dev,
of_clk_hw_onecell_get,
&clk_data->onecell_data);
error_out:
pr_err("%s failed error number %d\n", __func__, ret);
return ret;
}
static const struct of_device_id sg2042_pll_match[] = {
{ .compatible = "sophgo,sg2042-pll" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, sg2042_pll_match);
static struct platform_driver sg2042_pll_driver = {
.probe = sg2042_pll_probe,
.driver = {
.name = "clk-sophgo-sg2042-pll",
.of_match_table = sg2042_pll_match,
.suppress_bind_attrs = true,
},
};
module_platform_driver(sg2042_pll_driver);
MODULE_AUTHOR("Chen Wang");
MODULE_DESCRIPTION("Sophgo SG2042 pll clock driver");
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,291 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Sophgo SG2042 RP clock Driver
*
* Copyright (C) 2024 Sophgo Technology Inc.
* Copyright (C) 2024 Chen Wang <unicorn_wang@outlook.com>
*/
#include <linux/array_size.h>
#include <linux/clk-provider.h>
#include <linux/platform_device.h>
#include <dt-bindings/clock/sophgo,sg2042-rpgate.h>
#include "clk-sg2042.h"
#define R_SYSGATE_BEGIN 0x0368
#define R_RP_RXU_CLK_ENABLE (0x0368 - R_SYSGATE_BEGIN)
#define R_MP0_STATUS_REG (0x0380 - R_SYSGATE_BEGIN)
#define R_MP0_CONTROL_REG (0x0384 - R_SYSGATE_BEGIN)
#define R_MP1_STATUS_REG (0x0388 - R_SYSGATE_BEGIN)
#define R_MP1_CONTROL_REG (0x038C - R_SYSGATE_BEGIN)
#define R_MP2_STATUS_REG (0x0390 - R_SYSGATE_BEGIN)
#define R_MP2_CONTROL_REG (0x0394 - R_SYSGATE_BEGIN)
#define R_MP3_STATUS_REG (0x0398 - R_SYSGATE_BEGIN)
#define R_MP3_CONTROL_REG (0x039C - R_SYSGATE_BEGIN)
#define R_MP4_STATUS_REG (0x03A0 - R_SYSGATE_BEGIN)
#define R_MP4_CONTROL_REG (0x03A4 - R_SYSGATE_BEGIN)
#define R_MP5_STATUS_REG (0x03A8 - R_SYSGATE_BEGIN)
#define R_MP5_CONTROL_REG (0x03AC - R_SYSGATE_BEGIN)
#define R_MP6_STATUS_REG (0x03B0 - R_SYSGATE_BEGIN)
#define R_MP6_CONTROL_REG (0x03B4 - R_SYSGATE_BEGIN)
#define R_MP7_STATUS_REG (0x03B8 - R_SYSGATE_BEGIN)
#define R_MP7_CONTROL_REG (0x03BC - R_SYSGATE_BEGIN)
#define R_MP8_STATUS_REG (0x03C0 - R_SYSGATE_BEGIN)
#define R_MP8_CONTROL_REG (0x03C4 - R_SYSGATE_BEGIN)
#define R_MP9_STATUS_REG (0x03C8 - R_SYSGATE_BEGIN)
#define R_MP9_CONTROL_REG (0x03CC - R_SYSGATE_BEGIN)
#define R_MP10_STATUS_REG (0x03D0 - R_SYSGATE_BEGIN)
#define R_MP10_CONTROL_REG (0x03D4 - R_SYSGATE_BEGIN)
#define R_MP11_STATUS_REG (0x03D8 - R_SYSGATE_BEGIN)
#define R_MP11_CONTROL_REG (0x03DC - R_SYSGATE_BEGIN)
#define R_MP12_STATUS_REG (0x03E0 - R_SYSGATE_BEGIN)
#define R_MP12_CONTROL_REG (0x03E4 - R_SYSGATE_BEGIN)
#define R_MP13_STATUS_REG (0x03E8 - R_SYSGATE_BEGIN)
#define R_MP13_CONTROL_REG (0x03EC - R_SYSGATE_BEGIN)
#define R_MP14_STATUS_REG (0x03F0 - R_SYSGATE_BEGIN)
#define R_MP14_CONTROL_REG (0x03F4 - R_SYSGATE_BEGIN)
#define R_MP15_STATUS_REG (0x03F8 - R_SYSGATE_BEGIN)
#define R_MP15_CONTROL_REG (0x03FC - R_SYSGATE_BEGIN)
/**
* struct sg2042_rpgate_clock - Gate clock for RP(riscv processors) subsystem
* @hw: clk_hw for initialization
* @id: used to map clk_onecell_data
* @offset_enable: offset of gate enable registers
* @bit_idx: which bit in the register controls gating of this clock
*/
struct sg2042_rpgate_clock {
struct clk_hw hw;
unsigned int id;
u32 offset_enable;
u8 bit_idx;
};
/*
* Clock initialization macro naming rules:
* FW: use CLK_HW_INIT_FW_NAME
*/
#define SG2042_GATE_FW(_id, _name, _parent, _flags, \
_r_enable, _bit_idx) { \
.hw.init = CLK_HW_INIT_FW_NAME( \
_name, \
_parent, \
NULL, \
_flags), \
.id = _id, \
.offset_enable = _r_enable, \
.bit_idx = _bit_idx, \
}
/*
* Gate clocks for RP subsystem (including the MP subsystem), which control
* registers are defined in SYS_CTRL.
*/
static const struct sg2042_rpgate_clock sg2042_gate_rp[] = {
/* downstream of clk_gate_rp_cpu_normal about rxu */
SG2042_GATE_FW(GATE_CLK_RXU0, "clk_gate_rxu0", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 0),
SG2042_GATE_FW(GATE_CLK_RXU1, "clk_gate_rxu1", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 1),
SG2042_GATE_FW(GATE_CLK_RXU2, "clk_gate_rxu2", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 2),
SG2042_GATE_FW(GATE_CLK_RXU3, "clk_gate_rxu3", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 3),
SG2042_GATE_FW(GATE_CLK_RXU4, "clk_gate_rxu4", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 4),
SG2042_GATE_FW(GATE_CLK_RXU5, "clk_gate_rxu5", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 5),
SG2042_GATE_FW(GATE_CLK_RXU6, "clk_gate_rxu6", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 6),
SG2042_GATE_FW(GATE_CLK_RXU7, "clk_gate_rxu7", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 7),
SG2042_GATE_FW(GATE_CLK_RXU8, "clk_gate_rxu8", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 8),
SG2042_GATE_FW(GATE_CLK_RXU9, "clk_gate_rxu9", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 9),
SG2042_GATE_FW(GATE_CLK_RXU10, "clk_gate_rxu10", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 10),
SG2042_GATE_FW(GATE_CLK_RXU11, "clk_gate_rxu11", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 11),
SG2042_GATE_FW(GATE_CLK_RXU12, "clk_gate_rxu12", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 12),
SG2042_GATE_FW(GATE_CLK_RXU13, "clk_gate_rxu13", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 13),
SG2042_GATE_FW(GATE_CLK_RXU14, "clk_gate_rxu14", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 14),
SG2042_GATE_FW(GATE_CLK_RXU15, "clk_gate_rxu15", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 15),
SG2042_GATE_FW(GATE_CLK_RXU16, "clk_gate_rxu16", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 16),
SG2042_GATE_FW(GATE_CLK_RXU17, "clk_gate_rxu17", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 17),
SG2042_GATE_FW(GATE_CLK_RXU18, "clk_gate_rxu18", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 18),
SG2042_GATE_FW(GATE_CLK_RXU19, "clk_gate_rxu19", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 19),
SG2042_GATE_FW(GATE_CLK_RXU20, "clk_gate_rxu20", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 20),
SG2042_GATE_FW(GATE_CLK_RXU21, "clk_gate_rxu21", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 21),
SG2042_GATE_FW(GATE_CLK_RXU22, "clk_gate_rxu22", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 22),
SG2042_GATE_FW(GATE_CLK_RXU23, "clk_gate_rxu23", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 23),
SG2042_GATE_FW(GATE_CLK_RXU24, "clk_gate_rxu24", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 24),
SG2042_GATE_FW(GATE_CLK_RXU25, "clk_gate_rxu25", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 25),
SG2042_GATE_FW(GATE_CLK_RXU26, "clk_gate_rxu26", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 26),
SG2042_GATE_FW(GATE_CLK_RXU27, "clk_gate_rxu27", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 27),
SG2042_GATE_FW(GATE_CLK_RXU28, "clk_gate_rxu28", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 28),
SG2042_GATE_FW(GATE_CLK_RXU29, "clk_gate_rxu29", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 29),
SG2042_GATE_FW(GATE_CLK_RXU30, "clk_gate_rxu30", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 30),
SG2042_GATE_FW(GATE_CLK_RXU31, "clk_gate_rxu31", "rpgate",
0, R_RP_RXU_CLK_ENABLE, 31),
/* downstream of clk_gate_rp_cpu_normal about mp */
SG2042_GATE_FW(GATE_CLK_MP0, "clk_gate_mp0", "rpgate",
CLK_IS_CRITICAL, R_MP0_CONTROL_REG, 0),
SG2042_GATE_FW(GATE_CLK_MP1, "clk_gate_mp1", "rpgate",
CLK_IS_CRITICAL, R_MP1_CONTROL_REG, 0),
SG2042_GATE_FW(GATE_CLK_MP2, "clk_gate_mp2", "rpgate",
CLK_IS_CRITICAL, R_MP2_CONTROL_REG, 0),
SG2042_GATE_FW(GATE_CLK_MP3, "clk_gate_mp3", "rpgate",
CLK_IS_CRITICAL, R_MP3_CONTROL_REG, 0),
SG2042_GATE_FW(GATE_CLK_MP4, "clk_gate_mp4", "rpgate",
CLK_IS_CRITICAL, R_MP4_CONTROL_REG, 0),
SG2042_GATE_FW(GATE_CLK_MP5, "clk_gate_mp5", "rpgate",
CLK_IS_CRITICAL, R_MP5_CONTROL_REG, 0),
SG2042_GATE_FW(GATE_CLK_MP6, "clk_gate_mp6", "rpgate",
CLK_IS_CRITICAL, R_MP6_CONTROL_REG, 0),
SG2042_GATE_FW(GATE_CLK_MP7, "clk_gate_mp7", "rpgate",
CLK_IS_CRITICAL, R_MP7_CONTROL_REG, 0),
SG2042_GATE_FW(GATE_CLK_MP8, "clk_gate_mp8", "rpgate",
CLK_IS_CRITICAL, R_MP8_CONTROL_REG, 0),
SG2042_GATE_FW(GATE_CLK_MP9, "clk_gate_mp9", "rpgate",
CLK_IS_CRITICAL, R_MP9_CONTROL_REG, 0),
SG2042_GATE_FW(GATE_CLK_MP10, "clk_gate_mp10", "rpgate",
CLK_IS_CRITICAL, R_MP10_CONTROL_REG, 0),
SG2042_GATE_FW(GATE_CLK_MP11, "clk_gate_mp11", "rpgate",
CLK_IS_CRITICAL, R_MP11_CONTROL_REG, 0),
SG2042_GATE_FW(GATE_CLK_MP12, "clk_gate_mp12", "rpgate",
CLK_IS_CRITICAL, R_MP12_CONTROL_REG, 0),
SG2042_GATE_FW(GATE_CLK_MP13, "clk_gate_mp13", "rpgate",
CLK_IS_CRITICAL, R_MP13_CONTROL_REG, 0),
SG2042_GATE_FW(GATE_CLK_MP14, "clk_gate_mp14", "rpgate",
CLK_IS_CRITICAL, R_MP14_CONTROL_REG, 0),
SG2042_GATE_FW(GATE_CLK_MP15, "clk_gate_mp15", "rpgate",
CLK_IS_CRITICAL, R_MP15_CONTROL_REG, 0),
};
static DEFINE_SPINLOCK(sg2042_clk_lock);
static int sg2042_clk_register_rpgates(struct device *dev,
struct sg2042_clk_data *clk_data,
const struct sg2042_rpgate_clock gate_clks[],
int num_gate_clks)
{
const struct sg2042_rpgate_clock *gate;
struct clk_hw *hw;
int i, ret = 0;
for (i = 0; i < num_gate_clks; i++) {
gate = &gate_clks[i];
hw = devm_clk_hw_register_gate_parent_data
(dev,
gate->hw.init->name,
gate->hw.init->parent_data,
gate->hw.init->flags,
clk_data->iobase + gate->offset_enable,
gate->bit_idx,
0,
&sg2042_clk_lock);
if (IS_ERR(hw)) {
pr_err("failed to register clock %s\n", gate->hw.init->name);
ret = PTR_ERR(hw);
break;
}
clk_data->onecell_data.hws[gate->id] = hw;
}
return ret;
}
static int sg2042_init_clkdata(struct platform_device *pdev,
int num_clks,
struct sg2042_clk_data **pp_clk_data)
{
struct sg2042_clk_data *clk_data;
clk_data = devm_kzalloc(&pdev->dev,
struct_size(clk_data, onecell_data.hws, num_clks),
GFP_KERNEL);
if (!clk_data)
return -ENOMEM;
clk_data->iobase = devm_platform_ioremap_resource(pdev, 0);
if (WARN_ON(IS_ERR(clk_data->iobase)))
return PTR_ERR(clk_data->iobase);
clk_data->onecell_data.num = num_clks;
*pp_clk_data = clk_data;
return 0;
}
static int sg2042_rpgate_probe(struct platform_device *pdev)
{
struct sg2042_clk_data *clk_data = NULL;
int num_clks;
int ret;
num_clks = ARRAY_SIZE(sg2042_gate_rp);
ret = sg2042_init_clkdata(pdev, num_clks, &clk_data);
if (ret)
goto error_out;
ret = sg2042_clk_register_rpgates(&pdev->dev, clk_data, sg2042_gate_rp,
num_clks);
if (ret)
goto error_out;
return devm_of_clk_add_hw_provider(&pdev->dev,
of_clk_hw_onecell_get,
&clk_data->onecell_data);
error_out:
pr_err("%s failed error number %d\n", __func__, ret);
return ret;
}
static const struct of_device_id sg2042_rpgate_match[] = {
{ .compatible = "sophgo,sg2042-rpgate" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, sg2042_rpgate_match);
static struct platform_driver sg2042_rpgate_driver = {
.probe = sg2042_rpgate_probe,
.driver = {
.name = "clk-sophgo-sg2042-rpgate",
.of_match_table = sg2042_rpgate_match,
.suppress_bind_attrs = true,
},
};
module_platform_driver(sg2042_rpgate_driver);
MODULE_AUTHOR("Chen Wang");
MODULE_DESCRIPTION("Sophgo SG2042 rp subsystem clock driver");
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _CLK_SOPHGO_SG2042_H_
#define _CLK_SOPHGO_SG2042_H_
#include <linux/io.h>
#include <linux/clk-provider.h>
/**
* struct sg2042_clk_data - Common data of clock-controller
* @iobase: base address of clock-controller
* @onecell_data: used for adding providers.
*/
struct sg2042_clk_data {
void __iomem *iobase;
struct clk_hw_onecell_data onecell_data;
};
#endif /* _CLK_SOPHGO_SG2042_H_ */

View File

@@ -0,0 +1,111 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */
/*
* Copyright (C) 2023 Sophgo Technology Inc. All rights reserved.
*/
#ifndef __DT_BINDINGS_SOPHGO_SG2042_CLKGEN_H__
#define __DT_BINDINGS_SOPHGO_SG2042_CLKGEN_H__
#define DIV_CLK_MPLL_RP_CPU_NORMAL_0 0
#define DIV_CLK_MPLL_AXI_DDR_0 1
#define DIV_CLK_FPLL_DDR01_1 2
#define DIV_CLK_FPLL_DDR23_1 3
#define DIV_CLK_FPLL_RP_CPU_NORMAL_1 4
#define DIV_CLK_FPLL_50M_A53 5
#define DIV_CLK_FPLL_TOP_RP_CMN_DIV2 6
#define DIV_CLK_FPLL_UART_500M 7
#define DIV_CLK_FPLL_AHB_LPC 8
#define DIV_CLK_FPLL_EFUSE 9
#define DIV_CLK_FPLL_TX_ETH0 10
#define DIV_CLK_FPLL_PTP_REF_I_ETH0 11
#define DIV_CLK_FPLL_REF_ETH0 12
#define DIV_CLK_FPLL_EMMC 13
#define DIV_CLK_FPLL_SD 14
#define DIV_CLK_FPLL_TOP_AXI0 15
#define DIV_CLK_FPLL_TOP_AXI_HSPERI 16
#define DIV_CLK_FPLL_AXI_DDR_1 17
#define DIV_CLK_FPLL_DIV_TIMER1 18
#define DIV_CLK_FPLL_DIV_TIMER2 19
#define DIV_CLK_FPLL_DIV_TIMER3 20
#define DIV_CLK_FPLL_DIV_TIMER4 21
#define DIV_CLK_FPLL_DIV_TIMER5 22
#define DIV_CLK_FPLL_DIV_TIMER6 23
#define DIV_CLK_FPLL_DIV_TIMER7 24
#define DIV_CLK_FPLL_DIV_TIMER8 25
#define DIV_CLK_FPLL_100K_EMMC 26
#define DIV_CLK_FPLL_100K_SD 27
#define DIV_CLK_FPLL_GPIO_DB 28
#define DIV_CLK_DPLL0_DDR01_0 29
#define DIV_CLK_DPLL1_DDR23_0 30
#define GATE_CLK_RP_CPU_NORMAL_DIV0 31
#define GATE_CLK_AXI_DDR_DIV0 32
#define GATE_CLK_RP_CPU_NORMAL_DIV1 33
#define GATE_CLK_A53_50M 34
#define GATE_CLK_TOP_RP_CMN_DIV2 35
#define GATE_CLK_HSDMA 36
#define GATE_CLK_EMMC_100M 37
#define GATE_CLK_SD_100M 38
#define GATE_CLK_TX_ETH0 39
#define GATE_CLK_PTP_REF_I_ETH0 40
#define GATE_CLK_REF_ETH0 41
#define GATE_CLK_UART_500M 42
#define GATE_CLK_EFUSE 43
#define GATE_CLK_AHB_LPC 44
#define GATE_CLK_AHB_ROM 45
#define GATE_CLK_AHB_SF 46
#define GATE_CLK_APB_UART 47
#define GATE_CLK_APB_TIMER 48
#define GATE_CLK_APB_EFUSE 49
#define GATE_CLK_APB_GPIO 50
#define GATE_CLK_APB_GPIO_INTR 51
#define GATE_CLK_APB_SPI 52
#define GATE_CLK_APB_I2C 53
#define GATE_CLK_APB_WDT 54
#define GATE_CLK_APB_PWM 55
#define GATE_CLK_APB_RTC 56
#define GATE_CLK_AXI_PCIE0 57
#define GATE_CLK_AXI_PCIE1 58
#define GATE_CLK_SYSDMA_AXI 59
#define GATE_CLK_AXI_DBG_I2C 60
#define GATE_CLK_AXI_SRAM 61
#define GATE_CLK_AXI_ETH0 62
#define GATE_CLK_AXI_EMMC 63
#define GATE_CLK_AXI_SD 64
#define GATE_CLK_TOP_AXI0 65
#define GATE_CLK_TOP_AXI_HSPERI 66
#define GATE_CLK_TIMER1 67
#define GATE_CLK_TIMER2 68
#define GATE_CLK_TIMER3 69
#define GATE_CLK_TIMER4 70
#define GATE_CLK_TIMER5 71
#define GATE_CLK_TIMER6 72
#define GATE_CLK_TIMER7 73
#define GATE_CLK_TIMER8 74
#define GATE_CLK_100K_EMMC 75
#define GATE_CLK_100K_SD 76
#define GATE_CLK_GPIO_DB 77
#define GATE_CLK_AXI_DDR_DIV1 78
#define GATE_CLK_DDR01_DIV1 79
#define GATE_CLK_DDR23_DIV1 80
#define GATE_CLK_DDR01_DIV0 81
#define GATE_CLK_DDR23_DIV0 82
#define GATE_CLK_DDR01 83
#define GATE_CLK_DDR23 84
#define GATE_CLK_RP_CPU_NORMAL 85
#define GATE_CLK_AXI_DDR 86
#define MUX_CLK_DDR01 87
#define MUX_CLK_DDR23 88
#define MUX_CLK_RP_CPU_NORMAL 89
#define MUX_CLK_AXI_DDR 90
#endif /* __DT_BINDINGS_SOPHGO_SG2042_CLKGEN_H__ */

View File

@@ -0,0 +1,14 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */
/*
* Copyright (C) 2023 Sophgo Technology Inc. All rights reserved.
*/
#ifndef __DT_BINDINGS_SOPHGO_SG2042_PLL_H__
#define __DT_BINDINGS_SOPHGO_SG2042_PLL_H__
#define MPLL_CLK 0
#define FPLL_CLK 1
#define DPLL0_CLK 2
#define DPLL1_CLK 3
#endif /* __DT_BINDINGS_SOPHGO_SG2042_PLL_H__ */

View File

@@ -0,0 +1,58 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */
/*
* Copyright (C) 2023 Sophgo Technology Inc. All rights reserved.
*/
#ifndef __DT_BINDINGS_SOPHGO_SG2042_RPGATE_H__
#define __DT_BINDINGS_SOPHGO_SG2042_RPGATE_H__
#define GATE_CLK_RXU0 0
#define GATE_CLK_RXU1 1
#define GATE_CLK_RXU2 2
#define GATE_CLK_RXU3 3
#define GATE_CLK_RXU4 4
#define GATE_CLK_RXU5 5
#define GATE_CLK_RXU6 6
#define GATE_CLK_RXU7 7
#define GATE_CLK_RXU8 8
#define GATE_CLK_RXU9 9
#define GATE_CLK_RXU10 10
#define GATE_CLK_RXU11 11
#define GATE_CLK_RXU12 12
#define GATE_CLK_RXU13 13
#define GATE_CLK_RXU14 14
#define GATE_CLK_RXU15 15
#define GATE_CLK_RXU16 16
#define GATE_CLK_RXU17 17
#define GATE_CLK_RXU18 18
#define GATE_CLK_RXU19 19
#define GATE_CLK_RXU20 20
#define GATE_CLK_RXU21 21
#define GATE_CLK_RXU22 22
#define GATE_CLK_RXU23 23
#define GATE_CLK_RXU24 24
#define GATE_CLK_RXU25 25
#define GATE_CLK_RXU26 26
#define GATE_CLK_RXU27 27
#define GATE_CLK_RXU28 28
#define GATE_CLK_RXU29 29
#define GATE_CLK_RXU30 30
#define GATE_CLK_RXU31 31
#define GATE_CLK_MP0 32
#define GATE_CLK_MP1 33
#define GATE_CLK_MP2 34
#define GATE_CLK_MP3 35
#define GATE_CLK_MP4 36
#define GATE_CLK_MP5 37
#define GATE_CLK_MP6 38
#define GATE_CLK_MP7 39
#define GATE_CLK_MP8 40
#define GATE_CLK_MP9 41
#define GATE_CLK_MP10 42
#define GATE_CLK_MP11 43
#define GATE_CLK_MP12 44
#define GATE_CLK_MP13 45
#define GATE_CLK_MP14 46
#define GATE_CLK_MP15 47
#endif /* __DT_BINDINGS_SOPHGO_SG2042_RPGATE_H__ */