spi: mvebu_a3700_spi: Use Armada 37xx clk driver for SPI clock frequency

Since now we have driver for clocks on Armada 37xx, use it to determine
SQF clock frequency for the SPI driver.

Also change the default config files for Armada 37xx devices so that
the clock driver is enabled by default, otherwise the SPI driver cannot
be enabled.

Signed-off-by: Marek Behun <marek.behun@nic.cz>
Signed-off-by: Stefan Roese <sr@denx.de>
This commit is contained in:
Marek Behún 2018-04-24 17:21:26 +02:00 committed by Stefan Roese
parent 82a248df9a
commit dbbd5bdd27
5 changed files with 37 additions and 26 deletions

View File

@ -301,8 +301,8 @@
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
#clock-cells = <0>; #clock-cells = <0>;
clock-frequency = <160000>; spi-max-frequency = <50000000>;
spi-max-frequency = <40000>; clocks = <&nb_periph_clk 7>;
status = "disabled"; status = "disabled";
}; };

View File

@ -36,6 +36,9 @@ CONFIG_DM_GPIO=y
# CONFIG_MVEBU_GPIO is not set # CONFIG_MVEBU_GPIO is not set
CONFIG_DM_I2C=y CONFIG_DM_I2C=y
CONFIG_MISC=y CONFIG_MISC=y
CONFIG_CLK=y
CONFIG_CLK_MVEBU=y
CONFIG_CLK_ARMADA_3720=y
CONFIG_DM_MMC=y CONFIG_DM_MMC=y
CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_SDMA=y CONFIG_MMC_SDHCI_SDMA=y

View File

@ -35,6 +35,9 @@ CONFIG_BLOCK_CACHE=y
CONFIG_DM_GPIO=y CONFIG_DM_GPIO=y
CONFIG_DM_I2C=y CONFIG_DM_I2C=y
CONFIG_MISC=y CONFIG_MISC=y
CONFIG_CLK=y
CONFIG_CLK_MVEBU=y
CONFIG_CLK_ARMADA_3720=y
CONFIG_DM_MMC=y CONFIG_DM_MMC=y
CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_SDMA=y CONFIG_MMC_SDHCI_SDMA=y

View File

@ -104,6 +104,7 @@ config ICH_SPI
config MVEBU_A3700_SPI config MVEBU_A3700_SPI
bool "Marvell Armada 3700 SPI driver" bool "Marvell Armada 3700 SPI driver"
select CLK_ARMADA_3720
help help
Enable the Marvell Armada 3700 SPI driver. This driver can be Enable the Marvell Armada 3700 SPI driver. This driver can be
used to access the SPI NOR flash on platforms embedding this used to access the SPI NOR flash on platforms embedding this

View File

@ -9,6 +9,7 @@
#include <dm.h> #include <dm.h>
#include <malloc.h> #include <malloc.h>
#include <spi.h> #include <spi.h>
#include <clk.h>
#include <wait_bit.h> #include <wait_bit.h>
#include <asm/io.h> #include <asm/io.h>
@ -21,9 +22,8 @@ DECLARE_GLOBAL_DATA_PTR;
#define MVEBU_SPI_A3700_CLK_POL BIT(7) #define MVEBU_SPI_A3700_CLK_POL BIT(7)
#define MVEBU_SPI_A3700_FIFO_EN BIT(17) #define MVEBU_SPI_A3700_FIFO_EN BIT(17)
#define MVEBU_SPI_A3700_SPI_EN_0 BIT(16) #define MVEBU_SPI_A3700_SPI_EN_0 BIT(16)
#define MVEBU_SPI_A3700_CLK_PRESCALE_BIT 0 #define MVEBU_SPI_A3700_CLK_PRESCALE_MASK 0x1f
#define MVEBU_SPI_A3700_CLK_PRESCALE_MASK \
(0x1f << MVEBU_SPI_A3700_CLK_PRESCALE_BIT)
/* SPI registers */ /* SPI registers */
struct spi_reg { struct spi_reg {
@ -35,8 +35,7 @@ struct spi_reg {
struct mvebu_spi_platdata { struct mvebu_spi_platdata {
struct spi_reg *spireg; struct spi_reg *spireg;
unsigned int frequency; struct clk clk;
unsigned int clock;
}; };
static void spi_cs_activate(struct spi_reg *reg, int cs) static void spi_cs_activate(struct spi_reg *reg, int cs)
@ -177,17 +176,18 @@ static int mvebu_spi_set_speed(struct udevice *bus, uint hz)
{ {
struct mvebu_spi_platdata *plat = dev_get_platdata(bus); struct mvebu_spi_platdata *plat = dev_get_platdata(bus);
struct spi_reg *reg = plat->spireg; struct spi_reg *reg = plat->spireg;
u32 data; u32 data, prescale;
data = readl(&reg->cfg); data = readl(&reg->cfg);
/* Set Prescaler */ prescale = DIV_ROUND_UP(clk_get_rate(&plat->clk), hz);
data &= ~MVEBU_SPI_A3700_CLK_PRESCALE_MASK; if (prescale > 0x1f)
prescale = 0x1f;
else if (prescale > 0xf)
prescale = 0x10 + (prescale + 1) / 2;
/* Calculate Prescaler = (spi_input_freq / spi_max_freq) */ data &= ~MVEBU_SPI_A3700_CLK_PRESCALE_MASK;
if (hz > plat->frequency) data |= prescale & MVEBU_SPI_A3700_CLK_PRESCALE_MASK;
hz = plat->frequency;
data |= plat->clock / hz;
writel(data, &reg->cfg); writel(data, &reg->cfg);
@ -251,21 +251,24 @@ static int mvebu_spi_probe(struct udevice *bus)
static int mvebu_spi_ofdata_to_platdata(struct udevice *bus) static int mvebu_spi_ofdata_to_platdata(struct udevice *bus)
{ {
struct mvebu_spi_platdata *plat = dev_get_platdata(bus); struct mvebu_spi_platdata *plat = dev_get_platdata(bus);
int ret;
plat->spireg = (struct spi_reg *)devfdt_get_addr(bus); plat->spireg = (struct spi_reg *)devfdt_get_addr(bus);
/* ret = clk_get_by_index(bus, 0, &plat->clk);
* FIXME if (ret) {
* Right now, mvebu does not have a clock infrastructure in U-Boot dev_err(bus, "cannot get clock\n");
* which should be used to query the input clock to the SPI return ret;
* controller. Once this clock driver is integrated into U-Boot }
* it should be used to read the input clock and the DT property
* can be removed. return 0;
*/ }
plat->clock = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus),
"clock-frequency", 160000); static int mvebu_spi_remove(struct udevice *bus)
plat->frequency = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus), {
"spi-max-frequency", 40000); struct mvebu_spi_platdata *plat = dev_get_platdata(bus);
clk_free(&plat->clk);
return 0; return 0;
} }
@ -293,4 +296,5 @@ U_BOOT_DRIVER(mvebu_spi) = {
.ofdata_to_platdata = mvebu_spi_ofdata_to_platdata, .ofdata_to_platdata = mvebu_spi_ofdata_to_platdata,
.platdata_auto_alloc_size = sizeof(struct mvebu_spi_platdata), .platdata_auto_alloc_size = sizeof(struct mvebu_spi_platdata),
.probe = mvebu_spi_probe, .probe = mvebu_spi_probe,
.remove = mvebu_spi_remove,
}; };