blob: 21a1b6842972273187eec30d8deb8a0f04bcfb43 [file] [log] [blame]
Jacky Baid746daa12019-11-25 13:19:37 +08001/*
Jacky Baie9361902020-10-19 15:45:16 +08002 * Copyright 2018-2023 NXP
Jacky Baid746daa12019-11-25 13:19:37 +08003 *
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
21void 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
35void 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
49void 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)
58void 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);
Jacky Baia51b11a2020-01-14 14:19:05 +080079 while (!(mmio_read_32(HW_DRAM_PLL_CFG0) & BIT(31))) {
Jacky Baid746daa12019-11-25 13:19:37 +080080 ;
81 }
82}
83#else
84void 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) {
Jacky Baie9361902020-10-19 15:45:16 +080091 case 4000:
92 mmio_write_32(DRAM_PLL_CTRL + 0x4, (250 << 12) | (3 << 4) | 1);
93 break;
Marek Vasut38945f02023-11-30 22:12:45 +010094 case 3734:
Marek Vasut37110cd2023-08-31 02:59:08 +020095 case 3733:
96 case 3732:
97 mmio_write_32(DRAM_PLL_CTRL + 0x4, (311 << 12) | (4 << 4) | 1);
98 break;
Marek Vasut6d441612023-11-30 22:18:49 +010099 case 3600:
100 mmio_write_32(DRAM_PLL_CTRL + 0x4, (300 << 12) | (8 << 4) | 0);
101 break;
Jacky Baie9361902020-10-19 15:45:16 +0800102 case 3200:
Marek Vasutea6ce4e2023-11-30 22:14:31 +0100103 mmio_write_32(DRAM_PLL_CTRL + 0x4, (300 << 12) | (9 << 4) | 0);
Jacky Baie9361902020-10-19 15:45:16 +0800104 break;
Jacky Baid746daa12019-11-25 13:19:37 +0800105 case 2400:
106 mmio_write_32(DRAM_PLL_CTRL + 0x4, (300 << 12) | (3 << 4) | 2);
107 break;
108 case 1600:
109 mmio_write_32(DRAM_PLL_CTRL + 0x4, (400 << 12) | (3 << 4) | 3);
110 break;
111 case 1066:
112 mmio_write_32(DRAM_PLL_CTRL + 0x4, (266 << 12) | (3 << 4) | 3);
113 break;
114 case 667:
115 mmio_write_32(DRAM_PLL_CTRL + 0x4, (334 << 12) | (3 << 4) | 4);
116 break;
117 default:
118 break;
119 }
120
121 mmio_setbits_32(DRAM_PLL_CTRL, BIT(9));
122 /* wait for PLL locked */
123 while (!(mmio_read_32(DRAM_PLL_CTRL) & BIT(31))) {
124 ;
125 }
126
127 /* unbypass the PLL */
128 mmio_clrbits_32(DRAM_PLL_CTRL, BIT(16));
129}
130#endif
131
132/* change the dram clock frequency */
133void dram_clock_switch(unsigned int target_drate, bool bypass_mode)
134{
135 if (bypass_mode) {
136 switch (target_drate) {
137 case 400:
138 ddr_pll_bypass_400mts();
139 break;
140 case 100:
141 ddr_pll_bypass_100mts();
142 break;
143 default:
144 ddr_pll_unbypass();
145 break;
146 }
147 } else {
148 dram_pll_init(target_drate);
149 }
150}