From c624d07f3ff7ae7d29672bab189d2aeb99c63a95 Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Mon, 2 Nov 2015 17:11:21 -0600 Subject: arm: socfpga: reset: correct dma, qspi, and sdmmc reset bit defines The DMA, QSPI, and SD/MMC reset bits are located in the permodrst register, not the mpumodrst. So the bank for these reset bits should be 1, not 0. Signed-off-by: Dinh Nguyen --- arch/arm/mach-socfpga/include/mach/reset_manager.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-socfpga/include/mach/reset_manager.h b/arch/arm/mach-socfpga/include/mach/reset_manager.h index 8e59578..666a2ef 100644 --- a/arch/arm/mach-socfpga/include/mach/reset_manager.h +++ b/arch/arm/mach-socfpga/include/mach/reset_manager.h @@ -69,9 +69,9 @@ struct socfpga_reset_manager { #define RSTMGR_UART0 RSTMGR_DEFINE(1, 16) #define RSTMGR_SPIM0 RSTMGR_DEFINE(1, 18) #define RSTMGR_SPIM1 RSTMGR_DEFINE(1, 19) -#define RSTMGR_QSPI RSTMGR_DEFINE(0, 5) -#define RSTMGR_SDMMC RSTMGR_DEFINE(0, 22) -#define RSTMGR_DMA RSTMGR_DEFINE(0, 28) +#define RSTMGR_QSPI RSTMGR_DEFINE(1, 5) +#define RSTMGR_SDMMC RSTMGR_DEFINE(1, 22) +#define RSTMGR_DMA RSTMGR_DEFINE(1, 28) #define RSTMGR_SDR RSTMGR_DEFINE(1, 29) /* Create a human-readable reference to SoCFPGA reset. */ -- cgit v1.1 From bfa3e55b440e120739d2b4dd4cb57e6b40752113 Mon Sep 17 00:00:00 2001 From: Chin Liang See Date: Sat, 17 Oct 2015 08:30:32 -0500 Subject: lib, fdt: Adding fdtdec_get_uint function Adding fdtdec_get_uint function which is the unsigned version for fdtdec_get_int Signed-off-by: Chin Liang See Cc: Dinh Nguyen Cc: Dinh Nguyen Cc: Marek Vasut Cc: Stefan Roese Cc: Vikas Manocha Cc: Jagannadh Teki Cc: Pavel Machek Cc: Heiko Schocher --- include/fdtdec.h | 13 +++++++++++++ lib/fdtdec_common.c | 18 ++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/include/fdtdec.h b/include/fdtdec.h index 2de6dda..d51e643 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -490,6 +490,19 @@ s32 fdtdec_get_int(const void *blob, int node, const char *prop_name, s32 default_val); /** + * Unsigned version of fdtdec_get_int. The property must have at least + * 4 bytes of data. The value of the first cell is returned. + * + * @param blob FDT blob + * @param node node to examine + * @param prop_name name of property to find + * @param default_val default value to return if the property is not found + * @return unsigned integer value, if found, or default_val if not + */ +unsigned int fdtdec_get_uint(const void *blob, int node, const char *prop_name, + unsigned int default_val); + +/** * Get a variable-sized number from a property * * This reads a number from one or more cells. diff --git a/lib/fdtdec_common.c b/lib/fdtdec_common.c index 757931a..63b704a 100644 --- a/lib/fdtdec_common.c +++ b/lib/fdtdec_common.c @@ -36,3 +36,21 @@ int fdtdec_get_int(const void *blob, int node, const char *prop_name, debug("(not found)\n"); return default_val; } + +unsigned int fdtdec_get_uint(const void *blob, int node, const char *prop_name, + unsigned int default_val) +{ + const int *cell; + int len; + + debug("%s: %s: ", __func__, prop_name); + cell = fdt_getprop(blob, node, prop_name, &len); + if (cell && len >= sizeof(unsigned int)) { + unsigned int val = fdt32_to_cpu(cell[0]); + + debug("%#x (%d)\n", val, val); + return val; + } + debug("(not found)\n"); + return default_val; +} -- cgit v1.1 From 98fbd71d7a4492e23377b8753cfd77add26c63ec Mon Sep 17 00:00:00 2001 From: Chin Liang See Date: Sat, 17 Oct 2015 08:31:55 -0500 Subject: spi: cadence_qspi: Ensure spi_calibration is run when sclk change Ensuring spi_calibration is run when there is a change of sclk frequency. This will ensure the qspi flash access works for high sclk frequency Signed-off-by: Chin Liang See Cc: Dinh Nguyen Cc: Dinh Nguyen Cc: Marek Vasut Cc: Stefan Roese Cc: Vikas Manocha Cc: Jagannadh Teki Cc: Pavel Machek Acked-by: Marek Vasut Reviewed-by: Jagan Teki --- drivers/spi/cadence_qspi.c | 22 +++++++++++++--------- drivers/spi/cadence_qspi.h | 1 + 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c index 34a0f46..c5a4276 100644 --- a/drivers/spi/cadence_qspi.c +++ b/drivers/spi/cadence_qspi.c @@ -37,9 +37,8 @@ static int cadence_spi_write_speed(struct udevice *bus, uint hz) } /* Calibration sequence to determine the read data capture delay register */ -static int spi_calibration(struct udevice *bus) +static int spi_calibration(struct udevice *bus, uint hz) { - struct cadence_spi_platdata *plat = bus->platdata; struct cadence_spi_priv *priv = dev_get_priv(bus); void *base = priv->regbase; u8 opcode_rdid = 0x9F; @@ -64,7 +63,7 @@ static int spi_calibration(struct udevice *bus) } /* use back the intended clock and find low range */ - cadence_spi_write_speed(bus, plat->max_hz); + cadence_spi_write_speed(bus, hz); for (i = 0; i < CQSPI_READ_CAPTURE_MAX_DELAY; i++) { /* Disable QSPI */ cadence_qspi_apb_controller_disable(base); @@ -111,7 +110,7 @@ static int spi_calibration(struct udevice *bus) (range_hi + range_lo) / 2, range_lo, range_hi); /* just to ensure we do once only when speed or chip select change */ - priv->qspi_calibrated_hz = plat->max_hz; + priv->qspi_calibrated_hz = hz; priv->qspi_calibrated_cs = spi_chip_select(bus); return 0; @@ -126,14 +125,19 @@ static int cadence_spi_set_speed(struct udevice *bus, uint hz) /* Disable QSPI */ cadence_qspi_apb_controller_disable(priv->regbase); - cadence_spi_write_speed(bus, hz); - - /* Calibration required for different SCLK speed or chip select */ - if (priv->qspi_calibrated_hz != plat->max_hz || + /* + * Calibration required for different current SCLK speed, requested + * SCLK speed or chip select + */ + if (priv->previous_hz != hz || + priv->qspi_calibrated_hz != hz || priv->qspi_calibrated_cs != spi_chip_select(bus)) { - err = spi_calibration(bus); + err = spi_calibration(bus, hz); if (err) return err; + + /* prevent calibration run when same as previous request */ + priv->previous_hz = hz; } /* Enable QSPI */ diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h index 98e57aa..2912e36 100644 --- a/drivers/spi/cadence_qspi.h +++ b/drivers/spi/cadence_qspi.h @@ -38,6 +38,7 @@ struct cadence_spi_priv { int qspi_is_init; unsigned int qspi_calibrated_hz; unsigned int qspi_calibrated_cs; + unsigned int previous_hz; }; /* Functions call declaration */ -- cgit v1.1 From 040f4ba742700529d950a92da5ddbe99d9ae335e Mon Sep 17 00:00:00 2001 From: Chin Liang See Date: Sat, 17 Oct 2015 08:32:14 -0500 Subject: spi: cadence_qspi: Fix fdt read of spi-max-frequency Fix the fdt read for spi-max-frequency as it's contained in the child node. Current state of code is always returning default value. Signed-off-by: Chin Liang See Cc: Dinh Nguyen Cc: Dinh Nguyen Cc: Marek Vasut Cc: Stefan Roese Cc: Vikas Manocha Cc: Jagannadh Teki Cc: Pavel Machek Acked-by: Marek Vasut Acked-by: Pavel Machek --- drivers/spi/cadence_qspi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c index c5a4276..5756178 100644 --- a/drivers/spi/cadence_qspi.c +++ b/drivers/spi/cadence_qspi.c @@ -295,10 +295,6 @@ static int cadence_spi_ofdata_to_platdata(struct udevice *bus) plat->regbase = (void *)data[0]; plat->ahbbase = (void *)data[2]; - /* Use 500KHz as a suitable default */ - plat->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", - 500000); - /* All other paramters are embedded in the child node */ subnode = fdt_first_subnode(blob, node); if (subnode < 0) { @@ -306,6 +302,10 @@ static int cadence_spi_ofdata_to_platdata(struct udevice *bus) return -ENODEV; } + /* Use 500 KHz as a suitable default */ + plat->max_hz = fdtdec_get_uint(blob, subnode, "spi-max-frequency", + 500000); + /* Read other parameters from DT */ plat->page_size = fdtdec_get_int(blob, subnode, "page-size", 256); plat->block_size = fdtdec_get_int(blob, subnode, "block-size", 16); -- cgit v1.1 From 4e609b6cb1e6e8cb14c55fd50c73c5affcba26b5 Mon Sep 17 00:00:00 2001 From: Chin Liang See Date: Sat, 17 Oct 2015 08:32:38 -0500 Subject: spi: cadence_qspi: Ensure check for max frequency in place Ensure the intended SCLK frequency not exceeding the maximum frequency. If that happen, SCLK will set to maximum frequency. Signed-off-by: Chin Liang See Cc: Dinh Nguyen Cc: Dinh Nguyen Cc: Marek Vasut Cc: Stefan Roese Cc: Vikas Manocha Cc: Jagannadh Teki Cc: Pavel Machek Acked-by: Pavel Machek --- drivers/spi/cadence_qspi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c index 5756178..4f7fd52 100644 --- a/drivers/spi/cadence_qspi.c +++ b/drivers/spi/cadence_qspi.c @@ -122,6 +122,9 @@ static int cadence_spi_set_speed(struct udevice *bus, uint hz) struct cadence_spi_priv *priv = dev_get_priv(bus); int err; + if (hz > plat->max_hz) + hz = plat->max_hz; + /* Disable QSPI */ cadence_qspi_apb_controller_disable(priv->regbase); -- cgit v1.1 From a55f28624e97e1e43ac333c39713b8b9435fcbd3 Mon Sep 17 00:00:00 2001 From: Chin Liang See Date: Sat, 17 Oct 2015 08:32:56 -0500 Subject: arm: dts: socfpga: Increase the spi-max-frequency for QSPI flash With a working QSPI calibration, the SCLK can now run up to 100MHz Signed-off-by: Chin Liang See Cc: Dinh Nguyen Cc: Dinh Nguyen Cc: Marek Vasut Cc: Stefan Roese Cc: Vikas Manocha Cc: Jagannadh Teki Cc: Pavel Machek Reviewed-by: Marek Vasut Acked-by: Marek Vasut Reviewed-by: Jagan Teki --- arch/arm/dts/socfpga_cyclone5_socdk.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/dts/socfpga_cyclone5_socdk.dts b/arch/arm/dts/socfpga_cyclone5_socdk.dts index 5465609..9eb5a22 100644 --- a/arch/arm/dts/socfpga_cyclone5_socdk.dts +++ b/arch/arm/dts/socfpga_cyclone5_socdk.dts @@ -89,7 +89,7 @@ #size-cells = <1>; compatible = "n25q00"; reg = <0>; /* chip select */ - spi-max-frequency = <50000000>; + spi-max-frequency = <100000000>; m25p,fast-read; page-size = <256>; block-size = <16>; /* 2^16, 64KB */ -- cgit v1.1