soc/amd/common/block/spi: Add support for common SPI configuration
This change adds support for following SPI configuration functions to common block SPI driver and exposes them to be used by SoC: 1. fch_spi_early_init(): Sets up SPI ROM base, enables SPI ROM, enables prefetching, disables 4dw burst mode and sets SPI speed and mode. 2. fch_spi_config_modes(): This allows SoC to configure SPI speed and mode. It uses SPI settings from soc_amd_common_config to configure the speed and mode. These functions expect SoC to include soc_amd_common_config in SoC chip config and mainboard to configure these settings in device tree. Signed-off-by: Furquan Shaikh <furquan@google.com> Change-Id: Ia4f231bab69e8450005dd6abe7a8e014d5eb7261 Reviewed-on: https://review.coreboot.org/c/coreboot/+/41248 Reviewed-by: Aaron Durbin <adurbin@chromium.org> Reviewed-by: Raul Rangel <rrangel@chromium.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
56875113b7
commit
08c524c0b7
|
@ -4,7 +4,19 @@
|
|||
#ifndef __AMDBLOCKS_CHIP_H__
|
||||
#define __AMDBLOCKS_CHIP_H__
|
||||
|
||||
#include <amdblocks/spi.h>
|
||||
|
||||
struct soc_amd_common_config {
|
||||
/*
|
||||
* SPI configuration
|
||||
* Default values if not overridden by mainboard:
|
||||
* Read mode - Normal 33MHz
|
||||
* Normal speed - 66MHz
|
||||
* Fast speed - 66MHz
|
||||
* Alt speed - 66MHz
|
||||
* TPM speed - 66MHz
|
||||
*/
|
||||
struct spi_config spi_config;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* This file is part of the coreboot project. */
|
||||
|
||||
#ifndef __AMDBLOCKS_SPI_H__
|
||||
#define __AMDBLOCKS_SPI_H__
|
||||
|
||||
#define SPI_CNTRL0 0x00
|
||||
#define SPI_BUSY BIT(31)
|
||||
|
||||
enum spi_read_mode {
|
||||
SPI_READ_MODE_NORMAL33M = 0,
|
||||
/* 1 is reserved. */
|
||||
SPI_READ_MODE_DUAL112 = 2,
|
||||
SPI_READ_MODE_QUAD114 = 3,
|
||||
SPI_READ_MODE_DUAL122 = 4,
|
||||
SPI_READ_MODE_QUAD144 = 5,
|
||||
SPI_READ_MODE_NORMAL66M = 6,
|
||||
SPI_READ_MODE_FAST_READ = 7,
|
||||
};
|
||||
/*
|
||||
* SPI read mode is split into bits 18, 29, 30 such that [30:29:18] correspond to bits [2:0] for
|
||||
* SpiReadMode.
|
||||
*/
|
||||
#define SPI_READ_MODE_MASK (BIT(30) | BIT(29) | BIT(18))
|
||||
#define SPI_READ_MODE_UPPER_BITS(x) ((((x) >> 1) & 0x3) << 29)
|
||||
#define SPI_READ_MODE_LOWER_BITS(x) (((x) & 0x1) << 18)
|
||||
#define SPI_READ_MODE(x) (SPI_READ_MODE_UPPER_BITS(x) | \
|
||||
SPI_READ_MODE_LOWER_BITS(x))
|
||||
#define SPI_ACCESS_MAC_ROM_EN BIT(22)
|
||||
|
||||
#define SPI100_ENABLE 0x20
|
||||
#define SPI_USE_SPI100 BIT(0)
|
||||
|
||||
/* Use SPI_SPEED_16M-SPI_SPEED_66M below for the southbridge */
|
||||
#define SPI100_SPEED_CONFIG 0x22
|
||||
enum spi100_speed {
|
||||
SPI_SPEED_66M = 0,
|
||||
SPI_SPEED_33M = 1,
|
||||
SPI_SPEED_22M = 2,
|
||||
SPI_SPEED_16M = 3,
|
||||
SPI_SPEED_100M = 4,
|
||||
SPI_SPEED_800K = 5,
|
||||
};
|
||||
|
||||
#define SPI_SPEED_MASK 0xf
|
||||
#define SPI_SPEED_MODE(x, shift) (((x) & SPI_SPEED_MASK) << shift)
|
||||
#define SPI_NORM_SPEED(x) SPI_SPEED_MODE(x, 12)
|
||||
#define SPI_FAST_SPEED(x) SPI_SPEED_MODE(x, 8)
|
||||
#define SPI_ALT_SPEED(x) SPI_SPEED_MODE(x, 4)
|
||||
#define SPI_TPM_SPEED(x) SPI_SPEED_MODE(x, 0)
|
||||
|
||||
#define SPI_SPEED_CFG(n, f, a, t) (SPI_NORM_SPEED(n) | SPI_FAST_SPEED(f) | \
|
||||
SPI_ALT_SPEED(a) | SPI_TPM_SPEED(t))
|
||||
|
||||
#define SPI100_HOST_PREF_CONFIG 0x2c
|
||||
#define SPI_RD4DW_EN_HOST BIT(15)
|
||||
|
||||
#define SPI_FIFO 0x80
|
||||
#define SPI_FIFO_DEPTH (0xc7 - SPI_FIFO)
|
||||
|
||||
struct spi_config {
|
||||
/*
|
||||
* Default values if not overridden by mainboard:
|
||||
* Read mode - Normal 33MHz
|
||||
* Normal speed - 66MHz
|
||||
* Fast speed - 66MHz
|
||||
* Alt speed - 66MHz
|
||||
* TPM speed - 66MHz
|
||||
*/
|
||||
enum spi_read_mode read_mode;
|
||||
enum spi100_speed normal_speed;
|
||||
enum spi100_speed fast_speed;
|
||||
enum spi100_speed altio_speed;
|
||||
enum spi100_speed tpm_speed;
|
||||
};
|
||||
|
||||
/*
|
||||
* Perform early SPI initialization:
|
||||
* 1. Sets SPI ROM base and enables SPI ROM
|
||||
* 2. Enables SPI ROM prefetching
|
||||
* 3. Disables 4dw burst
|
||||
* 4. Configures SPI speed and read mode.
|
||||
*
|
||||
* This function expects SoC to include soc_amd_common_config in chip SoC config and uses
|
||||
* settings from mainboard devicetree to configure speed and read mode.
|
||||
*/
|
||||
void fch_spi_early_init(void);
|
||||
|
||||
/*
|
||||
* Configure SPI speed and read mode.
|
||||
*
|
||||
* This function expects SoC to include soc_amd_common_config in chip SoC config and uses
|
||||
* settings from mainboard devicetree to configure speed and read mode.
|
||||
*/
|
||||
void fch_spi_config_modes(void);
|
||||
|
||||
#endif /* __AMDBLOCKS_SPI_H__ */
|
|
@ -9,4 +9,13 @@ ifeq ($(CONFIG_SPI_FLASH_SMM),y)
|
|||
smm-y += fch_spi_ctrl.c
|
||||
endif
|
||||
|
||||
bootblock-y += fch_spi.c
|
||||
romstage-y += fch_spi.c
|
||||
postcar-y += fch_spi.c
|
||||
ramstage-y += fch_spi.c
|
||||
verstage-y += fch_spi.c
|
||||
ifeq ($(CONFIG_SPI_FLASH_SMM),y)
|
||||
smm-y += fch_spi.c
|
||||
endif
|
||||
|
||||
endif
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* This file is part of the coreboot project. */
|
||||
|
||||
#include <amdblocks/chip.h>
|
||||
#include <amdblocks/lpc.h>
|
||||
#include <amdblocks/spi.h>
|
||||
#include <arch/mmio.h>
|
||||
#include <console/console.h>
|
||||
#include <soc/iomap.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static uintptr_t fch_spi_base(void)
|
||||
{
|
||||
uintptr_t base;
|
||||
|
||||
base = lpc_get_spibase();
|
||||
|
||||
if (base)
|
||||
return base;
|
||||
|
||||
lpc_set_spibase(SPI_BASE_ADDRESS);
|
||||
lpc_enable_spi_rom(SPI_ROM_ENABLE);
|
||||
|
||||
return SPI_BASE_ADDRESS;
|
||||
}
|
||||
|
||||
static void fch_spi_set_spi100(int norm, int fast, int alt, int tpm)
|
||||
{
|
||||
uintptr_t base = fch_spi_base();
|
||||
|
||||
write16((void *)(base + SPI100_SPEED_CONFIG), SPI_SPEED_CFG(norm, fast, alt, tpm));
|
||||
write16((void *)(base + SPI100_ENABLE), SPI_USE_SPI100);
|
||||
}
|
||||
|
||||
static void fch_spi_disable_4dw_burst(void)
|
||||
{
|
||||
uintptr_t base = fch_spi_base();
|
||||
uint16_t val = read16((void *)(base + SPI100_HOST_PREF_CONFIG));
|
||||
|
||||
write16((void *)(base + SPI100_HOST_PREF_CONFIG), val & ~SPI_RD4DW_EN_HOST);
|
||||
}
|
||||
|
||||
static void fch_spi_set_read_mode(u32 mode)
|
||||
{
|
||||
uintptr_t base = fch_spi_base();
|
||||
uint32_t val = read32((void *)(base + SPI_CNTRL0)) & ~SPI_READ_MODE_MASK;
|
||||
|
||||
write32((void *)(base + SPI_CNTRL0), val | SPI_READ_MODE(mode));
|
||||
}
|
||||
|
||||
static void fch_spi_config_mb_modes(void)
|
||||
{
|
||||
const struct soc_amd_common_config *cfg = soc_get_common_config();
|
||||
|
||||
if (!cfg)
|
||||
die("Common config structure is NULL!\n");
|
||||
|
||||
const struct spi_config *spi_cfg = &cfg->spi_config;
|
||||
|
||||
fch_spi_set_read_mode(spi_cfg->read_mode);
|
||||
fch_spi_set_spi100(spi_cfg->normal_speed, spi_cfg->fast_speed,
|
||||
spi_cfg->altio_speed, spi_cfg->tpm_speed);
|
||||
}
|
||||
|
||||
static void fch_spi_config_em100_modes(void)
|
||||
{
|
||||
fch_spi_set_read_mode(SPI_READ_MODE_NORMAL33M);
|
||||
fch_spi_set_spi100(SPI_SPEED_16M, SPI_SPEED_16M, SPI_SPEED_16M, SPI_SPEED_16M);
|
||||
}
|
||||
|
||||
void fch_spi_config_modes(void)
|
||||
{
|
||||
if (CONFIG(EM100))
|
||||
fch_spi_config_em100_modes();
|
||||
else
|
||||
fch_spi_config_mb_modes();
|
||||
}
|
||||
|
||||
void fch_spi_early_init(void)
|
||||
{
|
||||
lpc_set_spibase(SPI_BASE_ADDRESS);
|
||||
lpc_enable_spi_rom(SPI_ROM_ENABLE);
|
||||
lpc_enable_spi_prefetch();
|
||||
fch_spi_disable_4dw_burst();
|
||||
fch_spi_config_modes();
|
||||
}
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
#include <console/console.h>
|
||||
#include <spi_flash.h>
|
||||
#include <soc/southbridge.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <amdblocks/lpc.h>
|
||||
#include <amdblocks/spi.h>
|
||||
#include <device/pci_ops.h>
|
||||
#include <lib.h>
|
||||
#include <timer.h>
|
||||
|
|
Loading…
Reference in New Issue