summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/dts/armada-37xx.dtsi4
-rw-r--r--configs/mvebu_db-88f3720_defconfig3
-rw-r--r--configs/mvebu_espressobin-88f3720_defconfig3
-rw-r--r--drivers/spi/Kconfig1
-rw-r--r--drivers/spi/mvebu_a3700_spi.c52
5 files changed, 37 insertions, 26 deletions
diff --git a/arch/arm/dts/armada-37xx.dtsi b/arch/arm/dts/armada-37xx.dtsi
index c72fd25abc..5b4a1a49bb 100644
--- a/arch/arm/dts/armada-37xx.dtsi
+++ b/arch/arm/dts/armada-37xx.dtsi
@@ -301,8 +301,8 @@
#address-cells = <1>;
#size-cells = <0>;
#clock-cells = <0>;
- clock-frequency = <160000>;
- spi-max-frequency = <40000>;
+ spi-max-frequency = <50000000>;
+ clocks = <&nb_periph_clk 7>;
status = "disabled";
};
diff --git a/configs/mvebu_db-88f3720_defconfig b/configs/mvebu_db-88f3720_defconfig
index 67a8077a58..691d7211dc 100644
--- a/configs/mvebu_db-88f3720_defconfig
+++ b/configs/mvebu_db-88f3720_defconfig
@@ -36,6 +36,9 @@ CONFIG_DM_GPIO=y
# CONFIG_MVEBU_GPIO is not set
CONFIG_DM_I2C=y
CONFIG_MISC=y
+CONFIG_CLK=y
+CONFIG_CLK_MVEBU=y
+CONFIG_CLK_ARMADA_3720=y
CONFIG_DM_MMC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_SDMA=y
diff --git a/configs/mvebu_espressobin-88f3720_defconfig b/configs/mvebu_espressobin-88f3720_defconfig
index 48dae2d791..60259bcf2c 100644
--- a/configs/mvebu_espressobin-88f3720_defconfig
+++ b/configs/mvebu_espressobin-88f3720_defconfig
@@ -35,6 +35,9 @@ CONFIG_BLOCK_CACHE=y
CONFIG_DM_GPIO=y
CONFIG_DM_I2C=y
CONFIG_MISC=y
+CONFIG_CLK=y
+CONFIG_CLK_MVEBU=y
+CONFIG_CLK_ARMADA_3720=y
CONFIG_DM_MMC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_SDMA=y
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 6667f7321f..3532c2ad46 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -104,6 +104,7 @@ config ICH_SPI
config MVEBU_A3700_SPI
bool "Marvell Armada 3700 SPI driver"
+ select CLK_ARMADA_3720
help
Enable the Marvell Armada 3700 SPI driver. This driver can be
used to access the SPI NOR flash on platforms embedding this
diff --git a/drivers/spi/mvebu_a3700_spi.c b/drivers/spi/mvebu_a3700_spi.c
index e99252e153..feeafdceaa 100644
--- a/drivers/spi/mvebu_a3700_spi.c
+++ b/drivers/spi/mvebu_a3700_spi.c
@@ -9,6 +9,7 @@
#include <dm.h>
#include <malloc.h>
#include <spi.h>
+#include <clk.h>
#include <wait_bit.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_FIFO_EN BIT(17)
#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 << MVEBU_SPI_A3700_CLK_PRESCALE_BIT)
+#define MVEBU_SPI_A3700_CLK_PRESCALE_MASK 0x1f
+
/* SPI registers */
struct spi_reg {
@@ -35,8 +35,7 @@ struct spi_reg {
struct mvebu_spi_platdata {
struct spi_reg *spireg;
- unsigned int frequency;
- unsigned int clock;
+ struct clk clk;
};
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 spi_reg *reg = plat->spireg;
- u32 data;
+ u32 data, prescale;
data = readl(&reg->cfg);
- /* Set Prescaler */
- data &= ~MVEBU_SPI_A3700_CLK_PRESCALE_MASK;
+ prescale = DIV_ROUND_UP(clk_get_rate(&plat->clk), hz);
+ if (prescale > 0x1f)
+ prescale = 0x1f;
+ else if (prescale > 0xf)
+ prescale = 0x10 + (prescale + 1) / 2;
- /* Calculate Prescaler = (spi_input_freq / spi_max_freq) */
- if (hz > plat->frequency)
- hz = plat->frequency;
- data |= plat->clock / hz;
+ data &= ~MVEBU_SPI_A3700_CLK_PRESCALE_MASK;
+ data |= prescale & MVEBU_SPI_A3700_CLK_PRESCALE_MASK;
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)
{
struct mvebu_spi_platdata *plat = dev_get_platdata(bus);
+ int ret;
plat->spireg = (struct spi_reg *)devfdt_get_addr(bus);
- /*
- * FIXME
- * Right now, mvebu does not have a clock infrastructure in U-Boot
- * which should be used to query the input clock to the SPI
- * 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.
- */
- plat->clock = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus),
- "clock-frequency", 160000);
- plat->frequency = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus),
- "spi-max-frequency", 40000);
+ ret = clk_get_by_index(bus, 0, &plat->clk);
+ if (ret) {
+ dev_err(bus, "cannot get clock\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int mvebu_spi_remove(struct udevice *bus)
+{
+ struct mvebu_spi_platdata *plat = dev_get_platdata(bus);
+
+ clk_free(&plat->clk);
return 0;
}
@@ -293,4 +296,5 @@ U_BOOT_DRIVER(mvebu_spi) = {
.ofdata_to_platdata = mvebu_spi_ofdata_to_platdata,
.platdata_auto_alloc_size = sizeof(struct mvebu_spi_platdata),
.probe = mvebu_spi_probe,
+ .remove = mvebu_spi_remove,
};