mvebu-devbus.c (9464B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Marvell EBU SoC Device Bus Controller 4 * (memory controller for NOR/NAND/SRAM/FPGA devices) 5 * 6 * Copyright (C) 2013-2014 Marvell 7 */ 8 9#include <linux/kernel.h> 10#include <linux/module.h> 11#include <linux/slab.h> 12#include <linux/err.h> 13#include <linux/io.h> 14#include <linux/clk.h> 15#include <linux/mbus.h> 16#include <linux/of_platform.h> 17#include <linux/of_address.h> 18#include <linux/platform_device.h> 19 20/* Register definitions */ 21#define ARMADA_DEV_WIDTH_SHIFT 30 22#define ARMADA_BADR_SKEW_SHIFT 28 23#define ARMADA_RD_HOLD_SHIFT 23 24#define ARMADA_ACC_NEXT_SHIFT 17 25#define ARMADA_RD_SETUP_SHIFT 12 26#define ARMADA_ACC_FIRST_SHIFT 6 27 28#define ARMADA_SYNC_ENABLE_SHIFT 24 29#define ARMADA_WR_HIGH_SHIFT 16 30#define ARMADA_WR_LOW_SHIFT 8 31 32#define ARMADA_READ_PARAM_OFFSET 0x0 33#define ARMADA_WRITE_PARAM_OFFSET 0x4 34 35#define ORION_RESERVED (0x2 << 30) 36#define ORION_BADR_SKEW_SHIFT 28 37#define ORION_WR_HIGH_EXT_BIT BIT(27) 38#define ORION_WR_HIGH_EXT_MASK 0x8 39#define ORION_WR_LOW_EXT_BIT BIT(26) 40#define ORION_WR_LOW_EXT_MASK 0x8 41#define ORION_ALE_WR_EXT_BIT BIT(25) 42#define ORION_ALE_WR_EXT_MASK 0x8 43#define ORION_ACC_NEXT_EXT_BIT BIT(24) 44#define ORION_ACC_NEXT_EXT_MASK 0x10 45#define ORION_ACC_FIRST_EXT_BIT BIT(23) 46#define ORION_ACC_FIRST_EXT_MASK 0x10 47#define ORION_TURN_OFF_EXT_BIT BIT(22) 48#define ORION_TURN_OFF_EXT_MASK 0x8 49#define ORION_DEV_WIDTH_SHIFT 20 50#define ORION_WR_HIGH_SHIFT 17 51#define ORION_WR_HIGH_MASK 0x7 52#define ORION_WR_LOW_SHIFT 14 53#define ORION_WR_LOW_MASK 0x7 54#define ORION_ALE_WR_SHIFT 11 55#define ORION_ALE_WR_MASK 0x7 56#define ORION_ACC_NEXT_SHIFT 7 57#define ORION_ACC_NEXT_MASK 0xF 58#define ORION_ACC_FIRST_SHIFT 3 59#define ORION_ACC_FIRST_MASK 0xF 60#define ORION_TURN_OFF_SHIFT 0 61#define ORION_TURN_OFF_MASK 0x7 62 63struct devbus_read_params { 64 u32 bus_width; 65 u32 badr_skew; 66 u32 turn_off; 67 u32 acc_first; 68 u32 acc_next; 69 u32 rd_setup; 70 u32 rd_hold; 71}; 72 73struct devbus_write_params { 74 u32 sync_enable; 75 u32 wr_high; 76 u32 wr_low; 77 u32 ale_wr; 78}; 79 80struct devbus { 81 struct device *dev; 82 void __iomem *base; 83 unsigned long tick_ps; 84}; 85 86static int get_timing_param_ps(struct devbus *devbus, 87 struct device_node *node, 88 const char *name, 89 u32 *ticks) 90{ 91 u32 time_ps; 92 int err; 93 94 err = of_property_read_u32(node, name, &time_ps); 95 if (err < 0) { 96 dev_err(devbus->dev, "%pOF has no '%s' property\n", 97 node, name); 98 return err; 99 } 100 101 *ticks = (time_ps + devbus->tick_ps - 1) / devbus->tick_ps; 102 103 dev_dbg(devbus->dev, "%s: %u ps -> 0x%x\n", 104 name, time_ps, *ticks); 105 return 0; 106} 107 108static int devbus_get_timing_params(struct devbus *devbus, 109 struct device_node *node, 110 struct devbus_read_params *r, 111 struct devbus_write_params *w) 112{ 113 int err; 114 115 err = of_property_read_u32(node, "devbus,bus-width", &r->bus_width); 116 if (err < 0) { 117 dev_err(devbus->dev, 118 "%pOF has no 'devbus,bus-width' property\n", 119 node); 120 return err; 121 } 122 123 /* 124 * The bus width is encoded into the register as 0 for 8 bits, 125 * and 1 for 16 bits, so we do the necessary conversion here. 126 */ 127 if (r->bus_width == 8) { 128 r->bus_width = 0; 129 } else if (r->bus_width == 16) { 130 r->bus_width = 1; 131 } else { 132 dev_err(devbus->dev, "invalid bus width %d\n", r->bus_width); 133 return -EINVAL; 134 } 135 136 err = get_timing_param_ps(devbus, node, "devbus,badr-skew-ps", 137 &r->badr_skew); 138 if (err < 0) 139 return err; 140 141 err = get_timing_param_ps(devbus, node, "devbus,turn-off-ps", 142 &r->turn_off); 143 if (err < 0) 144 return err; 145 146 err = get_timing_param_ps(devbus, node, "devbus,acc-first-ps", 147 &r->acc_first); 148 if (err < 0) 149 return err; 150 151 err = get_timing_param_ps(devbus, node, "devbus,acc-next-ps", 152 &r->acc_next); 153 if (err < 0) 154 return err; 155 156 if (of_device_is_compatible(devbus->dev->of_node, "marvell,mvebu-devbus")) { 157 err = get_timing_param_ps(devbus, node, "devbus,rd-setup-ps", 158 &r->rd_setup); 159 if (err < 0) 160 return err; 161 162 err = get_timing_param_ps(devbus, node, "devbus,rd-hold-ps", 163 &r->rd_hold); 164 if (err < 0) 165 return err; 166 167 err = of_property_read_u32(node, "devbus,sync-enable", 168 &w->sync_enable); 169 if (err < 0) { 170 dev_err(devbus->dev, 171 "%pOF has no 'devbus,sync-enable' property\n", 172 node); 173 return err; 174 } 175 } 176 177 err = get_timing_param_ps(devbus, node, "devbus,ale-wr-ps", 178 &w->ale_wr); 179 if (err < 0) 180 return err; 181 182 err = get_timing_param_ps(devbus, node, "devbus,wr-low-ps", 183 &w->wr_low); 184 if (err < 0) 185 return err; 186 187 err = get_timing_param_ps(devbus, node, "devbus,wr-high-ps", 188 &w->wr_high); 189 if (err < 0) 190 return err; 191 192 return 0; 193} 194 195static void devbus_orion_set_timing_params(struct devbus *devbus, 196 struct device_node *node, 197 struct devbus_read_params *r, 198 struct devbus_write_params *w) 199{ 200 u32 value; 201 202 /* 203 * The hardware designers found it would be a good idea to 204 * split most of the values in the register into two fields: 205 * one containing all the low-order bits, and another one 206 * containing just the high-order bit. For all of those 207 * fields, we have to split the value into these two parts. 208 */ 209 value = (r->turn_off & ORION_TURN_OFF_MASK) << ORION_TURN_OFF_SHIFT | 210 (r->acc_first & ORION_ACC_FIRST_MASK) << ORION_ACC_FIRST_SHIFT | 211 (r->acc_next & ORION_ACC_NEXT_MASK) << ORION_ACC_NEXT_SHIFT | 212 (w->ale_wr & ORION_ALE_WR_MASK) << ORION_ALE_WR_SHIFT | 213 (w->wr_low & ORION_WR_LOW_MASK) << ORION_WR_LOW_SHIFT | 214 (w->wr_high & ORION_WR_HIGH_MASK) << ORION_WR_HIGH_SHIFT | 215 r->bus_width << ORION_DEV_WIDTH_SHIFT | 216 ((r->turn_off & ORION_TURN_OFF_EXT_MASK) ? ORION_TURN_OFF_EXT_BIT : 0) | 217 ((r->acc_first & ORION_ACC_FIRST_EXT_MASK) ? ORION_ACC_FIRST_EXT_BIT : 0) | 218 ((r->acc_next & ORION_ACC_NEXT_EXT_MASK) ? ORION_ACC_NEXT_EXT_BIT : 0) | 219 ((w->ale_wr & ORION_ALE_WR_EXT_MASK) ? ORION_ALE_WR_EXT_BIT : 0) | 220 ((w->wr_low & ORION_WR_LOW_EXT_MASK) ? ORION_WR_LOW_EXT_BIT : 0) | 221 ((w->wr_high & ORION_WR_HIGH_EXT_MASK) ? ORION_WR_HIGH_EXT_BIT : 0) | 222 (r->badr_skew << ORION_BADR_SKEW_SHIFT) | 223 ORION_RESERVED; 224 225 writel(value, devbus->base); 226} 227 228static void devbus_armada_set_timing_params(struct devbus *devbus, 229 struct device_node *node, 230 struct devbus_read_params *r, 231 struct devbus_write_params *w) 232{ 233 u32 value; 234 235 /* Set read timings */ 236 value = r->bus_width << ARMADA_DEV_WIDTH_SHIFT | 237 r->badr_skew << ARMADA_BADR_SKEW_SHIFT | 238 r->rd_hold << ARMADA_RD_HOLD_SHIFT | 239 r->acc_next << ARMADA_ACC_NEXT_SHIFT | 240 r->rd_setup << ARMADA_RD_SETUP_SHIFT | 241 r->acc_first << ARMADA_ACC_FIRST_SHIFT | 242 r->turn_off; 243 244 dev_dbg(devbus->dev, "read parameters register 0x%p = 0x%x\n", 245 devbus->base + ARMADA_READ_PARAM_OFFSET, 246 value); 247 248 writel(value, devbus->base + ARMADA_READ_PARAM_OFFSET); 249 250 /* Set write timings */ 251 value = w->sync_enable << ARMADA_SYNC_ENABLE_SHIFT | 252 w->wr_low << ARMADA_WR_LOW_SHIFT | 253 w->wr_high << ARMADA_WR_HIGH_SHIFT | 254 w->ale_wr; 255 256 dev_dbg(devbus->dev, "write parameters register: 0x%p = 0x%x\n", 257 devbus->base + ARMADA_WRITE_PARAM_OFFSET, 258 value); 259 260 writel(value, devbus->base + ARMADA_WRITE_PARAM_OFFSET); 261} 262 263static int mvebu_devbus_probe(struct platform_device *pdev) 264{ 265 struct device *dev = &pdev->dev; 266 struct device_node *node = pdev->dev.of_node; 267 struct devbus_read_params r; 268 struct devbus_write_params w; 269 struct devbus *devbus; 270 struct clk *clk; 271 unsigned long rate; 272 int err; 273 274 devbus = devm_kzalloc(&pdev->dev, sizeof(struct devbus), GFP_KERNEL); 275 if (!devbus) 276 return -ENOMEM; 277 278 devbus->dev = dev; 279 devbus->base = devm_platform_ioremap_resource(pdev, 0); 280 if (IS_ERR(devbus->base)) 281 return PTR_ERR(devbus->base); 282 283 clk = devm_clk_get(&pdev->dev, NULL); 284 if (IS_ERR(clk)) 285 return PTR_ERR(clk); 286 clk_prepare_enable(clk); 287 288 /* 289 * Obtain clock period in picoseconds, 290 * we need this in order to convert timing 291 * parameters from cycles to picoseconds. 292 */ 293 rate = clk_get_rate(clk) / 1000; 294 devbus->tick_ps = 1000000000 / rate; 295 296 dev_dbg(devbus->dev, "Setting timing parameter, tick is %lu ps\n", 297 devbus->tick_ps); 298 299 if (!of_property_read_bool(node, "devbus,keep-config")) { 300 /* Read the Device Tree node */ 301 err = devbus_get_timing_params(devbus, node, &r, &w); 302 if (err < 0) 303 return err; 304 305 /* Set the new timing parameters */ 306 if (of_device_is_compatible(node, "marvell,orion-devbus")) 307 devbus_orion_set_timing_params(devbus, node, &r, &w); 308 else 309 devbus_armada_set_timing_params(devbus, node, &r, &w); 310 } 311 312 /* 313 * We need to create a child device explicitly from here to 314 * guarantee that the child will be probed after the timing 315 * parameters for the bus are written. 316 */ 317 err = of_platform_populate(node, NULL, NULL, dev); 318 if (err < 0) 319 return err; 320 321 return 0; 322} 323 324static const struct of_device_id mvebu_devbus_of_match[] = { 325 { .compatible = "marvell,mvebu-devbus" }, 326 { .compatible = "marvell,orion-devbus" }, 327 {}, 328}; 329MODULE_DEVICE_TABLE(of, mvebu_devbus_of_match); 330 331static struct platform_driver mvebu_devbus_driver = { 332 .probe = mvebu_devbus_probe, 333 .driver = { 334 .name = "mvebu-devbus", 335 .of_match_table = mvebu_devbus_of_match, 336 }, 337}; 338 339static int __init mvebu_devbus_init(void) 340{ 341 return platform_driver_register(&mvebu_devbus_driver); 342} 343module_init(mvebu_devbus_init); 344 345MODULE_LICENSE("GPL v2"); 346MODULE_AUTHOR("Ezequiel Garcia <ezequiel.garcia@free-electrons.com>"); 347MODULE_DESCRIPTION("Marvell EBU SoC Device Bus controller");