nb/via/cx700: Implement raminit

This brings the old raminit implementation for CX700 back. It was
removed in commit e99f0390b9 (Remove VIA CX700 northbridge sup-
port). The code is mostly unchanged, three minor issues are fixed:

* A shift (>>= 2) was missing when reading tRRD from SPD byte 28.
  The fixed value matches  what the vendor BIOS of a VIA EPIA-EX
  board programs. The code also suggests that we are looking for
  a small value (<= 19 for DDR2-533).

* We allow the board port to specify which clock outputs should
  be enabled now.  This is necessary for the VIA EPIA-EX, which
  needs the ALL_MCLKO setting  (instead of the previously hard-
  coded MCLKO2.

* When programming the DQS output delays, we considered the 1~2
  rank values only for single-rank configurations. Changing the
  `< 2` to `<= 2`  brings us closer to the vendor values on the
  VIA EPIA-EX.

Otherwise a lot of cosmetics changed. Partly because the original
code was to be #included into another C file, but also to satisfy
checkpatch. Also, all the #if'd code was removed (32-bit width
option, ECC, etc.).

Change-Id: Ibc36b4f314cdf47f18c8be0fcb98218c50938e94
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/82770
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
This commit is contained in:
Nico Huber 2024-06-02 02:20:54 +02:00 committed by Angel Pons
commit 755ecc259c
10 changed files with 1800 additions and 7 deletions

View file

@ -3,4 +3,6 @@
bootblock-y += ../car/cache_as_ram.S
bootblock-y += ../../intel/car/bootblock.c
romstage-y += ../../intel/car/romstage.c
postcar-y += ../car/exit_car.S

View file

@ -1,6 +1,14 @@
chip northbridge/via/cx700
device domain 0 on
device ref dram_ctrl on
register "dram_cfg" = "{
.spd_addr = { 0x50, },
.mem_clocks = ALL_MCLKO,
}"
end
end
end

View file

@ -6,6 +6,7 @@ config NORTHBRIDGE_VIA_CX700
select NO_ECAM_MMCONF_SUPPORT
select HAVE_CF9_RESET
select SOUTHBRIDGE_INTEL_COMMON_SMBUS
select HAVE_DEBUG_RAM_SETUP
if NORTHBRIDGE_VIA_CX700

View file

@ -1,9 +1,13 @@
## SPDX-License-Identifier: GPL-2.0-only
ifeq ($(CONFIG_NORTHBRIDGE_VIA_CX700),y)
# raminit accesses addresses as low as 0
CFLAGS_bootblock += --param=min-pagesize=0
CFLAGS_romstage += --param=min-pagesize=0
bootblock-y += early_smbus.c bootblock.c
romstage-y += early_smbus.c romstage.c
ramstage-y += chip.c
romstage-y += early_smbus.c memmap.c romstage.c raminit.c
ramstage-y += memmap.c chip.c
all-y += clock.c reset.c
endif

View file

@ -0,0 +1,22 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef __VIA_CX700_CHIP_H__
#define __VIA_CX700_CHIP_H__
#define DIMM_SOCKETS 2
struct dram_cfg {
uint8_t spd_addr[DIMM_SOCKETS];
enum {
MCLKO0,
MCLKO1,
MCLKO2,
ALL_MCLKO
} mem_clocks;
};
struct northbridge_via_cx700_config {
struct dram_cfg dram_cfg;
};
#endif

View file

@ -0,0 +1,44 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#define __SIMPLE_DEVICE__
#include <commonlib/bsd/helpers.h>
#include <stddef.h>
#include <stdint.h>
#include <device/pci_ops.h>
#include <static_devices.h>
#include <arch/romstage.h>
#include <cbmem.h>
static uintptr_t top_of_low_ram(void)
{
return (uintptr_t)pci_read_config8(_sdev_dram_ctrl, 0x88) << 24;
}
static size_t get_stolen_framebuffer_size(void)
{
const size_t size_selection = pci_read_config8(_sdev_dram_ctrl, 0xa1) >> 4 & 7;
return size_selection ? 1 << (size_selection + 22) : 0;
}
static size_t get_tseg_size(void)
{
return pci_read_config8(_sdev_dram_ctrl, 0x86) & 0x04 ? 1*MiB : 0;
}
uintptr_t cbmem_top_chipset(void)
{
/* Keep it below 2GiB to leave space for PCI MMIO.
If more than 2GiB are installed, CBMEM won't be
at the top of the available memory. */
return MIN(2ul*GiB, top_of_low_ram() - get_stolen_framebuffer_size() - get_tseg_size());
}
void fill_postcar_frame(struct postcar_frame *pcf)
{
/* TSEG top is at least 8MiB aligned, so
we cache 8MiB including TSEG if enabled. */
const uintptr_t top_down = ALIGN_DOWN(cbmem_top_chipset() - 7*MiB, 8*MiB);
postcar_frame_add_mtrr(pcf, top_down, 8*MiB, MTRR_TYPE_WRBACK);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef __VIA_CX700_RAMINIT_H__
#define __VIA_CX700_RAMINIT_H__
struct dram_cfg;
void sdram_enable(const struct dram_cfg *);
#endif

View file

@ -0,0 +1,32 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef __VIA_CX700_REGISTERS_H__
#define __VIA_CX700_REGISTERS_H__
/* CX700 has 48 bytes of scratch registers in D0F4 starting at Reg. 0xd0 */
#define SCRATCH_REG_BASE 0xd0
#define SCRATCH_RANK_0 0xd0
#define SCRATCH_RANK_1 0xd1
#define SCRATCH_RANK_2 0xd2
#define SCRATCH_RANK_3 0xd3
#define SCRATCH_DIMM_NUM 0xd4
#define SCRATCH_RANK_NUM 0xd5
#define SCRATCH_RANK_MAP 0xd6
#define SCRATCH_DRAM_FREQ 0xd7
#define SCRATCH_DRAM_NB_ODT 0xd8
#define SCRATCH_RANK0_SIZE_REG 0xe0 /* RxE0~RxE3 */
#define SCRATCH_RANK0_MA_REG 0xe4 /* RxE4~RxE7 */
#define SCRATCH_CHA_DQSI_LOW_REG 0xe8
#define SCRATCH_CHA_DQSI_HIGH_REG 0xe9
#define SCRATCH_ChA_DQSI_REG 0xea
#define SCRATCH_DRAM_256M_BIT 0xee
#define SCRATCH_FLAGS 0xef
#define DDRII_666 0x5
#define DDRII_533 0x4
#define DDRII_400 0x3
#define DDRII_333 0x2
#define DDRII_266 0x1
#define DDRII_200 0x0
#endif

View file

@ -3,10 +3,14 @@
#include <stddef.h>
#include <stdint.h>
#include <commonlib/bsd/helpers.h>
#include <device/device.h>
#include <device/pci_ops.h>
#include <static_devices.h>
#include <romstage_common.h>
#include <halt.h>
#include <arch/romstage.h>
#include <cbmem.h>
#include "chip.h"
#include "raminit.h"
static void tune_fsb(void)
{
@ -41,13 +45,18 @@ static void tune_fsb(void)
pci_write_config8(_sdev_host_if, fsb_settings[i].reg, fsb_settings[i].val);
}
void __noreturn romstage_main(void)
void mainboard_romstage_entry(void)
{
const struct northbridge_via_cx700_config *config = config_of_soc();
/* Allows access to all northbridge PCI devfn's */
pci_write_config8(_sdev_host_ctrl, 0x4f, 0x01);
tune_fsb();
/* Needed for __noreturn */
halt();
sdram_enable(&config->dram_cfg);
cbmem_recovery(/* s3resume => */0);
prepare_and_run_postcar();
}