Commit 28824407f341fa424535e18e164ea94b5e2cfa8a
Exists in
v2017.01-smarct4x
and in
30 other branches
Merge git://git.denx.de/u-boot-socfpga
Showing 6 changed files Side-by-side Diff
arch/arm/dts/socfpga_cyclone5_socdk.dts
arch/arm/mach-socfpga/include/mach/reset_manager.h
... | ... | @@ -69,9 +69,9 @@ |
69 | 69 | #define RSTMGR_UART0 RSTMGR_DEFINE(1, 16) |
70 | 70 | #define RSTMGR_SPIM0 RSTMGR_DEFINE(1, 18) |
71 | 71 | #define RSTMGR_SPIM1 RSTMGR_DEFINE(1, 19) |
72 | -#define RSTMGR_QSPI RSTMGR_DEFINE(0, 5) | |
73 | -#define RSTMGR_SDMMC RSTMGR_DEFINE(0, 22) | |
74 | -#define RSTMGR_DMA RSTMGR_DEFINE(0, 28) | |
72 | +#define RSTMGR_QSPI RSTMGR_DEFINE(1, 5) | |
73 | +#define RSTMGR_SDMMC RSTMGR_DEFINE(1, 22) | |
74 | +#define RSTMGR_DMA RSTMGR_DEFINE(1, 28) | |
75 | 75 | #define RSTMGR_SDR RSTMGR_DEFINE(1, 29) |
76 | 76 | |
77 | 77 | /* Create a human-readable reference to SoCFPGA reset. */ |
drivers/spi/cadence_qspi.c
... | ... | @@ -37,9 +37,8 @@ |
37 | 37 | } |
38 | 38 | |
39 | 39 | /* Calibration sequence to determine the read data capture delay register */ |
40 | -static int spi_calibration(struct udevice *bus) | |
40 | +static int spi_calibration(struct udevice *bus, uint hz) | |
41 | 41 | { |
42 | - struct cadence_spi_platdata *plat = bus->platdata; | |
43 | 42 | struct cadence_spi_priv *priv = dev_get_priv(bus); |
44 | 43 | void *base = priv->regbase; |
45 | 44 | u8 opcode_rdid = 0x9F; |
... | ... | @@ -64,7 +63,7 @@ |
64 | 63 | } |
65 | 64 | |
66 | 65 | /* use back the intended clock and find low range */ |
67 | - cadence_spi_write_speed(bus, plat->max_hz); | |
66 | + cadence_spi_write_speed(bus, hz); | |
68 | 67 | for (i = 0; i < CQSPI_READ_CAPTURE_MAX_DELAY; i++) { |
69 | 68 | /* Disable QSPI */ |
70 | 69 | cadence_qspi_apb_controller_disable(base); |
... | ... | @@ -111,7 +110,7 @@ |
111 | 110 | (range_hi + range_lo) / 2, range_lo, range_hi); |
112 | 111 | |
113 | 112 | /* just to ensure we do once only when speed or chip select change */ |
114 | - priv->qspi_calibrated_hz = plat->max_hz; | |
113 | + priv->qspi_calibrated_hz = hz; | |
115 | 114 | priv->qspi_calibrated_cs = spi_chip_select(bus); |
116 | 115 | |
117 | 116 | return 0; |
118 | 117 | |
119 | 118 | |
120 | 119 | |
... | ... | @@ -123,17 +122,25 @@ |
123 | 122 | struct cadence_spi_priv *priv = dev_get_priv(bus); |
124 | 123 | int err; |
125 | 124 | |
125 | + if (hz > plat->max_hz) | |
126 | + hz = plat->max_hz; | |
127 | + | |
126 | 128 | /* Disable QSPI */ |
127 | 129 | cadence_qspi_apb_controller_disable(priv->regbase); |
128 | 130 | |
129 | - cadence_spi_write_speed(bus, hz); | |
130 | - | |
131 | - /* Calibration required for different SCLK speed or chip select */ | |
132 | - if (priv->qspi_calibrated_hz != plat->max_hz || | |
131 | + /* | |
132 | + * Calibration required for different current SCLK speed, requested | |
133 | + * SCLK speed or chip select | |
134 | + */ | |
135 | + if (priv->previous_hz != hz || | |
136 | + priv->qspi_calibrated_hz != hz || | |
133 | 137 | priv->qspi_calibrated_cs != spi_chip_select(bus)) { |
134 | - err = spi_calibration(bus); | |
138 | + err = spi_calibration(bus, hz); | |
135 | 139 | if (err) |
136 | 140 | return err; |
141 | + | |
142 | + /* prevent calibration run when same as previous request */ | |
143 | + priv->previous_hz = hz; | |
137 | 144 | } |
138 | 145 | |
139 | 146 | /* Enable QSPI */ |
140 | 147 | |
... | ... | @@ -291,16 +298,16 @@ |
291 | 298 | plat->regbase = (void *)data[0]; |
292 | 299 | plat->ahbbase = (void *)data[2]; |
293 | 300 | |
294 | - /* Use 500KHz as a suitable default */ | |
295 | - plat->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", | |
296 | - 500000); | |
297 | - | |
298 | 301 | /* All other paramters are embedded in the child node */ |
299 | 302 | subnode = fdt_first_subnode(blob, node); |
300 | 303 | if (subnode < 0) { |
301 | 304 | printf("Error: subnode with SPI flash config missing!\n"); |
302 | 305 | return -ENODEV; |
303 | 306 | } |
307 | + | |
308 | + /* Use 500 KHz as a suitable default */ | |
309 | + plat->max_hz = fdtdec_get_uint(blob, subnode, "spi-max-frequency", | |
310 | + 500000); | |
304 | 311 | |
305 | 312 | /* Read other parameters from DT */ |
306 | 313 | plat->page_size = fdtdec_get_int(blob, subnode, "page-size", 256); |
drivers/spi/cadence_qspi.h
include/fdtdec.h
... | ... | @@ -490,6 +490,19 @@ |
490 | 490 | s32 default_val); |
491 | 491 | |
492 | 492 | /** |
493 | + * Unsigned version of fdtdec_get_int. The property must have at least | |
494 | + * 4 bytes of data. The value of the first cell is returned. | |
495 | + * | |
496 | + * @param blob FDT blob | |
497 | + * @param node node to examine | |
498 | + * @param prop_name name of property to find | |
499 | + * @param default_val default value to return if the property is not found | |
500 | + * @return unsigned integer value, if found, or default_val if not | |
501 | + */ | |
502 | +unsigned int fdtdec_get_uint(const void *blob, int node, const char *prop_name, | |
503 | + unsigned int default_val); | |
504 | + | |
505 | +/** | |
493 | 506 | * Get a variable-sized number from a property |
494 | 507 | * |
495 | 508 | * This reads a number from one or more cells. |
lib/fdtdec_common.c
... | ... | @@ -36,4 +36,22 @@ |
36 | 36 | debug("(not found)\n"); |
37 | 37 | return default_val; |
38 | 38 | } |
39 | + | |
40 | +unsigned int fdtdec_get_uint(const void *blob, int node, const char *prop_name, | |
41 | + unsigned int default_val) | |
42 | +{ | |
43 | + const int *cell; | |
44 | + int len; | |
45 | + | |
46 | + debug("%s: %s: ", __func__, prop_name); | |
47 | + cell = fdt_getprop(blob, node, prop_name, &len); | |
48 | + if (cell && len >= sizeof(unsigned int)) { | |
49 | + unsigned int val = fdt32_to_cpu(cell[0]); | |
50 | + | |
51 | + debug("%#x (%d)\n", val, val); | |
52 | + return val; | |
53 | + } | |
54 | + debug("(not found)\n"); | |
55 | + return default_val; | |
56 | +} |