1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright 2018 NXP 4 */ 5 6#include <common.h> 7#include <errno.h> 8#include <log.h> 9#include <asm/io.h> 10#include <asm/arch/ddr.h> 11#include <asm/arch/clock.h> 12#include <asm/arch/ddr.h> 13#include <asm/arch/sys_proto.h> 14 15static inline void poll_pmu_message_ready(void) 16{ 17 unsigned int reg; 18 19 do { 20 reg = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + ddrphy_addr_remap(0xd0004)); 21 } while (reg & 0x1); 22} 23 24static inline void ack_pmu_message_receive(void) 25{ 26 unsigned int reg; 27 28 reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + ddrphy_addr_remap(0xd0031), 0x0); 29 30 do { 31 reg = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + ddrphy_addr_remap(0xd0004)); 32 } while (!(reg & 0x1)); 33 34 reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + ddrphy_addr_remap(0xd0031), 0x1); 35} 36 37static inline unsigned int get_mail(void) 38{ 39 unsigned int reg; 40 41 poll_pmu_message_ready(); 42 43 reg = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + ddrphy_addr_remap(0xd0032)); 44 45 ack_pmu_message_receive(); 46 47 return reg; 48} 49 50static inline unsigned int get_stream_message(void) 51{ 52 unsigned int reg, reg2; 53 54 poll_pmu_message_ready(); 55 56 reg = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + ddrphy_addr_remap(0xd0032)); 57 58 reg2 = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + ddrphy_addr_remap(0xd0034)); 59 60 reg2 = (reg2 << 16) | reg; 61 62 ack_pmu_message_receive(); 63 64 return reg2; 65} 66 67static inline void decode_major_message(unsigned int mail) 68{ 69 debug("[PMU Major message = 0x%08x]\n", mail); 70} 71 72static inline void decode_streaming_message(void) 73{ 74 unsigned int string_index, arg __maybe_unused; 75 int i = 0; 76 77 string_index = get_stream_message(); 78 debug("PMU String index = 0x%08x\n", string_index); 79 while (i < (string_index & 0xffff)) { 80 arg = get_stream_message(); 81 debug("arg[%d] = 0x%08x\n", i, arg); 82 i++; 83 } 84 85 debug("\n"); 86} 87 88int wait_ddrphy_training_complete(void) 89{ 90 unsigned int mail; 91 92 while (1) { 93 mail = get_mail(); 94 decode_major_message(mail); 95 if (mail == 0x08) { 96 decode_streaming_message(); 97 } else if (mail == 0x07) { 98 debug("Training PASS\n"); 99 return 0; 100 } else if (mail == 0xff) { 101 printf("Training FAILED\n"); 102 return -1; 103 } 104 } 105} 106 107void ddrphy_init_set_dfi_clk(unsigned int drate) 108{ 109 switch (drate) { 110 case 4000: 111 dram_pll_init(MHZ(1000)); 112 dram_disable_bypass(); 113 break; 114 case 3734: 115 case 3733: 116 case 3732: 117 dram_pll_init(MHZ(933)); 118 dram_disable_bypass(); 119 break; 120 case 3600: 121 dram_pll_init(MHZ(900)); 122 dram_disable_bypass(); 123 break; 124 case 3200: 125 dram_pll_init(MHZ(800)); 126 dram_disable_bypass(); 127 break; 128 case 3000: 129 dram_pll_init(MHZ(750)); 130 dram_disable_bypass(); 131 break; 132 case 2800: 133 dram_pll_init(MHZ(700)); 134 dram_disable_bypass(); 135 break; 136 case 2400: 137 dram_pll_init(MHZ(600)); 138 dram_disable_bypass(); 139 break; 140 case 1866: 141 dram_pll_init(MHZ(466)); 142 dram_disable_bypass(); 143 break; 144 case 1600: 145 dram_pll_init(MHZ(400)); 146 dram_disable_bypass(); 147 break; 148 case 1066: 149 dram_pll_init(MHZ(266)); 150 dram_disable_bypass(); 151 break; 152 case 667: 153 dram_pll_init(MHZ(167)); 154 dram_disable_bypass(); 155 break; 156 case 625: 157 dram_enable_bypass(MHZ(625)); 158 break; 159 case 400: 160 dram_enable_bypass(MHZ(400)); 161 break; 162 case 333: 163 dram_enable_bypass(MHZ(333)); 164 break; 165 case 200: 166 dram_enable_bypass(MHZ(200)); 167 break; 168 case 100: 169 dram_enable_bypass(MHZ(100)); 170 break; 171 default: 172 return; 173 } 174} 175 176void ddrphy_init_read_msg_block(enum fw_type type) 177{ 178} 179