physmap-ixp4xx.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Intel IXP4xx OF physmap add-on
  4. * Copyright (C) 2019 Linus Walleij <linus.walleij@linaro.org>
  5. *
  6. * Based on the ixp4xx.c map driver, originally written by:
  7. * Intel Corporation
  8. * Deepak Saxena <dsaxena@mvista.com>
  9. * Copyright (C) 2002 Intel Corporation
  10. * Copyright (C) 2003-2004 MontaVista Software, Inc.
  11. */
  12. #include <linux/export.h>
  13. #include <linux/of.h>
  14. #include <linux/of_device.h>
  15. #include <linux/mtd/map.h>
  16. #include <linux/mtd/xip.h>
  17. #include "physmap-ixp4xx.h"
  18. /*
  19. * Read/write a 16 bit word from flash address 'addr'.
  20. *
  21. * When the cpu is in little-endian mode it swizzles the address lines
  22. * ('address coherency') so we need to undo the swizzling to ensure commands
  23. * and the like end up on the correct flash address.
  24. *
  25. * To further complicate matters, due to the way the expansion bus controller
  26. * handles 32 bit reads, the byte stream ABCD is stored on the flash as:
  27. * D15 D0
  28. * +---+---+
  29. * | A | B | 0
  30. * +---+---+
  31. * | C | D | 2
  32. * +---+---+
  33. * This means that on LE systems each 16 bit word must be swapped. Note that
  34. * this requires CONFIG_MTD_CFI_BE_BYTE_SWAP to be enabled to 'unswap' the CFI
  35. * data and other flash commands which are always in D7-D0.
  36. */
  37. #ifndef CONFIG_CPU_BIG_ENDIAN
  38. static inline u16 flash_read16(void __iomem *addr)
  39. {
  40. return be16_to_cpu(__raw_readw((void __iomem *)((unsigned long)addr ^ 0x2)));
  41. }
  42. static inline void flash_write16(u16 d, void __iomem *addr)
  43. {
  44. __raw_writew(cpu_to_be16(d), (void __iomem *)((unsigned long)addr ^ 0x2));
  45. }
  46. #define BYTE0(h) ((h) & 0xFF)
  47. #define BYTE1(h) (((h) >> 8) & 0xFF)
  48. #else
  49. static inline u16 flash_read16(const void __iomem *addr)
  50. {
  51. return __raw_readw(addr);
  52. }
  53. static inline void flash_write16(u16 d, void __iomem *addr)
  54. {
  55. __raw_writew(d, addr);
  56. }
  57. #define BYTE0(h) (((h) >> 8) & 0xFF)
  58. #define BYTE1(h) ((h) & 0xFF)
  59. #endif
  60. static map_word ixp4xx_read16(struct map_info *map, unsigned long ofs)
  61. {
  62. map_word val;
  63. val.x[0] = flash_read16(map->virt + ofs);
  64. return val;
  65. }
  66. /*
  67. * The IXP4xx expansion bus only allows 16-bit wide acceses
  68. * when attached to a 16-bit wide device (such as the 28F128J3A),
  69. * so we can't just memcpy_fromio().
  70. */
  71. static void ixp4xx_copy_from(struct map_info *map, void *to,
  72. unsigned long from, ssize_t len)
  73. {
  74. u8 *dest = (u8 *) to;
  75. void __iomem *src = map->virt + from;
  76. if (len <= 0)
  77. return;
  78. if (from & 1) {
  79. *dest++ = BYTE1(flash_read16(src-1));
  80. src++;
  81. --len;
  82. }
  83. while (len >= 2) {
  84. u16 data = flash_read16(src);
  85. *dest++ = BYTE0(data);
  86. *dest++ = BYTE1(data);
  87. src += 2;
  88. len -= 2;
  89. }
  90. if (len > 0)
  91. *dest++ = BYTE0(flash_read16(src));
  92. }
  93. static void ixp4xx_write16(struct map_info *map, map_word d, unsigned long adr)
  94. {
  95. flash_write16(d.x[0], map->virt + adr);
  96. }
  97. int of_flash_probe_ixp4xx(struct platform_device *pdev,
  98. struct device_node *np,
  99. struct map_info *map)
  100. {
  101. struct device *dev = &pdev->dev;
  102. /* Multiplatform guard */
  103. if (!of_device_is_compatible(np, "intel,ixp4xx-flash"))
  104. return 0;
  105. map->read = ixp4xx_read16;
  106. map->write = ixp4xx_write16;
  107. map->copy_from = ixp4xx_copy_from;
  108. map->copy_to = NULL;
  109. dev_info(dev, "initialized Intel IXP4xx-specific physmap control\n");
  110. return 0;
  111. }