[PATCH] ddr: marvell: a38x: Add support for DDR4 from Marvell mv-ddr-marvell repository
Pali Rohár
pali at kernel.org
Sat Jan 14 02:30:52 CET 2023
Hello! Thanks for this DDR4 patch.
I have a few comments below, mostly about adding dead/removed code.
On Friday 13 January 2023 16:38:55 Tony Dinh wrote:
> This syncs drivers/ddr/marvell/a38x/ with the master branch of repository
> https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git
>
> up to the commit "mv_ddr: a3700: Use the right size for memset to not overflow"
> d5acc10c287e40cc2feeb28710b92e45c93c702c
>
> This patch was created by following steps:
>
> 1. Replace all a38x files in U-Boot tree by files from upstream github
> Marvell mv-ddr-marvell repository.
>
> 2. Run following command to omit portions not relevant for a38x, ddr3, and ddr4:
>
> files=drivers/ddr/marvell/a38x/*
> sed 's/#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X)/#ifdef TRUE/' -i $files
> unifdef -m -UMV_DDR -UMV_DDR_ATF -UCONFIG_APN806 \
> -UCONFIG_MC_STATIC -UCONFIG_MC_STATIC_PRINT -UCONFIG_PHY_STATIC \
> -UCONFIG_PHY_STATIC_PRINT -UCONFIG_CUSTOMER_BOARD_SUPPORT \
> -UCONFIG_A3700 -UA3900 -UA80X0 -UA70X0 -DTRUE $files
marvell/a38x/ subdir contains only a38x code. Moreover all a39x stubs
were already removed from u-boot (it was never complete):
https://source.denx.de/u-boot/u-boot/-/commit/15942805b7efe47e186d8b30ec378666561ad1f9
So do not re-introduce CONFIG_ARMADA_39X code. Instead run unifdef with
additional args: -DCONFIG_ARMADA_38X -UCONFIG_ARMADA_39X
And with that, additional 'sed' and -DTRUE is not needed at all. It was
needed only as a hack for simulating logical OR: defined(A) || defined(B)
Also I see there CONFIG_64BIT checks. I think that CONFIG_64BIT code is
not relevant for 32-bit A38x, so I would suggest to eliminate it with
unifdef -UCONFIG_64BIT.
> 3. Manually change license to SPDX-License-Identifier
> (upstream license in upstream github repository contains long license
> texts and U-Boot is using just SPDX-License-Identifier.
There are still some license comment style changes (// vs /* ... */).
> After applying this patch, a38x ddr3 ddr4 code in upstream Marvell github
> repository and in U-Boot would be fully identical. So in future applying
> above steps could be used to sync code again.
>
> The only change in this patch are:
> - Removal of common board_topology_map code using ifdefs in mv_ddr_brd.c
> - Some fixes with include files.
> - Some basic type defines (original from ATF headers) in mv_ddr_plat.c
>
> Reference:
> "ddr: marvell: a38x: Sync code with Marvell mv-ddr-marvell repository"
> https://source.denx.de/u-boot/u-boot/-/commit/107c3391b95bcc2ba09a876da4fa0c31b6c1e460
>
> Signed-off-by: Tony Dinh <mibodhi at gmail.com>
> ---
>
> drivers/ddr/marvell/a38x/Makefile | 8 +
> drivers/ddr/marvell/a38x/ddr3_debug.c | 120 +
> drivers/ddr/marvell/a38x/ddr3_init.c | 25 +
> drivers/ddr/marvell/a38x/ddr3_init.h | 14 +
> drivers/ddr/marvell/a38x/ddr3_logging_def.h | 29 +-
> drivers/ddr/marvell/a38x/ddr3_training.c | 135 +
> drivers/ddr/marvell/a38x/ddr3_training_bist.c | 12 +
> .../a38x/ddr3_training_centralization.c | 6 +
> drivers/ddr/marvell/a38x/ddr3_training_db.c | 278 ++
> drivers/ddr/marvell/a38x/ddr3_training_ip.h | 17 +
> .../ddr/marvell/a38x/ddr3_training_ip_db.h | 156 +-
> .../marvell/a38x/ddr3_training_ip_engine.c | 147 +-
> .../ddr/marvell/a38x/ddr3_training_ip_flow.h | 7 +-
> .../ddr/marvell/a38x/ddr3_training_leveling.c | 139 +-
> drivers/ddr/marvell/a38x/ddr_init.c | 8 +
> drivers/ddr/marvell/a38x/ddr_mv_wrapper.h | 47 +
> drivers/ddr/marvell/a38x/dram_if.c | 31 +
> drivers/ddr/marvell/a38x/mv_ddr4_mpr_pda_if.c | 674 +++++
> drivers/ddr/marvell/a38x/mv_ddr4_mpr_pda_if.h | 59 +
> drivers/ddr/marvell/a38x/mv_ddr4_training.c | 571 ++++
> drivers/ddr/marvell/a38x/mv_ddr4_training.h | 32 +
> .../a38x/mv_ddr4_training_calibration.c | 2340 +++++++++++++++++
> .../a38x/mv_ddr4_training_calibration.h | 26 +
> .../ddr/marvell/a38x/mv_ddr4_training_db.c | 545 ++++
> .../marvell/a38x/mv_ddr4_training_leveling.c | 441 ++++
> .../marvell/a38x/mv_ddr4_training_leveling.h | 11 +
> drivers/ddr/marvell/a38x/mv_ddr_brd.c | 82 +
> drivers/ddr/marvell/a38x/mv_ddr_init.c | 60 +
> drivers/ddr/marvell/a38x/mv_ddr_init.h | 11 +
> drivers/ddr/marvell/a38x/mv_ddr_mrs.c | 248 ++
> drivers/ddr/marvell/a38x/mv_ddr_mrs.h | 83 +
> drivers/ddr/marvell/a38x/mv_ddr_plat.c | 257 ++
> drivers/ddr/marvell/a38x/mv_ddr_plat.h | 11 +
> drivers/ddr/marvell/a38x/mv_ddr_regs.h | 59 +
> drivers/ddr/marvell/a38x/mv_ddr_static.c | 12 +
> drivers/ddr/marvell/a38x/mv_ddr_static.h | 11 +
> drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.h | 7 +
> drivers/ddr/marvell/a38x/mv_ddr_topology.h | 72 +
> 38 files changed, 6786 insertions(+), 5 deletions(-)
> create mode 100644 drivers/ddr/marvell/a38x/ddr_init.c
> create mode 100644 drivers/ddr/marvell/a38x/ddr_mv_wrapper.h
> create mode 100644 drivers/ddr/marvell/a38x/dram_if.c
> create mode 100644 drivers/ddr/marvell/a38x/mv_ddr4_mpr_pda_if.c
> create mode 100644 drivers/ddr/marvell/a38x/mv_ddr4_mpr_pda_if.h
> create mode 100644 drivers/ddr/marvell/a38x/mv_ddr4_training.c
> create mode 100644 drivers/ddr/marvell/a38x/mv_ddr4_training.h
> create mode 100644 drivers/ddr/marvell/a38x/mv_ddr4_training_calibration.c
> create mode 100644 drivers/ddr/marvell/a38x/mv_ddr4_training_calibration.h
> create mode 100644 drivers/ddr/marvell/a38x/mv_ddr4_training_db.c
> create mode 100644 drivers/ddr/marvell/a38x/mv_ddr4_training_leveling.c
> create mode 100644 drivers/ddr/marvell/a38x/mv_ddr4_training_leveling.h
> create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_brd.c
> create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_init.c
> create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_init.h
> create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_mrs.c
> create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_mrs.h
> create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_static.c
> create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_static.h
>
...
> diff --git a/drivers/ddr/marvell/a38x/ddr_init.c b/drivers/ddr/marvell/a38x/ddr_init.c
> new file mode 100644
> index 0000000000..871ff0c926
> --- /dev/null
> +++ b/drivers/ddr/marvell/a38x/ddr_init.c
> @@ -0,0 +1,8 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) Marvell International Ltd. and its affiliates
> + */
> +
> +#include "ddr3_init.h"
> +
> +/* U-BOOT MARVELL 2013.01 SUPPORT */
For sure this ddr_init.c file is not needed as it is empty.
> diff --git a/drivers/ddr/marvell/a38x/ddr_mv_wrapper.h b/drivers/ddr/marvell/a38x/ddr_mv_wrapper.h
> new file mode 100644
> index 0000000000..13241c17f4
> --- /dev/null
> +++ b/drivers/ddr/marvell/a38x/ddr_mv_wrapper.h
> @@ -0,0 +1,47 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) Marvell International Ltd. and its affiliates
> + */
> +
> +#ifndef _DDR_MV_WRAPPER_H
> +#define _DDR_MV_WRAPPER_H
> +
> +#define INTER_REGS_BASE 0xd0000000
> +
> +#include "mv_os.h"
> +#include "printf.h"
> +#include "mvUart.h"
> +#include "util.h"
> +
> +typedef unsigned long long uint64_t;
> +typedef uint64_t uintptr_t;
> +
> +static inline void mmio_write_64(uintptr_t addr, uint64_t value)
> +{
> +}
> +
> +static inline uint64_t mmio_read_64(uintptr_t addr)
> +{
> + return (uint64_t)0;
> +}
> +
> +/* u-boot/tools/marvell/bin_hdr/platform/utils/printf.c */
> +#define printf mvPrintf
> +
> +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
> +#define reg_write MV_REG_WRITE
> +#define reg_read MV_REG_READ
> +#define reg_bit_set MV_REG_BIT_SET
> +
> +/* uboot/tools/marvell/bin_hdr/platform/drivers/mv_time.c */
> +void mdelay(unsigned long);
> +
> +/* TODO: Check if LE/BE support is needed */
> +#define MV_MEMIO_LE32_WRITE2(data,addr) \
> + MV_MEMIO32_WRITE(addr, MV_32BIT_LE_FAST(data))
> +#define writel MV_MEMIO_LE32_WRITE2
> +#define readl MV_MEMIO_LE32_READ
> +#define writeq mmio_write_64
> +#define readq mmio_read_64
> +
> +#endif /* _DDR_MV_WRAPPER_H */
This file looks unusable as both mmio_write_64() and mmio_read_64() are
unimplemented. Instead ddr_ml_wrapper.h should be used.
> diff --git a/drivers/ddr/marvell/a38x/dram_if.c b/drivers/ddr/marvell/a38x/dram_if.c
> new file mode 100644
> index 0000000000..872a7820b6
> --- /dev/null
> +++ b/drivers/ddr/marvell/a38x/dram_if.c
> @@ -0,0 +1,31 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) Marvell International Ltd. and its affiliates
> + */
> +
> +#include "ddr_ml_wrapper.h"
> +
> +#include "mv_ddr_init.h"
> +#include "mv_ddr_plat.h"
> +#include "mv_ddr_topology.h"
> +
> +int dram_init(void)
> +{
> + return mv_ddr_init();
> +}
> +
> +void dram_mmap_config(void)
> +{
> + mv_ddr_mmap_config();
> +}
> +
> +unsigned long long dram_iface_mem_sz_get(void)
> +{
> + /*
> + * call mv_ddr_pre_config to update topology
> + * prior to mv_ddr_mem_sz_get call
> + */
> + mv_ddr_pre_config();
> +
> + return mv_ddr_mem_sz_get();
> +}
This file seems to not be needed too as none of these functions are
called.
...
> diff --git a/drivers/ddr/marvell/a38x/mv_ddr_brd.c b/drivers/ddr/marvell/a38x/mv_ddr_brd.c
> new file mode 100644
> index 0000000000..4cf3db5425
> --- /dev/null
> +++ b/drivers/ddr/marvell/a38x/mv_ddr_brd.c
> @@ -0,0 +1,82 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) Marvell International Ltd. and its affiliates
> + */
> +
> +#include "ddr3_init.h"
> +
> +/*
> + * Define the DDR layout / topology here in the board file. This will
> + * be used by the DDR3 init code in the SPL U-Boot version to configure
> + * the DDR3 controller.
> + */
> +
> +#if defined(CONFIG_DDR4)
> +#define SPEED_BIN_DDR_DB_68XX SPEED_BIN_DDR_2400R
> +#define BUS_WIDTH_DB_68XX MV_DDR_DEV_WIDTH_16BIT
> +#else /* CONFIG_DDR4 */
> +#define SPEED_BIN_DDR_DB_68XX SPEED_BIN_DDR_1866L
> +#define BUS_WIDTH_DB_68XX MV_DDR_DEV_WIDTH_8BIT
> +#endif /* CONFIG_DDR4 */
> +
> +/*
> + * board_topology_map and mv_ddr_topology_map_get()
> + * should be defined in each board file.
> + *
> + */
> +
> +#if 0
> +/* Marvell board - Board_ID = DB_68XX_ID = 1 (DDR3/4)*/
> +static struct mv_ddr_topology_map board_topology_map = {
> + DEBUG_LEVEL_ERROR,
> + 0x1, /* active interfaces */
> + /* cs_mask, mirror, dqs_swap, ck_swap X PUPs */
> + { { { {0x3, 0x2, 0, 0},
> + {0x3, 0x2, 0, 0},
> + {0x3, 0x2, 0, 0},
> + {0x3, 0x2, 0, 0},
> + {0x3, 0x2, 0, 0} },
> + SPEED_BIN_DDR_DB_68XX, /* speed_bin */
> + BUS_WIDTH_DB_68XX, /* sdram device width */
> + MV_DDR_DIE_CAP_4GBIT, /* die capacity */
> + MV_DDR_FREQ_SAR, /* frequency */
> + 0, 0, /* cas_l, cas_wl */
> + MV_DDR_TEMP_LOW} }, /* temperature */
> + BUS_MASK_32BIT, /* subphys mask */
> + MV_DDR_CFG_DEFAULT, /* ddr configuration data source */
> + { {0} }, /* raw spd data */
> + {0} /* timing parameters */
> +};
> +/* #else */
> +
> +/* Marvell board - Board_ID = DB_GP_68XX_ID = 4 */
> +static struct mv_ddr_topology_map board_topology_map = {
> + DEBUG_LEVEL_ERROR,
> + 0x1, /* active interfaces */
> + /* cs_mask, mirror, dqs_swap, ck_swap X PUPs */
> + { { { {0x1, 0, 0, 0},
> + {0x1, 0, 0, 0},
> + {0x1, 0, 0, 0},
> + {0x1, 0, 0, 0},
> + {0x1, 0, 0, 0} },
> + SPEED_BIN_DDR_DB_68XX, /* speed_bin */
> + BUS_WIDTH_DB_68XX, /* sdram device width */
> + MV_DDR_DIE_CAP_4GBIT, /* die capacity */
> + MV_DDR_FREQ_SAR, /* frequency */
> + 0, 0, /* cas_l cas_wl */
> + MV_DDR_TEMP_LOW} }, /* temperature */
> + BUS_MASK_32BIT, /* subphys mask */
> + MV_DDR_CFG_DEFAULT, /* ddr configuration data source */
> + NOT_COMBINED, /* ddr twin-die combined*/
> + { {0} }, /* raw spd data */
> + {0} /* timing parameters */
> +};
> +#endif /* 0 */
> +
> +#if 0
> +struct mv_ddr_topology_map *mv_ddr_topology_map_get(void)
> +{
> + /* Return the board topology as defined in the board code */
> + return &board_topology_map;
> +}
> +#endif
This file has all code commented. Also topology file is defined in
u-boot board directory. So file seems to not be needed too.
> diff --git a/drivers/ddr/marvell/a38x/mv_ddr_init.c b/drivers/ddr/marvell/a38x/mv_ddr_init.c
> new file mode 100644
> index 0000000000..e544ba87e5
> --- /dev/null
> +++ b/drivers/ddr/marvell/a38x/mv_ddr_init.c
> @@ -0,0 +1,60 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) Marvell International Ltd. and its affiliates
> + */
> +
> +/* TODO: need this wrapper block for ddr_topology_def.h resolution */
> +#include "ddr_ml_wrapper.h"
> +
> +#include "mv_ddr_common.h"
> +#include "mv_ddr_topology.h"
> +#include "mv_ddr_plat.h"
> +#include "ddr_topology_def.h"
> +#include "dram_if.h"
> +
> +int mv_ddr_init(void)
> +{
> + /* print mv_ddr version */
> + mv_ddr_ver_print();
> +
> + /* preliminary mv_ddr configuration */
> + if (mv_ddr_pre_config()) {
> + printf("error: %s failed\n", __func__);
> + return -1;
> + }
> +
> + /* remap overlapping dram region to the top */
> + if (mv_ddr_mc_remap() != 0)
> + return -1;
> +
> + /* mv_ddr_mc */
> + if (mv_ddr_mc_config()) {
> + printf("error: %s failed\n", __func__);
> + return -1;
> + }
> +
> +
> + if (mv_ddr_phy_config()) {
> + printf("error: %s failed\n", __func__);
> +#if defined(T9130)
> + reg_write(0x6f0084, 0x0);
> +#endif
> + return -1;
> + }
> +
> +
> + if (mv_ddr_mc_ena()) {
> + printf("error: %s failed\n", __func__);
> + return -1;
> + }
> +
> + /* post mv_ddr configuration */
> + if (mv_ddr_post_config()) {
> + printf("error: %s failed\n", __func__);
> + return -1;
> + }
> +
> + printf("mv_ddr: completed successfully\n");
> +
> + return 0;
> +}
Function mv_ddr_init() is not called, so whole mv_ddr_init.c file is not
needed.
> diff --git a/drivers/ddr/marvell/a38x/mv_ddr_init.h b/drivers/ddr/marvell/a38x/mv_ddr_init.h
> new file mode 100644
> index 0000000000..76fb20770f
> --- /dev/null
> +++ b/drivers/ddr/marvell/a38x/mv_ddr_init.h
> @@ -0,0 +1,11 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) Marvell International Ltd. and its affiliates
> + */
> +
> +#ifndef _MV_DDR_INIT_H
> +#define _MV_DDR_INIT_H
> +
> +int mv_ddr_init(void);
> +
> +#endif /* _MV_DDR_INIT_H */
Same for header file.
> diff --git a/drivers/ddr/marvell/a38x/mv_ddr_mrs.c b/drivers/ddr/marvell/a38x/mv_ddr_mrs.c
> new file mode 100644
> index 0000000000..55be36308b
> --- /dev/null
> +++ b/drivers/ddr/marvell/a38x/mv_ddr_mrs.c
> @@ -0,0 +1,248 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) Marvell International Ltd. and its affiliates
> + */
> +
> +#include "ddr_ml_wrapper.h"
> +#include "mv_ddr_plat.h"
> +
> +/*
> + * Based on Proposed DDR4 Full spec update (79-4B), Item No. 1716.78C
> + */
> +
> +/* MR0 WR (Write Recovery) and RTP (read to precharge), [13, 11:9] bits */
> +#define MV_DDR_MR0_WR10_RTP5 0x0 /* 0b00_0000_0000_0000 */
> +#define MV_DDR_MR0_WR12_RTP6 0x200 /* 0b00_0010_0000_0000 */
> +#define MV_DDR_MR0_WR14_RTP7 0x400 /* 0b00_0100_0000_0000 */
> +#define MV_DDR_MR0_WR16_RTP8 0x600 /* 0b00_0110_0000_0000 */
> +#define MV_DDR_MR0_WR18_RTP9 0x800 /* 0b00_1000_0000_0000 */
> +#define MV_DDR_MR0_WR20_RTP10 0xa00 /* 0b00_1010_0000_0000 */
> +#define MV_DDR_MR0_WR24_RTP12 0xc00 /* 0b00_1100_0000_0000 */
> +#define MV_DDR_MR0_WR22_RTP11 0xe00 /* 0b00_1110_0000_0000 */
> +#define MV_DDR_MR0_WR26_RTP13 0x2000 /* 0b10_0000_0000_0000 */
> +
> +int mv_ddr_mr0_wr_get(unsigned int wr, unsigned int *mr0_wr)
> +{
> + switch (wr) {
> + case 10:
> + *mr0_wr = MV_DDR_MR0_WR10_RTP5;
> + break;
> + case 12:
> + *mr0_wr = MV_DDR_MR0_WR12_RTP6;
> + break;
> + case 14:
> + *mr0_wr = MV_DDR_MR0_WR14_RTP7;
> + break;
> + case 16:
> + *mr0_wr = MV_DDR_MR0_WR16_RTP8;
> + break;
> + case 18:
> + *mr0_wr = MV_DDR_MR0_WR18_RTP9;
> + break;
> + case 20:
> + *mr0_wr = MV_DDR_MR0_WR20_RTP10;
> + break;
> + case 24:
> + *mr0_wr = MV_DDR_MR0_WR24_RTP12;
> + break;
> + case 22:
> + *mr0_wr = MV_DDR_MR0_WR22_RTP11;
> + break;
> + case 26:
> + *mr0_wr = MV_DDR_MR0_WR26_RTP13;
> + break;
> + default:
> + printf("error: %s: unsupported t_wr value found\n", __func__);
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +/* MR0 CL, [12, 6:4, 2] bits */
> +#define MV_DDR_MR0_CL9 0x0 /* 0b0_0000_0000_0000 */
> +#define MV_DDR_MR0_CL10 0x4 /* 0b0_0000_0000_0100 */
> +#define MV_DDR_MR0_CL11 0x10 /* 0b0_0000_0001_0000 */
> +#define MV_DDR_MR0_CL12 0x14 /* 0b0_0000_0001_0100 */
> +#define MV_DDR_MR0_CL13 0x20 /* 0b0_0000_0010_0000 */
> +#define MV_DDR_MR0_CL14 0x24 /* 0b0_0000_0010_0100 */
> +#define MV_DDR_MR0_CL15 0x30 /* 0b0_0000_0011_0000 */
> +#define MV_DDR_MR0_CL16 0x34 /* 0b0_0000_0011_0100 */
> +#define MV_DDR_MR0_CL18 0x40 /* 0b0_0000_0100_0000 */
> +#define MV_DDR_MR0_CL20 0x44 /* 0b0_0000_0100_0100 */
> +#define MV_DDR_MR0_CL22 0x50 /* 0b0_0000_0101_0000 */
> +#define MV_DDR_MR0_CL24 0x54 /* 0b0_0000_0101_0100 */
> +#define MV_DDR_MR0_CL23 0x60 /* 0b0_0000_0110_0000 */
> +#define MV_DDR_MR0_CL17 0x64 /* 0b0_0000_0110_0100 */
> +#define MV_DDR_MR0_CL19 0x70 /* 0b0_0000_0111_0000 */
> +#define MV_DDR_MR0_CL21 0x74 /* 0b0_0000_0111_0100 */
> +#define MV_DDR_MR0_CL25 0x1000 /* 0b1_0000_0000_0000 */
> +#define MV_DDR_MR0_CL26 0x1004 /* 0b1_0000_0000_0100 */
> +#define MV_DDR_MR0_CL27 0x1010 /* 0b1_0000_0001_0000 */
> +#define MV_DDR_MR0_CL28 0x1014 /* 0b1_0000_0001_0100 */
> +#define MV_DDR_MR0_CL29 0x1020 /* 0b1_0000_0010_0000 */
> +#define MV_DDR_MR0_CL30 0x1024 /* 0b1_0000_0010_0100 */
> +#define MV_DDR_MR0_CL31 0x1030 /* 0b1_0000_0011_0000 */
> +#define MV_DDR_MR0_CL32 0x1034 /* 0b1_0000_0011_0100 */
> +
> +int mv_ddr_mr0_cl_get(unsigned int cl, unsigned int *mr0_cl)
> +{
> + switch (cl) {
> + case 9:
> + *mr0_cl = MV_DDR_MR0_CL9;
> + break;
> + case 10:
> + *mr0_cl = MV_DDR_MR0_CL10;
> + break;
> + case 11:
> + *mr0_cl = MV_DDR_MR0_CL11;
> + break;
> + case 12:
> + *mr0_cl = MV_DDR_MR0_CL12;
> + break;
> + case 13:
> + *mr0_cl = MV_DDR_MR0_CL13;
> + break;
> + case 14:
> + *mr0_cl = MV_DDR_MR0_CL14;
> + break;
> + case 15:
> + *mr0_cl = MV_DDR_MR0_CL15;
> + break;
> + case 16:
> + *mr0_cl = MV_DDR_MR0_CL16;
> + break;
> + case 18:
> + *mr0_cl = MV_DDR_MR0_CL18;
> + break;
> + case 20:
> + *mr0_cl = MV_DDR_MR0_CL20;
> + break;
> + case 22:
> + *mr0_cl = MV_DDR_MR0_CL22;
> + break;
> + case 24:
> + *mr0_cl = MV_DDR_MR0_CL24;
> + break;
> + case 23:
> + *mr0_cl = MV_DDR_MR0_CL23;
> + break;
> + case 17:
> + *mr0_cl = MV_DDR_MR0_CL17;
> + break;
> + case 19:
> + *mr0_cl = MV_DDR_MR0_CL19;
> + break;
> + case 21:
> + *mr0_cl = MV_DDR_MR0_CL21;
> + break;
> + case 25:
> + *mr0_cl = MV_DDR_MR0_CL25;
> + break;
> + case 26:
> + *mr0_cl = MV_DDR_MR0_CL26;
> + break;
> + case 27:
> + *mr0_cl = MV_DDR_MR0_CL27;
> + break;
> + case 28:
> + *mr0_cl = MV_DDR_MR0_CL28;
> + break;
> + case 29:
> + *mr0_cl = MV_DDR_MR0_CL29;
> + break;
> + case 30:
> + *mr0_cl = MV_DDR_MR0_CL30;
> + break;
> + case 31:
> + *mr0_cl = MV_DDR_MR0_CL31;
> + break;
> + case 32:
> + *mr0_cl = MV_DDR_MR0_CL32;
> + break;
> + default:
> + printf("error: %s: unsupported cl value found\n", __func__);
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +/* MR2 CWL, [5:3] bits */
> +#define MV_DDR_MR2_CWL9 0x0 /* 0b0000_0000 */
> +#define MV_DDR_MR2_CWL10 0x8 /* 0b0000_1000 */
> +#define MV_DDR_MR2_CWL11 0x10 /* 0b0001_0000 */
> +#define MV_DDR_MR2_CWL12 0x18 /* 0b0001_1000 */
> +#define MV_DDR_MR2_CWL14 0x20 /* 0b0010_0000 */
> +#define MV_DDR_MR2_CWL16 0x28 /* 0b0010_1000 */
> +#define MV_DDR_MR2_CWL18 0x30 /* 0b0011_0000 */
> +#define MV_DDR_MR2_CWL20 0x38 /* 0b0011_1000 */
> +
> +int mv_ddr_mr2_cwl_get(unsigned int cwl, unsigned int *mr2_cwl)
> +{
> + switch (cwl) {
> + case 9:
> + *mr2_cwl = MV_DDR_MR2_CWL9;
> + break;
> + case 10:
> + *mr2_cwl = MV_DDR_MR2_CWL10;
> + break;
> + case 11:
> + *mr2_cwl = MV_DDR_MR2_CWL11;
> + break;
> + case 12:
> + *mr2_cwl = MV_DDR_MR2_CWL12;
> + break;
> + case 14:
> + *mr2_cwl = MV_DDR_MR2_CWL14;
> + break;
> + case 16:
> + *mr2_cwl = MV_DDR_MR2_CWL16;
> + break;
> + case 18:
> + *mr2_cwl = MV_DDR_MR2_CWL18;
> + break;
> + case 20:
> + *mr2_cwl = MV_DDR_MR2_CWL20;
> + break;
> + default:
> + printf("error: %s: unsupported cwl value found\n", __func__);
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +/* MR6 tCCD_L, [12:10] bits */
> +#define MV_DDR_MR6_TCCDL_OFFS 10
> +#define MV_DDR_MR6_TCCDL_MASK 0x7
> +#define MV_DDR_MR6_TCCDL4 0x0
> +#define MV_DDR_MR6_TCCDL5 0x1
> +#define MV_DDR_MR6_TCCDL6 0x2
> +#define MV_DDR_MR6_TCCDL7 0x3
> +#define MV_DDR_MR6_TCCDL8 0x4
> +int mv_ddr_mr6_tccdl_get(unsigned int tccdl, unsigned int *mr6_tccdl)
> +{
> + switch (tccdl) {
> + case 4:
> + *mr6_tccdl = MV_DDR_MR6_TCCDL4 << MV_DDR_MR6_TCCDL_OFFS;
> + break;
> + case 5:
> + *mr6_tccdl = MV_DDR_MR6_TCCDL5 << MV_DDR_MR6_TCCDL_OFFS;
> + break;
> + case 6:
> + *mr6_tccdl = MV_DDR_MR6_TCCDL6 << MV_DDR_MR6_TCCDL_OFFS;
> + break;
> + case 7:
> + *mr6_tccdl = MV_DDR_MR6_TCCDL7 << MV_DDR_MR6_TCCDL_OFFS;
> + break;
> + case 8:
> + *mr6_tccdl = MV_DDR_MR6_TCCDL8 << MV_DDR_MR6_TCCDL_OFFS;
> + break;
> + default:
> + printf("error: %s: unsupported t_ccd_l value found\n", __func__);
> + return -1;
> + }
> +
> + return 0;
> +}
This file seems to be unused for a38x too.
> diff --git a/drivers/ddr/marvell/a38x/mv_ddr_mrs.h b/drivers/ddr/marvell/a38x/mv_ddr_mrs.h
> new file mode 100644
> index 0000000000..92295159c7
> --- /dev/null
> +++ b/drivers/ddr/marvell/a38x/mv_ddr_mrs.h
> @@ -0,0 +1,83 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) Marvell International Ltd. and its affiliates
> + */
> +
> +#ifndef _MV_DDR_MRS_H
> +#define _MV_DDR_MRS_H
> +
> +/*
> + * Based on Proposed DDR4 Full spec update (79-4B), Item No. 1716.78C
> + */
> +
> +/* MR1 DIC, [2:1] bits */
> +#define MV_DDR_MR1_DIC_OFFS 1
> +
> +/* MR1 RTT_NOM, [10:8] bits */
> +#define MV_DDR_MR1_RTT_NOM_OFFS 8
> +#define MV_DDR_MR1_RTT_NOM_MASK 0x7
> +#define MV_DDR_MR1_RTT_NOM_DISABLE 0x0 /* 0b000_0000_0000 */
> +#define MV_DDR_MR1_RTT_NOM_RZQ_DIV4 0x100 /* 0b001_0000_0000; 60-Ohm */
> +#define MV_DDR_MR1_RTT_NOM_RZQ_DIV2 0x200 /* 0b010_0000_0000; 120-Ohm */
> +#define MV_DDR_MR1_RTT_NOM_RZQ_DIV6 0x300 /* 0b011_0000_0000; 40-Ohm */
> +#define MV_DDR_MR1_RTT_NOM_RZQ_DIV1 0x400 /* 0b100_0000_0000; 240-Ohm */
> +#define MV_DDR_MR1_RTT_NOM_RZQ_DIV5 0x500 /* 0b101_0000_0000; 48-Ohm */
> +#define MV_DDR_MR1_RTT_NOM_RZQ_DIV3 0x600 /* 0b110_0000_0000; 80-Ohm */
> +#define MV_DDR_MR1_RTT_NOM_RZQ_DIV7 0x700 /* 0b111_0000_0000; 34-Ohm */
> +
> +/* MR2 RTT_WR, [11:9] bits */
> +#define MV_DDR_MR2_RTT_WR_OFFS 9
> +#define MV_DDR_MR2_RTT_WR_MASK 0x7
> +#define MV_DDR_MR2_RTT_WR_DYN_ODT_OFF 0x0 /* 0b0000_0000_0000 */
> +#define MV_DDR_MR2_RTT_WR_RZQ_DIV2 0x200 /* 0b0010_0000_0000; 120-Ohm */
> +#define MV_DDR_MR2_RTT_WR_RZQ_DIV1 0x400 /* 0b0100_0000_0000; 240-Ohm */
> +#define MV_DDR_MR2_RTT_WR_HIZ 0x600 /* 0b0110_0000_0000 */
> +#define MV_DDR_MR2_RTT_WR_RZQ_DIV3 0x800 /* 0b1000_0000_0000; 80-Ohm */
> +
> +/* MR5 ODT Input Buffer during Power Down mode, bit 5 */
> +#define MV_DDR_MR5_PD_ODT_IBUF_OFFS 5
> +#define MV_DDR_MR5_PD_ODT_IBUF_MASK 0x1
> +#define MV_DDR_MR5_PD_ODT_IBUF_ENA 0
> +#define MV_DDR_MR5_PD_ODT_IBUF_DIS 1
> +
> +/* MR5 Data Mask, bit 10 */
> +#define MV_DDR_MR5_DM_OFFS 10
> +#define MV_DDR_MR5_DM_MASK 0x1
> +#define MV_DDR_MR5_DM_ENA 1
> +#define MV_DDR_MR5_DM_DIS 0
> +
> +/* MR5 RTT_PARK, [8:6] bits */
> +#define MV_DDR_MR5_RTT_PARK_OFFS 6
> +#define MV_DDR_MR5_RTT_PARK_MASK 0x7
> +#define MV_DDR_MR5_RTT_PARK_DISABLE 0x0 /* 0b0_0000_0000 */
> +#define MV_DDR_MR5_RTT_PARK_RZQ_DIV4 0x40 /* 0b0_0100_0000; 60-Ohm */
> +#define MV_DDR_MR5_RTT_PARK_RZQ_DIV2 0x80 /* 0b0_1000_0000; 120-Ohm */
> +#define MV_DDR_MR5_RTT_PARK_RZQ_DIV6 0xc0 /* 0b0_1100_0000; 40-Ohm */
> +#define MV_DDR_MR5_RTT_PARK_RZQ_DIV1 0x100 /* 0b1_0000_0000; 240-Ohm */
> +#define MV_DDR_MR5_RTT_PARK_RZQ_DIV5 0x140 /* 0b1_0100_0000; 48-Ohm */
> +#define MV_DDR_MR5_RTT_PARK_RZQ_DIV3 0x180 /* 0b1_1000_0000; 80-Ohm */
> +#define MV_DDR_MR5_RTT_PARK_RZQ_DIV7 0x1c0 /* 0b1_1100_0000; 34-Ohm */
> +
> +/* MR6 VrefDQ Training Enable, bit 7 */
> +#define MV_DDR_MR6_VREFDQ_TRNG_ENA_OFFS 7
> +#define MV_DDR_MR6_VREFDQ_TRNG_ENA_MASK 0x1
> +#define MV_DDR_MR6_VREFDQ_TRNG_ENA 1 /* training mode */
> +#define MV_DDR_MR6_VREFDQ_TRNG_DIS 0 /* normal operation mode */
> +
> +/* MR6 VrefDQ Training Range, bit 6 */
> +#define MV_DDR_MR6_VREFDQ_TRNG_RNG_OFFS 6
> +#define MV_DDR_MR6_VREFDQ_TRNG_RNG_MASK 0x1
> +#define MV_DDR_MR6_VREFDQ_TRNG_RNG1 0 /* range 1 */
> +#define MV_DDR_MR6_VREFDQ_TRNG_RNG2 1 /* range 2 */
> +
> +/* MR6 VrefDQ Training Range Values, [5:0] bits */
> +#define MV_DDR_MR6_VREFDQ_TRNG_VAL_OFFS 0
> +#define MV_DDR_MR6_VREFDQ_TRNG_VAL_MASK 0x3f
> +#define MV_DDR_MR6_VREFDQ_TRNG_VAL 0x9 /* range 1: 65.85%; range 2: 50.85% */
> +
> +int mv_ddr_mr0_wr_get(unsigned int wr, unsigned int *mr0_wr);
> +int mv_ddr_mr0_cl_get(unsigned int cl, unsigned int *mr0_cl);
> +int mv_ddr_mr2_cwl_get(unsigned int cwl, unsigned int *mr2_cwl);
> +int mv_ddr_mr6_tccdl_get(unsigned int tccdl, unsigned int *mr6_tccdl);
> +
> +#endif /* _MV_DDR_MRS_H */
And also header file.
...
> diff --git a/drivers/ddr/marvell/a38x/mv_ddr_static.c b/drivers/ddr/marvell/a38x/mv_ddr_static.c
> new file mode 100644
> index 0000000000..269e62c213
> --- /dev/null
> +++ b/drivers/ddr/marvell/a38x/mv_ddr_static.c
> @@ -0,0 +1,12 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) Marvell International Ltd. and its affiliates
> + */
> +
> +#include "mv_ddr_static.h"
> +#include "ddr3_training_ip_def.h"
> +
> +
> +
> +
> +
This file is empty.
> diff --git a/drivers/ddr/marvell/a38x/mv_ddr_static.h b/drivers/ddr/marvell/a38x/mv_ddr_static.h
> new file mode 100644
> index 0000000000..b5c131963e
> --- /dev/null
> +++ b/drivers/ddr/marvell/a38x/mv_ddr_static.h
> @@ -0,0 +1,11 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) Marvell International Ltd. and its affiliates
> + */
> +
> +#ifndef _MV_DDR_STATIC_H
> +#define _MV_DDR_STATIC_H
> +
> +
> +
> +#endif /* _MV_DDR_STATIC_H */
And header file too.
More information about the U-Boot
mailing list