warp-nand.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. * PIKA Warp(tm) NAND flash specific routines
  3. *
  4. * Copyright (c) 2008 PIKA Technologies
  5. * Sean MacLennan <smaclennan@pikatech.com>
  6. */
  7. #include <linux/platform_device.h>
  8. #include <linux/mtd/mtd.h>
  9. #include <linux/mtd/map.h>
  10. #include <linux/mtd/partitions.h>
  11. #include <linux/mtd/nand.h>
  12. #include <linux/mtd/ndfc.h>
  13. #include <linux/of.h>
  14. #include <asm/machdep.h>
  15. #ifdef CONFIG_MTD_NAND_NDFC
  16. #define CS_NAND_0 1 /* use chip select 1 for NAND device 0 */
  17. #define WARP_NAND_FLASH_REG_ADDR 0xD0000000UL
  18. #define WARP_NAND_FLASH_REG_SIZE 0x2000
  19. static struct resource warp_ndfc = {
  20. .start = WARP_NAND_FLASH_REG_ADDR,
  21. .end = WARP_NAND_FLASH_REG_ADDR + WARP_NAND_FLASH_REG_SIZE - 1,
  22. .flags = IORESOURCE_MEM,
  23. };
  24. static struct mtd_partition nand_parts[] = {
  25. {
  26. .name = "kernel",
  27. .offset = 0,
  28. .size = 0x0200000
  29. },
  30. {
  31. .name = "root",
  32. .offset = 0x0200000,
  33. .size = 0x3E00000
  34. },
  35. {
  36. .name = "persistent",
  37. .offset = 0x4000000,
  38. .size = 0x4000000
  39. },
  40. {
  41. .name = "persistent1",
  42. .offset = 0x8000000,
  43. .size = 0x4000000
  44. },
  45. {
  46. .name = "persistent2",
  47. .offset = 0xC000000,
  48. .size = 0x4000000
  49. }
  50. };
  51. struct ndfc_controller_settings warp_ndfc_settings = {
  52. .ccr_settings = (NDFC_CCR_BS(CS_NAND_0) | NDFC_CCR_ARAC1),
  53. .ndfc_erpn = 0,
  54. };
  55. static struct ndfc_chip_settings warp_chip0_settings = {
  56. .bank_settings = 0x80002222,
  57. };
  58. struct platform_nand_ctrl warp_nand_ctrl = {
  59. .priv = &warp_ndfc_settings,
  60. };
  61. static struct platform_device warp_ndfc_device = {
  62. .name = "ndfc-nand",
  63. .id = 0,
  64. .dev = {
  65. .platform_data = &warp_nand_ctrl,
  66. },
  67. .num_resources = 1,
  68. .resource = &warp_ndfc,
  69. };
  70. /* Do NOT set the ecclayout: let it default so it is correct for both
  71. * 64M and 256M flash chips.
  72. */
  73. static struct platform_nand_chip warp_nand_chip0 = {
  74. .nr_chips = 1,
  75. .chip_offset = CS_NAND_0,
  76. .nr_partitions = ARRAY_SIZE(nand_parts),
  77. .partitions = nand_parts,
  78. .chip_delay = 20,
  79. .priv = &warp_chip0_settings,
  80. };
  81. static struct platform_device warp_nand_device = {
  82. .name = "ndfc-chip",
  83. .id = 0,
  84. .num_resources = 0,
  85. .dev = {
  86. .platform_data = &warp_nand_chip0,
  87. .parent = &warp_ndfc_device.dev,
  88. }
  89. };
  90. static int warp_setup_nand_flash(void)
  91. {
  92. struct device_node *np;
  93. /* Try to detect a rev A based on NOR size. */
  94. np = of_find_compatible_node(NULL, NULL, "cfi-flash");
  95. if (np) {
  96. struct property *pp;
  97. pp = of_find_property(np, "reg", NULL);
  98. if (pp && (pp->length == 12)) {
  99. u32 *v = pp->value;
  100. if (v[2] == 0x4000000) {
  101. /* Rev A = 64M NAND */
  102. warp_nand_chip0.nr_partitions = 3;
  103. nand_parts[1].size = 0x3000000;
  104. nand_parts[2].offset = 0x3200000;
  105. nand_parts[2].size = 0x0e00000;
  106. }
  107. }
  108. of_node_put(np);
  109. }
  110. platform_device_register(&warp_ndfc_device);
  111. platform_device_register(&warp_nand_device);
  112. return 0;
  113. }
  114. machine_device_initcall(warp, warp_setup_nand_flash);
  115. #endif