Browse Source

Merge git://git.denx.de/u-boot-arc

Tom Rini 6 years ago
parent
commit
c4cb6e64bf

+ 6 - 0
arch/arc/dts/hsdk.dts

@@ -24,6 +24,12 @@
 		};
 	};
 
+	cgu_clk: cgu-clk@f0000000 {
+		compatible = "snps,hsdk-cgu-clock";
+		reg = <0xf0000000 0x10>, <0xf00014B8 0x4>;
+		#clock-cells = <1>;
+	};
+
 	uart0: serial0@f0005000 {
 		compatible = "snps,dw-apb-uart";
 		reg = <0xf0005000 0x1000>;

+ 7 - 0
arch/arc/include/asm/arcregs.h

@@ -63,8 +63,15 @@
 #define ARC_AUX_SLC_INVALIDATE	0x905
 #define ARC_AUX_SLC_IVDL	0x910
 #define ARC_AUX_SLC_FLDL	0x912
+#define ARC_AUX_SLC_RGN_START	0x914
+#define ARC_AUX_SLC_RGN_START1	0x915
+#define ARC_AUX_SLC_RGN_END	0x916
+#define ARC_AUX_SLC_RGN_END1	0x917
 #define ARC_BCR_CLUSTER		0xcf
 
+/* MMU Management regs */
+#define ARC_AUX_MMU_BCR		0x06f
+
 /* IO coherency related auxiliary registers */
 #define ARC_AUX_IO_COH_ENABLE	0x500
 #define ARC_AUX_IO_COH_PARTIAL	0x501

+ 128 - 80
arch/arc/lib/cache.c

@@ -13,19 +13,24 @@
 #include <asm/cache.h>
 
 /* Bit values in IC_CTRL */
-#define IC_CTRL_CACHE_DISABLE	(1 << 0)
+#define IC_CTRL_CACHE_DISABLE	BIT(0)
 
 /* Bit values in DC_CTRL */
-#define DC_CTRL_CACHE_DISABLE	(1 << 0)
-#define DC_CTRL_INV_MODE_FLUSH	(1 << 6)
-#define DC_CTRL_FLUSH_STATUS	(1 << 8)
+#define DC_CTRL_CACHE_DISABLE	BIT(0)
+#define DC_CTRL_INV_MODE_FLUSH	BIT(6)
+#define DC_CTRL_FLUSH_STATUS	BIT(8)
 #define CACHE_VER_NUM_MASK	0xF
-#define SLC_CTRL_SB		(1 << 2)
 
 #define OP_INV		0x1
 #define OP_FLUSH	0x2
 #define OP_INV_IC	0x3
 
+/* Bit val in SLC_CONTROL */
+#define SLC_CTRL_DIS		0x001
+#define SLC_CTRL_IM		0x040
+#define SLC_CTRL_BUSY		0x100
+#define SLC_CTRL_RGN_OP_INV	0x200
+
 /*
  * By default that variable will fall into .bss section.
  * But .bss section is not relocated and so it will be initilized before
@@ -41,88 +46,118 @@ bool icache_exists __section(".data") = false;
 int slc_line_sz __section(".data");
 bool slc_exists __section(".data") = false;
 bool ioc_exists __section(".data") = false;
+bool pae_exists __section(".data") = false;
+
+/* To force enable IOC set ioc_enable to 'true' */
+bool ioc_enable __section(".data") = false;
 
-static unsigned int __before_slc_op(const int op)
+void read_decode_mmu_bcr(void)
 {
-	unsigned int reg = reg;
+	/* TODO: should we compare mmu version from BCR and from CONFIG? */
+#if (CONFIG_ARC_MMU_VER >= 4)
+	u32 tmp;
 
-	if (op == OP_INV) {
-		/*
-		 * IM is set by default and implies Flush-n-inv
-		 * Clear it here for vanilla inv
-		 */
-		reg = read_aux_reg(ARC_AUX_SLC_CTRL);
-		write_aux_reg(ARC_AUX_SLC_CTRL, reg & ~DC_CTRL_INV_MODE_FLUSH);
-	}
+	tmp = read_aux_reg(ARC_AUX_MMU_BCR);
 
-	return reg;
-}
+	struct bcr_mmu_4 {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+	unsigned int ver:8, sasid:1, sz1:4, sz0:4, res:2, pae:1,
+		     n_ways:2, n_entry:2, n_super:2, u_itlb:3, u_dtlb:3;
+#else
+	/*           DTLB      ITLB      JES        JE         JA      */
+	unsigned int u_dtlb:3, u_itlb:3, n_super:2, n_entry:2, n_ways:2,
+		     pae:1, res:2, sz0:4, sz1:4, sasid:1, ver:8;
+#endif /* CONFIG_CPU_BIG_ENDIAN */
+	} *mmu4;
 
-static void __after_slc_op(const int op, unsigned int reg)
-{
-	if (op & OP_FLUSH) {	/* flush / flush-n-inv both wait */
-		/*
-		 * Make sure "busy" bit reports correct status,
-		 * see STAR 9001165532
-		 */
-		read_aux_reg(ARC_AUX_SLC_CTRL);
-		while (read_aux_reg(ARC_AUX_SLC_CTRL) &
-		       DC_CTRL_FLUSH_STATUS)
-			;
-	}
+	mmu4 = (struct bcr_mmu_4 *)&tmp;
 
-	/* Switch back to default Invalidate mode */
-	if (op == OP_INV)
-		write_aux_reg(ARC_AUX_SLC_CTRL, reg | DC_CTRL_INV_MODE_FLUSH);
+	pae_exists = !!mmu4->pae;
+#endif /* (CONFIG_ARC_MMU_VER >= 4) */
 }
 
-static inline void __slc_line_loop(unsigned long paddr, unsigned long sz,
-				   const int op)
+static void __slc_entire_op(const int op)
 {
-	unsigned int aux_cmd;
-	int num_lines;
+	unsigned int ctrl;
 
-#define SLC_LINE_MASK	(~(slc_line_sz - 1))
+	ctrl = read_aux_reg(ARC_AUX_SLC_CTRL);
 
-	aux_cmd = op & OP_INV ? ARC_AUX_SLC_IVDL : ARC_AUX_SLC_FLDL;
+	if (!(op & OP_FLUSH))		/* i.e. OP_INV */
+		ctrl &= ~SLC_CTRL_IM;	/* clear IM: Disable flush before Inv */
+	else
+		ctrl |= SLC_CTRL_IM;
 
-	sz += paddr & ~SLC_LINE_MASK;
-	paddr &= SLC_LINE_MASK;
+	write_aux_reg(ARC_AUX_SLC_CTRL, ctrl);
 
-	num_lines = DIV_ROUND_UP(sz, slc_line_sz);
+	if (op & OP_INV)	/* Inv or flush-n-inv use same cmd reg */
+		write_aux_reg(ARC_AUX_SLC_INVALIDATE, 0x1);
+	else
+		write_aux_reg(ARC_AUX_SLC_FLUSH, 0x1);
 
-	while (num_lines-- > 0) {
-		write_aux_reg(aux_cmd, paddr);
-		paddr += slc_line_sz;
-	}
+	/* Make sure "busy" bit reports correct stataus, see STAR 9001165532 */
+	read_aux_reg(ARC_AUX_SLC_CTRL);
+
+	/* Important to wait for flush to complete */
+	while (read_aux_reg(ARC_AUX_SLC_CTRL) & SLC_CTRL_BUSY);
 }
 
-static inline void __slc_entire_op(const int cacheop)
+static void slc_upper_region_init(void)
 {
-	int aux;
-	unsigned int ctrl_reg = __before_slc_op(cacheop);
+	/*
+	 * ARC_AUX_SLC_RGN_END1 and ARC_AUX_SLC_RGN_START1 are always == 0
+	 * as we don't use PAE40.
+	 */
+	write_aux_reg(ARC_AUX_SLC_RGN_END1, 0);
+	write_aux_reg(ARC_AUX_SLC_RGN_START1, 0);
+}
 
-	if (cacheop & OP_INV)	/* Inv or flush-n-inv use same cmd reg */
-		aux = ARC_AUX_SLC_INVALIDATE;
+static void __slc_rgn_op(unsigned long paddr, unsigned long sz, const int op)
+{
+	unsigned int ctrl;
+	unsigned long end;
+
+	/*
+	 * The Region Flush operation is specified by CTRL.RGN_OP[11..9]
+	 *  - b'000 (default) is Flush,
+	 *  - b'001 is Invalidate if CTRL.IM == 0
+	 *  - b'001 is Flush-n-Invalidate if CTRL.IM == 1
+	 */
+	ctrl = read_aux_reg(ARC_AUX_SLC_CTRL);
+
+	/* Don't rely on default value of IM bit */
+	if (!(op & OP_FLUSH))		/* i.e. OP_INV */
+		ctrl &= ~SLC_CTRL_IM;	/* clear IM: Disable flush before Inv */
 	else
-		aux = ARC_AUX_SLC_FLUSH;
+		ctrl |= SLC_CTRL_IM;
 
-	write_aux_reg(aux, 0x1);
+	if (op & OP_INV)
+		ctrl |= SLC_CTRL_RGN_OP_INV;	/* Inv or flush-n-inv */
+	else
+		ctrl &= ~SLC_CTRL_RGN_OP_INV;
 
-	__after_slc_op(cacheop, ctrl_reg);
-}
+	write_aux_reg(ARC_AUX_SLC_CTRL, ctrl);
 
-static inline void __slc_line_op(unsigned long paddr, unsigned long sz,
-				 const int cacheop)
-{
-	unsigned int ctrl_reg = __before_slc_op(cacheop);
-	__slc_line_loop(paddr, sz, cacheop);
-	__after_slc_op(cacheop, ctrl_reg);
+	/*
+	 * Lower bits are ignored, no need to clip
+	 * END needs to be setup before START (latter triggers the operation)
+	 * END can't be same as START, so add (l2_line_sz - 1) to sz
+	 */
+	end = paddr + sz + slc_line_sz - 1;
+
+	/*
+	 * Upper addresses (ARC_AUX_SLC_RGN_END1 and ARC_AUX_SLC_RGN_START1)
+	 * are always == 0 as we don't use PAE40, so we only setup lower ones
+	 * (ARC_AUX_SLC_RGN_END and ARC_AUX_SLC_RGN_START)
+	 */
+	write_aux_reg(ARC_AUX_SLC_RGN_END, end);
+	write_aux_reg(ARC_AUX_SLC_RGN_START, paddr);
+
+	/* Make sure "busy" bit reports correct stataus, see STAR 9001165532 */
+	read_aux_reg(ARC_AUX_SLC_CTRL);
+
+	while (read_aux_reg(ARC_AUX_SLC_CTRL) & SLC_CTRL_BUSY);
 }
-#else
-#define __slc_entire_op(cacheop)
-#define __slc_line_op(paddr, sz, cacheop)
-#endif
+#endif /* CONFIG_ISA_ARCV2 */
 
 #ifdef CONFIG_ISA_ARCV2
 static void read_decode_cache_bcr_arcv2(void)
@@ -168,7 +203,7 @@ static void read_decode_cache_bcr_arcv2(void)
 	} cbcr;
 
 	cbcr.word = read_aux_reg(ARC_BCR_CLUSTER);
-	if (cbcr.fields.c)
+	if (cbcr.fields.c && ioc_enable)
 		ioc_exists = true;
 }
 #endif
@@ -197,7 +232,7 @@ void read_decode_cache_bcr(void)
 	}
 
 	dbcr.word = read_aux_reg(ARC_BCR_DC_BUILD);
-	if (dbcr.fields.ver){
+	if (dbcr.fields.ver) {
 		dcache_exists = true;
 		l1_line_sz = dc_line_sz = 16 << dbcr.fields.line_len;
 		if (!dc_line_sz)
@@ -232,8 +267,7 @@ void cache_init(void)
 		 * so setting 0x11 implies 512M, 0x12 implies 1G...
 		 */
 		write_aux_reg(ARC_AUX_IO_COH_AP0_SIZE,
-			      order_base_2(ap_size/1024) - 2);
-
+			      order_base_2(ap_size / 1024) - 2);
 
 		/* IOC Aperture start must be aligned to the size of the aperture */
 		if (ap_base % ap_size != 0)
@@ -242,9 +276,18 @@ void cache_init(void)
 		write_aux_reg(ARC_AUX_IO_COH_AP0_BASE, ap_base >> 12);
 		write_aux_reg(ARC_AUX_IO_COH_PARTIAL, 1);
 		write_aux_reg(ARC_AUX_IO_COH_ENABLE, 1);
-
 	}
-#endif
+
+	read_decode_mmu_bcr();
+
+	/*
+	 * ARC_AUX_SLC_RGN_START1 and ARC_AUX_SLC_RGN_END1 register exist
+	 * only if PAE exists in current HW. So we had to check pae_exist
+	 * before using them.
+	 */
+	if (slc_exists && pae_exists)
+		slc_upper_region_init();
+#endif /* CONFIG_ISA_ARCV2 */
 }
 
 int icache_status(void)
@@ -272,7 +315,6 @@ void icache_disable(void)
 			      IC_CTRL_CACHE_DISABLE);
 }
 
-#ifndef CONFIG_SYS_DCACHE_OFF
 void invalidate_icache_all(void)
 {
 	/* Any write to IC_IVIC register triggers invalidation of entire I$ */
@@ -287,12 +329,12 @@ void invalidate_icache_all(void)
 		__builtin_arc_nop();
 		read_aux_reg(ARC_AUX_IC_CTRL);	/* blocks */
 	}
-}
-#else
-void invalidate_icache_all(void)
-{
-}
+
+#ifdef CONFIG_ISA_ARCV2
+	if (slc_exists)
+		__slc_entire_op(OP_INV);
 #endif
+}
 
 int dcache_status(void)
 {
@@ -382,8 +424,7 @@ static unsigned int __before_dc_op(const int op)
 static void __after_dc_op(const int op, unsigned int reg)
 {
 	if (op & OP_FLUSH)	/* flush / flush-n-inv both wait */
-		while (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS)
-			;
+		while (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS);
 
 	/* Switch back to default Invalidate mode */
 	if (op == OP_INV)
@@ -409,6 +450,7 @@ static inline void __dc_line_op(unsigned long paddr, unsigned long sz,
 				const int cacheop)
 {
 	unsigned int ctrl_reg = __before_dc_op(cacheop);
+
 	__cache_line_loop(paddr, sz, cacheop);
 	__after_dc_op(cacheop, ctrl_reg);
 }
@@ -419,6 +461,9 @@ static inline void __dc_line_op(unsigned long paddr, unsigned long sz,
 
 void invalidate_dcache_range(unsigned long start, unsigned long end)
 {
+	if (start >= end)
+		return;
+
 #ifdef CONFIG_ISA_ARCV2
 	if (!ioc_exists)
 #endif
@@ -426,12 +471,15 @@ void invalidate_dcache_range(unsigned long start, unsigned long end)
 
 #ifdef CONFIG_ISA_ARCV2
 	if (slc_exists && !ioc_exists)
-		__slc_line_op(start, end - start, OP_INV);
+		__slc_rgn_op(start, end - start, OP_INV);
 #endif
 }
 
 void flush_dcache_range(unsigned long start, unsigned long end)
 {
+	if (start >= end)
+		return;
+
 #ifdef CONFIG_ISA_ARCV2
 	if (!ioc_exists)
 #endif
@@ -439,7 +487,7 @@ void flush_dcache_range(unsigned long start, unsigned long end)
 
 #ifdef CONFIG_ISA_ARCV2
 	if (slc_exists && !ioc_exists)
-		__slc_line_op(start, end - start, OP_FLUSH);
+		__slc_rgn_op(start, end - start, OP_FLUSH);
 #endif
 }
 

+ 12 - 0
arch/arc/lib/start.S

@@ -44,6 +44,14 @@ ENTRY(_start)
 #endif
 	sr	r5, [ARC_AUX_IC_CTRL]
 
+	mov	r5, 1
+	sr	r5, [ARC_AUX_IC_IVIC]
+	; As per ARC HS databook (see chapter 5.3.3.2)
+	; it is required to add 3 NOPs after each write to IC_IVIC.
+	nop
+	nop
+	nop
+
 1:
 	; Disable/enable D-cache according to configuration
 	lr	r5, [ARC_BCR_DC_BUILD]
@@ -57,6 +65,10 @@ ENTRY(_start)
 #endif
 	sr	r5, [ARC_AUX_DC_CTRL]
 
+	mov	r5, 1
+	sr	r5, [ARC_AUX_DC_IVDC]
+
+
 1:
 #ifdef CONFIG_ISA_ARCV2
 	; Disable System-Level Cache (SLC)

+ 1 - 0
configs/hsdk_defconfig

@@ -39,3 +39,4 @@ CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_OHCI_GENERIC=y
 CONFIG_USB_STORAGE=y
 CONFIG_USE_PRIVATE_LIBGCC=y
+CONFIG_PANIC_HANG=y

+ 167 - 10
drivers/clk/clk-hsdk-cgu.c

@@ -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 }
 };
@@ -423,7 +492,7 @@ static ulong pll_set(struct clk *sclk, ulong rate)
 		}
 	}
 
-	pr_err("invalid rate=%ld, parent_rate=%d\n", best_rate, PARENT_RATE);
+	pr_err("invalid rate=%ld Hz, parent_rate=%d Hz\n", best_rate, PARENT_RATE);
 
 	return -EINVAL;
 }
@@ -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);
@@ -466,14 +623,14 @@ static ulong idiv_set(struct clk *sclk, ulong rate)
 	}
 
 	if (div_factor & ~CGU_IDIV_MASK) {
-		pr_err("invalid rate=%ld, parent_rate=%ld, div=%d: max divider valie is%d\n",
+		pr_err("invalid rate=%ld Hz, parent_rate=%ld Hz, div=%d: max divider valie is%d\n",
 		       rate, parent_rate, div_factor, CGU_IDIV_MASK);
 
 		div_factor = CGU_IDIV_MASK;
 	}
 
 	if (div_factor == 0) {
-		pr_err("invalid rate=%ld, parent_rate=%ld, div=%d: min divider valie is 1\n",
+		pr_err("invalid rate=%ld Hz, parent_rate=%ld Hz, div=%d: min divider valie is 1\n",
 		       rate, parent_rate, div_factor);
 
 		div_factor = 1;
@@ -559,6 +716,6 @@ U_BOOT_DRIVER(hsdk_cgu_clk) = {
 	.id = UCLASS_CLK,
 	.of_match = hsdk_cgu_clk_id,
 	.probe = hsdk_cgu_clk_probe,
-	.platdata_auto_alloc_size = sizeof(struct hsdk_cgu_clk),
+	.priv_auto_alloc_size = sizeof(struct hsdk_cgu_clk),
 	.ops = &hsdk_cgu_ops,
 };

+ 1 - 1
include/configs/axs10x.h

@@ -29,7 +29,7 @@
 	(CONFIG_SYS_SDRAM_BASE + 0x1000 - GENERATED_GBL_DATA_SIZE)
 
 #define CONFIG_SYS_MALLOC_LEN		SZ_2M
-#define CONFIG_SYS_BOOTM_LEN		SZ_32M
+#define CONFIG_SYS_BOOTM_LEN		SZ_128M
 #define CONFIG_SYS_LOAD_ADDR		0x82000000
 
 /*

+ 1 - 1
include/configs/hsdk.h

@@ -29,7 +29,7 @@
 	(CONFIG_SYS_SDRAM_BASE + 0x1000 - GENERATED_GBL_DATA_SIZE)
 
 #define CONFIG_SYS_MALLOC_LEN		SZ_2M
-#define CONFIG_SYS_BOOTM_LEN		SZ_32M
+#define CONFIG_SYS_BOOTM_LEN		SZ_128M
 #define CONFIG_SYS_LOAD_ADDR		0x82000000
 
 /*

+ 5 - 3
include/dt-bindings/clock/snps,hsdk-cgu.h

@@ -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_ */