aemif.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /*
  2. * AEMIF support for DaVinci SoCs
  3. *
  4. * Copyright (C) 2010 Texas Instruments Incorporated. http://www.ti.com/
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. */
  10. #include <linux/kernel.h>
  11. #include <linux/io.h>
  12. #include <linux/err.h>
  13. #include <linux/clk.h>
  14. #include <linux/module.h>
  15. #include <linux/time.h>
  16. #include <linux/platform_data/mtd-davinci-aemif.h>
  17. #include <linux/platform_data/mtd-davinci.h>
  18. /* Timing value configuration */
  19. #define TA(x) ((x) << 2)
  20. #define RHOLD(x) ((x) << 4)
  21. #define RSTROBE(x) ((x) << 7)
  22. #define RSETUP(x) ((x) << 13)
  23. #define WHOLD(x) ((x) << 17)
  24. #define WSTROBE(x) ((x) << 20)
  25. #define WSETUP(x) ((x) << 26)
  26. #define TA_MAX 0x3
  27. #define RHOLD_MAX 0x7
  28. #define RSTROBE_MAX 0x3f
  29. #define RSETUP_MAX 0xf
  30. #define WHOLD_MAX 0x7
  31. #define WSTROBE_MAX 0x3f
  32. #define WSETUP_MAX 0xf
  33. #define TIMING_MASK (TA(TA_MAX) | \
  34. RHOLD(RHOLD_MAX) | \
  35. RSTROBE(RSTROBE_MAX) | \
  36. RSETUP(RSETUP_MAX) | \
  37. WHOLD(WHOLD_MAX) | \
  38. WSTROBE(WSTROBE_MAX) | \
  39. WSETUP(WSETUP_MAX))
  40. static inline unsigned int davinci_aemif_readl(void __iomem *base, int offset)
  41. {
  42. return readl_relaxed(base + offset);
  43. }
  44. static inline void davinci_aemif_writel(void __iomem *base,
  45. int offset, unsigned long value)
  46. {
  47. writel_relaxed(value, base + offset);
  48. }
  49. /*
  50. * aemif_calc_rate - calculate timing data.
  51. * @wanted: The cycle time needed in nanoseconds.
  52. * @clk: The input clock rate in kHz.
  53. * @max: The maximum divider value that can be programmed.
  54. *
  55. * On success, returns the calculated timing value minus 1 for easy
  56. * programming into AEMIF timing registers, else negative errno.
  57. */
  58. static int aemif_calc_rate(int wanted, unsigned long clk, int max)
  59. {
  60. int result;
  61. result = DIV_ROUND_UP((wanted * clk), NSEC_PER_MSEC) - 1;
  62. pr_debug("%s: result %d from %ld, %d\n", __func__, result, clk, wanted);
  63. /* It is generally OK to have a more relaxed timing than requested... */
  64. if (result < 0)
  65. result = 0;
  66. /* ... But configuring tighter timings is not an option. */
  67. else if (result > max)
  68. result = -EINVAL;
  69. return result;
  70. }
  71. /**
  72. * davinci_aemif_setup_timing - setup timing values for a given AEMIF interface
  73. * @t: timing values to be progammed
  74. * @base: The virtual base address of the AEMIF interface
  75. * @cs: chip-select to program the timing values for
  76. * @clkrate: the AEMIF clkrate
  77. *
  78. * This function programs the given timing values (in real clock) into the
  79. * AEMIF registers taking the AEMIF clock into account.
  80. *
  81. * This function does not use any locking while programming the AEMIF
  82. * because it is expected that there is only one user of a given
  83. * chip-select.
  84. *
  85. * Returns 0 on success, else negative errno.
  86. */
  87. static int davinci_aemif_setup_timing(struct davinci_aemif_timing *t,
  88. void __iomem *base, unsigned cs,
  89. unsigned long clkrate)
  90. {
  91. unsigned set, val;
  92. int ta, rhold, rstrobe, rsetup, whold, wstrobe, wsetup;
  93. unsigned offset = A1CR_OFFSET + cs * 4;
  94. if (!t)
  95. return 0; /* Nothing to do */
  96. clkrate /= 1000; /* turn clock into kHz for ease of use */
  97. ta = aemif_calc_rate(t->ta, clkrate, TA_MAX);
  98. rhold = aemif_calc_rate(t->rhold, clkrate, RHOLD_MAX);
  99. rstrobe = aemif_calc_rate(t->rstrobe, clkrate, RSTROBE_MAX);
  100. rsetup = aemif_calc_rate(t->rsetup, clkrate, RSETUP_MAX);
  101. whold = aemif_calc_rate(t->whold, clkrate, WHOLD_MAX);
  102. wstrobe = aemif_calc_rate(t->wstrobe, clkrate, WSTROBE_MAX);
  103. wsetup = aemif_calc_rate(t->wsetup, clkrate, WSETUP_MAX);
  104. if (ta < 0 || rhold < 0 || rstrobe < 0 || rsetup < 0 ||
  105. whold < 0 || wstrobe < 0 || wsetup < 0) {
  106. pr_err("%s: cannot get suitable timings\n", __func__);
  107. return -EINVAL;
  108. }
  109. set = TA(ta) | RHOLD(rhold) | RSTROBE(rstrobe) | RSETUP(rsetup) |
  110. WHOLD(whold) | WSTROBE(wstrobe) | WSETUP(wsetup);
  111. val = __raw_readl(base + offset);
  112. val &= ~TIMING_MASK;
  113. val |= set;
  114. __raw_writel(val, base + offset);
  115. return 0;
  116. }
  117. /**
  118. * davinci_aemif_setup - setup AEMIF interface by davinci_nand_pdata
  119. * @pdev - link to platform device to setup settings for
  120. *
  121. * This function does not use any locking while programming the AEMIF
  122. * because it is expected that there is only one user of a given
  123. * chip-select.
  124. *
  125. * Returns 0 on success, else negative errno.
  126. */
  127. int davinci_aemif_setup(struct platform_device *pdev)
  128. {
  129. struct davinci_nand_pdata *pdata = dev_get_platdata(&pdev->dev);
  130. uint32_t val;
  131. unsigned long clkrate;
  132. struct resource *res;
  133. void __iomem *base;
  134. struct clk *clk;
  135. int ret = 0;
  136. clk = clk_get(&pdev->dev, "aemif");
  137. if (IS_ERR(clk)) {
  138. ret = PTR_ERR(clk);
  139. dev_dbg(&pdev->dev, "unable to get AEMIF clock, err %d\n", ret);
  140. return ret;
  141. }
  142. ret = clk_prepare_enable(clk);
  143. if (ret < 0) {
  144. dev_dbg(&pdev->dev, "unable to enable AEMIF clock, err %d\n",
  145. ret);
  146. goto err_put;
  147. }
  148. res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
  149. if (!res) {
  150. dev_err(&pdev->dev, "cannot get IORESOURCE_MEM\n");
  151. ret = -ENOMEM;
  152. goto err;
  153. }
  154. base = ioremap(res->start, resource_size(res));
  155. if (!base) {
  156. dev_err(&pdev->dev, "ioremap failed for resource %pR\n", res);
  157. ret = -ENOMEM;
  158. goto err;
  159. }
  160. /*
  161. * Setup Async configuration register in case we did not boot
  162. * from NAND and so bootloader did not bother to set it up.
  163. */
  164. val = davinci_aemif_readl(base, A1CR_OFFSET + pdev->id * 4);
  165. /*
  166. * Extended Wait is not valid and Select Strobe mode is not
  167. * used
  168. */
  169. val &= ~(ACR_ASIZE_MASK | ACR_EW_MASK | ACR_SS_MASK);
  170. if (pdata->options & NAND_BUSWIDTH_16)
  171. val |= 0x1;
  172. davinci_aemif_writel(base, A1CR_OFFSET + pdev->id * 4, val);
  173. clkrate = clk_get_rate(clk);
  174. if (pdata->timing)
  175. ret = davinci_aemif_setup_timing(pdata->timing, base, pdev->id,
  176. clkrate);
  177. if (ret < 0)
  178. dev_dbg(&pdev->dev, "NAND timing values setup fail\n");
  179. iounmap(base);
  180. err:
  181. clk_disable_unprepare(clk);
  182. err_put:
  183. clk_put(clk);
  184. return ret;
  185. }