config.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. * Purna Chandra Mandal, purna.mandal@microchip.com
  3. * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
  4. *
  5. * This program is free software; you can distribute it and/or modify it
  6. * under the terms of the GNU General Public License (Version 2) as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  12. * for more details.
  13. */
  14. #include <linux/init.h>
  15. #include <linux/io.h>
  16. #include <linux/of_platform.h>
  17. #include <asm/mach-pic32/pic32.h>
  18. #include "pic32mzda.h"
  19. #define PIC32_CFGCON 0x0000
  20. #define PIC32_DEVID 0x0020
  21. #define PIC32_SYSKEY 0x0030
  22. #define PIC32_CFGEBIA 0x00c0
  23. #define PIC32_CFGEBIC 0x00d0
  24. #define PIC32_CFGCON2 0x00f0
  25. #define PIC32_RCON 0x1240
  26. static void __iomem *pic32_conf_base;
  27. static DEFINE_SPINLOCK(config_lock);
  28. static u32 pic32_reset_status;
  29. static u32 pic32_conf_get_reg_field(u32 offset, u32 rshift, u32 mask)
  30. {
  31. u32 v;
  32. v = readl(pic32_conf_base + offset);
  33. v >>= rshift;
  34. v &= mask;
  35. return v;
  36. }
  37. static u32 pic32_conf_modify_atomic(u32 offset, u32 mask, u32 set)
  38. {
  39. u32 v;
  40. unsigned long flags;
  41. spin_lock_irqsave(&config_lock, flags);
  42. v = readl(pic32_conf_base + offset);
  43. v &= ~mask;
  44. v |= (set & mask);
  45. writel(v, pic32_conf_base + offset);
  46. spin_unlock_irqrestore(&config_lock, flags);
  47. return 0;
  48. }
  49. int pic32_enable_lcd(void)
  50. {
  51. return pic32_conf_modify_atomic(PIC32_CFGCON2, BIT(31), BIT(31));
  52. }
  53. int pic32_disable_lcd(void)
  54. {
  55. return pic32_conf_modify_atomic(PIC32_CFGCON2, BIT(31), 0);
  56. }
  57. int pic32_set_lcd_mode(int mode)
  58. {
  59. u32 mask = mode ? BIT(30) : 0;
  60. return pic32_conf_modify_atomic(PIC32_CFGCON2, BIT(30), mask);
  61. }
  62. int pic32_set_sdhci_adma_fifo_threshold(u32 rthrsh, u32 wthrsh)
  63. {
  64. u32 clr, set;
  65. clr = (0x3ff << 4) | (0x3ff << 16);
  66. set = (rthrsh << 4) | (wthrsh << 16);
  67. return pic32_conf_modify_atomic(PIC32_CFGCON2, clr, set);
  68. }
  69. void pic32_syskey_unlock_debug(const char *func, const ulong line)
  70. {
  71. void __iomem *syskey = pic32_conf_base + PIC32_SYSKEY;
  72. pr_debug("%s: called from %s:%lu\n", __func__, func, line);
  73. writel(0x00000000, syskey);
  74. writel(0xAA996655, syskey);
  75. writel(0x556699AA, syskey);
  76. }
  77. static u32 pic32_get_device_id(void)
  78. {
  79. return pic32_conf_get_reg_field(PIC32_DEVID, 0, 0x0fffffff);
  80. }
  81. static u32 pic32_get_device_version(void)
  82. {
  83. return pic32_conf_get_reg_field(PIC32_DEVID, 28, 0xf);
  84. }
  85. u32 pic32_get_boot_status(void)
  86. {
  87. return pic32_reset_status;
  88. }
  89. EXPORT_SYMBOL(pic32_get_boot_status);
  90. void __init pic32_config_init(void)
  91. {
  92. pic32_conf_base = ioremap(PIC32_BASE_CONFIG, 0x110);
  93. if (!pic32_conf_base)
  94. panic("pic32: config base not mapped");
  95. /* Boot Status */
  96. pic32_reset_status = readl(pic32_conf_base + PIC32_RCON);
  97. writel(-1, PIC32_CLR(pic32_conf_base + PIC32_RCON));
  98. /* Device Inforation */
  99. pr_info("Device Id: 0x%08x, Device Ver: 0x%04x\n",
  100. pic32_get_device_id(),
  101. pic32_get_device_version());
  102. }