^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Cortina Systems Gemini OF physmap add-on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * This SoC has an elaborate flash control register, so we need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * detect and set it up when booting on this platform.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/mtd/map.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/mtd/xip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/mfd/syscon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/pinctrl/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "physmap-gemini.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * The Flash-relevant parts of the global status register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * These would also be relevant for a NAND driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define GLOBAL_STATUS 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define FLASH_TYPE_MASK (0x3 << 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define FLASH_TYPE_NAND_2K (0x3 << 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define FLASH_TYPE_NAND_512 (0x2 << 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define FLASH_TYPE_PARALLEL (0x1 << 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define FLASH_TYPE_SERIAL (0x0 << 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /* if parallel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define FLASH_WIDTH_16BIT (1 << 23) /* else 8 bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /* if serial */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define FLASH_ATMEL (1 << 23) /* else STM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define FLASH_SIZE_MASK (0x3 << 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define NAND_256M (0x3 << 21) /* and more */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define NAND_128M (0x2 << 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define NAND_64M (0x1 << 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define NAND_32M (0x0 << 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define ATMEL_16M (0x3 << 21) /* and more */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define ATMEL_8M (0x2 << 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define ATMEL_4M_2M (0x1 << 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define ATMEL_1M (0x0 << 21) /* and less */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define STM_32M (1 << 22) /* and more */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define STM_16M (0 << 22) /* and less */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define FLASH_PARALLEL_HIGH_PIN_CNT (1 << 20) /* else low pin cnt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct gemini_flash {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct pinctrl *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct pinctrl_state *enabled_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct pinctrl_state *disabled_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /* Static local state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static struct gemini_flash *gf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static void gemini_flash_enable_pins(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (IS_ERR(gf->enabled_state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) ret = pinctrl_select_state(gf->p, gf->enabled_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) dev_err(gf->dev, "failed to enable pins\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static void gemini_flash_disable_pins(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (IS_ERR(gf->disabled_state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) ret = pinctrl_select_state(gf->p, gf->disabled_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) dev_err(gf->dev, "failed to disable pins\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static map_word __xipram gemini_flash_map_read(struct map_info *map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) unsigned long ofs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) map_word ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) gemini_flash_enable_pins();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) ret = inline_map_read(map, ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) gemini_flash_disable_pins();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static void __xipram gemini_flash_map_write(struct map_info *map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) const map_word datum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) unsigned long ofs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) gemini_flash_enable_pins();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) inline_map_write(map, datum, ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) gemini_flash_disable_pins();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static void __xipram gemini_flash_map_copy_from(struct map_info *map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) void *to, unsigned long from,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) ssize_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) gemini_flash_enable_pins();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) inline_map_copy_from(map, to, from, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) gemini_flash_disable_pins();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static void __xipram gemini_flash_map_copy_to(struct map_info *map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) unsigned long to,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) const void *from, ssize_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) gemini_flash_enable_pins();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) inline_map_copy_to(map, to, from, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) gemini_flash_disable_pins();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) int of_flash_probe_gemini(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct map_info *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct regmap *rmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /* Multiplatform guard */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (!of_device_is_compatible(np, "cortina,gemini-flash"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) gf = devm_kzalloc(dev, sizeof(*gf), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (!gf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) gf->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) rmap = syscon_regmap_lookup_by_phandle(np, "syscon");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (IS_ERR(rmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) dev_err(dev, "no syscon\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return PTR_ERR(rmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) ret = regmap_read(rmap, GLOBAL_STATUS, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) dev_err(dev, "failed to read global status register\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) dev_dbg(dev, "global status reg: %08x\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * It would be contradictory if a physmap flash was NOT parallel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if ((val & FLASH_TYPE_MASK) != FLASH_TYPE_PARALLEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) dev_err(dev, "flash is not parallel\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * Complain if DT data and hardware definition is different.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (val & FLASH_WIDTH_16BIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (map->bankwidth != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) dev_warn(dev, "flash hardware say flash is 16 bit wide but DT says it is %d bits wide\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) map->bankwidth * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (map->bankwidth != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) dev_warn(dev, "flash hardware say flash is 8 bit wide but DT says it is %d bits wide\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) map->bankwidth * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) gf->p = devm_pinctrl_get(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (IS_ERR(gf->p)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) dev_err(dev, "no pinctrl handle\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) ret = PTR_ERR(gf->p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) gf->enabled_state = pinctrl_lookup_state(gf->p, "enabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (IS_ERR(gf->enabled_state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) dev_err(dev, "no enabled pin control state\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) gf->disabled_state = pinctrl_lookup_state(gf->p, "disabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (IS_ERR(gf->enabled_state)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) dev_err(dev, "no disabled pin control state\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) ret = pinctrl_select_state(gf->p, gf->disabled_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) dev_err(gf->dev, "failed to disable pins\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) map->read = gemini_flash_map_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) map->write = gemini_flash_map_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) map->copy_from = gemini_flash_map_copy_from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) map->copy_to = gemini_flash_map_copy_to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) dev_info(dev, "initialized Gemini-specific physmap control\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }