ARC: HSDK: CGU: Update AXI, TUN, ARC clock options
Update default AXI, TUN, ARC clock set options: instead of changing only IDIV divider settings adjust also domain PLL settings. Add support of TUN_ROM and TUN_PWM clocks (subclocks of TUNN_PLL) Signed-off-by: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
This commit is contained in:
parent
5aec2569a6
commit
075cbae163
@ -42,7 +42,9 @@
|
||||
* |-->| TUNNEL PLL |
|
||||
* | --------------
|
||||
* | |
|
||||
* | |-->|CGU_TUN_IDIV|----------->
|
||||
* | |-->|CGU_TUN_IDIV_TUN|----------->
|
||||
* | |-->|CGU_TUN_IDIV_ROM|----------->
|
||||
* | |-->|CGU_TUN_IDIV_PWM|----------->
|
||||
* |
|
||||
* | ------------
|
||||
* |-->| HDMI PLL |
|
||||
@ -60,7 +62,9 @@
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define CGU_ARC_IDIV 0x080
|
||||
#define CGU_TUN_IDIV 0x380
|
||||
#define CGU_TUN_IDIV_TUN 0x380
|
||||
#define CGU_TUN_IDIV_ROM 0x390
|
||||
#define CGU_TUN_IDIV_PWM 0x3A0
|
||||
#define CGU_HDMI_IDIV_APB 0x480
|
||||
#define CGU_SYS_IDIV_APB 0x180
|
||||
#define CGU_SYS_IDIV_AXI 0x190
|
||||
@ -114,8 +118,68 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||
#define CREG_CORE_IF_CLK_DIV_1 0x0
|
||||
#define CREG_CORE_IF_CLK_DIV_2 0x1
|
||||
|
||||
#define MIN_PLL_RATE 100000000 /* 100 MHz */
|
||||
#define PARENT_RATE 33333333 /* fixed clock - xtal */
|
||||
#define CGU_MAX_CLOCKS 24
|
||||
#define CGU_MAX_CLOCKS 26
|
||||
|
||||
#define CGU_SYS_CLOCKS 16
|
||||
#define MAX_AXI_CLOCKS 4
|
||||
|
||||
#define CGU_TUN_CLOCKS 3
|
||||
#define MAX_TUN_CLOCKS 6
|
||||
|
||||
struct hsdk_tun_idiv_cfg {
|
||||
u32 oft;
|
||||
u8 val[MAX_TUN_CLOCKS];
|
||||
};
|
||||
|
||||
struct hsdk_tun_clk_cfg {
|
||||
const u32 clk_rate[MAX_TUN_CLOCKS];
|
||||
const u32 pll_rate[MAX_TUN_CLOCKS];
|
||||
const struct hsdk_tun_idiv_cfg idiv[CGU_TUN_CLOCKS];
|
||||
};
|
||||
|
||||
static const struct hsdk_tun_clk_cfg tun_clk_cfg = {
|
||||
{ 25000000, 50000000, 75000000, 100000000, 125000000, 150000000 },
|
||||
{ 600000000, 600000000, 600000000, 600000000, 700000000, 600000000 }, {
|
||||
{ CGU_TUN_IDIV_TUN, { 24, 12, 8, 6, 6, 4 } },
|
||||
{ CGU_TUN_IDIV_ROM, { 4, 4, 4, 4, 5, 4 } },
|
||||
{ CGU_TUN_IDIV_PWM, { 8, 8, 8, 8, 10, 8 } }
|
||||
}
|
||||
};
|
||||
|
||||
struct hsdk_sys_idiv_cfg {
|
||||
u32 oft;
|
||||
u8 val[MAX_AXI_CLOCKS];
|
||||
};
|
||||
|
||||
struct hsdk_axi_clk_cfg {
|
||||
const u32 clk_rate[MAX_AXI_CLOCKS];
|
||||
const u32 pll_rate[MAX_AXI_CLOCKS];
|
||||
const struct hsdk_sys_idiv_cfg idiv[CGU_SYS_CLOCKS];
|
||||
};
|
||||
|
||||
static const struct hsdk_axi_clk_cfg axi_clk_cfg = {
|
||||
{ 200000000, 400000000, 600000000, 800000000 },
|
||||
{ 800000000, 800000000, 600000000, 800000000 }, {
|
||||
{ CGU_SYS_IDIV_APB, { 4, 4, 3, 4 } }, /* APB */
|
||||
{ CGU_SYS_IDIV_AXI, { 4, 2, 1, 1 } }, /* AXI */
|
||||
{ CGU_SYS_IDIV_ETH, { 2, 2, 2, 2 } }, /* ETH */
|
||||
{ CGU_SYS_IDIV_USB, { 2, 2, 2, 2 } }, /* USB */
|
||||
{ CGU_SYS_IDIV_SDIO, { 2, 2, 2, 2 } }, /* SDIO */
|
||||
{ CGU_SYS_IDIV_HDMI, { 2, 2, 2, 2 } }, /* HDMI */
|
||||
{ CGU_SYS_IDIV_GFX_CORE, { 1, 1, 1, 1 } }, /* GPU-CORE */
|
||||
{ CGU_SYS_IDIV_GFX_DMA, { 2, 2, 2, 2 } }, /* GPU-DMA */
|
||||
{ CGU_SYS_IDIV_GFX_CFG, { 4, 4, 3, 4 } }, /* GPU-CFG */
|
||||
{ CGU_SYS_IDIV_DMAC_CORE,{ 2, 2, 2, 2 } }, /* DMAC-CORE */
|
||||
{ CGU_SYS_IDIV_DMAC_CFG, { 4, 4, 3, 4 } }, /* DMAC-CFG */
|
||||
{ CGU_SYS_IDIV_SDIO_REF, { 8, 8, 6, 8 } }, /* SDIO-REF */
|
||||
{ CGU_SYS_IDIV_SPI_REF, { 24, 24, 18, 24 } }, /* SPI-REF */
|
||||
{ CGU_SYS_IDIV_I2C_REF, { 4, 4, 3, 4 } }, /* I2C-REF */
|
||||
{ CGU_SYS_IDIV_UART_REF, { 24, 24, 18, 24 } }, /* UART-REF */
|
||||
{ CGU_SYS_IDIV_EBI_REF, { 16, 16, 12, 16 } } /* EBI-REF */
|
||||
}
|
||||
};
|
||||
|
||||
struct hsdk_pll_cfg {
|
||||
u32 rate;
|
||||
@ -201,6 +265,9 @@ static const struct hsdk_pll_devdata hdmi_pll_dat = {
|
||||
};
|
||||
|
||||
static ulong idiv_set(struct clk *, ulong);
|
||||
static ulong cpu_clk_set(struct clk *, ulong);
|
||||
static ulong axi_clk_set(struct clk *, ulong);
|
||||
static ulong tun_clk_set(struct clk *, ulong);
|
||||
static ulong idiv_get(struct clk *);
|
||||
static int idiv_off(struct clk *);
|
||||
static ulong pll_set(struct clk *, ulong);
|
||||
@ -218,11 +285,11 @@ struct hsdk_cgu_clock_map {
|
||||
|
||||
static const struct hsdk_cgu_clock_map clock_map[] = {
|
||||
{ CGU_ARC_PLL, 0, 0, &core_pll_dat, pll_get, pll_set, NULL },
|
||||
{ CGU_ARC_PLL, 0, CGU_ARC_IDIV, &core_pll_dat, idiv_get, idiv_set, idiv_off },
|
||||
{ CGU_ARC_PLL, 0, CGU_ARC_IDIV, &core_pll_dat, idiv_get, cpu_clk_set, idiv_off },
|
||||
{ CGU_DDR_PLL, 0, 0, &sdt_pll_dat, pll_get, pll_set, NULL },
|
||||
{ CGU_SYS_PLL, 0, 0, &sdt_pll_dat, pll_get, pll_set, NULL },
|
||||
{ CGU_SYS_PLL, 0, CGU_SYS_IDIV_APB, &sdt_pll_dat, idiv_get, idiv_set, idiv_off },
|
||||
{ CGU_SYS_PLL, 0, CGU_SYS_IDIV_AXI, &sdt_pll_dat, idiv_get, idiv_set, idiv_off },
|
||||
{ CGU_SYS_PLL, 0, CGU_SYS_IDIV_AXI, &sdt_pll_dat, idiv_get, axi_clk_set, idiv_off },
|
||||
{ CGU_SYS_PLL, 0, CGU_SYS_IDIV_ETH, &sdt_pll_dat, idiv_get, idiv_set, idiv_off },
|
||||
{ CGU_SYS_PLL, 0, CGU_SYS_IDIV_USB, &sdt_pll_dat, idiv_get, idiv_set, idiv_off },
|
||||
{ CGU_SYS_PLL, 0, CGU_SYS_IDIV_SDIO, &sdt_pll_dat, idiv_get, idiv_set, idiv_off },
|
||||
@ -238,7 +305,9 @@ static const struct hsdk_cgu_clock_map clock_map[] = {
|
||||
{ CGU_SYS_PLL, 0, CGU_SYS_IDIV_UART_REF, &sdt_pll_dat, idiv_get, idiv_set, idiv_off },
|
||||
{ CGU_SYS_PLL, 0, CGU_SYS_IDIV_EBI_REF, &sdt_pll_dat, idiv_get, idiv_set, idiv_off },
|
||||
{ CGU_TUN_PLL, 0, 0, &sdt_pll_dat, pll_get, pll_set, NULL },
|
||||
{ CGU_TUN_PLL, 0, CGU_TUN_IDIV, &sdt_pll_dat, idiv_get, idiv_set, idiv_off },
|
||||
{ CGU_TUN_PLL, 0, CGU_TUN_IDIV_TUN, &sdt_pll_dat, idiv_get, tun_clk_set, idiv_off },
|
||||
{ CGU_TUN_PLL, 0, CGU_TUN_IDIV_ROM, &sdt_pll_dat, idiv_get, idiv_set, idiv_off },
|
||||
{ CGU_TUN_PLL, 0, CGU_TUN_IDIV_PWM, &sdt_pll_dat, idiv_get, idiv_set, idiv_off },
|
||||
{ CGU_HDMI_PLL, 0, 0, &hdmi_pll_dat, pll_get, pll_set, NULL },
|
||||
{ CGU_HDMI_PLL, 0, CGU_HDMI_IDIV_APB, &hdmi_pll_dat, idiv_get, idiv_set, idiv_off }
|
||||
};
|
||||
@ -453,6 +522,94 @@ static ulong idiv_get(struct clk *sclk)
|
||||
return parent_rate / div_factor;
|
||||
}
|
||||
|
||||
/* Special behavior: wen we set this clock we set both idiv and pll */
|
||||
static ulong cpu_clk_set(struct clk *sclk, ulong rate)
|
||||
{
|
||||
ulong ret;
|
||||
|
||||
ret = pll_set(sclk, rate);
|
||||
idiv_set(sclk, rate);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Special behavior: wen we set this clock we set both idiv and pll and all pll dividers */
|
||||
static ulong axi_clk_set(struct clk *sclk, ulong rate)
|
||||
{
|
||||
struct hsdk_cgu_clk *clk = dev_get_priv(sclk->dev);
|
||||
ulong pll_rate;
|
||||
int i, freq_idx = -1;
|
||||
ulong ret = 0;
|
||||
|
||||
pll_rate = pll_get(sclk);
|
||||
|
||||
for (i = 0; i < MAX_AXI_CLOCKS; i++) {
|
||||
if (axi_clk_cfg.clk_rate[i] == rate) {
|
||||
freq_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (freq_idx < 0) {
|
||||
pr_err("axi clk: invalid rate=%ld Hz\n", rate);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* configure PLL before dividers */
|
||||
if (axi_clk_cfg.pll_rate[freq_idx] < pll_rate)
|
||||
ret = pll_set(sclk, axi_clk_cfg.pll_rate[freq_idx]);
|
||||
|
||||
/* configure SYS dividers */
|
||||
for (i = 0; i < CGU_SYS_CLOCKS; i++) {
|
||||
clk->idiv_regs = clk->cgu_regs + axi_clk_cfg.idiv[i].oft;
|
||||
hsdk_idiv_write(clk, axi_clk_cfg.idiv[i].val[freq_idx]);
|
||||
}
|
||||
|
||||
/* configure PLL after dividers */
|
||||
if (axi_clk_cfg.pll_rate[freq_idx] >= pll_rate)
|
||||
ret = pll_set(sclk, axi_clk_cfg.pll_rate[freq_idx]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ulong tun_clk_set(struct clk *sclk, ulong rate)
|
||||
{
|
||||
struct hsdk_cgu_clk *clk = dev_get_priv(sclk->dev);
|
||||
ulong pll_rate;
|
||||
int i, freq_idx = -1;
|
||||
ulong ret = 0;
|
||||
|
||||
pll_rate = pll_get(sclk);
|
||||
|
||||
for (i = 0; i < MAX_TUN_CLOCKS; i++) {
|
||||
if (tun_clk_cfg.clk_rate[i] == rate) {
|
||||
freq_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (freq_idx < 0) {
|
||||
pr_err("tun clk: invalid rate=%ld Hz\n", rate);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* configure PLL before dividers */
|
||||
if (tun_clk_cfg.pll_rate[freq_idx] < pll_rate)
|
||||
ret = pll_set(sclk, tun_clk_cfg.pll_rate[freq_idx]);
|
||||
|
||||
/* configure SYS dividers */
|
||||
for (i = 0; i < CGU_TUN_CLOCKS; i++) {
|
||||
clk->idiv_regs = clk->cgu_regs + tun_clk_cfg.idiv[i].oft;
|
||||
hsdk_idiv_write(clk, tun_clk_cfg.idiv[i].val[freq_idx]);
|
||||
}
|
||||
|
||||
/* configure PLL after dividers */
|
||||
if (tun_clk_cfg.pll_rate[freq_idx] >= pll_rate)
|
||||
ret = pll_set(sclk, tun_clk_cfg.pll_rate[freq_idx]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ulong idiv_set(struct clk *sclk, ulong rate)
|
||||
{
|
||||
struct hsdk_cgu_clk *clk = dev_get_priv(sclk->dev);
|
||||
|
@ -33,8 +33,10 @@
|
||||
#define CLK_SYS_UART_REF 18
|
||||
#define CLK_SYS_EBI_REF 19
|
||||
#define CLK_TUN_PLL 20
|
||||
#define CLK_TUN 21
|
||||
#define CLK_HDMI_PLL 22
|
||||
#define CLK_HDMI 23
|
||||
#define CLK_TUN_TUN 21
|
||||
#define CLK_TUN_ROM 22
|
||||
#define CLK_TUN_PWM 23
|
||||
#define CLK_HDMI_PLL 24
|
||||
#define CLK_HDMI 25
|
||||
|
||||
#endif /* __DT_BINDINGS_CLK_HSDK_CGU_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user