Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c065909e authored by Ganesan Ramalingam's avatar Ganesan Ramalingam Committed by Ralf Baechle
Browse files

MIPS: Netlogic: PIC freq calculation for XLP 9XX/2XX



Update PIC frequency calculation for XLP9XX and 2XX processors using
the correct PLL registers. This should work for all possible board
configurations.

Signed-off-by: default avatarGanesan Ramalingam <ganesanr@broadcom.com>
Signed-off-by: default avatarJayachandran C <jchandra@broadcom.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/6876/


Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 77bef0e4
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -120,6 +120,8 @@
#define XLP9XX_IO_UART_OFFSET(node)	XLP9XX_HDR_OFFSET(node, 2, 2)
#define XLP9XX_IO_SYS_OFFSET(node)	XLP9XX_HDR_OFFSET(node, 6, 0)
#define XLP9XX_IO_FUSE_OFFSET(node)	XLP9XX_HDR_OFFSET(node, 6, 1)
#define XLP9XX_IO_CLOCK_OFFSET(node)	XLP9XX_HDR_OFFSET(node, 6, 2)
#define XLP9XX_IO_POWER_OFFSET(node)	XLP9XX_HDR_OFFSET(node, 6, 3)
#define XLP9XX_IO_JTAG_OFFSET(node)	XLP9XX_HDR_OFFSET(node, 6, 4)

#define XLP9XX_IO_PCIE_OFFSET(node, i)	XLP9XX_HDR_OFFSET(node, 1, i)
+27 −0
Original line number Diff line number Diff line
@@ -147,6 +147,28 @@
#define SYS_SYS_PLL_MEM_REQ			0x2a3
#define SYS_PLL_MEM_STAT			0x2a4

/* PLL registers XLP9XX */
#define SYS_9XX_DMC_PLL_CTRL0			0x140
#define SYS_9XX_DMC_PLL_CTRL1			0x141
#define SYS_9XX_DMC_PLL_CTRL2			0x142
#define SYS_9XX_DMC_PLL_CTRL3			0x143
#define SYS_9XX_PLL_CTRL0			0x144
#define SYS_9XX_PLL_CTRL1			0x145
#define SYS_9XX_PLL_CTRL2			0x146
#define SYS_9XX_PLL_CTRL3			0x147

#define SYS_9XX_PLL_CTRL0_DEVX(x)		(0x148 + (x) * 4)
#define SYS_9XX_PLL_CTRL1_DEVX(x)		(0x149 + (x) * 4)
#define SYS_9XX_PLL_CTRL2_DEVX(x)		(0x14a + (x) * 4)
#define SYS_9XX_PLL_CTRL3_DEVX(x)		(0x14b + (x) * 4)

#define SYS_9XX_CPU_PLL_CHG_CTRL		0x188
#define SYS_9XX_PLL_CHG_CTRL			0x189
#define SYS_9XX_CLK_DEV_DIS			0x18a
#define SYS_9XX_CLK_DEV_SEL			0x18b
#define SYS_9XX_CLK_DEV_DIV			0x18d
#define SYS_9XX_CLK_DEV_CHG			0x18f

/* Registers changed on 9XX */
#define SYS_9XX_POWER_ON_RESET_CFG		0x00
#define SYS_9XX_CHIP_RESET			0x01
@@ -170,6 +192,11 @@
#define nlm_get_fuse_regbase(node)	\
			(nlm_get_fuse_pcibase(node) + XLP_IO_PCI_HDRSZ)

#define nlm_get_clock_pcibase(node)	\
			nlm_pcicfg_base(XLP9XX_IO_CLOCK_OFFSET(node))
#define nlm_get_clock_regbase(node)	\
			(nlm_get_clock_pcibase(node) + XLP_IO_PCI_HDRSZ)

unsigned int nlm_get_pic_frequency(int node);
#endif
#endif
+4 −1
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@ static struct clocksource csrc_pic = {
static void nlm_init_pic_timer(void)
{
	uint64_t picbase = nlm_get_node(0)->picbase;
	u32 picfreq;

	nlm_pic_set_timer(picbase, PIC_CLOCK_TIMER, ~0ULL, 0, 0);
	if (current_cpu_data.cputype == CPU_XLR) {
@@ -92,7 +93,9 @@ static void nlm_init_pic_timer(void)
		csrc_pic.read	= nlm_get_pic_timer;
	}
	csrc_pic.rating = 1000;
	clocksource_register_hz(&csrc_pic, pic_timer_freq());
	picfreq = pic_timer_freq();
	clocksource_register_hz(&csrc_pic, picfreq);
	pr_info("PIC clock source added, frequency %d\n", picfreq);
}

void __init plat_time_init(void)
+81 −33
Original line number Diff line number Diff line
@@ -234,21 +234,28 @@ unsigned int nlm_get_core_frequency(int node, int core)
	return (unsigned int)num;
}

/* Calculate Frequency to the PIC from PLL.
/*
 * Calculate PIC frequency from PLL registers.
 * freq_out = (ref_freq/2 * (6 + ctrl2[7:0]) + ctrl2[20:8]/2^13) /
 * 		((2^ctrl0[7:5]) * Table(ctrl0[26:24]))
 */
static unsigned int nlm_2xx_get_pic_frequency(int node)
static unsigned int nlm_xlp2_get_pic_frequency(int node)
{
	u32 ctrl_val0, ctrl_val2, vco_post_div, pll_post_div;
	u32 ctrl_val0, ctrl_val2, vco_post_div, pll_post_div, cpu_xlp9xx;
	u32 mdiv, fdiv, pll_out_freq_den, reg_select, ref_div, pic_div;
	u64 ref_clk, sysbase, pll_out_freq_num, ref_clk_select;
	u64 sysbase, pll_out_freq_num, ref_clk_select, clockbase, ref_clk;

	sysbase = nlm_get_node(node)->sysbase;
	clockbase = nlm_get_clock_regbase(node);
	cpu_xlp9xx = cpu_is_xlp9xx();

	/* Find ref_clk_base */
	ref_clk_select =
		(nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG) >> 18) & 0x3;
	if (cpu_xlp9xx)
		ref_clk_select = (nlm_read_sys_reg(sysbase,
				SYS_9XX_POWER_ON_RESET_CFG) >> 18) & 0x3;
	else
		ref_clk_select = (nlm_read_sys_reg(sysbase,
					SYS_POWER_ON_RESET_CFG) >> 18) & 0x3;
	switch (ref_clk_select) {
	case 0:
		ref_clk = 200000000ULL;
@@ -269,30 +276,70 @@ static unsigned int nlm_2xx_get_pic_frequency(int node)
	}

	/* Find the clock source PLL device for PIC */
	reg_select = (nlm_read_sys_reg(sysbase, SYS_CLK_DEV_SEL) >> 22) & 0x3;
	if (cpu_xlp9xx) {
		reg_select = nlm_read_sys_reg(clockbase,
				SYS_9XX_CLK_DEV_SEL) & 0x3;
		switch (reg_select) {
		case 0:
		ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0);
		ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2);
			ctrl_val0 = nlm_read_sys_reg(clockbase,
					SYS_9XX_PLL_CTRL0);
			ctrl_val2 = nlm_read_sys_reg(clockbase,
					SYS_9XX_PLL_CTRL2);
			break;
		case 1:
		ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0_DEVX(0));
		ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2_DEVX(0));
			ctrl_val0 = nlm_read_sys_reg(clockbase,
					SYS_9XX_PLL_CTRL0_DEVX(0));
			ctrl_val2 = nlm_read_sys_reg(clockbase,
					SYS_9XX_PLL_CTRL2_DEVX(0));
			break;
		case 2:
		ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0_DEVX(1));
		ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2_DEVX(1));
			ctrl_val0 = nlm_read_sys_reg(clockbase,
					SYS_9XX_PLL_CTRL0_DEVX(1));
			ctrl_val2 = nlm_read_sys_reg(clockbase,
					SYS_9XX_PLL_CTRL2_DEVX(1));
			break;
		case 3:
		ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0_DEVX(2));
		ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2_DEVX(2));
			ctrl_val0 = nlm_read_sys_reg(clockbase,
					SYS_9XX_PLL_CTRL0_DEVX(2));
			ctrl_val2 = nlm_read_sys_reg(clockbase,
					SYS_9XX_PLL_CTRL2_DEVX(2));
			break;
		}
	} else {
		reg_select = (nlm_read_sys_reg(sysbase,
					SYS_CLK_DEV_SEL) >> 22) & 0x3;
		switch (reg_select) {
		case 0:
			ctrl_val0 = nlm_read_sys_reg(sysbase,
					SYS_PLL_CTRL0);
			ctrl_val2 = nlm_read_sys_reg(sysbase,
					SYS_PLL_CTRL2);
			break;
		case 1:
			ctrl_val0 = nlm_read_sys_reg(sysbase,
					SYS_PLL_CTRL0_DEVX(0));
			ctrl_val2 = nlm_read_sys_reg(sysbase,
					SYS_PLL_CTRL2_DEVX(0));
			break;
		case 2:
			ctrl_val0 = nlm_read_sys_reg(sysbase,
					SYS_PLL_CTRL0_DEVX(1));
			ctrl_val2 = nlm_read_sys_reg(sysbase,
					SYS_PLL_CTRL2_DEVX(1));
			break;
		case 3:
			ctrl_val0 = nlm_read_sys_reg(sysbase,
					SYS_PLL_CTRL0_DEVX(2));
			ctrl_val2 = nlm_read_sys_reg(sysbase,
					SYS_PLL_CTRL2_DEVX(2));
			break;
		}
	}

	vco_post_div = (ctrl_val0 >> 5) & 0x7;
	pll_post_div = (ctrl_val0 >> 24) & 0x7;
	mdiv = ctrl_val2 & 0xff;
	fdiv = (ctrl_val2 >> 8) & 0xfff;
	fdiv = (ctrl_val2 >> 8) & 0x1fff;

	/* Find PLL post divider value */
	switch (pll_post_div) {
@@ -322,7 +369,12 @@ static unsigned int nlm_2xx_get_pic_frequency(int node)
		do_div(pll_out_freq_num, pll_out_freq_den);

	/* PIC post divider, which happens after PLL */
	pic_div = (nlm_read_sys_reg(sysbase, SYS_CLK_DEV_DIV) >> 22) & 0x3;
	if (cpu_xlp9xx)
		pic_div = nlm_read_sys_reg(clockbase,
				SYS_9XX_CLK_DEV_DIV) & 0x3;
	else
		pic_div = (nlm_read_sys_reg(sysbase,
					SYS_CLK_DEV_DIV) >> 22) & 0x3;
	do_div(pll_out_freq_num, 1 << pic_div);

	return pll_out_freq_num;
@@ -330,12 +382,8 @@ static unsigned int nlm_2xx_get_pic_frequency(int node)

unsigned int nlm_get_pic_frequency(int node)
{
	/* TODO Has to calculate freq as like 2xx */
	if (cpu_is_xlp9xx())
		return 250000000;

	if (cpu_is_xlpii())
		return nlm_2xx_get_pic_frequency(node);
		return nlm_xlp2_get_pic_frequency(node);
	else
		return 133333333;
}