xref: /rk3399_ARM-atf/plat/imx/imx8m/ddr/clock.c (revision 1b491eead580d7849a45a38f2c6a935a5d8d1160)
1 /*
2  * Copyright 2018-2023 NXP
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <stdbool.h>
8 
9 #include <lib/mmio.h>
10 #include <platform_def.h>
11 
12 #define IMX_CCM_IP_BASE				(IMX_CCM_BASE + 0xa000)
13 #define DRAM_SEL_CFG				(IMX_CCM_BASE + 0x9800)
14 #define CCM_IP_CLK_ROOT_GEN_TAGET(i)		(IMX_CCM_IP_BASE + 0x80 * (i) + 0x00)
15 #define CCM_IP_CLK_ROOT_GEN_TAGET_SET(i)	(IMX_CCM_IP_BASE + 0x80 * (i) + 0x04)
16 #define CCM_IP_CLK_ROOT_GEN_TAGET_CLR(i)	(IMX_CCM_IP_BASE + 0x80 * (i) + 0x08)
17 #define PLL_FREQ_800M	U(0x00ece580)
18 #define PLL_FREQ_400M	U(0x00ec6984)
19 #define PLL_FREQ_167M	U(0x00f5a406)
20 
21 void ddr_pll_bypass_100mts(void)
22 {
23 	/* change the clock source of dram_alt_clk_root to source 2 --100MHz */
24 	mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(0), (0x7 << 24) | (0x7 << 16));
25 	mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_SET(0), (0x2 << 24));
26 
27 	/* change the clock source of dram_apb_clk_root to source 2 --40MHz/2 */
28 	mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(1), (0x7 << 24) | (0x7 << 16));
29 	mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_SET(1), (0x2 << 24) | (0x1 << 16));
30 
31 	/* configure pll bypass mode */
32 	mmio_write_32(DRAM_SEL_CFG + 0x4, BIT(24));
33 }
34 
35 void ddr_pll_bypass_400mts(void)
36 {
37 	/* change the clock source of dram_alt_clk_root to source 1 --400MHz */
38 	mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(0), (0x7 << 24) | (0x7 << 16));
39 	mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_SET(0), (0x1 << 24) | (0x1 << 16));
40 
41 	/* change the clock source of dram_apb_clk_root to source 3 --160MHz/2 */
42 	mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(1), (0x7 << 24) | (0x7 << 16));
43 	mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_SET(1), (0x3 << 24) | (0x1 << 16));
44 
45 	/* configure pll bypass mode */
46 	mmio_write_32(DRAM_SEL_CFG + 0x4, BIT(24));
47 }
48 
49 void ddr_pll_unbypass(void)
50 {
51 	mmio_write_32(DRAM_SEL_CFG + 0x8, BIT(24));
52 	mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(1), (0x7 << 24) | (0x7 << 16));
53 	/* to source 4 --800MHz/5 */
54 	mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_SET(1), (0x4 << 24) | (0x4 << 16));
55 }
56 
57 #if defined(PLAT_imx8mq)
58 void dram_pll_init(unsigned int drate)
59 {
60 	/* bypass the PLL */
61 	mmio_setbits_32(HW_DRAM_PLL_CFG0, 0x30);
62 
63 	switch (drate) {
64 	case 3200:
65 		mmio_write_32(HW_DRAM_PLL_CFG2, PLL_FREQ_800M);
66 		break;
67 	case 1600:
68 		mmio_write_32(HW_DRAM_PLL_CFG2, PLL_FREQ_400M);
69 		break;
70 	case 667:
71 		mmio_write_32(HW_DRAM_PLL_CFG2, PLL_FREQ_167M);
72 		break;
73 	default:
74 		break;
75 	}
76 
77 	/* unbypass the PLL */
78 	mmio_clrbits_32(HW_DRAM_PLL_CFG0, 0x30);
79 	while (!(mmio_read_32(HW_DRAM_PLL_CFG0) & BIT(31))) {
80 		;
81 	}
82 }
83 #else
84 void dram_pll_init(unsigned int drate)
85 {
86 	/* bypass the PLL */
87 	mmio_setbits_32(DRAM_PLL_CTRL, (1 << 16));
88 	mmio_clrbits_32(DRAM_PLL_CTRL, (1 << 9));
89 
90 	switch (drate) {
91 	case 4000:
92 		mmio_write_32(DRAM_PLL_CTRL + 0x4, (250 << 12) | (3 << 4) | 1);
93 		break;
94 	case 3200:
95 		mmio_write_32(DRAM_PLL_CTRL + 0x4, (200 << 12) | (3 << 4) | 1);
96 		break;
97 	case 2400:
98 		mmio_write_32(DRAM_PLL_CTRL + 0x4, (300 << 12) | (3 << 4) | 2);
99 		break;
100 	case 1600:
101 		mmio_write_32(DRAM_PLL_CTRL + 0x4, (400 << 12) | (3 << 4) | 3);
102 		break;
103 	case 1066:
104 		mmio_write_32(DRAM_PLL_CTRL + 0x4, (266 << 12) | (3 << 4) | 3);
105 		break;
106 	case 667:
107 		mmio_write_32(DRAM_PLL_CTRL + 0x4, (334 << 12) | (3 << 4) | 4);
108 		break;
109 	default:
110 		break;
111 	}
112 
113 	mmio_setbits_32(DRAM_PLL_CTRL, BIT(9));
114 	/* wait for PLL locked */
115 	while (!(mmio_read_32(DRAM_PLL_CTRL) & BIT(31))) {
116 		;
117 	}
118 
119 	/* unbypass the PLL */
120 	mmio_clrbits_32(DRAM_PLL_CTRL, BIT(16));
121 }
122 #endif
123 
124 /* change the dram clock frequency */
125 void dram_clock_switch(unsigned int target_drate, bool bypass_mode)
126 {
127 	if (bypass_mode) {
128 		switch (target_drate) {
129 		case 400:
130 			ddr_pll_bypass_400mts();
131 			break;
132 		case 100:
133 			ddr_pll_bypass_100mts();
134 			break;
135 		default:
136 			ddr_pll_unbypass();
137 			break;
138 		}
139 	} else {
140 		dram_pll_init(target_drate);
141 	}
142 }
143