Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

memory: pl353: Add driver for arm pl353 static memory controller

Add driver for arm pl353 static memory controller. This controller is used in
Xilinx Zynq SoC for interfacing the NAND and NOR/SRAM memory devices.

Signed-off-by: Naga Sureshkumar Relli <naga.sureshkumar.relli@xilinx.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>

authored by

Naga Sureshkumar Relli and committed by
Michal Simek
fee10bd2 b0b41af1

+503
+9
drivers/memory/Kconfig
··· 145 145 Texas Instruments da8xx SoCs. It's used to tweak various memory 146 146 controller configuration options. 147 147 148 + config PL353_SMC 149 + tristate "ARM PL35X Static Memory Controller(SMC) driver" 150 + default y 151 + depends on ARM 152 + depends on ARM_AMBA 153 + help 154 + This driver is for the ARM PL351/PL353 Static Memory 155 + Controller(SMC) module. 156 + 148 157 source "drivers/memory/samsung/Kconfig" 149 158 source "drivers/memory/tegra/Kconfig" 150 159
+1
drivers/memory/Makefile
··· 19 19 obj-$(CONFIG_JZ4780_NEMC) += jz4780-nemc.o 20 20 obj-$(CONFIG_MTK_SMI) += mtk-smi.o 21 21 obj-$(CONFIG_DA8XX_DDRCTL) += da8xx-ddrctl.o 22 + obj-$(CONFIG_PL353_SMC) += pl353-smc.o 22 23 23 24 obj-$(CONFIG_SAMSUNG_MC) += samsung/ 24 25 obj-$(CONFIG_TEGRA_MC) += tegra/
+463
drivers/memory/pl353-smc.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * ARM PL353 SMC driver 4 + * 5 + * Copyright (C) 2012 - 2018 Xilinx, Inc 6 + * Author: Punnaiah Choudary Kalluri <punnaiah@xilinx.com> 7 + * Author: Naga Sureshkumar Relli <nagasure@xilinx.com> 8 + */ 9 + 10 + #include <linux/clk.h> 11 + #include <linux/io.h> 12 + #include <linux/kernel.h> 13 + #include <linux/module.h> 14 + #include <linux/of_platform.h> 15 + #include <linux/platform_device.h> 16 + #include <linux/slab.h> 17 + #include <linux/pl353-smc.h> 18 + #include <linux/amba/bus.h> 19 + 20 + /* Register definitions */ 21 + #define PL353_SMC_MEMC_STATUS_OFFS 0 /* Controller status reg, RO */ 22 + #define PL353_SMC_CFG_CLR_OFFS 0xC /* Clear config reg, WO */ 23 + #define PL353_SMC_DIRECT_CMD_OFFS 0x10 /* Direct command reg, WO */ 24 + #define PL353_SMC_SET_CYCLES_OFFS 0x14 /* Set cycles register, WO */ 25 + #define PL353_SMC_SET_OPMODE_OFFS 0x18 /* Set opmode register, WO */ 26 + #define PL353_SMC_ECC_STATUS_OFFS 0x400 /* ECC status register */ 27 + #define PL353_SMC_ECC_MEMCFG_OFFS 0x404 /* ECC mem config reg */ 28 + #define PL353_SMC_ECC_MEMCMD1_OFFS 0x408 /* ECC mem cmd1 reg */ 29 + #define PL353_SMC_ECC_MEMCMD2_OFFS 0x40C /* ECC mem cmd2 reg */ 30 + #define PL353_SMC_ECC_VALUE0_OFFS 0x418 /* ECC value 0 reg */ 31 + 32 + /* Controller status register specific constants */ 33 + #define PL353_SMC_MEMC_STATUS_RAW_INT_1_SHIFT 6 34 + 35 + /* Clear configuration register specific constants */ 36 + #define PL353_SMC_CFG_CLR_INT_CLR_1 0x10 37 + #define PL353_SMC_CFG_CLR_ECC_INT_DIS_1 0x40 38 + #define PL353_SMC_CFG_CLR_INT_DIS_1 0x2 39 + #define PL353_SMC_CFG_CLR_DEFAULT_MASK (PL353_SMC_CFG_CLR_INT_CLR_1 | \ 40 + PL353_SMC_CFG_CLR_ECC_INT_DIS_1 | \ 41 + PL353_SMC_CFG_CLR_INT_DIS_1) 42 + 43 + /* Set cycles register specific constants */ 44 + #define PL353_SMC_SET_CYCLES_T0_MASK 0xF 45 + #define PL353_SMC_SET_CYCLES_T0_SHIFT 0 46 + #define PL353_SMC_SET_CYCLES_T1_MASK 0xF 47 + #define PL353_SMC_SET_CYCLES_T1_SHIFT 4 48 + #define PL353_SMC_SET_CYCLES_T2_MASK 0x7 49 + #define PL353_SMC_SET_CYCLES_T2_SHIFT 8 50 + #define PL353_SMC_SET_CYCLES_T3_MASK 0x7 51 + #define PL353_SMC_SET_CYCLES_T3_SHIFT 11 52 + #define PL353_SMC_SET_CYCLES_T4_MASK 0x7 53 + #define PL353_SMC_SET_CYCLES_T4_SHIFT 14 54 + #define PL353_SMC_SET_CYCLES_T5_MASK 0x7 55 + #define PL353_SMC_SET_CYCLES_T5_SHIFT 17 56 + #define PL353_SMC_SET_CYCLES_T6_MASK 0xF 57 + #define PL353_SMC_SET_CYCLES_T6_SHIFT 20 58 + 59 + /* ECC status register specific constants */ 60 + #define PL353_SMC_ECC_STATUS_BUSY BIT(6) 61 + #define PL353_SMC_ECC_REG_SIZE_OFFS 4 62 + 63 + /* ECC memory config register specific constants */ 64 + #define PL353_SMC_ECC_MEMCFG_MODE_MASK 0xC 65 + #define PL353_SMC_ECC_MEMCFG_MODE_SHIFT 2 66 + #define PL353_SMC_ECC_MEMCFG_PGSIZE_MASK 0xC 67 + 68 + #define PL353_SMC_DC_UPT_NAND_REGS ((4 << 23) | /* CS: NAND chip */ \ 69 + (2 << 21)) /* UpdateRegs operation */ 70 + 71 + #define PL353_NAND_ECC_CMD1 ((0x80) | /* Write command */ \ 72 + (0 << 8) | /* Read command */ \ 73 + (0x30 << 16) | /* Read End command */ \ 74 + (1 << 24)) /* Read End command calid */ 75 + 76 + #define PL353_NAND_ECC_CMD2 ((0x85) | /* Write col change cmd */ \ 77 + (5 << 8) | /* Read col change cmd */ \ 78 + (0xE0 << 16) | /* Read col change end cmd */ \ 79 + (1 << 24)) /* Read col change end cmd valid */ 80 + #define PL353_NAND_ECC_BUSY_TIMEOUT (1 * HZ) 81 + /** 82 + * struct pl353_smc_data - Private smc driver structure 83 + * @memclk: Pointer to the peripheral clock 84 + * @aclk: Pointer to the APER clock 85 + */ 86 + struct pl353_smc_data { 87 + struct clk *memclk; 88 + struct clk *aclk; 89 + }; 90 + 91 + /* SMC virtual register base */ 92 + static void __iomem *pl353_smc_base; 93 + 94 + /** 95 + * pl353_smc_set_buswidth - Set memory buswidth 96 + * @bw: Memory buswidth (8 | 16) 97 + * Return: 0 on success or negative errno. 98 + */ 99 + int pl353_smc_set_buswidth(unsigned int bw) 100 + { 101 + if (bw != PL353_SMC_MEM_WIDTH_8 && bw != PL353_SMC_MEM_WIDTH_16) 102 + return -EINVAL; 103 + 104 + writel(bw, pl353_smc_base + PL353_SMC_SET_OPMODE_OFFS); 105 + writel(PL353_SMC_DC_UPT_NAND_REGS, pl353_smc_base + 106 + PL353_SMC_DIRECT_CMD_OFFS); 107 + 108 + return 0; 109 + } 110 + EXPORT_SYMBOL_GPL(pl353_smc_set_buswidth); 111 + 112 + /** 113 + * pl353_smc_set_cycles - Set memory timing parameters 114 + * @timings: NAND controller timing parameters 115 + * 116 + * Sets NAND chip specific timing parameters. 117 + */ 118 + void pl353_smc_set_cycles(u32 timings[]) 119 + { 120 + /* 121 + * Set write pulse timing. This one is easy to extract: 122 + * 123 + * NWE_PULSE = tWP 124 + */ 125 + timings[0] &= PL353_SMC_SET_CYCLES_T0_MASK; 126 + timings[1] = (timings[1] & PL353_SMC_SET_CYCLES_T1_MASK) << 127 + PL353_SMC_SET_CYCLES_T1_SHIFT; 128 + timings[2] = (timings[2] & PL353_SMC_SET_CYCLES_T2_MASK) << 129 + PL353_SMC_SET_CYCLES_T2_SHIFT; 130 + timings[3] = (timings[3] & PL353_SMC_SET_CYCLES_T3_MASK) << 131 + PL353_SMC_SET_CYCLES_T3_SHIFT; 132 + timings[4] = (timings[4] & PL353_SMC_SET_CYCLES_T4_MASK) << 133 + PL353_SMC_SET_CYCLES_T4_SHIFT; 134 + timings[5] = (timings[5] & PL353_SMC_SET_CYCLES_T5_MASK) << 135 + PL353_SMC_SET_CYCLES_T5_SHIFT; 136 + timings[6] = (timings[6] & PL353_SMC_SET_CYCLES_T6_MASK) << 137 + PL353_SMC_SET_CYCLES_T6_SHIFT; 138 + timings[0] |= timings[1] | timings[2] | timings[3] | 139 + timings[4] | timings[5] | timings[6]; 140 + 141 + writel(timings[0], pl353_smc_base + PL353_SMC_SET_CYCLES_OFFS); 142 + writel(PL353_SMC_DC_UPT_NAND_REGS, pl353_smc_base + 143 + PL353_SMC_DIRECT_CMD_OFFS); 144 + } 145 + EXPORT_SYMBOL_GPL(pl353_smc_set_cycles); 146 + 147 + /** 148 + * pl353_smc_ecc_is_busy - Read ecc busy flag 149 + * Return: the ecc_status bit from the ecc_status register. 1 = busy, 0 = idle 150 + */ 151 + bool pl353_smc_ecc_is_busy(void) 152 + { 153 + return ((readl(pl353_smc_base + PL353_SMC_ECC_STATUS_OFFS) & 154 + PL353_SMC_ECC_STATUS_BUSY) == PL353_SMC_ECC_STATUS_BUSY); 155 + } 156 + EXPORT_SYMBOL_GPL(pl353_smc_ecc_is_busy); 157 + 158 + /** 159 + * pl353_smc_get_ecc_val - Read ecc_valueN registers 160 + * @ecc_reg: Index of the ecc_value reg (0..3) 161 + * Return: the content of the requested ecc_value register. 162 + * 163 + * There are four valid ecc_value registers. The argument is truncated to stay 164 + * within this valid boundary. 165 + */ 166 + u32 pl353_smc_get_ecc_val(int ecc_reg) 167 + { 168 + u32 addr, reg; 169 + 170 + addr = PL353_SMC_ECC_VALUE0_OFFS + 171 + (ecc_reg * PL353_SMC_ECC_REG_SIZE_OFFS); 172 + reg = readl(pl353_smc_base + addr); 173 + 174 + return reg; 175 + } 176 + EXPORT_SYMBOL_GPL(pl353_smc_get_ecc_val); 177 + 178 + /** 179 + * pl353_smc_get_nand_int_status_raw - Get NAND interrupt status bit 180 + * Return: the raw_int_status1 bit from the memc_status register 181 + */ 182 + int pl353_smc_get_nand_int_status_raw(void) 183 + { 184 + u32 reg; 185 + 186 + reg = readl(pl353_smc_base + PL353_SMC_MEMC_STATUS_OFFS); 187 + reg >>= PL353_SMC_MEMC_STATUS_RAW_INT_1_SHIFT; 188 + reg &= 1; 189 + 190 + return reg; 191 + } 192 + EXPORT_SYMBOL_GPL(pl353_smc_get_nand_int_status_raw); 193 + 194 + /** 195 + * pl353_smc_clr_nand_int - Clear NAND interrupt 196 + */ 197 + void pl353_smc_clr_nand_int(void) 198 + { 199 + writel(PL353_SMC_CFG_CLR_INT_CLR_1, 200 + pl353_smc_base + PL353_SMC_CFG_CLR_OFFS); 201 + } 202 + EXPORT_SYMBOL_GPL(pl353_smc_clr_nand_int); 203 + 204 + /** 205 + * pl353_smc_set_ecc_mode - Set SMC ECC mode 206 + * @mode: ECC mode (BYPASS, APB, MEM) 207 + * Return: 0 on success or negative errno. 208 + */ 209 + int pl353_smc_set_ecc_mode(enum pl353_smc_ecc_mode mode) 210 + { 211 + u32 reg; 212 + int ret = 0; 213 + 214 + switch (mode) { 215 + case PL353_SMC_ECCMODE_BYPASS: 216 + case PL353_SMC_ECCMODE_APB: 217 + case PL353_SMC_ECCMODE_MEM: 218 + 219 + reg = readl(pl353_smc_base + PL353_SMC_ECC_MEMCFG_OFFS); 220 + reg &= ~PL353_SMC_ECC_MEMCFG_MODE_MASK; 221 + reg |= mode << PL353_SMC_ECC_MEMCFG_MODE_SHIFT; 222 + writel(reg, pl353_smc_base + PL353_SMC_ECC_MEMCFG_OFFS); 223 + 224 + break; 225 + default: 226 + ret = -EINVAL; 227 + } 228 + 229 + return ret; 230 + } 231 + EXPORT_SYMBOL_GPL(pl353_smc_set_ecc_mode); 232 + 233 + /** 234 + * pl353_smc_set_ecc_pg_size - Set SMC ECC page size 235 + * @pg_sz: ECC page size 236 + * Return: 0 on success or negative errno. 237 + */ 238 + int pl353_smc_set_ecc_pg_size(unsigned int pg_sz) 239 + { 240 + u32 reg, sz; 241 + 242 + switch (pg_sz) { 243 + case 0: 244 + sz = 0; 245 + break; 246 + case SZ_512: 247 + sz = 1; 248 + break; 249 + case SZ_1K: 250 + sz = 2; 251 + break; 252 + case SZ_2K: 253 + sz = 3; 254 + break; 255 + default: 256 + return -EINVAL; 257 + } 258 + 259 + reg = readl(pl353_smc_base + PL353_SMC_ECC_MEMCFG_OFFS); 260 + reg &= ~PL353_SMC_ECC_MEMCFG_PGSIZE_MASK; 261 + reg |= sz; 262 + writel(reg, pl353_smc_base + PL353_SMC_ECC_MEMCFG_OFFS); 263 + 264 + return 0; 265 + } 266 + EXPORT_SYMBOL_GPL(pl353_smc_set_ecc_pg_size); 267 + 268 + static int __maybe_unused pl353_smc_suspend(struct device *dev) 269 + { 270 + struct pl353_smc_data *pl353_smc = dev_get_drvdata(dev); 271 + 272 + clk_disable(pl353_smc->memclk); 273 + clk_disable(pl353_smc->aclk); 274 + 275 + return 0; 276 + } 277 + 278 + static int __maybe_unused pl353_smc_resume(struct device *dev) 279 + { 280 + int ret; 281 + struct pl353_smc_data *pl353_smc = dev_get_drvdata(dev); 282 + 283 + ret = clk_enable(pl353_smc->aclk); 284 + if (ret) { 285 + dev_err(dev, "Cannot enable axi domain clock.\n"); 286 + return ret; 287 + } 288 + 289 + ret = clk_enable(pl353_smc->memclk); 290 + if (ret) { 291 + dev_err(dev, "Cannot enable memory clock.\n"); 292 + clk_disable(pl353_smc->aclk); 293 + return ret; 294 + } 295 + 296 + return ret; 297 + } 298 + 299 + static struct amba_driver pl353_smc_driver; 300 + 301 + static SIMPLE_DEV_PM_OPS(pl353_smc_dev_pm_ops, pl353_smc_suspend, 302 + pl353_smc_resume); 303 + 304 + /** 305 + * pl353_smc_init_nand_interface - Initialize the NAND interface 306 + * @adev: Pointer to the amba_device struct 307 + * @nand_node: Pointer to the pl353_nand device_node struct 308 + */ 309 + static void pl353_smc_init_nand_interface(struct amba_device *adev, 310 + struct device_node *nand_node) 311 + { 312 + unsigned long timeout; 313 + 314 + pl353_smc_set_buswidth(PL353_SMC_MEM_WIDTH_8); 315 + writel(PL353_SMC_CFG_CLR_INT_CLR_1, 316 + pl353_smc_base + PL353_SMC_CFG_CLR_OFFS); 317 + writel(PL353_SMC_DC_UPT_NAND_REGS, pl353_smc_base + 318 + PL353_SMC_DIRECT_CMD_OFFS); 319 + 320 + timeout = jiffies + PL353_NAND_ECC_BUSY_TIMEOUT; 321 + /* Wait till the ECC operation is complete */ 322 + do { 323 + if (pl353_smc_ecc_is_busy()) 324 + cpu_relax(); 325 + else 326 + break; 327 + } while (!time_after_eq(jiffies, timeout)); 328 + 329 + if (time_after_eq(jiffies, timeout)) 330 + return; 331 + 332 + writel(PL353_NAND_ECC_CMD1, 333 + pl353_smc_base + PL353_SMC_ECC_MEMCMD1_OFFS); 334 + writel(PL353_NAND_ECC_CMD2, 335 + pl353_smc_base + PL353_SMC_ECC_MEMCMD2_OFFS); 336 + } 337 + 338 + static const struct of_device_id pl353_smc_supported_children[] = { 339 + { 340 + .compatible = "cfi-flash" 341 + }, 342 + { 343 + .compatible = "arm,pl353-nand-r2p1", 344 + .data = pl353_smc_init_nand_interface 345 + }, 346 + {} 347 + }; 348 + 349 + static int pl353_smc_probe(struct amba_device *adev, const struct amba_id *id) 350 + { 351 + struct pl353_smc_data *pl353_smc; 352 + struct device_node *child; 353 + struct resource *res; 354 + int err; 355 + struct device_node *of_node = adev->dev.of_node; 356 + static void (*init)(struct amba_device *adev, 357 + struct device_node *nand_node); 358 + const struct of_device_id *match = NULL; 359 + 360 + pl353_smc = devm_kzalloc(&adev->dev, sizeof(*pl353_smc), GFP_KERNEL); 361 + if (!pl353_smc) 362 + return -ENOMEM; 363 + 364 + /* Get the NAND controller virtual address */ 365 + res = &adev->res; 366 + pl353_smc_base = devm_ioremap_resource(&adev->dev, res); 367 + if (IS_ERR(pl353_smc_base)) 368 + return PTR_ERR(pl353_smc_base); 369 + 370 + pl353_smc->aclk = devm_clk_get(&adev->dev, "apb_pclk"); 371 + if (IS_ERR(pl353_smc->aclk)) { 372 + dev_err(&adev->dev, "aclk clock not found.\n"); 373 + return PTR_ERR(pl353_smc->aclk); 374 + } 375 + 376 + pl353_smc->memclk = devm_clk_get(&adev->dev, "memclk"); 377 + if (IS_ERR(pl353_smc->memclk)) { 378 + dev_err(&adev->dev, "memclk clock not found.\n"); 379 + return PTR_ERR(pl353_smc->memclk); 380 + } 381 + 382 + err = clk_prepare_enable(pl353_smc->aclk); 383 + if (err) { 384 + dev_err(&adev->dev, "Unable to enable AXI clock.\n"); 385 + return err; 386 + } 387 + 388 + err = clk_prepare_enable(pl353_smc->memclk); 389 + if (err) { 390 + dev_err(&adev->dev, "Unable to enable memory clock.\n"); 391 + goto out_clk_dis_aper; 392 + } 393 + 394 + amba_set_drvdata(adev, pl353_smc); 395 + 396 + /* clear interrupts */ 397 + writel(PL353_SMC_CFG_CLR_DEFAULT_MASK, 398 + pl353_smc_base + PL353_SMC_CFG_CLR_OFFS); 399 + 400 + /* Find compatible children. Only a single child is supported */ 401 + for_each_available_child_of_node(of_node, child) { 402 + match = of_match_node(pl353_smc_supported_children, child); 403 + if (!match) { 404 + dev_warn(&adev->dev, "unsupported child node\n"); 405 + continue; 406 + } 407 + break; 408 + } 409 + if (!match) { 410 + dev_err(&adev->dev, "no matching children\n"); 411 + goto out_clk_disable; 412 + } 413 + 414 + init = match->data; 415 + if (init) 416 + init(adev, child); 417 + of_platform_device_create(child, NULL, &adev->dev); 418 + 419 + return 0; 420 + 421 + out_clk_disable: 422 + clk_disable_unprepare(pl353_smc->memclk); 423 + out_clk_dis_aper: 424 + clk_disable_unprepare(pl353_smc->aclk); 425 + 426 + return err; 427 + } 428 + 429 + static int pl353_smc_remove(struct amba_device *adev) 430 + { 431 + struct pl353_smc_data *pl353_smc = amba_get_drvdata(adev); 432 + 433 + clk_disable_unprepare(pl353_smc->memclk); 434 + clk_disable_unprepare(pl353_smc->aclk); 435 + 436 + return 0; 437 + } 438 + 439 + static const struct amba_id pl353_ids[] = { 440 + { 441 + .id = 0x00041353, 442 + .mask = 0x000fffff, 443 + }, 444 + { 0, 0 }, 445 + }; 446 + MODULE_DEVICE_TABLE(amba, pl353_ids); 447 + 448 + static struct amba_driver pl353_smc_driver = { 449 + .drv = { 450 + .owner = THIS_MODULE, 451 + .name = "pl353-smc", 452 + .pm = &pl353_smc_dev_pm_ops, 453 + }, 454 + .id_table = pl353_ids, 455 + .probe = pl353_smc_probe, 456 + .remove = pl353_smc_remove, 457 + }; 458 + 459 + module_amba_driver(pl353_smc_driver); 460 + 461 + MODULE_AUTHOR("Xilinx, Inc."); 462 + MODULE_DESCRIPTION("ARM PL353 SMC Driver"); 463 + MODULE_LICENSE("GPL");
+30
include/linux/pl353-smc.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * ARM PL353 SMC Driver Header 4 + * 5 + * Copyright (C) 2012 - 2018 Xilinx, Inc 6 + */ 7 + 8 + #ifndef __LINUX_PL353_SMC_H 9 + #define __LINUX_PL353_SMC_H 10 + 11 + enum pl353_smc_ecc_mode { 12 + PL353_SMC_ECCMODE_BYPASS = 0, 13 + PL353_SMC_ECCMODE_APB = 1, 14 + PL353_SMC_ECCMODE_MEM = 2 15 + }; 16 + 17 + enum pl353_smc_mem_width { 18 + PL353_SMC_MEM_WIDTH_8 = 0, 19 + PL353_SMC_MEM_WIDTH_16 = 1 20 + }; 21 + 22 + u32 pl353_smc_get_ecc_val(int ecc_reg); 23 + bool pl353_smc_ecc_is_busy(void); 24 + int pl353_smc_get_nand_int_status_raw(void); 25 + void pl353_smc_clr_nand_int(void); 26 + int pl353_smc_set_ecc_mode(enum pl353_smc_ecc_mode mode); 27 + int pl353_smc_set_ecc_pg_size(unsigned int pg_sz); 28 + int pl353_smc_set_buswidth(unsigned int bw); 29 + void pl353_smc_set_cycles(u32 timings[]); 30 + #endif