summaryrefslogtreecommitdiff
path: root/drivers/spi/mvebu_a3700_spi.c
diff options
context:
space:
mode:
authorMarek BehĂșn <marek.behun@nic.cz>2018-04-24 18:21:26 +0300
committerStefan Roese <sr@denx.de>2018-05-14 11:00:15 +0300
commitdbbd5bdd27437909dac5c664303cd6e0fe420f39 (patch)
treef5015b634a9823fe5a753c04ef7f0539c3afc87a /drivers/spi/mvebu_a3700_spi.c
parent82a248df9af7057152a1359e7405585419accc1e (diff)
downloadu-boot-dbbd5bdd27437909dac5c664303cd6e0fe420f39.tar.xz
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>
Diffstat (limited to 'drivers/spi/mvebu_a3700_spi.c')
-rw-r--r--drivers/spi/mvebu_a3700_spi.c52
1 files changed, 28 insertions, 24 deletions
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,
};