refactor(st-clock): driver size optimization

Re-ordering structures to avoid gaps and minimize data.
Reduce type of gate_refcounts[], uint8_t is enough.
Re-ordering structures to avoid gaps and minimize data.
Use an unsigned char to define a clock ops type.

Signed-off-by: Gabriel Fernandez <gabriel.fernandez@foss.st.com>
Change-Id: I6b793dc34abdd6ef013609fc0f122da5d1824a34
This commit is contained in:
Gabriel Fernandez 2023-08-21 13:31:47 +02:00 committed by Yann Gautier
parent 698bba5e74
commit d9a7ddeb25
3 changed files with 100 additions and 52 deletions

View file

@ -224,6 +224,15 @@ const struct clk_stm32 *_clk_get(struct stm32_clk_priv *priv, int id)
return NULL;
}
static const struct stm32_clk_ops *_clk_get_ops(struct stm32_clk_priv *priv, int id)
{
const struct clk_stm32 *clk = _clk_get(priv, id);
assert(clk->ops != NO_OPS);
return priv->ops_array[clk->ops];
}
#define clk_div_mask(_width) GENMASK(((_width) - 1U), 0U)
static unsigned int _get_table_div(const struct clk_div_table *table,
@ -377,7 +386,7 @@ int _clk_stm32_set_parent_by_index(struct stm32_clk_priv *priv, int clk, int sel
int _clk_stm32_get_parent(struct stm32_clk_priv *priv, int clk_id)
{
const struct clk_stm32 *clk = _clk_get(priv, clk_id);
const struct stm32_clk_ops *ops = _clk_get_ops(priv, clk_id);
const struct parent_cfg *parent;
uint16_t mux_id;
int sel;
@ -394,8 +403,8 @@ int _clk_stm32_get_parent(struct stm32_clk_priv *priv, int clk_id)
mux_id &= MUX_PARENT_MASK;
parent = &priv->parents[mux_id];
if (clk->ops->get_parent != NULL) {
sel = clk->ops->get_parent(priv, clk_id);
if (ops->get_parent != NULL) {
sel = ops->get_parent(priv, clk_id);
} else {
sel = clk_mux_get_parent(priv, mux_id);
}
@ -464,7 +473,7 @@ int clk_get_index(struct stm32_clk_priv *priv, unsigned long binding_id)
unsigned long _clk_stm32_get_rate(struct stm32_clk_priv *priv, int id)
{
const struct clk_stm32 *clk = _clk_get(priv, id);
const struct stm32_clk_ops *ops = _clk_get_ops(priv, id);
int parent;
if ((unsigned int)id >= priv->num) {
@ -476,14 +485,14 @@ unsigned long _clk_stm32_get_rate(struct stm32_clk_priv *priv, int id)
return 0UL;
}
if (clk->ops->recalc_rate != NULL) {
if (ops->recalc_rate != NULL) {
unsigned long prate = 0UL;
if (parent != CLK_IS_ROOT) {
prate = _clk_stm32_get_rate(priv, parent);
}
return clk->ops->recalc_rate(priv, id, prate);
return ops->recalc_rate(priv, id, prate);
}
if (parent == CLK_IS_ROOT) {
@ -520,10 +529,10 @@ bool _stm32_clk_is_flags(struct stm32_clk_priv *priv, int id, uint8_t flag)
int clk_stm32_enable_call_ops(struct stm32_clk_priv *priv, uint16_t id)
{
const struct clk_stm32 *clk = _clk_get(priv, id);
const struct stm32_clk_ops *ops = _clk_get_ops(priv, id);
if (clk->ops->enable != NULL) {
clk->ops->enable(priv, id);
if (ops->enable != NULL) {
ops->enable(priv, id);
}
return 0;
@ -550,7 +559,7 @@ static int _clk_stm32_enable_core(struct stm32_clk_priv *priv, int id)
priv->gate_refcounts[id]++;
if (priv->gate_refcounts[id] == UINT_MAX) {
if (priv->gate_refcounts[id] == UINT8_MAX) {
ERROR("%s: %d max enable count !", __func__, id);
panic();
}
@ -571,10 +580,10 @@ int _clk_stm32_enable(struct stm32_clk_priv *priv, int id)
void clk_stm32_disable_call_ops(struct stm32_clk_priv *priv, uint16_t id)
{
const struct clk_stm32 *clk = _clk_get(priv, id);
const struct stm32_clk_ops *ops = _clk_get_ops(priv, id);
if (clk->ops->disable != NULL) {
clk->ops->disable(priv, id);
if (ops->disable != NULL) {
ops->disable(priv, id);
}
}
@ -619,10 +628,10 @@ void _clk_stm32_disable(struct stm32_clk_priv *priv, int id)
bool _clk_stm32_is_enabled(struct stm32_clk_priv *priv, int id)
{
const struct clk_stm32 *clk = _clk_get(priv, id);
const struct stm32_clk_ops *ops = _clk_get_ops(priv, id);
if (clk->ops->is_enabled != NULL) {
return clk->ops->is_enabled(priv, id);
if (ops->is_enabled != NULL) {
return ops->is_enabled(priv, id);
}
return priv->gate_refcounts[id];
@ -1081,12 +1090,10 @@ int clk_stm32_init(struct stm32_clk_priv *priv, uintptr_t base)
priv->base = base;
for (i = 0U; i < priv->num; i++) {
const struct clk_stm32 *clk = _clk_get(priv, i);
const struct stm32_clk_ops *ops = _clk_get_ops(priv, i);
assert(clk->ops != NULL);
if (clk->ops->init != NULL) {
clk->ops->init(priv, i);
if (ops->init != NULL) {
ops->init(priv, i);
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2022, STMicroelectronics - All Rights Reserved
* Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
*/
@ -21,23 +21,23 @@ struct gate_cfg {
};
struct clk_div_table {
unsigned int val;
unsigned int div;
uint16_t val;
uint16_t div;
};
struct div_cfg {
const struct clk_div_table *table;
uint16_t offset;
uint8_t shift;
uint8_t width;
uint8_t flags;
uint8_t bitrdy;
const struct clk_div_table *table;
};
struct parent_cfg {
uint8_t num_parents;
const uint16_t *id_parents;
struct mux_cfg *mux;
uint8_t num_parents;
};
struct stm32_clk_priv;
@ -56,9 +56,9 @@ struct stm32_clk_ops {
struct clk_stm32 {
uint16_t binding;
uint16_t parent;
uint8_t ops;
uint8_t flags;
void *clock_cfg;
const struct stm32_clk_ops *ops;
};
struct stm32_clk_priv {
@ -73,8 +73,9 @@ struct stm32_clk_priv {
const uint32_t nb_div;
struct clk_oscillator_data *osci_data;
const uint32_t nb_osci_data;
uint32_t *gate_refcounts;
uint8_t *gate_refcounts;
void *pdata;
const struct stm32_clk_ops **ops_array;
};
struct stm32_clk_bypass {
@ -97,13 +98,14 @@ struct stm32_clk_drive {
struct clk_oscillator_data {
const char *name;
uint16_t id_clk;
unsigned long frequency;
uint16_t gate_id;
uint16_t gate_rdy_id;
struct stm32_clk_bypass *bypass;
struct stm32_clk_css *css;
struct stm32_clk_drive *drive;
unsigned long frequency;
uint16_t id_clk;
uint16_t gate_id;
uint16_t gate_rdy_id;
};
struct clk_fixed_rate {
@ -218,7 +220,7 @@ void clk_stm32_display_clock_info(void);
#endif
struct clk_stm32_div_cfg {
int id;
uint8_t id;
};
#define STM32_DIV(idx, _binding, _parent, _flags, _div_id) \
@ -229,11 +231,11 @@ struct clk_stm32_div_cfg {
.clock_cfg = &(struct clk_stm32_div_cfg){\
.id = (_div_id),\
},\
.ops = &clk_stm32_divider_ops,\
.ops = STM32_DIVIDER_OPS,\
}
struct clk_stm32_gate_cfg {
int id;
uint8_t id;
};
#define STM32_GATE(idx, _binding, _parent, _flags, _gate_id) \
@ -244,12 +246,12 @@ struct clk_stm32_gate_cfg {
.clock_cfg = &(struct clk_stm32_gate_cfg){\
.id = (_gate_id),\
},\
.ops = &clk_stm32_gate_ops,\
.ops = STM32_GATE_OPS,\
}
struct fixed_factor_cfg {
unsigned int mult;
unsigned int div;
uint8_t mult;
uint8_t div;
};
unsigned long fixed_factor_recalc_rate(struct stm32_clk_priv *priv,
@ -263,7 +265,7 @@ unsigned long fixed_factor_recalc_rate(struct stm32_clk_priv *priv,
.mult = (_mult),\
.div = (_div),\
},\
.ops = &clk_fixed_factor_ops,\
.ops = FIXED_FACTOR_OPS,\
}
#define GATE(idx, _binding, _parent, _flags, _offset, _bit_idx) \
@ -275,7 +277,7 @@ unsigned long fixed_factor_recalc_rate(struct stm32_clk_priv *priv,
.offset = (_offset),\
.bit_idx = (_bit_idx),\
},\
.ops = &clk_gate_ops,\
.ops = GATE_OPS,\
}
#define STM32_MUX(idx, _binding, _mux_id, _flags) \
@ -284,7 +286,7 @@ unsigned long fixed_factor_recalc_rate(struct stm32_clk_priv *priv,
.parent = (MUX(_mux_id)),\
.flags = (_flags),\
.clock_cfg = NULL,\
.ops = (&clk_mux_ops),\
.ops = STM32_MUX_OPS\
}
struct clk_timer_cfg {
@ -301,7 +303,7 @@ struct clk_timer_cfg {
.apbdiv = (_apbdiv),\
.timpre = (_timpre),\
},\
.ops = &clk_timer_ops,\
.ops = STM32_TIMER_OPS,\
}
struct clk_stm32_fixed_rate_cfg {
@ -315,7 +317,7 @@ struct clk_stm32_fixed_rate_cfg {
.clock_cfg = &(struct clk_stm32_fixed_rate_cfg){\
.rate = (_rate),\
},\
.ops = &clk_stm32_fixed_rate_ops,\
.ops = STM32_FIXED_RATE_OPS,\
}
#define BYPASS(_offset, _bit_byp, _bit_digbyp) &(struct stm32_clk_bypass){\
@ -355,7 +357,7 @@ int clk_stm32_osc_gate_enable(struct stm32_clk_priv *priv, int id);
void clk_stm32_osc_gate_disable(struct stm32_clk_priv *priv, int id);
struct stm32_osc_cfg {
int osc_id;
uint8_t osc_id;
};
#define CLK_OSC(idx, _idx, _parent, _osc_id) \
@ -366,7 +368,7 @@ struct stm32_osc_cfg {
.clock_cfg = &(struct stm32_osc_cfg){\
.osc_id = (_osc_id),\
},\
.ops = &clk_stm32_osc_ops,\
.ops = STM32_OSC_OPS,\
}
#define CLK_OSC_FIXED(idx, _idx, _parent, _osc_id) \
@ -377,7 +379,7 @@ struct stm32_osc_cfg {
.clock_cfg = &(struct stm32_osc_cfg){\
.osc_id = (_osc_id),\
},\
.ops = &clk_stm32_osc_nogate_ops,\
.ops = STM32_OSC_NOGATE_OPS,\
}
extern const struct stm32_clk_ops clk_mux_ops;
@ -390,4 +392,19 @@ extern const struct stm32_clk_ops clk_stm32_fixed_rate_ops;
extern const struct stm32_clk_ops clk_stm32_osc_ops;
extern const struct stm32_clk_ops clk_stm32_osc_nogate_ops;
enum {
NO_OPS,
FIXED_FACTOR_OPS,
GATE_OPS,
STM32_MUX_OPS,
STM32_DIVIDER_OPS,
STM32_GATE_OPS,
STM32_TIMER_OPS,
STM32_FIXED_RATE_OPS,
STM32_OSC_OPS,
STM32_OSC_NOGATE_OPS,
STM32_LAST_OPS
};
#endif /* CLK_STM32_CORE_H */

View file

@ -889,7 +889,7 @@ static bool pll4_bootrom;
#endif
/* RCC clock device driver private */
static unsigned int refcounts_mp13[CK_LAST];
static uint8_t refcounts_mp13[CK_LAST];
static const struct stm32_clk_pll *clk_st32_pll_data(unsigned int idx);
@ -1693,7 +1693,7 @@ static const struct stm32_clk_pll *clk_st32_pll_data(unsigned int idx)
}
struct stm32_pll_cfg {
int pll_id;
uint8_t pll_id;
};
static unsigned long clk_stm32_pll_recalc_rate(struct stm32_clk_priv *priv, int id,
@ -1775,12 +1775,12 @@ static const struct stm32_clk_ops clk_stm32_pll_ops = {
.clock_cfg = &(struct stm32_pll_cfg) {\
.pll_id = _pll_id,\
},\
.ops = &clk_stm32_pll_ops,\
.ops = STM32_PLL_OPS,\
}
struct clk_stm32_composite_cfg {
int gate_id;
int div_id;
uint8_t gate_id;
uint8_t div_id;
};
static unsigned long clk_stm32_composite_recalc_rate(struct stm32_clk_priv *priv,
@ -1832,9 +1832,32 @@ static const struct stm32_clk_ops clk_stm32_composite_ops = {
.gate_id = (_gate_id),\
.div_id = (_div_id),\
},\
.ops = &clk_stm32_composite_ops,\
.ops = STM32_COMPOSITE_OPS,\
}
enum {
STM32_PLL_OPS = STM32_LAST_OPS,
STM32_COMPOSITE_OPS,
MP13_LAST_OPS
};
static const struct stm32_clk_ops *ops_array_mp13[MP13_LAST_OPS] = {
[NO_OPS] = NULL,
[FIXED_FACTOR_OPS] = &clk_fixed_factor_ops,
[GATE_OPS] = &clk_gate_ops,
[STM32_MUX_OPS] = &clk_mux_ops,
[STM32_DIVIDER_OPS] = &clk_stm32_divider_ops,
[STM32_GATE_OPS] = &clk_stm32_gate_ops,
[STM32_TIMER_OPS] = &clk_timer_ops,
[STM32_FIXED_RATE_OPS] = &clk_stm32_fixed_rate_ops,
[STM32_OSC_OPS] = &clk_stm32_osc_ops,
[STM32_OSC_NOGATE_OPS] = &clk_stm32_osc_nogate_ops,
[STM32_PLL_OPS] = &clk_stm32_pll_ops,
[STM32_COMPOSITE_OPS] = &clk_stm32_composite_ops
};
static const struct clk_stm32 stm32mp13_clk[CK_LAST] = {
/* ROOT CLOCKS */
CLK_FIXED_RATE(_CK_OFF, _NO_ID, 0),
@ -1994,6 +2017,7 @@ static struct stm32_clk_priv stm32mp13_clock_data = {
.nb_osci_data = ARRAY_SIZE(stm32mp13_osc_data),
.gate_refcounts = refcounts_mp13,
.pdata = &stm32mp13_clock_pdata,
.ops_array = ops_array_mp13,
};
static int stm32mp1_init_clock_tree(void)