Jacky Bai | d746daa1 | 2019-11-25 13:19:37 +0800 | [diff] [blame] | 1 | /* |
Jacky Bai | e936190 | 2020-10-19 15:45:16 +0800 | [diff] [blame] | 2 | * Copyright 2018-2023 NXP |
Jacky Bai | d746daa1 | 2019-11-25 13:19:37 +0800 | [diff] [blame] | 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); |
Jacky Bai | a51b11a | 2020-01-14 14:19:05 +0800 | [diff] [blame] | 79 | while (!(mmio_read_32(HW_DRAM_PLL_CFG0) & BIT(31))) { |
Jacky Bai | d746daa1 | 2019-11-25 13:19:37 +0800 | [diff] [blame] | 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) { |
Jacky Bai | e936190 | 2020-10-19 15:45:16 +0800 | [diff] [blame] | 91 | case 4000: |
| 92 | mmio_write_32(DRAM_PLL_CTRL + 0x4, (250 << 12) | (3 << 4) | 1); |
| 93 | break; |
Marek Vasut | 38945f0 | 2023-11-30 22:12:45 +0100 | [diff] [blame] | 94 | case 3734: |
Marek Vasut | 37110cd | 2023-08-31 02:59:08 +0200 | [diff] [blame] | 95 | case 3733: |
| 96 | case 3732: |
| 97 | mmio_write_32(DRAM_PLL_CTRL + 0x4, (311 << 12) | (4 << 4) | 1); |
| 98 | break; |
Marek Vasut | 6d44161 | 2023-11-30 22:18:49 +0100 | [diff] [blame] | 99 | case 3600: |
| 100 | mmio_write_32(DRAM_PLL_CTRL + 0x4, (300 << 12) | (8 << 4) | 0); |
| 101 | break; |
Jacky Bai | e936190 | 2020-10-19 15:45:16 +0800 | [diff] [blame] | 102 | case 3200: |
Marek Vasut | ea6ce4e | 2023-11-30 22:14:31 +0100 | [diff] [blame] | 103 | mmio_write_32(DRAM_PLL_CTRL + 0x4, (300 << 12) | (9 << 4) | 0); |
Jacky Bai | e936190 | 2020-10-19 15:45:16 +0800 | [diff] [blame] | 104 | break; |
Jacky Bai | d746daa1 | 2019-11-25 13:19:37 +0800 | [diff] [blame] | 105 | 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 */ |
| 133 | void 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 | } |