mvebu: backport mainline patches from kernel 3.11
[openwrt.git] / target / linux / mvebu / patches-3.10 / 0013-drivers-memory-Introduce-Marvell-EBU-Device-Bus-driv.patch
1 From 8b417cc752ac4158dcfcf02beafce80b90fd827d Mon Sep 17 00:00:00 2001
2 From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
3 Date: Tue, 23 Apr 2013 16:21:26 -0300
4 Subject: [PATCH 013/203] drivers: memory: Introduce Marvell EBU Device Bus
5  driver
6
7 Marvell EBU SoCs such as Armada 370/XP, Orion5x (88f5xxx) and
8 Discovery (mv78xx0) supports a Device Bus controller to access several
9 kinds of memories and I/O devices (NOR, NAND, SRAM, FPGA).
10
11 This commit adds a driver to handle this controller. So far only
12 Armada 370, Armada XP and Discovery SoCs are supported.
13
14 The driver must be registered through a device tree node;
15 as explained in the binding document.
16
17 For each child node in the device tree, this driver will:
18   * set timing parameters
19   * register a child device
20   * setup an address decoding window, using the mbus driver
21
22 Keep in mind the address decoding window setup is only a temporary hack.
23 This code will be removed from this devbus driver as soon as a proper device
24 tree binding for the mbus driver is added.
25
26 Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
27 Acked-by: Arnd Bergmann <arnd@arndb.de>
28 Acked-by: Jason Cooper <jason@lakedaemon.net>
29 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
30 ---
31  .../bindings/memory-controllers/mvebu-devbus.txt   | 156 ++++++++++
32  drivers/memory/Kconfig                             |  10 +
33  drivers/memory/Makefile                            |   1 +
34  drivers/memory/mvebu-devbus.c                      | 340 +++++++++++++++++++++
35  4 files changed, 507 insertions(+)
36  create mode 100644 Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt
37  create mode 100644 drivers/memory/mvebu-devbus.c
38
39 --- /dev/null
40 +++ b/Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt
41 @@ -0,0 +1,156 @@
42 +Device tree bindings for MVEBU Device Bus controllers
43 +
44 +The Device Bus controller available in some Marvell's SoC allows to control
45 +different types of standard memory and I/O devices such as NOR, NAND, and FPGA.
46 +The actual devices are instantiated from the child nodes of a Device Bus node.
47 +
48 +Required properties:
49 +
50 + - compatible:          Currently only Armada 370/XP SoC are supported,
51 +                        with this compatible string:
52 +
53 +                        marvell,mvebu-devbus
54 +
55 + - reg:                 A resource specifier for the register space.
56 +                        This is the base address of a chip select within
57 +                       the controller's register space.
58 +                        (see the example below)
59 +
60 + - #address-cells:      Must be set to 1
61 + - #size-cells:         Must be set to 1
62 + - ranges:              Must be set up to reflect the memory layout with four
63 +                        integer values for each chip-select line in use:
64 +                        0 <physical address of mapping> <size>
65 +
66 +Mandatory timing properties for child nodes:
67 +
68 +Read parameters:
69 +
70 + - devbus,turn-off-ps:  Defines the time during which the controller does not
71 +                        drive the AD bus after the completion of a device read.
72 +                        This prevents contentions on the Device Bus after a read
73 +                        cycle from a slow device.
74 +
75 + - devbus,bus-width:    Defines the bus width (e.g. <16>)
76 +
77 + - devbus,badr-skew-ps: Defines the time delay from from A[2:0] toggle,
78 +                        to read data sample. This parameter is useful for
79 +                        synchronous pipelined devices, where the address
80 +                        precedes the read data by one or two cycles.
81 +
82 + - devbus,acc-first-ps: Defines the time delay from the negation of
83 +                        ALE[0] to the cycle that the first read data is sampled
84 +                        by the controller.
85 +
86 + - devbus,acc-next-ps:  Defines the time delay between the cycle that
87 +                        samples data N and the cycle that samples data N+1
88 +                        (in burst accesses).
89 +
90 + - devbus,rd-setup-ps:  Defines the time delay between DEV_CSn assertion to
91 +                       DEV_OEn assertion. If set to 0 (default),
92 +                        DEV_OEn and DEV_CSn are asserted at the same cycle.
93 +                        This parameter has no affect on <acc-first-ps> parameter
94 +                        (no affect on first data sample). Set <rd-setup-ps>
95 +                        to a value smaller than <acc-first-ps>.
96 +
97 + - devbus,rd-hold-ps:   Defines the time between the last data sample to the
98 +                       de-assertion of DEV_CSn. If set to 0 (default),
99 +                       DEV_OEn and DEV_CSn are de-asserted at the same cycle
100 +                       (the cycle of the last data sample).
101 +                        This parameter has no affect on DEV_OEn de-assertion.
102 +                        DEV_OEn is always de-asserted the next cycle after
103 +                        last data sampled. Also this parameter has no
104 +                        affect on <turn-off-ps> parameter.
105 +                        Set <rd-hold-ps> to a value smaller than <turn-off-ps>.
106 +
107 +Write parameters:
108 +
109 + - devbus,ale-wr-ps:    Defines the time delay from the ALE[0] negation cycle
110 +                       to the DEV_WEn assertion.
111 +
112 + - devbus,wr-low-ps:    Defines the time during which DEV_WEn is active.
113 +                        A[2:0] and Data are kept valid as long as DEV_WEn
114 +                        is active. This parameter defines the setup time of
115 +                        address and data to DEV_WEn rise.
116 +
117 + - devbus,wr-high-ps:   Defines the time during which DEV_WEn is kept
118 +                        inactive (high) between data beats of a burst write.
119 +                        DEV_A[2:0] and Data are kept valid (do not toggle) for
120 +                        <wr-high-ps> - <tick> ps.
121 +                       This parameter defines the hold time of address and
122 +                       data after DEV_WEn rise.
123 +
124 + - devbus,sync-enable: Synchronous device enable.
125 +                       1: True
126 +                       0: False
127 +
128 +An example for an Armada XP GP board, with a 16 MiB NOR device as child
129 +is showed below. Note that the Device Bus driver is in charge of allocating
130 +the mbus address decoding window for each of its child devices.
131 +The window is created using the chip select specified in the child
132 +device node together with the base address and size specified in the ranges
133 +property. For instance, in the example below the allocated decoding window
134 +will start at base address 0xf0000000, with a size 0x1000000 (16 MiB)
135 +for chip select 0 (a.k.a DEV_BOOTCS).
136 +
137 +This address window handling is done in this mvebu-devbus only as a temporary
138 +solution. It will be removed when the support for mbus device tree binding is
139 +added.
140 +
141 +The reg property implicitly specifies the chip select as this:
142 +
143 +  0x10400: DEV_BOOTCS
144 +  0x10408: DEV_CS0
145 +  0x10410: DEV_CS1
146 +  0x10418: DEV_CS2
147 +  0x10420: DEV_CS3
148 +
149 +Example:
150 +
151 +       devbus-bootcs@d0010400 {
152 +               status = "okay";
153 +               ranges = <0 0xf0000000 0x1000000>; /* @addr 0xf0000000, size 0x1000000 */
154 +               #address-cells = <1>;
155 +               #size-cells = <1>;
156 +
157 +               /* Device Bus parameters are required */
158 +
159 +               /* Read parameters */
160 +               devbus,bus-width    = <8>;
161 +               devbus,turn-off-ps  = <60000>;
162 +               devbus,badr-skew-ps = <0>;
163 +               devbus,acc-first-ps = <124000>;
164 +               devbus,acc-next-ps  = <248000>;
165 +               devbus,rd-setup-ps  = <0>;
166 +               devbus,rd-hold-ps   = <0>;
167 +
168 +               /* Write parameters */
169 +               devbus,sync-enable = <0>;
170 +               devbus,wr-high-ps  = <60000>;
171 +               devbus,wr-low-ps   = <60000>;
172 +               devbus,ale-wr-ps   = <60000>;
173 +
174 +               flash@0 {
175 +                       compatible = "cfi-flash";
176 +
177 +                       /* 16 MiB */
178 +                       reg = <0 0x1000000>;
179 +                       bank-width = <2>;
180 +                       #address-cells = <1>;
181 +                       #size-cells = <1>;
182 +
183 +                       /*
184 +                        * We split the 16 MiB in two partitions,
185 +                        * just as an example.
186 +                        */
187 +                       partition@0 {
188 +                               label = "First";
189 +                               reg = <0 0x800000>;
190 +                       };
191 +
192 +                       partition@800000 {
193 +                               label = "Second";
194 +                               reg = <0x800000 0x800000>;
195 +                       };
196 +               };
197 +       };
198 --- a/drivers/memory/Kconfig
199 +++ b/drivers/memory/Kconfig
200 @@ -20,6 +20,16 @@ config TI_EMIF
201           parameters and other settings during frequency, voltage and
202           temperature changes
203  
204 +config MVEBU_DEVBUS
205 +       bool "Marvell EBU Device Bus Controller"
206 +       default y
207 +       depends on PLAT_ORION && OF
208 +       help
209 +         This driver is for the Device Bus controller available in some
210 +         Marvell EBU SoCs such as Discovery (mv78xx0), Orion (88f5xxx) and
211 +         Armada 370 and Armada XP. This controller allows to handle flash
212 +         devices such as NOR, NAND, SRAM, and FPGA.
213 +
214  config TEGRA20_MC
215         bool "Tegra20 Memory Controller(MC) driver"
216         default y
217 --- a/drivers/memory/Makefile
218 +++ b/drivers/memory/Makefile
219 @@ -6,5 +6,6 @@ ifeq ($(CONFIG_DDR),y)
220  obj-$(CONFIG_OF)               += of_memory.o
221  endif
222  obj-$(CONFIG_TI_EMIF)          += emif.o
223 +obj-$(CONFIG_MVEBU_DEVBUS)     += mvebu-devbus.o
224  obj-$(CONFIG_TEGRA20_MC)       += tegra20-mc.o
225  obj-$(CONFIG_TEGRA30_MC)       += tegra30-mc.o
226 --- /dev/null
227 +++ b/drivers/memory/mvebu-devbus.c
228 @@ -0,0 +1,340 @@
229 +/*
230 + * Marvell EBU SoC Device Bus Controller
231 + * (memory controller for NOR/NAND/SRAM/FPGA devices)
232 + *
233 + * Copyright (C) 2013 Marvell
234 + *
235 + * This program is free software: you can redistribute it and/or modify
236 + * it under the terms of the GNU General Public License as published by
237 + * the Free Software Foundation version 2 of the License.
238 + *
239 + * This program is distributed in the hope that it will be useful,
240 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
241 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
242 + * GNU General Public License for more details.
243 + *
244 + * You should have received a copy of the GNU General Public License
245 + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
246 + *
247 + */
248 +
249 +#include <linux/kernel.h>
250 +#include <linux/module.h>
251 +#include <linux/slab.h>
252 +#include <linux/err.h>
253 +#include <linux/io.h>
254 +#include <linux/clk.h>
255 +#include <linux/mbus.h>
256 +#include <linux/of_platform.h>
257 +#include <linux/of_address.h>
258 +#include <linux/platform_device.h>
259 +
260 +/* Register definitions */
261 +#define DEV_WIDTH_BIT          30
262 +#define BADR_SKEW_BIT          28
263 +#define RD_HOLD_BIT            23
264 +#define ACC_NEXT_BIT           17
265 +#define RD_SETUP_BIT           12
266 +#define ACC_FIRST_BIT          6
267 +
268 +#define SYNC_ENABLE_BIT                24
269 +#define WR_HIGH_BIT            16
270 +#define WR_LOW_BIT             8
271 +
272 +#define READ_PARAM_OFFSET      0x0
273 +#define WRITE_PARAM_OFFSET     0x4
274 +
275 +static const char * const devbus_wins[] = {
276 +       "devbus-boot",
277 +       "devbus-cs0",
278 +       "devbus-cs1",
279 +       "devbus-cs2",
280 +       "devbus-cs3",
281 +};
282 +
283 +struct devbus_read_params {
284 +       u32 bus_width;
285 +       u32 badr_skew;
286 +       u32 turn_off;
287 +       u32 acc_first;
288 +       u32 acc_next;
289 +       u32 rd_setup;
290 +       u32 rd_hold;
291 +};
292 +
293 +struct devbus_write_params {
294 +       u32 sync_enable;
295 +       u32 wr_high;
296 +       u32 wr_low;
297 +       u32 ale_wr;
298 +};
299 +
300 +struct devbus {
301 +       struct device *dev;
302 +       void __iomem *base;
303 +       unsigned long tick_ps;
304 +};
305 +
306 +static int get_timing_param_ps(struct devbus *devbus,
307 +                              struct device_node *node,
308 +                              const char *name,
309 +                              u32 *ticks)
310 +{
311 +       u32 time_ps;
312 +       int err;
313 +
314 +       err = of_property_read_u32(node, name, &time_ps);
315 +       if (err < 0) {
316 +               dev_err(devbus->dev, "%s has no '%s' property\n",
317 +                       name, node->full_name);
318 +               return err;
319 +       }
320 +
321 +       *ticks = (time_ps + devbus->tick_ps - 1) / devbus->tick_ps;
322 +
323 +       dev_dbg(devbus->dev, "%s: %u ps -> 0x%x\n",
324 +               name, time_ps, *ticks);
325 +       return 0;
326 +}
327 +
328 +static int devbus_set_timing_params(struct devbus *devbus,
329 +                                   struct device_node *node)
330 +{
331 +       struct devbus_read_params r;
332 +       struct devbus_write_params w;
333 +       u32 value;
334 +       int err;
335 +
336 +       dev_dbg(devbus->dev, "Setting timing parameter, tick is %lu ps\n",
337 +               devbus->tick_ps);
338 +
339 +       /* Get read timings */
340 +       err = of_property_read_u32(node, "devbus,bus-width", &r.bus_width);
341 +       if (err < 0) {
342 +               dev_err(devbus->dev,
343 +                       "%s has no 'devbus,bus-width' property\n",
344 +                       node->full_name);
345 +               return err;
346 +       }
347 +       /* Convert bit width to byte width */
348 +       r.bus_width /= 8;
349 +
350 +       err = get_timing_param_ps(devbus, node, "devbus,badr-skew-ps",
351 +                                &r.badr_skew);
352 +       if (err < 0)
353 +               return err;
354 +
355 +       err = get_timing_param_ps(devbus, node, "devbus,turn-off-ps",
356 +                                &r.turn_off);
357 +       if (err < 0)
358 +               return err;
359 +
360 +       err = get_timing_param_ps(devbus, node, "devbus,acc-first-ps",
361 +                                &r.acc_first);
362 +       if (err < 0)
363 +               return err;
364 +
365 +       err = get_timing_param_ps(devbus, node, "devbus,acc-next-ps",
366 +                                &r.acc_next);
367 +       if (err < 0)
368 +               return err;
369 +
370 +       err = get_timing_param_ps(devbus, node, "devbus,rd-setup-ps",
371 +                                &r.rd_setup);
372 +       if (err < 0)
373 +               return err;
374 +
375 +       err = get_timing_param_ps(devbus, node, "devbus,rd-hold-ps",
376 +                                &r.rd_hold);
377 +       if (err < 0)
378 +               return err;
379 +
380 +       /* Get write timings */
381 +       err = of_property_read_u32(node, "devbus,sync-enable",
382 +                                 &w.sync_enable);
383 +       if (err < 0) {
384 +               dev_err(devbus->dev,
385 +                       "%s has no 'devbus,sync-enable' property\n",
386 +                       node->full_name);
387 +               return err;
388 +       }
389 +
390 +       err = get_timing_param_ps(devbus, node, "devbus,ale-wr-ps",
391 +                                &w.ale_wr);
392 +       if (err < 0)
393 +               return err;
394 +
395 +       err = get_timing_param_ps(devbus, node, "devbus,wr-low-ps",
396 +                                &w.wr_low);
397 +       if (err < 0)
398 +               return err;
399 +
400 +       err = get_timing_param_ps(devbus, node, "devbus,wr-high-ps",
401 +                                &w.wr_high);
402 +       if (err < 0)
403 +               return err;
404 +
405 +       /* Set read timings */
406 +       value = r.bus_width << DEV_WIDTH_BIT |
407 +               r.badr_skew << BADR_SKEW_BIT |
408 +               r.rd_hold   << RD_HOLD_BIT   |
409 +               r.acc_next  << ACC_NEXT_BIT  |
410 +               r.rd_setup  << RD_SETUP_BIT  |
411 +               r.acc_first << ACC_FIRST_BIT |
412 +               r.turn_off;
413 +
414 +       dev_dbg(devbus->dev, "read parameters register 0x%p = 0x%x\n",
415 +               devbus->base + READ_PARAM_OFFSET,
416 +               value);
417 +
418 +       writel(value, devbus->base + READ_PARAM_OFFSET);
419 +
420 +       /* Set write timings */
421 +       value = w.sync_enable  << SYNC_ENABLE_BIT |
422 +               w.wr_low       << WR_LOW_BIT      |
423 +               w.wr_high      << WR_HIGH_BIT     |
424 +               w.ale_wr;
425 +
426 +       dev_dbg(devbus->dev, "write parameters register: 0x%p = 0x%x\n",
427 +               devbus->base + WRITE_PARAM_OFFSET,
428 +               value);
429 +
430 +       writel(value, devbus->base + WRITE_PARAM_OFFSET);
431 +
432 +       return 0;
433 +}
434 +
435 +static int mvebu_devbus_probe(struct platform_device *pdev)
436 +{
437 +       struct device *dev = &pdev->dev;
438 +       struct device_node *node = pdev->dev.of_node;
439 +       struct device_node *parent;
440 +       struct devbus *devbus;
441 +       struct resource *res;
442 +       struct clk *clk;
443 +       unsigned long rate;
444 +       const __be32 *ranges;
445 +       int err, cs;
446 +       int addr_cells, p_addr_cells, size_cells;
447 +       int ranges_len, tuple_len;
448 +       u32 base, size;
449 +
450 +       devbus = devm_kzalloc(&pdev->dev, sizeof(struct devbus), GFP_KERNEL);
451 +       if (!devbus)
452 +               return -ENOMEM;
453 +
454 +       devbus->dev = dev;
455 +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
456 +       devbus->base = devm_ioremap_resource(&pdev->dev, res);
457 +       if (IS_ERR(devbus->base))
458 +               return PTR_ERR(devbus->base);
459 +
460 +       clk = devm_clk_get(&pdev->dev, NULL);
461 +       if (IS_ERR(clk))
462 +               return PTR_ERR(clk);
463 +       clk_prepare_enable(clk);
464 +
465 +       /*
466 +        * Obtain clock period in picoseconds,
467 +        * we need this in order to convert timing
468 +        * parameters from cycles to picoseconds.
469 +        */
470 +       rate = clk_get_rate(clk) / 1000;
471 +       devbus->tick_ps = 1000000000 / rate;
472 +
473 +       /* Read the device tree node and set the new timing parameters */
474 +       err = devbus_set_timing_params(devbus, node);
475 +       if (err < 0)
476 +               return err;
477 +
478 +       /*
479 +        * Allocate an address window for this device.
480 +        * If the device probing fails, then we won't be able to
481 +        * remove the allocated address decoding window.
482 +        *
483 +        * FIXME: This is only a temporary hack! We need to do this here
484 +        * because we still don't have device tree bindings for mbus.
485 +        * Once that support is added, we will declare these address windows
486 +        * statically in the device tree, and remove the window configuration
487 +        * from here.
488 +        */
489 +
490 +       /*
491 +        * Get the CS to choose the window string.
492 +        * This is a bit hacky, but it will be removed once the
493 +        * address windows are declared in the device tree.
494 +        */
495 +       cs = (((unsigned long)devbus->base) % 0x400) / 8;
496 +
497 +       /*
498 +        * Parse 'ranges' property to obtain a (base,size) window tuple.
499 +        * This will be removed once the address windows
500 +        * are declared in the device tree.
501 +        */
502 +       parent = of_get_parent(node);
503 +       if (!parent)
504 +               return -EINVAL;
505 +
506 +       p_addr_cells = of_n_addr_cells(parent);
507 +       of_node_put(parent);
508 +
509 +       addr_cells = of_n_addr_cells(node);
510 +       size_cells = of_n_size_cells(node);
511 +       tuple_len = (p_addr_cells + addr_cells + size_cells) * sizeof(__be32);
512 +
513 +       ranges = of_get_property(node, "ranges", &ranges_len);
514 +       if (ranges == NULL || ranges_len != tuple_len)
515 +               return -EINVAL;
516 +
517 +       base = of_translate_address(node, ranges + addr_cells);
518 +       if (base == OF_BAD_ADDR)
519 +               return -EINVAL;
520 +       size = of_read_number(ranges + addr_cells + p_addr_cells, size_cells);
521 +
522 +       /*
523 +        * Create an mbus address windows.
524 +        * FIXME: Remove this, together with the above code, once the
525 +        * address windows are declared in the device tree.
526 +        */
527 +       err = mvebu_mbus_add_window(devbus_wins[cs], base, size);
528 +       if (err < 0)
529 +               return err;
530 +
531 +       /*
532 +        * We need to create a child device explicitly from here to
533 +        * guarantee that the child will be probed after the timing
534 +        * parameters for the bus are written.
535 +        */
536 +       err = of_platform_populate(node, NULL, NULL, dev);
537 +       if (err < 0) {
538 +               mvebu_mbus_del_window(base, size);
539 +               return err;
540 +       }
541 +
542 +       return 0;
543 +}
544 +
545 +static const struct of_device_id mvebu_devbus_of_match[] = {
546 +       { .compatible = "marvell,mvebu-devbus" },
547 +       {},
548 +};
549 +MODULE_DEVICE_TABLE(of, mvebu_devbus_of_match);
550 +
551 +static struct platform_driver mvebu_devbus_driver = {
552 +       .probe          = mvebu_devbus_probe,
553 +       .driver         = {
554 +               .name   = "mvebu-devbus",
555 +               .owner  = THIS_MODULE,
556 +               .of_match_table = mvebu_devbus_of_match,
557 +       },
558 +};
559 +
560 +static int __init mvebu_devbus_init(void)
561 +{
562 +       return platform_driver_register(&mvebu_devbus_driver);
563 +}
564 +module_init(mvebu_devbus_init);
565 +
566 +MODULE_LICENSE("GPL v2");
567 +MODULE_AUTHOR("Ezequiel Garcia <ezequiel.garcia@free-electrons.com>");
568 +MODULE_DESCRIPTION("Marvell EBU SoC Device Bus controller");