-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Terry Bai <[email protected]>
- Loading branch information
Showing
17 changed files
with
710 additions
and
689 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,18 @@ | ||
// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) | ||
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) | ||
/* | ||
* Operations for MPLL clocks are derived from: | ||
* https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/meson/clk-mpll.c | ||
* https://github.com/torvalds/linux/blob/ | ||
* befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/meson/clk-mpll.c | ||
* | ||
* Copyright (c) 2016 AmLogic, Inc. | ||
* Author: Michael Turquette <[email protected]> | ||
*/ | ||
|
||
// SPDX-License-Identifier: GPL-2.0 | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
/* | ||
* Operations for PLL clocks are derived from: | ||
* https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/meson/clk-pll.c | ||
* https://github.com/torvalds/linux/blob/ | ||
* befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/meson/clk-pll.c | ||
* | ||
* Copyright (c) 2015 Endless Mobile, Inc. | ||
* Author: Carlo Caione <[email protected]> | ||
|
@@ -19,27 +21,30 @@ | |
* Author: Jerome Brunet <[email protected]> | ||
*/ | ||
|
||
// SPDX-License-Identifier: GPL-2.0 | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
/* | ||
* Operations for gate clocks are derived from: | ||
* https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/meson/clk-regmap.c | ||
* https://github.com/torvalds/linux/blob/ | ||
* befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/meson/clk-regmap.c | ||
* | ||
* Copyright (c) 2018 BayLibre, SAS. | ||
* Author: Jerome Brunet <[email protected]> | ||
*/ | ||
|
||
// SPDX-License-Identifier: GPL-2.0 | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
/* | ||
* Operations for fixed factor clocks are derived from: | ||
* https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/clk-fixed-factor.c | ||
* https://github.com/torvalds/linux/blob/ | ||
* befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/clk-fixed-factor.c | ||
* | ||
* Copyright (C) 2011 Sascha Hauer, Pengutronix <[email protected]> | ||
*/ | ||
|
||
// SPDX-License-Identifier: GPL-2.0 | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
/* | ||
* Operations for divider clocks are derived from: | ||
* https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/clk-divider.c | ||
* https://github.com/torvalds/linux/blob/ | ||
* befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/clk-divider.c | ||
* | ||
* Copyright (C) 2011 Sascha Hauer, Pengutronix <[email protected]> | ||
* Copyright (C) 2011 Richard Zhao, Linaro <[email protected]> | ||
|
@@ -48,10 +53,11 @@ | |
* Adjustable divider clock implementation | ||
*/ | ||
|
||
// SPDX-License-Identifier: GPL-2.0 | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
/* | ||
* Operations for multiplexer clocks are derived from: | ||
* https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/clk-mux.c | ||
* https://github.com/torvalds/linux/blob/ | ||
* befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/clk-mux.c | ||
* | ||
* Copyright (C) 2011 Sascha Hauer, Pengutronix <[email protected]> | ||
* Copyright (C) 2011 Richard Zhao, Linaro <[email protected]> | ||
|
@@ -60,82 +66,23 @@ | |
* Simple multiplexer clock implementation | ||
*/ | ||
|
||
// SPDX-License-Identifier: GPL-2.0 | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
/* | ||
* Operations for meson_vid_pll_div are derived from: | ||
* https://github.com/torvalds/linux/blob/7ec462100ef9142344ddbf86f2c3008b97acddbe/drivers/clk/meson/vid-pll-div.c | ||
* https://github.com/torvalds/linux/blob/7ec462100ef9142344ddbf86f2c3008b97acddbe/drivers/clk/meson/vclk.c | ||
* https://github.com/torvalds/linux/blob/ | ||
* 7ec462100ef9142344ddbf86f2c3008b97acddbe/drivers/clk/meson/vid-pll-div.c | ||
* https://github.com/torvalds/linux/blob/ | ||
* 7ec462100ef9142344ddbf86f2c3008b97acddbe/drivers/clk/meson/vclk.c | ||
* | ||
* Copyright (c) 2018 BayLibre, SAS. | ||
* Author: Neil Armstrong <[email protected]> | ||
*/ | ||
|
||
#include <clk.h> | ||
#include <utils.h> | ||
#include <clk-operations.h> | ||
#include <sddf/timer/client.h> | ||
#include <sddf/util/printf.h> | ||
|
||
int reg_write(uint64_t base, uint32_t offset, uint32_t val) | ||
{ | ||
volatile uint32_t *clk_reg = ((void *)base + offset); | ||
*clk_reg = val; | ||
|
||
return 0; | ||
} | ||
|
||
int regmap_update_bits(uint64_t base, uint32_t offset, uint8_t shift, uint8_t width, uint32_t val) | ||
{ | ||
volatile uint32_t *clk_reg = ((void *)base + offset); | ||
uint32_t reg_val = *clk_reg; | ||
|
||
reg_val &= ~(MASK(width) << shift); | ||
reg_val |= ((MASK(width) & val) << shift); | ||
|
||
*clk_reg = reg_val; | ||
|
||
/* TODO: Check if the register has been updated correctly */ | ||
|
||
return 0; | ||
} | ||
|
||
int regmap_read_bits(uint64_t base, uint32_t offset, uint8_t shift, uint8_t width) | ||
{ | ||
volatile uint32_t *clk_reg = ((void *)base + offset); | ||
uint32_t reg_val = *clk_reg; | ||
|
||
reg_val >>= shift; | ||
reg_val &= MASK(width); | ||
|
||
return reg_val; | ||
} | ||
|
||
int regmap_mux_update_bits(uint64_t base, uint32_t offset, uint8_t shift, uint32_t mask, uint32_t val) | ||
{ | ||
volatile uint32_t *clk_reg = ((void *)base + offset); | ||
uint32_t reg_val = *clk_reg; | ||
|
||
reg_val &= ~(mask << shift); | ||
reg_val |= ((mask & val) << shift); | ||
|
||
*clk_reg = reg_val; | ||
|
||
/* TODO: Check if the register has been updated correctly */ | ||
|
||
return 0; | ||
} | ||
|
||
int regmap_mux_read_bits(uint64_t base, uint32_t offset, uint8_t shift, uint32_t mask) | ||
{ | ||
volatile uint32_t *clk_reg = ((void *)base + offset); | ||
uint32_t reg_val = *clk_reg; | ||
|
||
reg_val >>= shift; | ||
reg_val &= mask; | ||
|
||
return reg_val; | ||
} | ||
|
||
static int clk_gate_enable(struct clk *clk) | ||
{ | ||
struct clk_gate_data *data = (struct clk_gate_data *)(clk->data); | ||
|
@@ -175,11 +122,13 @@ const struct clk_ops clk_gate_ro_ops = { | |
.is_enabled = clk_gate_is_enabled, | ||
}; | ||
|
||
static unsigned long clk_div_recalc_rate(const struct clk *clk, unsigned long prate) | ||
static unsigned long clk_div_recalc_rate(const struct clk *clk, | ||
unsigned long prate) | ||
{ | ||
|
||
struct clk_div_data *data = (struct clk_div_data *)(clk->data); | ||
uint32_t div = regmap_read_bits(clk->base, data->offset, data->shift, data->width); | ||
uint32_t div = regmap_read_bits(clk->base, data->offset, data->shift, | ||
data->width); | ||
|
||
/* TODO: Need to verify the following cases */ | ||
if (data->flags & CLK_DIVIDER_ONE_BASED) { | ||
|
@@ -195,7 +144,8 @@ static unsigned long clk_div_recalc_rate(const struct clk *clk, unsigned long pr | |
return DIV_ROUND_UP_ULL((uint64_t)prate, div); | ||
} | ||
|
||
static int clk_div_set_rate(const struct clk *clk, uint32_t rate, uint32_t parent_rate) | ||
static int clk_div_set_rate(const struct clk *clk, uint32_t rate, | ||
uint32_t parent_rate) | ||
{ | ||
struct clk_div_data *data = (struct clk_div_data *)(clk->data); | ||
uint32_t div = DIV_ROUND_UP(parent_rate, rate); | ||
|
@@ -210,30 +160,10 @@ static int clk_div_set_rate(const struct clk *clk, uint32_t rate, uint32_t paren | |
} else { | ||
div -= 1; | ||
} | ||
return regmap_update_bits(clk->base, data->offset, data->shift, data->width, div); | ||
return regmap_update_bits(clk->base, data->offset, data->shift, | ||
data->width, div); | ||
} | ||
|
||
/* static int clk_div_determine_rate(struct clk_hw *hw, */ | ||
/* struct clk_rate_request *req) */ | ||
/* { */ | ||
/* struct clk_div_data *data = (struct clk_div_data *)(hw->clk->data); */ | ||
/* /\* struct clk_regmap *clk = to_clk_regmap(hw); *\/ */ | ||
/* /\* struct clk_div_data *div = clk_get_regmap_div_data(clk); *\/ */ | ||
/* uint32_t val; */ | ||
|
||
/* /\* if read only, just return current value *\/ */ | ||
/* if (data->flags & CLK_DIVIDER_READ_ONLY) { */ | ||
/* val = regmap_read_bits(data->offset, data->shift, data->width); */ | ||
|
||
/* /\* return divider_ro_determine_rate(hw, req, div->table, *\/ */ | ||
/* /\* div->width, div->flags, val); *\/ */ | ||
/* } */ | ||
|
||
/* /\* return divider_determine_rate(hw, req, div->table, div->width, *\/ */ | ||
/* /\* div->flags); *\/ */ | ||
/* return 0; */ | ||
/* } */ | ||
|
||
const struct clk_ops clk_divider_ops = { | ||
.enable = NULL, | ||
.recalc_rate = clk_div_recalc_rate, | ||
|
@@ -250,7 +180,8 @@ static uint8_t clk_mux_get_parent(const struct clk *clk) | |
{ | ||
struct clk_mux_data *data = (struct clk_mux_data *)(clk->data); | ||
uint32_t num_parents = clk->hw.init->num_parents; | ||
uint32_t val = regmap_mux_read_bits(clk->base, data->offset, data->shift, data->mask); | ||
uint32_t val = regmap_mux_read_bits(clk->base, data->offset, | ||
data->shift, data->mask); | ||
|
||
if (data->table) { | ||
int i; | ||
|
@@ -282,7 +213,8 @@ static int clk_mux_set_parent(struct clk *clk, uint8_t index) | |
|
||
if (data->table) { | ||
unsigned int val = data->table[index]; | ||
regmap_mux_update_bits(clk->base, data->offset, data->shift, data->mask, val); | ||
regmap_mux_update_bits(clk->base, data->offset, data->shift, | ||
data->mask, val); | ||
} | ||
/* TODO: handle cases without table given */ | ||
|
||
|
@@ -298,9 +230,11 @@ const struct clk_ops clk_mux_ro_ops = { | |
.get_parent = clk_mux_get_parent, | ||
}; | ||
|
||
static unsigned long clk_factor_recalc_rate(const struct clk *clk, unsigned long parent_rate) | ||
static unsigned long clk_factor_recalc_rate(const struct clk *clk, | ||
unsigned long parent_rate) | ||
{ | ||
struct clk_fixed_factor_data *data = (struct clk_fixed_factor_data *)(clk->data); | ||
struct clk_fixed_factor_data *data = | ||
(struct clk_fixed_factor_data *)(clk->data); | ||
unsigned long long int rate; | ||
|
||
rate = (unsigned long long int)parent_rate * data->mult; | ||
|
@@ -315,15 +249,17 @@ const struct clk_ops clk_fixed_factor_ops = { | |
/* .recalc_accuracy = clk_factor_recalc_accuracy, */ | ||
}; | ||
|
||
static int clk_source_set_rate(const struct clk *clk, uint32_t rate, uint32_t parent_rate) | ||
static int clk_source_set_rate(const struct clk *clk, uint32_t rate, | ||
uint32_t parent_rate) | ||
{ | ||
struct clk_source_data *data = (struct clk_source_data *)(clk->data); | ||
data->rate = rate; | ||
|
||
return 0; | ||
} | ||
|
||
static unsigned long clk_source_get_rate(const struct clk *clk, unsigned long prate) | ||
static unsigned long clk_source_get_rate(const struct clk *clk, | ||
unsigned long prate) | ||
{ | ||
struct clk_source_data *data = (struct clk_source_data *)(clk->data); | ||
|
||
|
Oops, something went wrong.