1 /* 2 * Marvell EBU SoC Device Bus Controller 3 * (memory controller for NOR/NAND/SRAM/FPGA devices) 4 * 5 * Copyright (C) 2013-2014 Marvell 6 * 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 9 * the Free Software Foundation version 2 of the License. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 * 19 */ 20 21 #include <linux/kernel.h> 22 #include <linux/module.h> 23 #include <linux/slab.h> 24 #include <linux/err.h> 25 #include <linux/io.h> 26 #include <linux/clk.h> 27 #include <linux/mbus.h> 28 #include <linux/of_platform.h> 29 #include <linux/of_address.h> 30 #include <linux/platform_device.h> 31 32 /* Register definitions */ 33 #define ARMADA_DEV_WIDTH_SHIFT 30 34 #define ARMADA_BADR_SKEW_SHIFT 28 35 #define ARMADA_RD_HOLD_SHIFT 23 36 #define ARMADA_ACC_NEXT_SHIFT 17 37 #define ARMADA_RD_SETUP_SHIFT 12 38 #define ARMADA_ACC_FIRST_SHIFT 6 39 40 #define ARMADA_SYNC_ENABLE_SHIFT 24 41 #define ARMADA_WR_HIGH_SHIFT 16 42 #define ARMADA_WR_LOW_SHIFT 8 43 44 #define ARMADA_READ_PARAM_OFFSET 0x0 45 #define ARMADA_WRITE_PARAM_OFFSET 0x4 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 75 struct devbus_read_params { 76 u32 bus_width; 77 u32 badr_skew; 78 u32 turn_off; 79 u32 acc_first; 80 u32 acc_next; 81 u32 rd_setup; 82 u32 rd_hold; 83 }; 84 85 struct devbus_write_params { 86 u32 sync_enable; 87 u32 wr_high; 88 u32 wr_low; 89 u32 ale_wr; 90 }; 91 92 struct devbus { 93 struct device *dev; 94 void __iomem *base; 95 unsigned long tick_ps; 96 }; 97 98 static int get_timing_param_ps(struct devbus *devbus, 99 struct device_node *node, 100 const char *name, 101 u32 *ticks) 102 { 103 u32 time_ps; 104 int err; 105 106 err = of_property_read_u32(node, name, &time_ps); 107 if (err < 0) { 108 dev_err(devbus->dev, "%pOF has no '%s' property\n", 109 node, name); 110 return err; 111 } 112 113 *ticks = (time_ps + devbus->tick_ps - 1) / devbus->tick_ps; 114 115 dev_dbg(devbus->dev, "%s: %u ps -> 0x%x\n", 116 name, time_ps, *ticks); 117 return 0; 118 } 119 120 static int devbus_get_timing_params(struct devbus *devbus, 121 struct device_node *node, 122 struct devbus_read_params *r, 123 struct devbus_write_params *w) 124 { 125 int err; 126 127 err = of_property_read_u32(node, "devbus,bus-width", &r->bus_width); 128 if (err < 0) { 129 dev_err(devbus->dev, 130 "%pOF has no 'devbus,bus-width' property\n", 131 node); 132 return err; 133 } 134 135 /* 136 * The bus width is encoded into the register as 0 for 8 bits, 137 * and 1 for 16 bits, so we do the necessary conversion here. 138 */ 139 if (r->bus_width == 8) 140 r->bus_width = 0; 141 else if (r->bus_width == 16) 142 r->bus_width = 1; 143 else { 144 dev_err(devbus->dev, "invalid bus width %d\n", r->bus_width); 145 return -EINVAL; 146 } 147 148 err = get_timing_param_ps(devbus, node, "devbus,badr-skew-ps", 149 &r->badr_skew); 150 if (err < 0) 151 return err; 152 153 err = get_timing_param_ps(devbus, node, "devbus,turn-off-ps", 154 &r->turn_off); 155 if (err < 0) 156 return err; 157 158 err = get_timing_param_ps(devbus, node, "devbus,acc-first-ps", 159 &r->acc_first); 160 if (err < 0) 161 return err; 162 163 err = get_timing_param_ps(devbus, node, "devbus,acc-next-ps", 164 &r->acc_next); 165 if (err < 0) 166 return err; 167 168 if (of_device_is_compatible(devbus->dev->of_node, "marvell,mvebu-devbus")) { 169 err = get_timing_param_ps(devbus, node, "devbus,rd-setup-ps", 170 &r->rd_setup); 171 if (err < 0) 172 return err; 173 174 err = get_timing_param_ps(devbus, node, "devbus,rd-hold-ps", 175 &r->rd_hold); 176 if (err < 0) 177 return err; 178 179 err = of_property_read_u32(node, "devbus,sync-enable", 180 &w->sync_enable); 181 if (err < 0) { 182 dev_err(devbus->dev, 183 "%pOF has no 'devbus,sync-enable' property\n", 184 node); 185 return err; 186 } 187 } 188 189 err = get_timing_param_ps(devbus, node, "devbus,ale-wr-ps", 190 &w->ale_wr); 191 if (err < 0) 192 return err; 193 194 err = get_timing_param_ps(devbus, node, "devbus,wr-low-ps", 195 &w->wr_low); 196 if (err < 0) 197 return err; 198 199 err = get_timing_param_ps(devbus, node, "devbus,wr-high-ps", 200 &w->wr_high); 201 if (err < 0) 202 return err; 203 204 return 0; 205 } 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 240 static void devbus_armada_set_timing_params(struct devbus *devbus, 241 struct device_node *node, 242 struct devbus_read_params *r, 243 struct devbus_write_params *w) 244 { 245 u32 value; 246 247 /* Set read timings */ 248 value = r->bus_width << ARMADA_DEV_WIDTH_SHIFT | 249 r->badr_skew << ARMADA_BADR_SKEW_SHIFT | 250 r->rd_hold << ARMADA_RD_HOLD_SHIFT | 251 r->acc_next << ARMADA_ACC_NEXT_SHIFT | 252 r->rd_setup << ARMADA_RD_SETUP_SHIFT | 253 r->acc_first << ARMADA_ACC_FIRST_SHIFT | 254 r->turn_off; 255 256 dev_dbg(devbus->dev, "read parameters register 0x%p = 0x%x\n", 257 devbus->base + ARMADA_READ_PARAM_OFFSET, 258 value); 259 260 writel(value, devbus->base + ARMADA_READ_PARAM_OFFSET); 261 262 /* Set write timings */ 263 value = w->sync_enable << ARMADA_SYNC_ENABLE_SHIFT | 264 w->wr_low << ARMADA_WR_LOW_SHIFT | 265 w->wr_high << ARMADA_WR_HIGH_SHIFT | 266 w->ale_wr; 267 268 dev_dbg(devbus->dev, "write parameters register: 0x%p = 0x%x\n", 269 devbus->base + ARMADA_WRITE_PARAM_OFFSET, 270 value); 271 272 writel(value, devbus->base + ARMADA_WRITE_PARAM_OFFSET); 273 } 274 275 static int mvebu_devbus_probe(struct platform_device *pdev) 276 { 277 struct device *dev = &pdev->dev; 278 struct device_node *node = pdev->dev.of_node; 279 struct devbus_read_params r; 280 struct devbus_write_params w; 281 struct devbus *devbus; 282 struct resource *res; 283 struct clk *clk; 284 unsigned long rate; 285 int err; 286 287 devbus = devm_kzalloc(&pdev->dev, sizeof(struct devbus), GFP_KERNEL); 288 if (!devbus) 289 return -ENOMEM; 290 291 devbus->dev = dev; 292 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 293 devbus->base = devm_ioremap_resource(&pdev->dev, res); 294 if (IS_ERR(devbus->base)) 295 return PTR_ERR(devbus->base); 296 297 clk = devm_clk_get(&pdev->dev, NULL); 298 if (IS_ERR(clk)) 299 return PTR_ERR(clk); 300 clk_prepare_enable(clk); 301 302 /* 303 * Obtain clock period in picoseconds, 304 * we need this in order to convert timing 305 * parameters from cycles to picoseconds. 306 */ 307 rate = clk_get_rate(clk) / 1000; 308 devbus->tick_ps = 1000000000 / rate; 309 310 dev_dbg(devbus->dev, "Setting timing parameter, tick is %lu ps\n", 311 devbus->tick_ps); 312 313 if (!of_property_read_bool(node, "devbus,keep-config")) { 314 /* Read the Device Tree node */ 315 err = devbus_get_timing_params(devbus, node, &r, &w); 316 if (err < 0) 317 return err; 318 319 /* Set the new timing parameters */ 320 if (of_device_is_compatible(node, "marvell,orion-devbus")) 321 devbus_orion_set_timing_params(devbus, node, &r, &w); 322 else 323 devbus_armada_set_timing_params(devbus, node, &r, &w); 324 } 325 326 /* 327 * We need to create a child device explicitly from here to 328 * guarantee that the child will be probed after the timing 329 * parameters for the bus are written. 330 */ 331 err = of_platform_populate(node, NULL, NULL, dev); 332 if (err < 0) 333 return err; 334 335 return 0; 336 } 337 338 static const struct of_device_id mvebu_devbus_of_match[] = { 339 { .compatible = "marvell,mvebu-devbus" }, 340 { .compatible = "marvell,orion-devbus" }, 341 {}, 342 }; 343 MODULE_DEVICE_TABLE(of, mvebu_devbus_of_match); 344 345 static struct platform_driver mvebu_devbus_driver = { 346 .probe = mvebu_devbus_probe, 347 .driver = { 348 .name = "mvebu-devbus", 349 .of_match_table = mvebu_devbus_of_match, 350 }, 351 }; 352 353 static int __init mvebu_devbus_init(void) 354 { 355 return platform_driver_register(&mvebu_devbus_driver); 356 } 357 module_init(mvebu_devbus_init); 358 359 MODULE_LICENSE("GPL v2"); 360 MODULE_AUTHOR("Ezequiel Garcia <ezequiel.garcia@free-electrons.com>"); 361 MODULE_DESCRIPTION("Marvell EBU SoC Device Bus controller"); 362