[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