config.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Purna Chandra Mandal, [email protected]
  4. * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
  5. */
  6. #include <linux/init.h>
  7. #include <linux/io.h>
  8. #include <linux/of_platform.h>
  9. #include <asm/mach-pic32/pic32.h>
  10. #include "pic32mzda.h"
  11. #define PIC32_CFGCON 0x0000
  12. #define PIC32_DEVID 0x0020
  13. #define PIC32_SYSKEY 0x0030
  14. #define PIC32_CFGEBIA 0x00c0
  15. #define PIC32_CFGEBIC 0x00d0
  16. #define PIC32_CFGCON2 0x00f0
  17. #define PIC32_RCON 0x1240
  18. static void __iomem *pic32_conf_base;
  19. static DEFINE_SPINLOCK(config_lock);
  20. static u32 pic32_reset_status;
  21. static u32 pic32_conf_get_reg_field(u32 offset, u32 rshift, u32 mask)
  22. {
  23. u32 v;
  24. v = readl(pic32_conf_base + offset);
  25. v >>= rshift;
  26. v &= mask;
  27. return v;
  28. }
  29. static u32 pic32_conf_modify_atomic(u32 offset, u32 mask, u32 set)
  30. {
  31. u32 v;
  32. unsigned long flags;
  33. spin_lock_irqsave(&config_lock, flags);
  34. v = readl(pic32_conf_base + offset);
  35. v &= ~mask;
  36. v |= (set & mask);
  37. writel(v, pic32_conf_base + offset);
  38. spin_unlock_irqrestore(&config_lock, flags);
  39. return 0;
  40. }
  41. int pic32_enable_lcd(void)
  42. {
  43. return pic32_conf_modify_atomic(PIC32_CFGCON2, BIT(31), BIT(31));
  44. }
  45. int pic32_disable_lcd(void)
  46. {
  47. return pic32_conf_modify_atomic(PIC32_CFGCON2, BIT(31), 0);
  48. }
  49. int pic32_set_lcd_mode(int mode)
  50. {
  51. u32 mask = mode ? BIT(30) : 0;
  52. return pic32_conf_modify_atomic(PIC32_CFGCON2, BIT(30), mask);
  53. }
  54. int pic32_set_sdhci_adma_fifo_threshold(u32 rthrsh, u32 wthrsh)
  55. {
  56. u32 clr, set;
  57. clr = (0x3ff << 4) | (0x3ff << 16);
  58. set = (rthrsh << 4) | (wthrsh << 16);
  59. return pic32_conf_modify_atomic(PIC32_CFGCON2, clr, set);
  60. }
  61. void pic32_syskey_unlock_debug(const char *func, const ulong line)
  62. {
  63. void __iomem *syskey = pic32_conf_base + PIC32_SYSKEY;
  64. pr_debug("%s: called from %s:%lu\n", __func__, func, line);
  65. writel(0x00000000, syskey);
  66. writel(0xAA996655, syskey);
  67. writel(0x556699AA, syskey);
  68. }
  69. static u32 pic32_get_device_id(void)
  70. {
  71. return pic32_conf_get_reg_field(PIC32_DEVID, 0, 0x0fffffff);
  72. }
  73. static u32 pic32_get_device_version(void)
  74. {
  75. return pic32_conf_get_reg_field(PIC32_DEVID, 28, 0xf);
  76. }
  77. u32 pic32_get_boot_status(void)
  78. {
  79. return pic32_reset_status;
  80. }
  81. EXPORT_SYMBOL(pic32_get_boot_status);
  82. void __init pic32_config_init(void)
  83. {
  84. pic32_conf_base = ioremap(PIC32_BASE_CONFIG, 0x110);
  85. if (!pic32_conf_base)
  86. panic("pic32: config base not mapped");
  87. /* Boot Status */
  88. pic32_reset_status = readl(pic32_conf_base + PIC32_RCON);
  89. writel(-1, PIC32_CLR(pic32_conf_base + PIC32_RCON));
  90. /* Device Information */
  91. pr_info("Device Id: 0x%08x, Device Ver: 0x%04x\n",
  92. pic32_get_device_id(),
  93. pic32_get_device_version());
  94. }