hsmc.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /*
  2. * Static Memory Controller for AT32 chips
  3. *
  4. * Copyright (C) 2006 Atmel Corporation
  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. #define DEBUG
  11. #include <linux/clk.h>
  12. #include <linux/err.h>
  13. #include <linux/init.h>
  14. #include <linux/module.h>
  15. #include <linux/platform_device.h>
  16. #include <asm/io.h>
  17. #include <asm/arch/smc.h>
  18. #include "hsmc.h"
  19. #define NR_CHIP_SELECTS 6
  20. struct hsmc {
  21. void __iomem *regs;
  22. struct clk *pclk;
  23. struct clk *mck;
  24. };
  25. static struct hsmc *hsmc;
  26. int smc_set_configuration(int cs, const struct smc_config *config)
  27. {
  28. unsigned long mul;
  29. unsigned long offset;
  30. u32 setup, pulse, cycle, mode;
  31. if (!hsmc)
  32. return -ENODEV;
  33. if (cs >= NR_CHIP_SELECTS)
  34. return -EINVAL;
  35. /*
  36. * cycles = x / T = x * f
  37. * = ((x * 1000000000) * ((f * 65536) / 1000000000)) / 65536
  38. * = ((x * 1000000000) * (((f / 10000) * 65536) / 100000)) / 65536
  39. */
  40. mul = (clk_get_rate(hsmc->mck) / 10000) << 16;
  41. mul /= 100000;
  42. #define ns2cyc(x) ((((x) * mul) + 65535) >> 16)
  43. setup = (HSMC_BF(NWE_SETUP, ns2cyc(config->nwe_setup))
  44. | HSMC_BF(NCS_WR_SETUP, ns2cyc(config->ncs_write_setup))
  45. | HSMC_BF(NRD_SETUP, ns2cyc(config->nrd_setup))
  46. | HSMC_BF(NCS_RD_SETUP, ns2cyc(config->ncs_read_setup)));
  47. pulse = (HSMC_BF(NWE_PULSE, ns2cyc(config->nwe_pulse))
  48. | HSMC_BF(NCS_WR_PULSE, ns2cyc(config->ncs_write_pulse))
  49. | HSMC_BF(NRD_PULSE, ns2cyc(config->nrd_pulse))
  50. | HSMC_BF(NCS_RD_PULSE, ns2cyc(config->ncs_read_pulse)));
  51. cycle = (HSMC_BF(NWE_CYCLE, ns2cyc(config->write_cycle))
  52. | HSMC_BF(NRD_CYCLE, ns2cyc(config->read_cycle)));
  53. switch (config->bus_width) {
  54. case 1:
  55. mode = HSMC_BF(DBW, HSMC_DBW_8_BITS);
  56. break;
  57. case 2:
  58. mode = HSMC_BF(DBW, HSMC_DBW_16_BITS);
  59. break;
  60. case 4:
  61. mode = HSMC_BF(DBW, HSMC_DBW_32_BITS);
  62. break;
  63. default:
  64. return -EINVAL;
  65. }
  66. switch (config->nwait_mode) {
  67. case 0:
  68. mode |= HSMC_BF(EXNW_MODE, HSMC_EXNW_MODE_DISABLED);
  69. break;
  70. case 1:
  71. mode |= HSMC_BF(EXNW_MODE, HSMC_EXNW_MODE_RESERVED);
  72. break;
  73. case 2:
  74. mode |= HSMC_BF(EXNW_MODE, HSMC_EXNW_MODE_FROZEN);
  75. break;
  76. case 3:
  77. mode |= HSMC_BF(EXNW_MODE, HSMC_EXNW_MODE_READY);
  78. break;
  79. default:
  80. return -EINVAL;
  81. }
  82. if (config->tdf_cycles) {
  83. mode |= HSMC_BF(TDF_CYCLES, config->tdf_cycles);
  84. }
  85. if (config->nrd_controlled)
  86. mode |= HSMC_BIT(READ_MODE);
  87. if (config->nwe_controlled)
  88. mode |= HSMC_BIT(WRITE_MODE);
  89. if (config->byte_write)
  90. mode |= HSMC_BIT(BAT);
  91. if (config->tdf_mode)
  92. mode |= HSMC_BIT(TDF_MODE);
  93. pr_debug("smc cs%d: setup/%08x pulse/%08x cycle/%08x mode/%08x\n",
  94. cs, setup, pulse, cycle, mode);
  95. offset = cs * 0x10;
  96. hsmc_writel(hsmc, SETUP0 + offset, setup);
  97. hsmc_writel(hsmc, PULSE0 + offset, pulse);
  98. hsmc_writel(hsmc, CYCLE0 + offset, cycle);
  99. hsmc_writel(hsmc, MODE0 + offset, mode);
  100. hsmc_readl(hsmc, MODE0); /* I/O barrier */
  101. return 0;
  102. }
  103. EXPORT_SYMBOL(smc_set_configuration);
  104. static int hsmc_probe(struct platform_device *pdev)
  105. {
  106. struct resource *regs;
  107. struct clk *pclk, *mck;
  108. int ret;
  109. if (hsmc)
  110. return -EBUSY;
  111. regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  112. if (!regs)
  113. return -ENXIO;
  114. pclk = clk_get(&pdev->dev, "pclk");
  115. if (IS_ERR(pclk))
  116. return PTR_ERR(pclk);
  117. mck = clk_get(&pdev->dev, "mck");
  118. if (IS_ERR(mck)) {
  119. ret = PTR_ERR(mck);
  120. goto out_put_pclk;
  121. }
  122. ret = -ENOMEM;
  123. hsmc = kzalloc(sizeof(struct hsmc), GFP_KERNEL);
  124. if (!hsmc)
  125. goto out_put_clocks;
  126. clk_enable(pclk);
  127. clk_enable(mck);
  128. hsmc->pclk = pclk;
  129. hsmc->mck = mck;
  130. hsmc->regs = ioremap(regs->start, regs->end - regs->start + 1);
  131. if (!hsmc->regs)
  132. goto out_disable_clocks;
  133. dev_info(&pdev->dev, "Atmel Static Memory Controller at 0x%08lx\n",
  134. (unsigned long)regs->start);
  135. platform_set_drvdata(pdev, hsmc);
  136. return 0;
  137. out_disable_clocks:
  138. clk_disable(mck);
  139. clk_disable(pclk);
  140. kfree(hsmc);
  141. out_put_clocks:
  142. clk_put(mck);
  143. out_put_pclk:
  144. clk_put(pclk);
  145. hsmc = NULL;
  146. return ret;
  147. }
  148. static struct platform_driver hsmc_driver = {
  149. .probe = hsmc_probe,
  150. .driver = {
  151. .name = "smc",
  152. },
  153. };
  154. static int __init hsmc_init(void)
  155. {
  156. return platform_driver_register(&hsmc_driver);
  157. }
  158. arch_initcall(hsmc_init);