Skip to content

Commit

Permalink
clk: mediatek: fhctl: Add support for older fhctl register layout
Browse files Browse the repository at this point in the history
The Frequency Hopping Controller (FHCTL) seems to have different
versions, as it has a slightly different register layout on some
older SoCs like MT6795, MT8173, MT8183 (and others).

This driver is indeed compatible with at least some of those older
IP revisions, so all we need to do is to add a way to select the
right register layout at registration time.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Link: https://lore.kernel.org/r/20230206100105.861720-2-angelogioacchino.delregno@collabora.com
Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
  • Loading branch information
AngeloGioacchino Del Regno authored and Stephen Boyd committed Mar 13, 2023
1 parent fe15c26 commit 8da312d
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 9 deletions.
26 changes: 23 additions & 3 deletions drivers/clk/mediatek/clk-fhctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,20 @@
#define PERCENT_TO_DDSLMT(dds, percent_m10) \
((((dds) * (percent_m10)) >> 5) / 100)

static const struct fhctl_offset fhctl_offset = {
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,
};

const struct fhctl_offset fhctl_offset_v2 = {
.offset_hp_en = 0x0,
.offset_clk_con = 0x8,
.offset_rst_con = 0xc,
Expand All @@ -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,
Expand Down
9 changes: 8 additions & 1 deletion drivers/clk/mediatek/clk-fhctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);

Expand Down
2 changes: 2 additions & 0 deletions drivers/clk/mediatek/clk-mt8186-apmixedsys.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <linux/platform_device.h>
#include <dt-bindings/clock/mt8186-clk.h>

#include "clk-fhctl.h"
#include "clk-mtk.h"
#include "clk-pll.h"
#include "clk-pllfh.h"
Expand Down Expand Up @@ -98,6 +99,7 @@ enum fh_pll_id {
.data = { \
.pll_id = _pllid, \
.fh_id = _fhid, \
.fh_ver = FHCTL_PLLFH_V2, \
.fhx_offset = _offset, \
.dds_mask = GENMASK(21, 0), \
.slope0_value = 0x6003c97, \
Expand Down
23 changes: 18 additions & 5 deletions drivers/clk/mediatek/clk-pllfh.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,16 @@ void fhctl_parse_dt(const u8 *compatible_node, struct mtk_pllfh_data *pllfhs,
}
}

static void pllfh_init(struct mtk_fh *fh, struct mtk_pllfh_data *pllfh_data)
static int pllfh_init(struct mtk_fh *fh, struct mtk_pllfh_data *pllfh_data)
{
struct fh_pll_regs *regs = &fh->regs;
const struct fhctl_offset *offset;
void __iomem *base = pllfh_data->state.base;
void __iomem *fhx_base = base + pllfh_data->data.fhx_offset;

offset = fhctl_get_offset_table();
offset = fhctl_get_offset_table(pllfh_data->data.fh_ver);
if (IS_ERR(offset))
return PTR_ERR(offset);

regs->reg_hp_en = base + offset->offset_hp_en;
regs->reg_clk_con = base + offset->offset_clk_con;
Expand All @@ -129,6 +131,8 @@ static void pllfh_init(struct mtk_fh *fh, struct mtk_pllfh_data *pllfh_data)
fh->lock = &pllfh_lock;

fh->ops = fhctl_get_ops();

return 0;
}

static bool fhctl_is_supported_and_enabled(const struct mtk_pllfh_data *pllfh)
Expand All @@ -142,20 +146,29 @@ mtk_clk_register_pllfh(const struct mtk_pll_data *pll_data,
{
struct clk_hw *hw;
struct mtk_fh *fh;
int ret;

fh = kzalloc(sizeof(*fh), GFP_KERNEL);
if (!fh)
return ERR_PTR(-ENOMEM);

pllfh_init(fh, pllfh_data);
ret = pllfh_init(fh, pllfh_data);
if (ret) {
hw = ERR_PTR(ret);
goto out;
}

hw = mtk_clk_register_pll_ops(&fh->clk_pll, pll_data, base,
&mtk_pllfh_ops);

if (IS_ERR(hw))
goto out;

fhctl_hw_init(fh);

out:
if (IS_ERR(hw))
kfree(fh);
else
fhctl_hw_init(fh);

return hw;
}
Expand Down
1 change: 1 addition & 0 deletions drivers/clk/mediatek/clk-pllfh.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ struct fh_pll_state {
struct fh_pll_data {
int pll_id;
int fh_id;
int fh_ver;
u32 fhx_offset;
u32 dds_mask;
u32 slope0_value;
Expand Down

0 comments on commit 8da312d

Please sign in to comment.