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 |
