diff options
-rw-r--r-- | Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt | 25 | ||||
-rw-r--r-- | drivers/memory/mvebu-devbus.c | 107 |
2 files changed, 106 insertions, 26 deletions
diff --git a/Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt b/Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt index 653c90c34a71..55adde214627 100644 --- a/Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt +++ b/Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt | |||
@@ -6,10 +6,11 @@ The actual devices are instantiated from the child nodes of a Device Bus node. | |||
6 | 6 | ||
7 | Required properties: | 7 | Required properties: |
8 | 8 | ||
9 | - compatible: Currently only Armada 370/XP SoC are supported, | 9 | - compatible: Armada 370/XP SoC are supported using the |
10 | with this compatible string: | 10 | "marvell,mvebu-devbus" compatible string. |
11 | 11 | ||
12 | marvell,mvebu-devbus | 12 | Orion5x SoC are supported using the |
13 | "marvell,orion-devbus" compatible string. | ||
13 | 14 | ||
14 | - reg: A resource specifier for the register space. | 15 | - reg: A resource specifier for the register space. |
15 | This is the base address of a chip select within | 16 | This is the base address of a chip select within |
@@ -22,7 +23,7 @@ Required properties: | |||
22 | integer values for each chip-select line in use: | 23 | integer values for each chip-select line in use: |
23 | 0 <physical address of mapping> <size> | 24 | 0 <physical address of mapping> <size> |
24 | 25 | ||
25 | Mandatory timing properties for child nodes: | 26 | Timing properties for child nodes: |
26 | 27 | ||
27 | Read parameters: | 28 | Read parameters: |
28 | 29 | ||
@@ -30,21 +31,26 @@ Read parameters: | |||
30 | drive the AD bus after the completion of a device read. | 31 | drive the AD bus after the completion of a device read. |
31 | This prevents contentions on the Device Bus after a read | 32 | This prevents contentions on the Device Bus after a read |
32 | cycle from a slow device. | 33 | cycle from a slow device. |
34 | Mandatory. | ||
33 | 35 | ||
34 | - devbus,bus-width: Defines the bus width (e.g. <16>) | 36 | - devbus,bus-width: Defines the bus width, in bits (e.g. <16>). |
37 | Mandatory. | ||
35 | 38 | ||
36 | - devbus,badr-skew-ps: Defines the time delay from from A[2:0] toggle, | 39 | - devbus,badr-skew-ps: Defines the time delay from from A[2:0] toggle, |
37 | to read data sample. This parameter is useful for | 40 | to read data sample. This parameter is useful for |
38 | synchronous pipelined devices, where the address | 41 | synchronous pipelined devices, where the address |
39 | precedes the read data by one or two cycles. | 42 | precedes the read data by one or two cycles. |
43 | Mandatory. | ||
40 | 44 | ||
41 | - devbus,acc-first-ps: Defines the time delay from the negation of | 45 | - devbus,acc-first-ps: Defines the time delay from the negation of |
42 | ALE[0] to the cycle that the first read data is sampled | 46 | ALE[0] to the cycle that the first read data is sampled |
43 | by the controller. | 47 | by the controller. |
48 | Mandatory. | ||
44 | 49 | ||
45 | - devbus,acc-next-ps: Defines the time delay between the cycle that | 50 | - devbus,acc-next-ps: Defines the time delay between the cycle that |
46 | samples data N and the cycle that samples data N+1 | 51 | samples data N and the cycle that samples data N+1 |
47 | (in burst accesses). | 52 | (in burst accesses). |
53 | Mandatory. | ||
48 | 54 | ||
49 | - devbus,rd-setup-ps: Defines the time delay between DEV_CSn assertion to | 55 | - devbus,rd-setup-ps: Defines the time delay between DEV_CSn assertion to |
50 | DEV_OEn assertion. If set to 0 (default), | 56 | DEV_OEn assertion. If set to 0 (default), |
@@ -52,6 +58,8 @@ Read parameters: | |||
52 | This parameter has no affect on <acc-first-ps> parameter | 58 | This parameter has no affect on <acc-first-ps> parameter |
53 | (no affect on first data sample). Set <rd-setup-ps> | 59 | (no affect on first data sample). Set <rd-setup-ps> |
54 | to a value smaller than <acc-first-ps>. | 60 | to a value smaller than <acc-first-ps>. |
61 | Mandatory for "marvell,mvebu-devbus" | ||
62 | compatible string, ignored otherwise. | ||
55 | 63 | ||
56 | - devbus,rd-hold-ps: Defines the time between the last data sample to the | 64 | - devbus,rd-hold-ps: Defines the time between the last data sample to the |
57 | de-assertion of DEV_CSn. If set to 0 (default), | 65 | de-assertion of DEV_CSn. If set to 0 (default), |
@@ -62,16 +70,20 @@ Read parameters: | |||
62 | last data sampled. Also this parameter has no | 70 | last data sampled. Also this parameter has no |
63 | affect on <turn-off-ps> parameter. | 71 | affect on <turn-off-ps> parameter. |
64 | Set <rd-hold-ps> to a value smaller than <turn-off-ps>. | 72 | Set <rd-hold-ps> to a value smaller than <turn-off-ps>. |
73 | Mandatory for "marvell,mvebu-devbus" | ||
74 | compatible string, ignored otherwise. | ||
65 | 75 | ||
66 | Write parameters: | 76 | Write parameters: |
67 | 77 | ||
68 | - devbus,ale-wr-ps: Defines the time delay from the ALE[0] negation cycle | 78 | - devbus,ale-wr-ps: Defines the time delay from the ALE[0] negation cycle |
69 | to the DEV_WEn assertion. | 79 | to the DEV_WEn assertion. |
80 | Mandatory. | ||
70 | 81 | ||
71 | - devbus,wr-low-ps: Defines the time during which DEV_WEn is active. | 82 | - devbus,wr-low-ps: Defines the time during which DEV_WEn is active. |
72 | A[2:0] and Data are kept valid as long as DEV_WEn | 83 | A[2:0] and Data are kept valid as long as DEV_WEn |
73 | is active. This parameter defines the setup time of | 84 | is active. This parameter defines the setup time of |
74 | address and data to DEV_WEn rise. | 85 | address and data to DEV_WEn rise. |
86 | Mandatory. | ||
75 | 87 | ||
76 | - devbus,wr-high-ps: Defines the time during which DEV_WEn is kept | 88 | - devbus,wr-high-ps: Defines the time during which DEV_WEn is kept |
77 | inactive (high) between data beats of a burst write. | 89 | inactive (high) between data beats of a burst write. |
@@ -79,10 +91,13 @@ Write parameters: | |||
79 | <wr-high-ps> - <tick> ps. | 91 | <wr-high-ps> - <tick> ps. |
80 | This parameter defines the hold time of address and | 92 | This parameter defines the hold time of address and |
81 | data after DEV_WEn rise. | 93 | data after DEV_WEn rise. |
94 | Mandatory. | ||
82 | 95 | ||
83 | - devbus,sync-enable: Synchronous device enable. | 96 | - devbus,sync-enable: Synchronous device enable. |
84 | 1: True | 97 | 1: True |
85 | 0: False | 98 | 0: False |
99 | Mandatory for "marvell,mvebu-devbus" compatible | ||
100 | string, ignored otherwise. | ||
86 | 101 | ||
87 | An example for an Armada XP GP board, with a 16 MiB NOR device as child | 102 | An example for an Armada XP GP board, with a 16 MiB NOR device as child |
88 | is showed below. Note that the Device Bus driver is in charge of allocating | 103 | is showed below. Note that the Device Bus driver is in charge of allocating |
diff --git a/drivers/memory/mvebu-devbus.c b/drivers/memory/mvebu-devbus.c index 5dc9c6360943..c8f3dad8a825 100644 --- a/drivers/memory/mvebu-devbus.c +++ b/drivers/memory/mvebu-devbus.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Marvell EBU SoC Device Bus Controller | 2 | * Marvell EBU SoC Device Bus Controller |
3 | * (memory controller for NOR/NAND/SRAM/FPGA devices) | 3 | * (memory controller for NOR/NAND/SRAM/FPGA devices) |
4 | * | 4 | * |
5 | * Copyright (C) 2013 Marvell | 5 | * Copyright (C) 2013-2014 Marvell |
6 | * | 6 | * |
7 | * This program is free software: you can redistribute it and/or modify | 7 | * This program is free software: you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
@@ -44,6 +44,34 @@ | |||
44 | #define ARMADA_READ_PARAM_OFFSET 0x0 | 44 | #define ARMADA_READ_PARAM_OFFSET 0x0 |
45 | #define ARMADA_WRITE_PARAM_OFFSET 0x4 | 45 | #define ARMADA_WRITE_PARAM_OFFSET 0x4 |
46 | 46 | ||
47 | #define ORION_RESERVED (0x2 << 30) | ||
48 | #define ORION_BADR_SKEW_SHIFT 28 | ||
49 | #define ORION_WR_HIGH_EXT_BIT BIT(27) | ||
50 | #define ORION_WR_HIGH_EXT_MASK 0x8 | ||
51 | #define ORION_WR_LOW_EXT_BIT BIT(26) | ||
52 | #define ORION_WR_LOW_EXT_MASK 0x8 | ||
53 | #define ORION_ALE_WR_EXT_BIT BIT(25) | ||
54 | #define ORION_ALE_WR_EXT_MASK 0x8 | ||
55 | #define ORION_ACC_NEXT_EXT_BIT BIT(24) | ||
56 | #define ORION_ACC_NEXT_EXT_MASK 0x10 | ||
57 | #define ORION_ACC_FIRST_EXT_BIT BIT(23) | ||
58 | #define ORION_ACC_FIRST_EXT_MASK 0x10 | ||
59 | #define ORION_TURN_OFF_EXT_BIT BIT(22) | ||
60 | #define ORION_TURN_OFF_EXT_MASK 0x8 | ||
61 | #define ORION_DEV_WIDTH_SHIFT 20 | ||
62 | #define ORION_WR_HIGH_SHIFT 17 | ||
63 | #define ORION_WR_HIGH_MASK 0x7 | ||
64 | #define ORION_WR_LOW_SHIFT 14 | ||
65 | #define ORION_WR_LOW_MASK 0x7 | ||
66 | #define ORION_ALE_WR_SHIFT 11 | ||
67 | #define ORION_ALE_WR_MASK 0x7 | ||
68 | #define ORION_ACC_NEXT_SHIFT 7 | ||
69 | #define ORION_ACC_NEXT_MASK 0xF | ||
70 | #define ORION_ACC_FIRST_SHIFT 3 | ||
71 | #define ORION_ACC_FIRST_MASK 0xF | ||
72 | #define ORION_TURN_OFF_SHIFT 0 | ||
73 | #define ORION_TURN_OFF_MASK 0x7 | ||
74 | |||
47 | struct devbus_read_params { | 75 | struct devbus_read_params { |
48 | u32 bus_width; | 76 | u32 bus_width; |
49 | u32 badr_skew; | 77 | u32 badr_skew; |
@@ -96,7 +124,6 @@ static int devbus_get_timing_params(struct devbus *devbus, | |||
96 | { | 124 | { |
97 | int err; | 125 | int err; |
98 | 126 | ||
99 | /* Get read timings */ | ||
100 | err = of_property_read_u32(node, "devbus,bus-width", &r->bus_width); | 127 | err = of_property_read_u32(node, "devbus,bus-width", &r->bus_width); |
101 | if (err < 0) { | 128 | if (err < 0) { |
102 | dev_err(devbus->dev, | 129 | dev_err(devbus->dev, |
@@ -138,24 +165,25 @@ static int devbus_get_timing_params(struct devbus *devbus, | |||
138 | if (err < 0) | 165 | if (err < 0) |
139 | return err; | 166 | return err; |
140 | 167 | ||
141 | err = get_timing_param_ps(devbus, node, "devbus,rd-setup-ps", | 168 | if (of_device_is_compatible(devbus->dev->of_node, "marvell,mvebu-devbus")) { |
142 | &r->rd_setup); | 169 | err = get_timing_param_ps(devbus, node, "devbus,rd-setup-ps", |
143 | if (err < 0) | 170 | &r->rd_setup); |
144 | return err; | 171 | if (err < 0) |
145 | 172 | return err; | |
146 | err = get_timing_param_ps(devbus, node, "devbus,rd-hold-ps", | 173 | |
147 | &r->rd_hold); | 174 | err = get_timing_param_ps(devbus, node, "devbus,rd-hold-ps", |
148 | if (err < 0) | 175 | &r->rd_hold); |
149 | return err; | 176 | if (err < 0) |
150 | 177 | return err; | |
151 | /* Get write timings */ | 178 | |
152 | err = of_property_read_u32(node, "devbus,sync-enable", | 179 | err = of_property_read_u32(node, "devbus,sync-enable", |
153 | &w->sync_enable); | 180 | &w->sync_enable); |
154 | if (err < 0) { | 181 | if (err < 0) { |
155 | dev_err(devbus->dev, | 182 | dev_err(devbus->dev, |
156 | "%s has no 'devbus,sync-enable' property\n", | 183 | "%s has no 'devbus,sync-enable' property\n", |
157 | node->full_name); | 184 | node->full_name); |
158 | return err; | 185 | return err; |
186 | } | ||
159 | } | 187 | } |
160 | 188 | ||
161 | err = get_timing_param_ps(devbus, node, "devbus,ale-wr-ps", | 189 | err = get_timing_param_ps(devbus, node, "devbus,ale-wr-ps", |
@@ -176,6 +204,39 @@ static int devbus_get_timing_params(struct devbus *devbus, | |||
176 | return 0; | 204 | return 0; |
177 | } | 205 | } |
178 | 206 | ||
207 | static void devbus_orion_set_timing_params(struct devbus *devbus, | ||
208 | struct device_node *node, | ||
209 | struct devbus_read_params *r, | ||
210 | struct devbus_write_params *w) | ||
211 | { | ||
212 | u32 value; | ||
213 | |||
214 | /* | ||
215 | * The hardware designers found it would be a good idea to | ||
216 | * split most of the values in the register into two fields: | ||
217 | * one containing all the low-order bits, and another one | ||
218 | * containing just the high-order bit. For all of those | ||
219 | * fields, we have to split the value into these two parts. | ||
220 | */ | ||
221 | value = (r->turn_off & ORION_TURN_OFF_MASK) << ORION_TURN_OFF_SHIFT | | ||
222 | (r->acc_first & ORION_ACC_FIRST_MASK) << ORION_ACC_FIRST_SHIFT | | ||
223 | (r->acc_next & ORION_ACC_NEXT_MASK) << ORION_ACC_NEXT_SHIFT | | ||
224 | (w->ale_wr & ORION_ALE_WR_MASK) << ORION_ALE_WR_SHIFT | | ||
225 | (w->wr_low & ORION_WR_LOW_MASK) << ORION_WR_LOW_SHIFT | | ||
226 | (w->wr_high & ORION_WR_HIGH_MASK) << ORION_WR_HIGH_SHIFT | | ||
227 | r->bus_width << ORION_DEV_WIDTH_SHIFT | | ||
228 | ((r->turn_off & ORION_TURN_OFF_EXT_MASK) ? ORION_TURN_OFF_EXT_BIT : 0) | | ||
229 | ((r->acc_first & ORION_ACC_FIRST_EXT_MASK) ? ORION_ACC_FIRST_EXT_BIT : 0) | | ||
230 | ((r->acc_next & ORION_ACC_NEXT_EXT_MASK) ? ORION_ACC_NEXT_EXT_BIT : 0) | | ||
231 | ((w->ale_wr & ORION_ALE_WR_EXT_MASK) ? ORION_ALE_WR_EXT_BIT : 0) | | ||
232 | ((w->wr_low & ORION_WR_LOW_EXT_MASK) ? ORION_WR_LOW_EXT_BIT : 0) | | ||
233 | ((w->wr_high & ORION_WR_HIGH_EXT_MASK) ? ORION_WR_HIGH_EXT_BIT : 0) | | ||
234 | (r->badr_skew << ORION_BADR_SKEW_SHIFT) | | ||
235 | ORION_RESERVED; | ||
236 | |||
237 | writel(value, devbus->base); | ||
238 | } | ||
239 | |||
179 | static void devbus_armada_set_timing_params(struct devbus *devbus, | 240 | static void devbus_armada_set_timing_params(struct devbus *devbus, |
180 | struct device_node *node, | 241 | struct device_node *node, |
181 | struct devbus_read_params *r, | 242 | struct devbus_read_params *r, |
@@ -255,7 +316,10 @@ static int mvebu_devbus_probe(struct platform_device *pdev) | |||
255 | return err; | 316 | return err; |
256 | 317 | ||
257 | /* Set the new timing parameters */ | 318 | /* Set the new timing parameters */ |
258 | devbus_armada_set_timing_params(devbus, node, &r, &w); | 319 | if (of_device_is_compatible(node, "marvell,orion-devbus")) |
320 | devbus_orion_set_timing_params(devbus, node, &r, &w); | ||
321 | else | ||
322 | devbus_armada_set_timing_params(devbus, node, &r, &w); | ||
259 | 323 | ||
260 | /* | 324 | /* |
261 | * We need to create a child device explicitly from here to | 325 | * We need to create a child device explicitly from here to |
@@ -271,6 +335,7 @@ static int mvebu_devbus_probe(struct platform_device *pdev) | |||
271 | 335 | ||
272 | static const struct of_device_id mvebu_devbus_of_match[] = { | 336 | static const struct of_device_id mvebu_devbus_of_match[] = { |
273 | { .compatible = "marvell,mvebu-devbus" }, | 337 | { .compatible = "marvell,mvebu-devbus" }, |
338 | { .compatible = "marvell,orion-devbus" }, | ||
274 | {}, | 339 | {}, |
275 | }; | 340 | }; |
276 | MODULE_DEVICE_TABLE(of, mvebu_devbus_of_match); | 341 | MODULE_DEVICE_TABLE(of, mvebu_devbus_of_match); |