diff options
-rw-r--r-- | arch/arm/dts/armada-37xx.dtsi | 4 | ||||
-rw-r--r-- | configs/mvebu_db-88f3720_defconfig | 3 | ||||
-rw-r--r-- | configs/mvebu_espressobin-88f3720_defconfig | 3 | ||||
-rw-r--r-- | drivers/spi/Kconfig | 1 | ||||
-rw-r--r-- | drivers/spi/mvebu_a3700_spi.c | 52 |
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(®->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, ®->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, }; |