u-boot/drivers/ddr/imx/phy/ddrphy_utils.c
Ye Li 1b631589d4 imx9: Add 233Mhz DDR PLL frequency
To support 1.866GTS LPDDR4x timing script, need to add 233Mhz freq
to DDR PLL for second mission point at 933MTS. Otherwise DDR training
will fail.

Reviewed-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
2024-09-19 00:12:41 -03:00

181 lines
3.3 KiB
C

// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2018 NXP
*/
#include <errno.h>
#include <log.h>
#include <asm/io.h>
#include <asm/arch/ddr.h>
#include <asm/arch/clock.h>
#include <asm/arch/ddr.h>
#include <asm/arch/sys_proto.h>
static inline void poll_pmu_message_ready(void)
{
unsigned int reg;
do {
reg = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + ddrphy_addr_remap(0xd0004));
} while (reg & 0x1);
}
static inline void ack_pmu_message_receive(void)
{
unsigned int reg;
reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + ddrphy_addr_remap(0xd0031), 0x0);
do {
reg = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + ddrphy_addr_remap(0xd0004));
} while (!(reg & 0x1));
reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + ddrphy_addr_remap(0xd0031), 0x1);
}
static inline unsigned int get_mail(void)
{
unsigned int reg;
poll_pmu_message_ready();
reg = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + ddrphy_addr_remap(0xd0032));
ack_pmu_message_receive();
return reg;
}
static inline unsigned int get_stream_message(void)
{
unsigned int reg, reg2;
poll_pmu_message_ready();
reg = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + ddrphy_addr_remap(0xd0032));
reg2 = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + ddrphy_addr_remap(0xd0034));
reg2 = (reg2 << 16) | reg;
ack_pmu_message_receive();
return reg2;
}
static inline void decode_major_message(unsigned int mail)
{
debug("[PMU Major message = 0x%08x]\n", mail);
}
static inline void decode_streaming_message(void)
{
unsigned int string_index, arg __maybe_unused;
int i = 0;
string_index = get_stream_message();
debug("PMU String index = 0x%08x\n", string_index);
while (i < (string_index & 0xffff)) {
arg = get_stream_message();
debug("arg[%d] = 0x%08x\n", i, arg);
i++;
}
debug("\n");
}
int wait_ddrphy_training_complete(void)
{
unsigned int mail;
while (1) {
mail = get_mail();
decode_major_message(mail);
if (mail == 0x08) {
decode_streaming_message();
} else if (mail == 0x07) {
debug("Training PASS\n");
return 0;
} else if (mail == 0xff) {
printf("Training FAILED\n");
return -1;
}
}
}
void ddrphy_init_set_dfi_clk(unsigned int drate)
{
switch (drate) {
case 4000:
dram_pll_init(MHZ(1000));
dram_disable_bypass();
break;
case 3734:
case 3733:
case 3732:
dram_pll_init(MHZ(933));
dram_disable_bypass();
break;
case 3600:
dram_pll_init(MHZ(900));
dram_disable_bypass();
break;
case 3200:
dram_pll_init(MHZ(800));
dram_disable_bypass();
break;
case 3000:
dram_pll_init(MHZ(750));
dram_disable_bypass();
break;
case 2800:
dram_pll_init(MHZ(700));
dram_disable_bypass();
break;
case 2400:
dram_pll_init(MHZ(600));
dram_disable_bypass();
break;
case 1866:
dram_pll_init(MHZ(466));
dram_disable_bypass();
break;
case 1600:
dram_pll_init(MHZ(400));
dram_disable_bypass();
break;
case 1066:
dram_pll_init(MHZ(266));
dram_disable_bypass();
break;
case 933:
dram_pll_init(MHZ(233));
dram_disable_bypass();
break;
case 667:
dram_pll_init(MHZ(167));
dram_disable_bypass();
break;
case 625:
dram_enable_bypass(MHZ(625));
break;
case 400:
dram_enable_bypass(MHZ(400));
break;
case 333:
dram_enable_bypass(MHZ(333));
break;
case 200:
dram_enable_bypass(MHZ(200));
break;
case 100:
dram_enable_bypass(MHZ(100));
break;
default:
return;
}
}
void ddrphy_init_read_msg_block(enum fw_type type)
{
}