mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-05-05 12:46:14 +02:00
venice: lpddr4_timing_imx8mm: add 4gb single die support
Add dram support for the MT53E1G32D2FW-046 RevC part which is a single die 32Gbit density part vs RevA/B which were dual-die parts: - use a previously unused EEPROM byte to denote a variant of the base config to be patched - add a dram description string - return the board struct from eeprom_init and pass it to the spl_dram_init function so that it has access to the EEPROM - move ddr_init into the spl_dram_init so that it can be patched in the per-soc init function Signed-off-by: Tim Harvey <tharvey@gateworks.com>
This commit is contained in:
parent
393c3de771
commit
c2bfdb24c8
@ -356,7 +356,7 @@ static int eeprom_info(bool verbose)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int venice_eeprom_init(int quiet)
|
||||
struct venice_board_info *venice_eeprom_init(int quiet)
|
||||
{
|
||||
char rev_pcb;
|
||||
int rev_bom;
|
||||
@ -466,10 +466,10 @@ int venice_eeprom_init(int quiet)
|
||||
|
||||
if (!strncmp(venice_model, "GW7901-SP486", 12) &&
|
||||
strcmp(venice_model, "GW7901-SP486-C")) {
|
||||
return 2048;
|
||||
som_info.sdram_size++;
|
||||
}
|
||||
|
||||
return (16 << som_info.sdram_size);
|
||||
return &som_info;
|
||||
}
|
||||
|
||||
void board_gsc_info(void)
|
||||
|
||||
@ -18,13 +18,14 @@ struct venice_board_info {
|
||||
u8 sdram_size; /* 0x2B: (16 << n) MB */
|
||||
u8 sdram_speed; /* 0x2C: (33.333 * n) MHz */
|
||||
u8 sdram_width; /* 0x2D: (8 << n) bit */
|
||||
u8 res3[2]; /* 0x2E */
|
||||
u8 sdram_variant; /* 0x2E */
|
||||
u8 res3[1]; /* 0x2D */
|
||||
char model[16]; /* 0x30: model string */
|
||||
u8 config[14]; /* 0x40: model config */
|
||||
u8 chksum[2]; /* 0x4E */
|
||||
};
|
||||
|
||||
int venice_eeprom_init(int quiet);
|
||||
struct venice_board_info *venice_eeprom_init(int quiet);
|
||||
const char *eeprom_get_model(void);
|
||||
const char *eeprom_get_som_model(void);
|
||||
const char *eeprom_get_baseboard_model(void);
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#ifndef __LPDDR4_TIMING_H__
|
||||
#define __LPDDR4_TIMING_H__
|
||||
|
||||
extern struct dram_timing_info *spl_dram_init(const char *model, int sizemb);
|
||||
struct dram_timing_info *spl_dram_init(const char *model, struct venice_board_info *info,
|
||||
char *dram_desc, size_t sz_desc);
|
||||
|
||||
#endif /* __LPDDR4_TIMING_H__ */
|
||||
|
||||
@ -10,6 +10,8 @@
|
||||
#include <asm/arch/ddr.h>
|
||||
#include <asm/arch/lpddr4_define.h>
|
||||
|
||||
#include "eeprom.h"
|
||||
|
||||
/* ddr phy trained csr */
|
||||
static struct dram_cfg_param lpddr4_ddrphy_trained_csr[] = {
|
||||
{ 0x200b2, 0x0 },
|
||||
@ -3561,9 +3563,36 @@ static struct dram_cfg_param ddr_ddrphy_cfg_alt_patch[] = {
|
||||
{ 0x120a5, 0x2 },
|
||||
};
|
||||
|
||||
struct dram_timing_info *spl_dram_init(const char *model, int sizemb)
|
||||
/* 4GB single Die patch (MT53E1G32D2FW-046 revC) */
|
||||
static struct dram_cfg_param ddr_ddrc_cfg_4gb_single_die_patch[] = {
|
||||
{ 0x3d400000, 0xa1080020 },
|
||||
{ 0x3d400064, 0x5b011d },
|
||||
{ 0x3d40011c, 0x402 },
|
||||
{ 0x3d400138, 0x123 },
|
||||
{ 0x3d4000f4, 0x699 },
|
||||
{ 0x3d400200, 0x1f },
|
||||
{ 0x3d40021c, 0xf07 },
|
||||
{ 0x3d402064, 0xc0026 },
|
||||
{ 0x3d40211c, 0x302 },
|
||||
{ 0x3d402138, 0x27 },
|
||||
{ 0x3d4020f4, 0x599 },
|
||||
{ 0x3d403064, 0x3000a },
|
||||
{ 0x3d40311c, 0x302 },
|
||||
{ 0x3d403138, 0xa },
|
||||
{ 0x3d4030f4, 0x599 }
|
||||
};
|
||||
|
||||
static struct dram_cfg_param fsp_msg_4gb_single_die_patch[] = {
|
||||
{ 0x00054012, 0x110 },
|
||||
{ 0x0005402c, 0x1 },
|
||||
};
|
||||
|
||||
struct dram_timing_info *spl_dram_init(const char *model, struct venice_board_info *info,
|
||||
char *dram_desc, size_t sz_desc)
|
||||
{
|
||||
struct dram_timing_info *dram_timing;
|
||||
int sizemb = (16 << info->sdram_size);
|
||||
int i;
|
||||
|
||||
switch (sizemb) {
|
||||
case 512:
|
||||
@ -3577,6 +3606,21 @@ struct dram_timing_info *spl_dram_init(const char *model, int sizemb)
|
||||
break;
|
||||
case 4096:
|
||||
dram_timing = &dram_timing_4gb;
|
||||
if (info->sdram_variant == 1) {
|
||||
if (dram_desc)
|
||||
strlcpy(dram_desc, "single-die", sz_desc);
|
||||
apply_cfg_patch(dram_timing->ddrc_cfg, dram_timing->ddrc_cfg_num,
|
||||
ddr_ddrc_cfg_4gb_single_die_patch,
|
||||
ARRAY_SIZE(ddr_ddrc_cfg_4gb_single_die_patch));
|
||||
for (i = 0; i < 4; i++) {
|
||||
apply_cfg_patch(dram_timing->fsp_msg[i].fsp_cfg,
|
||||
dram_timing->fsp_msg[i].fsp_cfg_num,
|
||||
fsp_msg_4gb_single_die_patch,
|
||||
ARRAY_SIZE(fsp_msg_4gb_single_die_patch));
|
||||
}
|
||||
} else if (dram_desc) {
|
||||
strlcpy(dram_desc, "dual-die", sz_desc);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("unsupported");
|
||||
@ -3596,5 +3640,8 @@ struct dram_timing_info *spl_dram_init(const char *model, int sizemb)
|
||||
ARRAY_SIZE(ddr_ddrphy_cfg_alt_patch));
|
||||
}
|
||||
|
||||
if (ddr_init(dram_timing))
|
||||
return NULL;
|
||||
|
||||
return dram_timing;
|
||||
}
|
||||
|
||||
@ -4,6 +4,8 @@
|
||||
#include <string.h>
|
||||
#include <asm/arch/ddr.h>
|
||||
|
||||
#include "eeprom.h"
|
||||
|
||||
/*
|
||||
* Generated code from MX8M_DDR_tool v3.20 using RPAv15
|
||||
*/
|
||||
@ -2369,26 +2371,36 @@ static struct dram_timing_info dram_timing_2gb_dual_die = {
|
||||
.fsp_table = { 3200, 400, 100, },
|
||||
};
|
||||
|
||||
struct dram_timing_info *spl_dram_init(const char *model, int sizemb)
|
||||
struct dram_timing_info *spl_dram_init(const char *model, struct venice_board_info *info,
|
||||
char *dram_desc, size_t sz_desc)
|
||||
{
|
||||
struct dram_timing_info *dram_timing;
|
||||
int sizemb = (16 << info->sdram_size);
|
||||
|
||||
switch (sizemb) {
|
||||
case 1024:
|
||||
dram_timing = &dram_timing_1gb_single_die;
|
||||
if (dram_desc)
|
||||
strlcpy(dram_desc, "single-die", sz_desc);
|
||||
break;
|
||||
case 2048:
|
||||
if (!strcmp(model, "GW7902-SP466-A") ||
|
||||
!strcmp(model, "GW7902-SP466-B")) {
|
||||
dram_timing = &dram_timing_2gb_dual_die;
|
||||
if (dram_desc)
|
||||
strlcpy(dram_desc, "dual-die", sz_desc);
|
||||
} else {
|
||||
dram_timing = &dram_timing_2gb_single_die;
|
||||
if (dram_desc)
|
||||
strlcpy(dram_desc, "single-die", sz_desc);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("unsupported");
|
||||
dram_timing = &dram_timing_2gb_dual_die;
|
||||
}
|
||||
if (ddr_init(dram_timing))
|
||||
return NULL;
|
||||
|
||||
return dram_timing;
|
||||
}
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <string.h>
|
||||
#include <asm/arch/ddr.h>
|
||||
|
||||
#include "eeprom.h"
|
||||
|
||||
/*
|
||||
* Generated code from MX8M_DDR_tool v3.30 using MX8M_Plus RPAv7
|
||||
*/
|
||||
@ -2378,21 +2381,29 @@ static struct dram_timing_info dram_timing_4gb_dual_die = {
|
||||
.fsp_table = { 4000, 400, 100, },
|
||||
};
|
||||
|
||||
struct dram_timing_info *spl_dram_init(const char *model, int sizemb)
|
||||
struct dram_timing_info *spl_dram_init(const char *model, struct venice_board_info *info,
|
||||
char *dram_desc, size_t sz_desc)
|
||||
{
|
||||
struct dram_timing_info *dram_timing;
|
||||
int sizemb = (16 << info->sdram_size);
|
||||
|
||||
switch (sizemb) {
|
||||
case 1024:
|
||||
dram_timing = &dram_timing_1gb_single_die;
|
||||
if (dram_desc)
|
||||
strlcpy(dram_desc, "single-die", sz_desc);
|
||||
break;
|
||||
case 4096:
|
||||
dram_timing = &dram_timing_4gb_dual_die;
|
||||
if (dram_desc)
|
||||
strlcpy(dram_desc, "dual-die", sz_desc);
|
||||
break;
|
||||
default:
|
||||
printf("unsupported");
|
||||
dram_timing = &dram_timing_4gb_dual_die;
|
||||
}
|
||||
if (ddr_init(dram_timing))
|
||||
return NULL;
|
||||
|
||||
return dram_timing;
|
||||
}
|
||||
|
||||
@ -188,9 +188,10 @@ static int power_init_board(const char *model, struct udevice *gsc)
|
||||
void board_init_f(ulong dummy)
|
||||
{
|
||||
struct dram_timing_info *dram_timing;
|
||||
struct venice_board_info *eeprom;
|
||||
struct udevice *bus, *dev;
|
||||
const char *model;
|
||||
int dram_szmb;
|
||||
char dram_desc[32];
|
||||
int i, ret;
|
||||
|
||||
arch_cpu_init();
|
||||
@ -249,23 +250,31 @@ void board_init_f(ulong dummy)
|
||||
break;
|
||||
mdelay(1);
|
||||
}
|
||||
dram_szmb = venice_eeprom_init(0);
|
||||
eeprom = venice_eeprom_init(0);
|
||||
model = eeprom_get_model();
|
||||
|
||||
/* PMIC */
|
||||
power_init_board(model, dev);
|
||||
|
||||
/* DDR initialization */
|
||||
printf("DRAM : LPDDR4 ");
|
||||
if (dram_szmb > 512)
|
||||
printf("%d GiB", dram_szmb / 1024);
|
||||
else
|
||||
printf("%d MiB", dram_szmb);
|
||||
dram_timing = spl_dram_init(model, dram_szmb);
|
||||
printf(" %dMT/s %dMHz\n",
|
||||
dram_timing->fsp_msg[0].drate,
|
||||
dram_timing->fsp_msg[0].drate / 2);
|
||||
ddr_init(dram_timing);
|
||||
dram_desc[0] = 0;
|
||||
dram_timing = spl_dram_init(model, eeprom, dram_desc, sizeof(dram_desc));
|
||||
if (dram_timing) {
|
||||
int dram_szmb = (16 << eeprom->sdram_size);
|
||||
|
||||
printf("DRAM : LPDDR4 ");
|
||||
if (dram_szmb > 512)
|
||||
printf("%d GiB", dram_szmb / 1024);
|
||||
else
|
||||
printf("%d MiB", dram_szmb);
|
||||
printf(" %dMT/s %dMHz %s",
|
||||
dram_timing->fsp_msg[0].drate,
|
||||
dram_timing->fsp_msg[0].drate / 2,
|
||||
dram_desc[0] ? dram_desc : "");
|
||||
puts("\n");
|
||||
} else {
|
||||
hang();
|
||||
}
|
||||
|
||||
board_init_r(NULL, 0);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user