soc/intel/common/block/gspi: Add SOC_INTEL_COMMON_BLOCK_GSPI_VERSION_2
Even though kaby lake and cannon lake are using the same GSPI controller, bit meanings (for polarity and state) in SPI_CS_CONTROL register are significantly different. This change provides a new Kconfig option that can be selected by SoCs using these new bit definitions of SPI_CS_CONTROL. Common code takes care of setting the right value for polarity and state field depending upon the version selected by SoC. BUG=b:70628116 Change-Id: Ic69321483a58bb29f939b0d8b37f33ca30eb53b8 Signed-off-by: Furquan Shaikh <furquan@google.com> Reviewed-on: https://review.coreboot.org/22954 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Aaron Durbin <adurbin@chromium.org> Reviewed-by: Shelley Chen <shchen@google.com> Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
This commit is contained in:
parent
261b893b7c
commit
58a8c779b3
|
@ -10,3 +10,11 @@ config SOC_INTEL_COMMON_BLOCK_GSPI_MAX
|
||||||
Maximum number of GSPI controllers supported by the PCH. SoC
|
Maximum number of GSPI controllers supported by the PCH. SoC
|
||||||
must define this config if SOC_INTEL_COMMON_BLOCK_GSPI is
|
must define this config if SOC_INTEL_COMMON_BLOCK_GSPI is
|
||||||
selected.
|
selected.
|
||||||
|
|
||||||
|
config SOC_INTEL_COMMON_BLOCK_GSPI_VERSION_2
|
||||||
|
bool
|
||||||
|
default n
|
||||||
|
select SOC_INTEL_COMMON_BLOCK_GSPI
|
||||||
|
help
|
||||||
|
Intel Processor Common GSPI support with quirks to handle
|
||||||
|
SPI_CS_CONTROL changes introduced in CNL.
|
||||||
|
|
|
@ -92,12 +92,15 @@
|
||||||
#define SSP_REG 0x220 /* SSP Reg */
|
#define SSP_REG 0x220 /* SSP Reg */
|
||||||
#define DMA_FINISH_DISABLE (1 << 0)
|
#define DMA_FINISH_DISABLE (1 << 0)
|
||||||
#define SPI_CS_CONTROL 0x224 /* SPI CS Control */
|
#define SPI_CS_CONTROL 0x224 /* SPI CS Control */
|
||||||
#define CS_POLARITY_LOW (0 << 12)
|
#define CS_0_POL_SHIFT (12)
|
||||||
#define CS_POLARITY_HIGH (1 << 12)
|
#define CS_0_POL_MASK (1 << CS_0_POL_SHIFT)
|
||||||
|
#define CS_POL_LOW (0)
|
||||||
|
#define CS_POL_HIGH (1)
|
||||||
#define CS_0 (0 << 8)
|
#define CS_0 (0 << 8)
|
||||||
#define CS_STATE_LOW (0 << 1)
|
#define CS_STATE_SHIFT (1)
|
||||||
#define CS_STATE_HIGH (1 << 1)
|
#define CS_STATE_MASK (1 << CS_STATE_SHIFT)
|
||||||
#define CS_STATE_MASK (1 << 1)
|
#define CS_V1_STATE_LOW (0)
|
||||||
|
#define CS_V1_STATE_HIGH (1)
|
||||||
#define CS_MODE_HW (0 << 0)
|
#define CS_MODE_HW (0 << 0)
|
||||||
#define CS_MODE_SW (1 << 0)
|
#define CS_MODE_SW (1 << 0)
|
||||||
|
|
||||||
|
@ -265,20 +268,78 @@ enum cs_assert {
|
||||||
CS_DEASSERT,
|
CS_DEASSERT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SPI_CS_CONTROL bit definitions based on GSPI_VERSION_x:
|
||||||
|
*
|
||||||
|
* VERSION_2 (CNL GSPI controller):
|
||||||
|
* Polarity: Indicates inactive polarity of chip-select
|
||||||
|
* State : Indicates assert/de-assert of chip-select
|
||||||
|
*
|
||||||
|
* Default (SKL/KBL GSPI controller):
|
||||||
|
* Polarity: Indicates active polarity of chip-select
|
||||||
|
* State : Indicates low/high output state of chip-select
|
||||||
|
*/
|
||||||
|
static uint32_t gspi_csctrl_state_v2(uint32_t pol, enum cs_assert cs_assert)
|
||||||
|
{
|
||||||
|
return cs_assert;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t gspi_csctrl_state_v1(uint32_t pol, enum cs_assert cs_assert)
|
||||||
|
{
|
||||||
|
uint32_t state;
|
||||||
|
|
||||||
|
if (pol == CS_POL_HIGH)
|
||||||
|
state = (cs_assert == CS_ASSERT) ? CS_V1_STATE_HIGH :
|
||||||
|
CS_V1_STATE_LOW;
|
||||||
|
else
|
||||||
|
state = (cs_assert == CS_ASSERT) ? CS_V1_STATE_LOW :
|
||||||
|
CS_V1_STATE_HIGH;
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t gspi_csctrl_state(uint32_t pol, enum cs_assert cs_assert)
|
||||||
|
{
|
||||||
|
if (IS_ENABLED(CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_VERSION_2))
|
||||||
|
return gspi_csctrl_state_v2(pol, cs_assert);
|
||||||
|
|
||||||
|
return gspi_csctrl_state_v1(pol, cs_assert);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t gspi_csctrl_polarity_v2(enum spi_polarity active_pol)
|
||||||
|
{
|
||||||
|
/* Polarity field indicates cs inactive polarity */
|
||||||
|
if (active_pol == SPI_POLARITY_LOW)
|
||||||
|
return CS_POL_HIGH;
|
||||||
|
return CS_POL_LOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t gspi_csctrl_polarity_v1(enum spi_polarity active_pol)
|
||||||
|
{
|
||||||
|
/* Polarity field indicates cs active polarity */
|
||||||
|
if (active_pol == SPI_POLARITY_LOW)
|
||||||
|
return CS_POL_LOW;
|
||||||
|
return CS_POL_HIGH;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t gspi_csctrl_polarity(enum spi_polarity active_pol)
|
||||||
|
{
|
||||||
|
if (IS_ENABLED(CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_VERSION_2))
|
||||||
|
return gspi_csctrl_polarity_v2(active_pol);
|
||||||
|
|
||||||
|
return gspi_csctrl_polarity_v1(active_pol);
|
||||||
|
}
|
||||||
|
|
||||||
static void __gspi_cs_change(const struct gspi_ctrlr_params *p,
|
static void __gspi_cs_change(const struct gspi_ctrlr_params *p,
|
||||||
enum cs_assert cs_assert)
|
enum cs_assert cs_assert)
|
||||||
{
|
{
|
||||||
uint32_t cs_ctrl, state;
|
uint32_t cs_ctrl, pol;
|
||||||
cs_ctrl = gspi_read_mmio_reg(p, SPI_CS_CONTROL);
|
cs_ctrl = gspi_read_mmio_reg(p, SPI_CS_CONTROL);
|
||||||
|
|
||||||
cs_ctrl &= ~CS_STATE_MASK;
|
cs_ctrl &= ~CS_STATE_MASK;
|
||||||
|
|
||||||
if (cs_ctrl & CS_POLARITY_HIGH)
|
pol = !!(cs_ctrl & CS_0_POL_MASK);
|
||||||
state = (cs_assert == CS_ASSERT) ? CS_STATE_HIGH : CS_STATE_LOW;
|
cs_ctrl |= gspi_csctrl_state(pol, cs_assert) << CS_STATE_SHIFT;
|
||||||
else
|
|
||||||
state = (cs_assert == CS_ASSERT) ? CS_STATE_LOW : CS_STATE_HIGH;
|
|
||||||
|
|
||||||
cs_ctrl |= state;
|
|
||||||
|
|
||||||
gspi_write_mmio_reg(p, SPI_CS_CONTROL, cs_ctrl);
|
gspi_write_mmio_reg(p, SPI_CS_CONTROL, cs_ctrl);
|
||||||
}
|
}
|
||||||
|
@ -330,7 +391,7 @@ static uint32_t gspi_get_clk_div(unsigned int gspi_bus)
|
||||||
static int gspi_ctrlr_setup(const struct spi_slave *dev)
|
static int gspi_ctrlr_setup(const struct spi_slave *dev)
|
||||||
{
|
{
|
||||||
struct spi_cfg cfg;
|
struct spi_cfg cfg;
|
||||||
uint32_t cs_ctrl, sscr0, sscr1, clocks, sitf, sirf;
|
uint32_t cs_ctrl, sscr0, sscr1, clocks, sitf, sirf, pol;
|
||||||
struct gspi_ctrlr_params params, *p = ¶ms;
|
struct gspi_ctrlr_params params, *p = ¶ms;
|
||||||
|
|
||||||
/* Only chip select 0 is supported. */
|
/* Only chip select 0 is supported. */
|
||||||
|
@ -364,10 +425,9 @@ static int gspi_ctrlr_setup(const struct spi_slave *dev)
|
||||||
* - Do not assert CS.
|
* - Do not assert CS.
|
||||||
*/
|
*/
|
||||||
cs_ctrl = CS_MODE_SW | CS_0;
|
cs_ctrl = CS_MODE_SW | CS_0;
|
||||||
if (cfg.cs_polarity == SPI_POLARITY_LOW)
|
pol = gspi_csctrl_polarity(cfg.cs_polarity);
|
||||||
cs_ctrl |= CS_POLARITY_LOW | CS_STATE_HIGH;
|
cs_ctrl |= pol << CS_0_POL_SHIFT;
|
||||||
else
|
cs_ctrl |= gspi_csctrl_state(pol, CS_DEASSERT);
|
||||||
cs_ctrl |= CS_POLARITY_HIGH | CS_STATE_LOW;
|
|
||||||
gspi_write_mmio_reg(p, SPI_CS_CONTROL, cs_ctrl);
|
gspi_write_mmio_reg(p, SPI_CS_CONTROL, cs_ctrl);
|
||||||
|
|
||||||
/* Disable SPI controller. */
|
/* Disable SPI controller. */
|
||||||
|
|
Loading…
Reference in New Issue