diff options
author | Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | 2014-04-22 17:26:11 -0400 |
---|---|---|
committer | Jason Cooper <jason@lakedaemon.net> | 2014-04-29 09:16:53 -0400 |
commit | 30bd30b603462ae64a0b261a704a8b2b070c6688 (patch) | |
tree | 863cef40485f2197fe2a9fd8df67dfc32652fade /drivers/memory | |
parent | 8a33692ee8f10f1ceb38001101a4f55de921d726 (diff) |
memory: mvebu-devbus: split functions
The mvebu-devbus driver currently only supports the Armada 370/XP
family, but it can also cover the Orion5x family. However, the Orion5x
family has a different organization of the registers.
Therefore, in preparation to the introduction of Orion5x support, we
separate into two functions the code that 1/ retrieves the timing
parameters from the Device Tree and 2/ applies those timings
parameters into the hardware registers.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Acked-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Link: https://lkml.kernel.org/r/1398202002-28530-8-git-send-email-thomas.petazzoni@free-electrons.com
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
Diffstat (limited to 'drivers/memory')
-rw-r--r-- | drivers/memory/mvebu-devbus.c | 90 |
1 files changed, 51 insertions, 39 deletions
diff --git a/drivers/memory/mvebu-devbus.c b/drivers/memory/mvebu-devbus.c index 0f196b36cc3e..5dc9c6360943 100644 --- a/drivers/memory/mvebu-devbus.c +++ b/drivers/memory/mvebu-devbus.c | |||
@@ -89,19 +89,15 @@ static int get_timing_param_ps(struct devbus *devbus, | |||
89 | return 0; | 89 | return 0; |
90 | } | 90 | } |
91 | 91 | ||
92 | static int devbus_set_timing_params(struct devbus *devbus, | 92 | static int devbus_get_timing_params(struct devbus *devbus, |
93 | struct device_node *node) | 93 | struct device_node *node, |
94 | struct devbus_read_params *r, | ||
95 | struct devbus_write_params *w) | ||
94 | { | 96 | { |
95 | struct devbus_read_params r; | ||
96 | struct devbus_write_params w; | ||
97 | u32 value; | ||
98 | int err; | 97 | int err; |
99 | 98 | ||
100 | dev_dbg(devbus->dev, "Setting timing parameter, tick is %lu ps\n", | ||
101 | devbus->tick_ps); | ||
102 | |||
103 | /* Get read timings */ | 99 | /* Get read timings */ |
104 | err = of_property_read_u32(node, "devbus,bus-width", &r.bus_width); | 100 | err = of_property_read_u32(node, "devbus,bus-width", &r->bus_width); |
105 | if (err < 0) { | 101 | if (err < 0) { |
106 | dev_err(devbus->dev, | 102 | dev_err(devbus->dev, |
107 | "%s has no 'devbus,bus-width' property\n", | 103 | "%s has no 'devbus,bus-width' property\n", |
@@ -113,48 +109,48 @@ static int devbus_set_timing_params(struct devbus *devbus, | |||
113 | * The bus width is encoded into the register as 0 for 8 bits, | 109 | * The bus width is encoded into the register as 0 for 8 bits, |
114 | * and 1 for 16 bits, so we do the necessary conversion here. | 110 | * and 1 for 16 bits, so we do the necessary conversion here. |
115 | */ | 111 | */ |
116 | if (r.bus_width == 8) | 112 | if (r->bus_width == 8) |
117 | r.bus_width = 0; | 113 | r->bus_width = 0; |
118 | else if (r.bus_width == 16) | 114 | else if (r->bus_width == 16) |
119 | r.bus_width = 1; | 115 | r->bus_width = 1; |
120 | else { | 116 | else { |
121 | dev_err(devbus->dev, "invalid bus width %d\n", r.bus_width); | 117 | dev_err(devbus->dev, "invalid bus width %d\n", r->bus_width); |
122 | return -EINVAL; | 118 | return -EINVAL; |
123 | } | 119 | } |
124 | 120 | ||
125 | err = get_timing_param_ps(devbus, node, "devbus,badr-skew-ps", | 121 | err = get_timing_param_ps(devbus, node, "devbus,badr-skew-ps", |
126 | &r.badr_skew); | 122 | &r->badr_skew); |
127 | if (err < 0) | 123 | if (err < 0) |
128 | return err; | 124 | return err; |
129 | 125 | ||
130 | err = get_timing_param_ps(devbus, node, "devbus,turn-off-ps", | 126 | err = get_timing_param_ps(devbus, node, "devbus,turn-off-ps", |
131 | &r.turn_off); | 127 | &r->turn_off); |
132 | if (err < 0) | 128 | if (err < 0) |
133 | return err; | 129 | return err; |
134 | 130 | ||
135 | err = get_timing_param_ps(devbus, node, "devbus,acc-first-ps", | 131 | err = get_timing_param_ps(devbus, node, "devbus,acc-first-ps", |
136 | &r.acc_first); | 132 | &r->acc_first); |
137 | if (err < 0) | 133 | if (err < 0) |
138 | return err; | 134 | return err; |
139 | 135 | ||
140 | err = get_timing_param_ps(devbus, node, "devbus,acc-next-ps", | 136 | err = get_timing_param_ps(devbus, node, "devbus,acc-next-ps", |
141 | &r.acc_next); | 137 | &r->acc_next); |
142 | if (err < 0) | 138 | if (err < 0) |
143 | return err; | 139 | return err; |
144 | 140 | ||
145 | err = get_timing_param_ps(devbus, node, "devbus,rd-setup-ps", | 141 | err = get_timing_param_ps(devbus, node, "devbus,rd-setup-ps", |
146 | &r.rd_setup); | 142 | &r->rd_setup); |
147 | if (err < 0) | 143 | if (err < 0) |
148 | return err; | 144 | return err; |
149 | 145 | ||
150 | err = get_timing_param_ps(devbus, node, "devbus,rd-hold-ps", | 146 | err = get_timing_param_ps(devbus, node, "devbus,rd-hold-ps", |
151 | &r.rd_hold); | 147 | &r->rd_hold); |
152 | if (err < 0) | 148 | if (err < 0) |
153 | return err; | 149 | return err; |
154 | 150 | ||
155 | /* Get write timings */ | 151 | /* Get write timings */ |
156 | err = of_property_read_u32(node, "devbus,sync-enable", | 152 | err = of_property_read_u32(node, "devbus,sync-enable", |
157 | &w.sync_enable); | 153 | &w->sync_enable); |
158 | if (err < 0) { | 154 | if (err < 0) { |
159 | dev_err(devbus->dev, | 155 | dev_err(devbus->dev, |
160 | "%s has no 'devbus,sync-enable' property\n", | 156 | "%s has no 'devbus,sync-enable' property\n", |
@@ -163,28 +159,38 @@ static int devbus_set_timing_params(struct devbus *devbus, | |||
163 | } | 159 | } |
164 | 160 | ||
165 | err = get_timing_param_ps(devbus, node, "devbus,ale-wr-ps", | 161 | err = get_timing_param_ps(devbus, node, "devbus,ale-wr-ps", |
166 | &w.ale_wr); | 162 | &w->ale_wr); |
167 | if (err < 0) | 163 | if (err < 0) |
168 | return err; | 164 | return err; |
169 | 165 | ||
170 | err = get_timing_param_ps(devbus, node, "devbus,wr-low-ps", | 166 | err = get_timing_param_ps(devbus, node, "devbus,wr-low-ps", |
171 | &w.wr_low); | 167 | &w->wr_low); |
172 | if (err < 0) | 168 | if (err < 0) |
173 | return err; | 169 | return err; |
174 | 170 | ||
175 | err = get_timing_param_ps(devbus, node, "devbus,wr-high-ps", | 171 | err = get_timing_param_ps(devbus, node, "devbus,wr-high-ps", |
176 | &w.wr_high); | 172 | &w->wr_high); |
177 | if (err < 0) | 173 | if (err < 0) |
178 | return err; | 174 | return err; |
179 | 175 | ||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | static void devbus_armada_set_timing_params(struct devbus *devbus, | ||
180 | struct device_node *node, | ||
181 | struct devbus_read_params *r, | ||
182 | struct devbus_write_params *w) | ||
183 | { | ||
184 | u32 value; | ||
185 | |||
180 | /* Set read timings */ | 186 | /* Set read timings */ |
181 | value = r.bus_width << ARMADA_DEV_WIDTH_SHIFT | | 187 | value = r->bus_width << ARMADA_DEV_WIDTH_SHIFT | |
182 | r.badr_skew << ARMADA_BADR_SKEW_SHIFT | | 188 | r->badr_skew << ARMADA_BADR_SKEW_SHIFT | |
183 | r.rd_hold << ARMADA_RD_HOLD_SHIFT | | 189 | r->rd_hold << ARMADA_RD_HOLD_SHIFT | |
184 | r.acc_next << ARMADA_ACC_NEXT_SHIFT | | 190 | r->acc_next << ARMADA_ACC_NEXT_SHIFT | |
185 | r.rd_setup << ARMADA_RD_SETUP_SHIFT | | 191 | r->rd_setup << ARMADA_RD_SETUP_SHIFT | |
186 | r.acc_first << ARMADA_ACC_FIRST_SHIFT | | 192 | r->acc_first << ARMADA_ACC_FIRST_SHIFT | |
187 | r.turn_off; | 193 | r->turn_off; |
188 | 194 | ||
189 | dev_dbg(devbus->dev, "read parameters register 0x%p = 0x%x\n", | 195 | dev_dbg(devbus->dev, "read parameters register 0x%p = 0x%x\n", |
190 | devbus->base + ARMADA_READ_PARAM_OFFSET, | 196 | devbus->base + ARMADA_READ_PARAM_OFFSET, |
@@ -193,24 +199,24 @@ static int devbus_set_timing_params(struct devbus *devbus, | |||
193 | writel(value, devbus->base + ARMADA_READ_PARAM_OFFSET); | 199 | writel(value, devbus->base + ARMADA_READ_PARAM_OFFSET); |
194 | 200 | ||
195 | /* Set write timings */ | 201 | /* Set write timings */ |
196 | value = w.sync_enable << ARMADA_SYNC_ENABLE_SHIFT | | 202 | value = w->sync_enable << ARMADA_SYNC_ENABLE_SHIFT | |
197 | w.wr_low << ARMADA_WR_LOW_SHIFT | | 203 | w->wr_low << ARMADA_WR_LOW_SHIFT | |
198 | w.wr_high << ARMADA_WR_HIGH_SHIFT | | 204 | w->wr_high << ARMADA_WR_HIGH_SHIFT | |
199 | w.ale_wr; | 205 | w->ale_wr; |
200 | 206 | ||
201 | dev_dbg(devbus->dev, "write parameters register: 0x%p = 0x%x\n", | 207 | dev_dbg(devbus->dev, "write parameters register: 0x%p = 0x%x\n", |
202 | devbus->base + ARMADA_WRITE_PARAM_OFFSET, | 208 | devbus->base + ARMADA_WRITE_PARAM_OFFSET, |
203 | value); | 209 | value); |
204 | 210 | ||
205 | writel(value, devbus->base + ARMADA_WRITE_PARAM_OFFSET); | 211 | writel(value, devbus->base + ARMADA_WRITE_PARAM_OFFSET); |
206 | |||
207 | return 0; | ||
208 | } | 212 | } |
209 | 213 | ||
210 | static int mvebu_devbus_probe(struct platform_device *pdev) | 214 | static int mvebu_devbus_probe(struct platform_device *pdev) |
211 | { | 215 | { |
212 | struct device *dev = &pdev->dev; | 216 | struct device *dev = &pdev->dev; |
213 | struct device_node *node = pdev->dev.of_node; | 217 | struct device_node *node = pdev->dev.of_node; |
218 | struct devbus_read_params r; | ||
219 | struct devbus_write_params w; | ||
214 | struct devbus *devbus; | 220 | struct devbus *devbus; |
215 | struct resource *res; | 221 | struct resource *res; |
216 | struct clk *clk; | 222 | struct clk *clk; |
@@ -240,11 +246,17 @@ static int mvebu_devbus_probe(struct platform_device *pdev) | |||
240 | rate = clk_get_rate(clk) / 1000; | 246 | rate = clk_get_rate(clk) / 1000; |
241 | devbus->tick_ps = 1000000000 / rate; | 247 | devbus->tick_ps = 1000000000 / rate; |
242 | 248 | ||
243 | /* Read the device tree node and set the new timing parameters */ | 249 | dev_dbg(devbus->dev, "Setting timing parameter, tick is %lu ps\n", |
244 | err = devbus_set_timing_params(devbus, node); | 250 | devbus->tick_ps); |
251 | |||
252 | /* Read the Device Tree node */ | ||
253 | err = devbus_get_timing_params(devbus, node, &r, &w); | ||
245 | if (err < 0) | 254 | if (err < 0) |
246 | return err; | 255 | return err; |
247 | 256 | ||
257 | /* Set the new timing parameters */ | ||
258 | devbus_armada_set_timing_params(devbus, node, &r, &w); | ||
259 | |||
248 | /* | 260 | /* |
249 | * We need to create a child device explicitly from here to | 261 | * We need to create a child device explicitly from here to |
250 | * guarantee that the child will be probed after the timing | 262 | * guarantee that the child will be probed after the timing |