vexpress-config.c 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. *
  4. * Copyright (C) 2014 ARM Limited
  5. */
  6. #include <linux/err.h>
  7. #include <linux/init.h>
  8. #include <linux/io.h>
  9. #include <linux/module.h>
  10. #include <linux/of.h>
  11. #include <linux/platform_device.h>
  12. #include <linux/of_device.h>
  13. #include <linux/sched/signal.h>
  14. #include <linux/slab.h>
  15. #include <linux/vexpress.h>
  16. #define SYS_MISC 0x0
  17. #define SYS_MISC_MASTERSITE (1 << 14)
  18. #define SYS_PROCID0 0x24
  19. #define SYS_PROCID1 0x28
  20. #define SYS_HBI_MASK 0xfff
  21. #define SYS_PROCIDx_HBI_SHIFT 0
  22. #define SYS_CFGDATA 0x40
  23. #define SYS_CFGCTRL 0x44
  24. #define SYS_CFGCTRL_START (1 << 31)
  25. #define SYS_CFGCTRL_WRITE (1 << 30)
  26. #define SYS_CFGCTRL_DCC(n) (((n) & 0xf) << 26)
  27. #define SYS_CFGCTRL_FUNC(n) (((n) & 0x3f) << 20)
  28. #define SYS_CFGCTRL_SITE(n) (((n) & 0x3) << 16)
  29. #define SYS_CFGCTRL_POSITION(n) (((n) & 0xf) << 12)
  30. #define SYS_CFGCTRL_DEVICE(n) (((n) & 0xfff) << 0)
  31. #define SYS_CFGSTAT 0x48
  32. #define SYS_CFGSTAT_ERR (1 << 1)
  33. #define SYS_CFGSTAT_COMPLETE (1 << 0)
  34. #define VEXPRESS_SITE_MB 0
  35. #define VEXPRESS_SITE_DB1 1
  36. #define VEXPRESS_SITE_DB2 2
  37. #define VEXPRESS_SITE_MASTER 0xf
  38. struct vexpress_syscfg {
  39. struct device *dev;
  40. void __iomem *base;
  41. struct list_head funcs;
  42. };
  43. struct vexpress_syscfg_func {
  44. struct list_head list;
  45. struct vexpress_syscfg *syscfg;
  46. struct regmap *regmap;
  47. int num_templates;
  48. u32 template[]; /* Keep it last! */
  49. };
  50. struct vexpress_config_bridge_ops {
  51. struct regmap * (*regmap_init)(struct device *dev, void *context);
  52. void (*regmap_exit)(struct regmap *regmap, void *context);
  53. };
  54. struct vexpress_config_bridge {
  55. struct vexpress_config_bridge_ops *ops;
  56. void *context;
  57. };
  58. static DEFINE_MUTEX(vexpress_config_mutex);
  59. static u32 vexpress_config_site_master = VEXPRESS_SITE_MASTER;
  60. static void vexpress_config_set_master(u32 site)
  61. {
  62. vexpress_config_site_master = site;
  63. }
  64. static void vexpress_config_lock(void *arg)
  65. {
  66. mutex_lock(&vexpress_config_mutex);
  67. }
  68. static void vexpress_config_unlock(void *arg)
  69. {
  70. mutex_unlock(&vexpress_config_mutex);
  71. }
  72. static void vexpress_config_find_prop(struct device_node *node,
  73. const char *name, u32 *val)
  74. {
  75. /* Default value */
  76. *val = 0;
  77. of_node_get(node);
  78. while (node) {
  79. if (of_property_read_u32(node, name, val) == 0) {
  80. of_node_put(node);
  81. return;
  82. }
  83. node = of_get_next_parent(node);
  84. }
  85. }
  86. static int vexpress_config_get_topo(struct device_node *node, u32 *site,
  87. u32 *position, u32 *dcc)
  88. {
  89. vexpress_config_find_prop(node, "arm,vexpress,site", site);
  90. if (*site == VEXPRESS_SITE_MASTER)
  91. *site = vexpress_config_site_master;
  92. if (WARN_ON(vexpress_config_site_master == VEXPRESS_SITE_MASTER))
  93. return -EINVAL;
  94. vexpress_config_find_prop(node, "arm,vexpress,position", position);
  95. vexpress_config_find_prop(node, "arm,vexpress,dcc", dcc);
  96. return 0;
  97. }
  98. static void vexpress_config_devres_release(struct device *dev, void *res)
  99. {
  100. struct vexpress_config_bridge *bridge = dev_get_drvdata(dev->parent);
  101. struct regmap *regmap = res;
  102. bridge->ops->regmap_exit(regmap, bridge->context);
  103. }
  104. struct regmap *devm_regmap_init_vexpress_config(struct device *dev)
  105. {
  106. struct vexpress_config_bridge *bridge;
  107. struct regmap *regmap;
  108. struct regmap **res;
  109. bridge = dev_get_drvdata(dev->parent);
  110. if (WARN_ON(!bridge))
  111. return ERR_PTR(-EINVAL);
  112. res = devres_alloc(vexpress_config_devres_release, sizeof(*res),
  113. GFP_KERNEL);
  114. if (!res)
  115. return ERR_PTR(-ENOMEM);
  116. regmap = (bridge->ops->regmap_init)(dev, bridge->context);
  117. if (IS_ERR(regmap)) {
  118. devres_free(res);
  119. return regmap;
  120. }
  121. *res = regmap;
  122. devres_add(dev, res);
  123. return regmap;
  124. }
  125. EXPORT_SYMBOL_GPL(devm_regmap_init_vexpress_config);
  126. static int vexpress_syscfg_exec(struct vexpress_syscfg_func *func,
  127. int index, bool write, u32 *data)
  128. {
  129. struct vexpress_syscfg *syscfg = func->syscfg;
  130. u32 command, status;
  131. int tries;
  132. long timeout;
  133. if (WARN_ON(index >= func->num_templates))
  134. return -EINVAL;
  135. command = readl(syscfg->base + SYS_CFGCTRL);
  136. if (WARN_ON(command & SYS_CFGCTRL_START))
  137. return -EBUSY;
  138. command = func->template[index];
  139. command |= SYS_CFGCTRL_START;
  140. command |= write ? SYS_CFGCTRL_WRITE : 0;
  141. /* Use a canary for reads */
  142. if (!write)
  143. *data = 0xdeadbeef;
  144. dev_dbg(syscfg->dev, "func %p, command %x, data %x\n",
  145. func, command, *data);
  146. writel(*data, syscfg->base + SYS_CFGDATA);
  147. writel(0, syscfg->base + SYS_CFGSTAT);
  148. writel(command, syscfg->base + SYS_CFGCTRL);
  149. mb();
  150. /* The operation can take ages... Go to sleep, 100us initially */
  151. tries = 100;
  152. timeout = 100;
  153. do {
  154. if (!irqs_disabled()) {
  155. set_current_state(TASK_INTERRUPTIBLE);
  156. schedule_timeout(usecs_to_jiffies(timeout));
  157. if (signal_pending(current))
  158. return -EINTR;
  159. } else {
  160. udelay(timeout);
  161. }
  162. status = readl(syscfg->base + SYS_CFGSTAT);
  163. if (status & SYS_CFGSTAT_ERR)
  164. return -EFAULT;
  165. if (timeout > 20)
  166. timeout -= 20;
  167. } while (--tries && !(status & SYS_CFGSTAT_COMPLETE));
  168. if (WARN_ON_ONCE(!tries))
  169. return -ETIMEDOUT;
  170. if (!write) {
  171. *data = readl(syscfg->base + SYS_CFGDATA);
  172. dev_dbg(syscfg->dev, "func %p, read data %x\n", func, *data);
  173. }
  174. return 0;
  175. }
  176. static int vexpress_syscfg_read(void *context, unsigned int index,
  177. unsigned int *val)
  178. {
  179. struct vexpress_syscfg_func *func = context;
  180. return vexpress_syscfg_exec(func, index, false, val);
  181. }
  182. static int vexpress_syscfg_write(void *context, unsigned int index,
  183. unsigned int val)
  184. {
  185. struct vexpress_syscfg_func *func = context;
  186. return vexpress_syscfg_exec(func, index, true, &val);
  187. }
  188. static struct regmap_config vexpress_syscfg_regmap_config = {
  189. .lock = vexpress_config_lock,
  190. .unlock = vexpress_config_unlock,
  191. .reg_bits = 32,
  192. .val_bits = 32,
  193. .reg_read = vexpress_syscfg_read,
  194. .reg_write = vexpress_syscfg_write,
  195. .reg_format_endian = REGMAP_ENDIAN_LITTLE,
  196. .val_format_endian = REGMAP_ENDIAN_LITTLE,
  197. };
  198. static struct regmap *vexpress_syscfg_regmap_init(struct device *dev,
  199. void *context)
  200. {
  201. int err;
  202. struct vexpress_syscfg *syscfg = context;
  203. struct vexpress_syscfg_func *func;
  204. struct property *prop;
  205. const __be32 *val = NULL;
  206. __be32 energy_quirk[4];
  207. int num;
  208. u32 site, position, dcc;
  209. int i;
  210. err = vexpress_config_get_topo(dev->of_node, &site,
  211. &position, &dcc);
  212. if (err)
  213. return ERR_PTR(err);
  214. prop = of_find_property(dev->of_node,
  215. "arm,vexpress-sysreg,func", NULL);
  216. if (!prop)
  217. return ERR_PTR(-EINVAL);
  218. num = prop->length / sizeof(u32) / 2;
  219. val = prop->value;
  220. /*
  221. * "arm,vexpress-energy" function used to be described
  222. * by its first device only, now it requires both
  223. */
  224. if (num == 1 && of_device_is_compatible(dev->of_node,
  225. "arm,vexpress-energy")) {
  226. num = 2;
  227. energy_quirk[0] = *val;
  228. energy_quirk[2] = *val++;
  229. energy_quirk[1] = *val;
  230. energy_quirk[3] = cpu_to_be32(be32_to_cpup(val) + 1);
  231. val = energy_quirk;
  232. }
  233. func = kzalloc(struct_size(func, template, num), GFP_KERNEL);
  234. if (!func)
  235. return ERR_PTR(-ENOMEM);
  236. func->syscfg = syscfg;
  237. func->num_templates = num;
  238. for (i = 0; i < num; i++) {
  239. u32 function, device;
  240. function = be32_to_cpup(val++);
  241. device = be32_to_cpup(val++);
  242. dev_dbg(dev, "func %p: %u/%u/%u/%u/%u\n",
  243. func, site, position, dcc,
  244. function, device);
  245. func->template[i] = SYS_CFGCTRL_DCC(dcc);
  246. func->template[i] |= SYS_CFGCTRL_SITE(site);
  247. func->template[i] |= SYS_CFGCTRL_POSITION(position);
  248. func->template[i] |= SYS_CFGCTRL_FUNC(function);
  249. func->template[i] |= SYS_CFGCTRL_DEVICE(device);
  250. }
  251. vexpress_syscfg_regmap_config.max_register = num - 1;
  252. func->regmap = regmap_init(dev, NULL, func,
  253. &vexpress_syscfg_regmap_config);
  254. if (IS_ERR(func->regmap)) {
  255. void *err = func->regmap;
  256. kfree(func);
  257. return err;
  258. }
  259. list_add(&func->list, &syscfg->funcs);
  260. return func->regmap;
  261. }
  262. static void vexpress_syscfg_regmap_exit(struct regmap *regmap, void *context)
  263. {
  264. struct vexpress_syscfg *syscfg = context;
  265. struct vexpress_syscfg_func *func, *tmp;
  266. regmap_exit(regmap);
  267. list_for_each_entry_safe(func, tmp, &syscfg->funcs, list) {
  268. if (func->regmap == regmap) {
  269. list_del(&syscfg->funcs);
  270. kfree(func);
  271. break;
  272. }
  273. }
  274. }
  275. static struct vexpress_config_bridge_ops vexpress_syscfg_bridge_ops = {
  276. .regmap_init = vexpress_syscfg_regmap_init,
  277. .regmap_exit = vexpress_syscfg_regmap_exit,
  278. };
  279. static int vexpress_syscfg_probe(struct platform_device *pdev)
  280. {
  281. struct vexpress_syscfg *syscfg;
  282. struct resource *res;
  283. struct vexpress_config_bridge *bridge;
  284. struct device_node *node;
  285. int master;
  286. u32 dt_hbi;
  287. syscfg = devm_kzalloc(&pdev->dev, sizeof(*syscfg), GFP_KERNEL);
  288. if (!syscfg)
  289. return -ENOMEM;
  290. syscfg->dev = &pdev->dev;
  291. INIT_LIST_HEAD(&syscfg->funcs);
  292. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  293. syscfg->base = devm_ioremap_resource(&pdev->dev, res);
  294. if (IS_ERR(syscfg->base))
  295. return PTR_ERR(syscfg->base);
  296. bridge = devm_kmalloc(&pdev->dev, sizeof(*bridge), GFP_KERNEL);
  297. if (!bridge)
  298. return -ENOMEM;
  299. bridge->ops = &vexpress_syscfg_bridge_ops;
  300. bridge->context = syscfg;
  301. dev_set_drvdata(&pdev->dev, bridge);
  302. master = readl(syscfg->base + SYS_MISC) & SYS_MISC_MASTERSITE ?
  303. VEXPRESS_SITE_DB2 : VEXPRESS_SITE_DB1;
  304. vexpress_config_set_master(master);
  305. /* Confirm board type against DT property, if available */
  306. if (of_property_read_u32(of_root, "arm,hbi", &dt_hbi) == 0) {
  307. u32 id = readl(syscfg->base + (master == VEXPRESS_SITE_DB1 ?
  308. SYS_PROCID0 : SYS_PROCID1));
  309. u32 hbi = (id >> SYS_PROCIDx_HBI_SHIFT) & SYS_HBI_MASK;
  310. if (WARN_ON(dt_hbi != hbi))
  311. dev_warn(&pdev->dev, "DT HBI (%x) is not matching hardware (%x)!\n",
  312. dt_hbi, hbi);
  313. }
  314. for_each_compatible_node(node, NULL, "arm,vexpress,config-bus") {
  315. struct device_node *bridge_np;
  316. bridge_np = of_parse_phandle(node, "arm,vexpress,config-bridge", 0);
  317. if (bridge_np != pdev->dev.parent->of_node)
  318. continue;
  319. of_platform_populate(node, NULL, NULL, &pdev->dev);
  320. }
  321. return 0;
  322. }
  323. static const struct platform_device_id vexpress_syscfg_id_table[] = {
  324. { "vexpress-syscfg", },
  325. {},
  326. };
  327. MODULE_DEVICE_TABLE(platform, vexpress_syscfg_id_table);
  328. static struct platform_driver vexpress_syscfg_driver = {
  329. .driver.name = "vexpress-syscfg",
  330. .id_table = vexpress_syscfg_id_table,
  331. .probe = vexpress_syscfg_probe,
  332. };
  333. module_platform_driver(vexpress_syscfg_driver);
  334. MODULE_LICENSE("GPL v2");