aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/pic32
diff options
context:
space:
mode:
authorWe-unite <3205135446@qq.com>2025-03-08 22:04:20 +0800
committerWe-unite <3205135446@qq.com>2025-03-08 22:04:20 +0800
commita07bb8fd1299070229f0e8f3dcb57ffd5ef9870a (patch)
tree84f21bd0bf7071bc5fc7dd989e77d7ceb5476682 /arch/mips/pic32
downloadohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.tar.gz
ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.zip
Initial commit: OpenHarmony-v4.0-ReleaseOpenHarmony-v4.0-Release
Diffstat (limited to 'arch/mips/pic32')
-rw-r--r--arch/mips/pic32/Kconfig51
-rw-r--r--arch/mips/pic32/Makefile7
-rw-r--r--arch/mips/pic32/Platform6
-rw-r--r--arch/mips/pic32/common/Makefile6
-rw-r--r--arch/mips/pic32/common/irq.c13
-rw-r--r--arch/mips/pic32/common/reset.c54
-rw-r--r--arch/mips/pic32/pic32mzda/Makefile9
-rw-r--r--arch/mips/pic32/pic32mzda/config.c118
-rw-r--r--arch/mips/pic32/pic32mzda/early_clk.c98
-rw-r--r--arch/mips/pic32/pic32mzda/early_console.c161
-rw-r--r--arch/mips/pic32/pic32mzda/early_pin.c267
-rw-r--r--arch/mips/pic32/pic32mzda/early_pin.h233
-rw-r--r--arch/mips/pic32/pic32mzda/init.c147
-rw-r--r--arch/mips/pic32/pic32mzda/pic32mzda.h21
-rw-r--r--arch/mips/pic32/pic32mzda/time.c60
15 files changed, 1251 insertions, 0 deletions
diff --git a/arch/mips/pic32/Kconfig b/arch/mips/pic32/Kconfig
new file mode 100644
index 000000000..7acbb50c1
--- /dev/null
+++ b/arch/mips/pic32/Kconfig
@@ -0,0 +1,51 @@
1# SPDX-License-Identifier: GPL-2.0
2if MACH_PIC32
3
4choice
5 prompt "Machine Type"
6
7config PIC32MZDA
8 bool "Microchip PIC32MZDA Platform"
9 select BOOT_ELF32
10 select BOOT_RAW
11 select CEVT_R4K
12 select CSRC_R4K
13 select DMA_NONCOHERENT
14 select SYS_HAS_CPU_MIPS32_R2
15 select SYS_HAS_EARLY_PRINTK
16 select SYS_SUPPORTS_32BIT_KERNEL
17 select SYS_SUPPORTS_LITTLE_ENDIAN
18 select GPIOLIB
19 select COMMON_CLK
20 select CLKDEV_LOOKUP
21 select LIBFDT
22 select USE_OF
23 select PINCTRL
24 select PIC32_EVIC
25 help
26 Support for the Microchip PIC32MZDA microcontroller.
27
28 This is a 32-bit microcontroller with support for external or
29 internally packaged DDR2 memory up to 128MB.
30
31 For more information, see <http://www.microchip.com/>.
32
33endchoice
34
35choice
36 prompt "Devicetree selection"
37 default DTB_PIC32_NONE
38 help
39 Select the devicetree.
40
41config DTB_PIC32_NONE
42 bool "None"
43
44config DTB_PIC32_MZDA_SK
45 bool "PIC32MZDA Starter Kit"
46 depends on PIC32MZDA
47 select BUILTIN_DTB
48
49endchoice
50
51endif # MACH_PIC32
diff --git a/arch/mips/pic32/Makefile b/arch/mips/pic32/Makefile
new file mode 100644
index 000000000..6183e4a46
--- /dev/null
+++ b/arch/mips/pic32/Makefile
@@ -0,0 +1,7 @@
1# SPDX-License-Identifier: GPL-2.0-only
2#
3# Joshua Henderson, <joshua.henderson@microchip.com>
4# Copyright (C) 2015 Microchip Technology, Inc. All rights reserved.
5#
6obj-$(CONFIG_MACH_PIC32) += common/
7obj-$(CONFIG_PIC32MZDA) += pic32mzda/
diff --git a/arch/mips/pic32/Platform b/arch/mips/pic32/Platform
new file mode 100644
index 000000000..1e92e52a1
--- /dev/null
+++ b/arch/mips/pic32/Platform
@@ -0,0 +1,6 @@
1#
2# PIC32MZDA
3#
4cflags-$(CONFIG_PIC32MZDA) += -I$(srctree)/arch/mips/include/asm/mach-pic32
5load-$(CONFIG_PIC32MZDA) += 0xffffffff88000000
6all-$(CONFIG_PIC32MZDA) := $(COMPRESSION_FNAME).bin
diff --git a/arch/mips/pic32/common/Makefile b/arch/mips/pic32/common/Makefile
new file mode 100644
index 000000000..a60750ab7
--- /dev/null
+++ b/arch/mips/pic32/common/Makefile
@@ -0,0 +1,6 @@
1# SPDX-License-Identifier: GPL-2.0-only
2#
3# Joshua Henderson, <joshua.henderson@microchip.com>
4# Copyright (C) 2015 Microchip Technology, Inc. All rights reserved.
5#
6obj-y = reset.o irq.o
diff --git a/arch/mips/pic32/common/irq.c b/arch/mips/pic32/common/irq.c
new file mode 100644
index 000000000..fb00b797b
--- /dev/null
+++ b/arch/mips/pic32/common/irq.c
@@ -0,0 +1,13 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Joshua Henderson <joshua.henderson@microchip.com>
4 * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
5 */
6#include <linux/init.h>
7#include <linux/irqchip.h>
8#include <asm/irq.h>
9
10void __init arch_init_irq(void)
11{
12 irqchip_init();
13}
diff --git a/arch/mips/pic32/common/reset.c b/arch/mips/pic32/common/reset.c
new file mode 100644
index 000000000..a5fd7a8e2
--- /dev/null
+++ b/arch/mips/pic32/common/reset.c
@@ -0,0 +1,54 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Joshua Henderson <joshua.henderson@microchip.com>
4 * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
5 */
6#include <linux/init.h>
7#include <linux/pm.h>
8#include <asm/reboot.h>
9#include <asm/mach-pic32/pic32.h>
10
11#define PIC32_RSWRST 0x10
12
13static void pic32_halt(void)
14{
15 while (1) {
16 __asm__(".set push;\n"
17 ".set arch=r4000;\n"
18 "wait;\n"
19 ".set pop;\n"
20 );
21 }
22}
23
24static void pic32_machine_restart(char *command)
25{
26 void __iomem *reg =
27 ioremap(PIC32_BASE_RESET + PIC32_RSWRST, sizeof(u32));
28
29 pic32_syskey_unlock();
30
31 /* magic write/read */
32 __raw_writel(1, reg);
33 (void)__raw_readl(reg);
34
35 pic32_halt();
36}
37
38static void pic32_machine_halt(void)
39{
40 local_irq_disable();
41
42 pic32_halt();
43}
44
45static int __init mips_reboot_setup(void)
46{
47 _machine_restart = pic32_machine_restart;
48 _machine_halt = pic32_machine_halt;
49 pm_power_off = pic32_machine_halt;
50
51 return 0;
52}
53
54arch_initcall(mips_reboot_setup);
diff --git a/arch/mips/pic32/pic32mzda/Makefile b/arch/mips/pic32/pic32mzda/Makefile
new file mode 100644
index 000000000..3b505142b
--- /dev/null
+++ b/arch/mips/pic32/pic32mzda/Makefile
@@ -0,0 +1,9 @@
1# SPDX-License-Identifier: GPL-2.0-only
2#
3# Joshua Henderson, <joshua.henderson@microchip.com>
4# Copyright (C) 2015 Microchip Technology, Inc. All rights reserved.
5#
6obj-y := config.o early_clk.o init.o time.o
7
8obj-$(CONFIG_EARLY_PRINTK) += early_console.o \
9 early_pin.o
diff --git a/arch/mips/pic32/pic32mzda/config.c b/arch/mips/pic32/pic32mzda/config.c
new file mode 100644
index 000000000..36afe1b5b
--- /dev/null
+++ b/arch/mips/pic32/pic32mzda/config.c
@@ -0,0 +1,118 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Purna Chandra Mandal, purna.mandal@microchip.com
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
10#include <asm/mach-pic32/pic32.h>
11
12#include "pic32mzda.h"
13
14#define PIC32_CFGCON 0x0000
15#define PIC32_DEVID 0x0020
16#define PIC32_SYSKEY 0x0030
17#define PIC32_CFGEBIA 0x00c0
18#define PIC32_CFGEBIC 0x00d0
19#define PIC32_CFGCON2 0x00f0
20#define PIC32_RCON 0x1240
21
22static void __iomem *pic32_conf_base;
23static DEFINE_SPINLOCK(config_lock);
24static u32 pic32_reset_status;
25
26static u32 pic32_conf_get_reg_field(u32 offset, u32 rshift, u32 mask)
27{
28 u32 v;
29
30 v = readl(pic32_conf_base + offset);
31 v >>= rshift;
32 v &= mask;
33
34 return v;
35}
36
37static u32 pic32_conf_modify_atomic(u32 offset, u32 mask, u32 set)
38{
39 u32 v;
40 unsigned long flags;
41
42 spin_lock_irqsave(&config_lock, flags);
43 v = readl(pic32_conf_base + offset);
44 v &= ~mask;
45 v |= (set & mask);
46 writel(v, pic32_conf_base + offset);
47 spin_unlock_irqrestore(&config_lock, flags);
48
49 return 0;
50}
51
52int pic32_enable_lcd(void)
53{
54 return pic32_conf_modify_atomic(PIC32_CFGCON2, BIT(31), BIT(31));
55}
56
57int pic32_disable_lcd(void)
58{
59 return pic32_conf_modify_atomic(PIC32_CFGCON2, BIT(31), 0);
60}
61
62int pic32_set_lcd_mode(int mode)
63{
64 u32 mask = mode ? BIT(30) : 0;
65
66 return pic32_conf_modify_atomic(PIC32_CFGCON2, BIT(30), mask);
67}
68
69int pic32_set_sdhci_adma_fifo_threshold(u32 rthrsh, u32 wthrsh)
70{
71 u32 clr, set;
72
73 clr = (0x3ff << 4) | (0x3ff << 16);
74 set = (rthrsh << 4) | (wthrsh << 16);
75 return pic32_conf_modify_atomic(PIC32_CFGCON2, clr, set);
76}
77
78void pic32_syskey_unlock_debug(const char *func, const ulong line)
79{
80 void __iomem *syskey = pic32_conf_base + PIC32_SYSKEY;
81
82 pr_debug("%s: called from %s:%lu\n", __func__, func, line);
83 writel(0x00000000, syskey);
84 writel(0xAA996655, syskey);
85 writel(0x556699AA, syskey);
86}
87
88static u32 pic32_get_device_id(void)
89{
90 return pic32_conf_get_reg_field(PIC32_DEVID, 0, 0x0fffffff);
91}
92
93static u32 pic32_get_device_version(void)
94{
95 return pic32_conf_get_reg_field(PIC32_DEVID, 28, 0xf);
96}
97
98u32 pic32_get_boot_status(void)
99{
100 return pic32_reset_status;
101}
102EXPORT_SYMBOL(pic32_get_boot_status);
103
104void __init pic32_config_init(void)
105{
106 pic32_conf_base = ioremap(PIC32_BASE_CONFIG, 0x110);
107 if (!pic32_conf_base)
108 panic("pic32: config base not mapped");
109
110 /* Boot Status */
111 pic32_reset_status = readl(pic32_conf_base + PIC32_RCON);
112 writel(-1, PIC32_CLR(pic32_conf_base + PIC32_RCON));
113
114 /* Device Inforation */
115 pr_info("Device Id: 0x%08x, Device Ver: 0x%04x\n",
116 pic32_get_device_id(),
117 pic32_get_device_version());
118}
diff --git a/arch/mips/pic32/pic32mzda/early_clk.c b/arch/mips/pic32/pic32mzda/early_clk.c
new file mode 100644
index 000000000..6001e507d
--- /dev/null
+++ b/arch/mips/pic32/pic32mzda/early_clk.c
@@ -0,0 +1,98 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Joshua Henderson <joshua.henderson@microchip.com>
4 * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
5 */
6#include <asm/mach-pic32/pic32.h>
7
8#include "pic32mzda.h"
9
10/* Oscillators, PLL & clocks */
11#define ICLK_MASK 0x00000080
12#define PLLDIV_MASK 0x00000007
13#define CUROSC_MASK 0x00000007
14#define PLLMUL_MASK 0x0000007F
15#define PB_MASK 0x00000007
16#define FRC1 0
17#define FRC2 7
18#define SPLL 1
19#define POSC 2
20#define FRC_CLK 8000000
21
22#define PIC32_POSC_FREQ 24000000
23
24#define OSCCON 0x0000
25#define SPLLCON 0x0020
26#define PB1DIV 0x0140
27
28u32 pic32_get_sysclk(void)
29{
30 u32 osc_freq = 0;
31 u32 pllclk;
32 u32 frcdivn;
33 u32 osccon;
34 u32 spllcon;
35 int curr_osc;
36
37 u32 plliclk;
38 u32 pllidiv;
39 u32 pllodiv;
40 u32 pllmult;
41 u32 frcdiv;
42
43 void __iomem *osc_base = ioremap(PIC32_BASE_OSC, 0x200);
44
45 osccon = __raw_readl(osc_base + OSCCON);
46 spllcon = __raw_readl(osc_base + SPLLCON);
47
48 plliclk = (spllcon & ICLK_MASK);
49 pllidiv = ((spllcon >> 8) & PLLDIV_MASK) + 1;
50 pllodiv = ((spllcon >> 24) & PLLDIV_MASK);
51 pllmult = ((spllcon >> 16) & PLLMUL_MASK) + 1;
52 frcdiv = ((osccon >> 24) & PLLDIV_MASK);
53
54 pllclk = plliclk ? FRC_CLK : PIC32_POSC_FREQ;
55 frcdivn = ((1 << frcdiv) + 1) + (128 * (frcdiv == 7));
56
57 if (pllodiv < 2)
58 pllodiv = 2;
59 else if (pllodiv < 5)
60 pllodiv = (1 << pllodiv);
61 else
62 pllodiv = 32;
63
64 curr_osc = (int)((osccon >> 12) & CUROSC_MASK);
65
66 switch (curr_osc) {
67 case FRC1:
68 case FRC2:
69 osc_freq = FRC_CLK / frcdivn;
70 break;
71 case SPLL:
72 osc_freq = ((pllclk / pllidiv) * pllmult) / pllodiv;
73 break;
74 case POSC:
75 osc_freq = PIC32_POSC_FREQ;
76 break;
77 default:
78 break;
79 }
80
81 iounmap(osc_base);
82
83 return osc_freq;
84}
85
86u32 pic32_get_pbclk(int bus)
87{
88 u32 clk_freq;
89 void __iomem *osc_base = ioremap(PIC32_BASE_OSC, 0x200);
90 u32 pbxdiv = PB1DIV + ((bus - 1) * 0x10);
91 u32 pbdiv = (__raw_readl(osc_base + pbxdiv) & PB_MASK) + 1;
92
93 iounmap(osc_base);
94
95 clk_freq = pic32_get_sysclk();
96
97 return clk_freq / pbdiv;
98}
diff --git a/arch/mips/pic32/pic32mzda/early_console.c b/arch/mips/pic32/pic32mzda/early_console.c
new file mode 100644
index 000000000..3cd1b408f
--- /dev/null
+++ b/arch/mips/pic32/pic32mzda/early_console.c
@@ -0,0 +1,161 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Joshua Henderson <joshua.henderson@microchip.com>
4 * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
5 */
6#include <asm/mach-pic32/pic32.h>
7#include <asm/fw/fw.h>
8#include <asm/setup.h>
9
10#include "pic32mzda.h"
11#include "early_pin.h"
12
13/* Default early console parameters */
14#define EARLY_CONSOLE_PORT 1
15#define EARLY_CONSOLE_BAUDRATE 115200
16
17#define UART_ENABLE BIT(15)
18#define UART_ENABLE_RX BIT(12)
19#define UART_ENABLE_TX BIT(10)
20#define UART_TX_FULL BIT(9)
21
22/* UART1(x == 0) - UART6(x == 5) */
23#define UART_BASE(x) ((x) * 0x0200)
24#define U_MODE(x) UART_BASE(x)
25#define U_STA(x) (UART_BASE(x) + 0x10)
26#define U_TXR(x) (UART_BASE(x) + 0x20)
27#define U_BRG(x) (UART_BASE(x) + 0x40)
28
29static void __iomem *uart_base;
30static int console_port = -1;
31
32static int __init configure_uart_pins(int port)
33{
34 switch (port) {
35 case 1:
36 pic32_pps_input(IN_FUNC_U2RX, IN_RPB0);
37 pic32_pps_output(OUT_FUNC_U2TX, OUT_RPG9);
38 break;
39 case 5:
40 pic32_pps_input(IN_FUNC_U6RX, IN_RPD0);
41 pic32_pps_output(OUT_FUNC_U6TX, OUT_RPB8);
42 break;
43 default:
44 return -1;
45 }
46
47 return 0;
48}
49
50static void __init configure_uart(int port, int baud)
51{
52 u32 pbclk;
53
54 pbclk = pic32_get_pbclk(2);
55
56 __raw_writel(0, uart_base + U_MODE(port));
57 __raw_writel(((pbclk / baud) / 16) - 1, uart_base + U_BRG(port));
58 __raw_writel(UART_ENABLE, uart_base + U_MODE(port));
59 __raw_writel(UART_ENABLE_TX | UART_ENABLE_RX,
60 uart_base + PIC32_SET(U_STA(port)));
61}
62
63static void __init setup_early_console(int port, int baud)
64{
65 if (configure_uart_pins(port))
66 return;
67
68 console_port = port;
69 configure_uart(console_port, baud);
70}
71
72static char * __init pic32_getcmdline(void)
73{
74 /*
75 * arch_mem_init() has not been called yet, so we don't have a real
76 * command line setup if using CONFIG_CMDLINE_BOOL.
77 */
78#ifdef CONFIG_CMDLINE_OVERRIDE
79 return CONFIG_CMDLINE;
80#else
81 return fw_getcmdline();
82#endif
83}
84
85static int __init get_port_from_cmdline(char *arch_cmdline)
86{
87 char *s;
88 int port = -1;
89
90 if (!arch_cmdline || *arch_cmdline == '\0')
91 goto _out;
92
93 s = strstr(arch_cmdline, "earlyprintk=");
94 if (s) {
95 s = strstr(s, "ttyS");
96 if (s)
97 s += 4;
98 else
99 goto _out;
100
101 port = (*s) - '0';
102 }
103
104_out:
105 return port;
106}
107
108static int __init get_baud_from_cmdline(char *arch_cmdline)
109{
110 char *s;
111 int baud = -1;
112
113 if (!arch_cmdline || *arch_cmdline == '\0')
114 goto _out;
115
116 s = strstr(arch_cmdline, "earlyprintk=");
117 if (s) {
118 s = strstr(s, "ttyS");
119 if (s)
120 s += 6;
121 else
122 goto _out;
123
124 baud = 0;
125 while (*s >= '0' && *s <= '9')
126 baud = baud * 10 + *s++ - '0';
127 }
128
129_out:
130 return baud;
131}
132
133void __init fw_init_early_console(void)
134{
135 char *arch_cmdline = pic32_getcmdline();
136 int baud, port;
137
138 uart_base = ioremap(PIC32_BASE_UART, 0xc00);
139
140 baud = get_baud_from_cmdline(arch_cmdline);
141 port = get_port_from_cmdline(arch_cmdline);
142
143 if (port == -1)
144 port = EARLY_CONSOLE_PORT;
145
146 if (baud == -1)
147 baud = EARLY_CONSOLE_BAUDRATE;
148
149 setup_early_console(port, baud);
150}
151
152void prom_putchar(char c)
153{
154 if (console_port >= 0) {
155 while (__raw_readl(
156 uart_base + U_STA(console_port)) & UART_TX_FULL)
157 ;
158
159 __raw_writel(c, uart_base + U_TXR(console_port));
160 }
161}
diff --git a/arch/mips/pic32/pic32mzda/early_pin.c b/arch/mips/pic32/pic32mzda/early_pin.c
new file mode 100644
index 000000000..f2822632b
--- /dev/null
+++ b/arch/mips/pic32/pic32mzda/early_pin.c
@@ -0,0 +1,267 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Joshua Henderson <joshua.henderson@microchip.com>
4 * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
5 */
6#include <asm/io.h>
7
8#include "early_pin.h"
9
10#define PPS_BASE 0x1f800000
11
12/* Input PPS Registers */
13#define INT1R 0x1404
14#define INT2R 0x1408
15#define INT3R 0x140C
16#define INT4R 0x1410
17#define T2CKR 0x1418
18#define T3CKR 0x141C
19#define T4CKR 0x1420
20#define T5CKR 0x1424
21#define T6CKR 0x1428
22#define T7CKR 0x142C
23#define T8CKR 0x1430
24#define T9CKR 0x1434
25#define IC1R 0x1438
26#define IC2R 0x143C
27#define IC3R 0x1440
28#define IC4R 0x1444
29#define IC5R 0x1448
30#define IC6R 0x144C
31#define IC7R 0x1450
32#define IC8R 0x1454
33#define IC9R 0x1458
34#define OCFAR 0x1460
35#define U1RXR 0x1468
36#define U1CTSR 0x146C
37#define U2RXR 0x1470
38#define U2CTSR 0x1474
39#define U3RXR 0x1478
40#define U3CTSR 0x147C
41#define U4RXR 0x1480
42#define U4CTSR 0x1484
43#define U5RXR 0x1488
44#define U5CTSR 0x148C
45#define U6RXR 0x1490
46#define U6CTSR 0x1494
47#define SDI1R 0x149C
48#define SS1R 0x14A0
49#define SDI2R 0x14A8
50#define SS2R 0x14AC
51#define SDI3R 0x14B4
52#define SS3R 0x14B8
53#define SDI4R 0x14C0
54#define SS4R 0x14C4
55#define SDI5R 0x14CC
56#define SS5R 0x14D0
57#define SDI6R 0x14D8
58#define SS6R 0x14DC
59#define C1RXR 0x14E0
60#define C2RXR 0x14E4
61#define REFCLKI1R 0x14E8
62#define REFCLKI3R 0x14F0
63#define REFCLKI4R 0x14F4
64
65static const struct
66{
67 int function;
68 int reg;
69} input_pin_reg[] = {
70 { IN_FUNC_INT3, INT3R },
71 { IN_FUNC_T2CK, T2CKR },
72 { IN_FUNC_T6CK, T6CKR },
73 { IN_FUNC_IC3, IC3R },
74 { IN_FUNC_IC7, IC7R },
75 { IN_FUNC_U1RX, U1RXR },
76 { IN_FUNC_U2CTS, U2CTSR },
77 { IN_FUNC_U5RX, U5RXR },
78 { IN_FUNC_U6CTS, U6CTSR },
79 { IN_FUNC_SDI1, SDI1R },
80 { IN_FUNC_SDI3, SDI3R },
81 { IN_FUNC_SDI5, SDI5R },
82 { IN_FUNC_SS6, SS6R },
83 { IN_FUNC_REFCLKI1, REFCLKI1R },
84 { IN_FUNC_INT4, INT4R },
85 { IN_FUNC_T5CK, T5CKR },
86 { IN_FUNC_T7CK, T7CKR },
87 { IN_FUNC_IC4, IC4R },
88 { IN_FUNC_IC8, IC8R },
89 { IN_FUNC_U3RX, U3RXR },
90 { IN_FUNC_U4CTS, U4CTSR },
91 { IN_FUNC_SDI2, SDI2R },
92 { IN_FUNC_SDI4, SDI4R },
93 { IN_FUNC_C1RX, C1RXR },
94 { IN_FUNC_REFCLKI4, REFCLKI4R },
95 { IN_FUNC_INT2, INT2R },
96 { IN_FUNC_T3CK, T3CKR },
97 { IN_FUNC_T8CK, T8CKR },
98 { IN_FUNC_IC2, IC2R },
99 { IN_FUNC_IC5, IC5R },
100 { IN_FUNC_IC9, IC9R },
101 { IN_FUNC_U1CTS, U1CTSR },
102 { IN_FUNC_U2RX, U2RXR },
103 { IN_FUNC_U5CTS, U5CTSR },
104 { IN_FUNC_SS1, SS1R },
105 { IN_FUNC_SS3, SS3R },
106 { IN_FUNC_SS4, SS4R },
107 { IN_FUNC_SS5, SS5R },
108 { IN_FUNC_C2RX, C2RXR },
109 { IN_FUNC_INT1, INT1R },
110 { IN_FUNC_T4CK, T4CKR },
111 { IN_FUNC_T9CK, T9CKR },
112 { IN_FUNC_IC1, IC1R },
113 { IN_FUNC_IC6, IC6R },
114 { IN_FUNC_U3CTS, U3CTSR },
115 { IN_FUNC_U4RX, U4RXR },
116 { IN_FUNC_U6RX, U6RXR },
117 { IN_FUNC_SS2, SS2R },
118 { IN_FUNC_SDI6, SDI6R },
119 { IN_FUNC_OCFA, OCFAR },
120 { IN_FUNC_REFCLKI3, REFCLKI3R },
121};
122
123void pic32_pps_input(int function, int pin)
124{
125 void __iomem *pps_base = ioremap(PPS_BASE, 0xF4);
126 int i;
127
128 for (i = 0; i < ARRAY_SIZE(input_pin_reg); i++) {
129 if (input_pin_reg[i].function == function) {
130 __raw_writel(pin, pps_base + input_pin_reg[i].reg);
131 return;
132 }
133 }
134
135 iounmap(pps_base);
136}
137
138/* Output PPS Registers */
139#define RPA14R 0x1538
140#define RPA15R 0x153C
141#define RPB0R 0x1540
142#define RPB1R 0x1544
143#define RPB2R 0x1548
144#define RPB3R 0x154C
145#define RPB5R 0x1554
146#define RPB6R 0x1558
147#define RPB7R 0x155C
148#define RPB8R 0x1560
149#define RPB9R 0x1564
150#define RPB10R 0x1568
151#define RPB14R 0x1578
152#define RPB15R 0x157C
153#define RPC1R 0x1584
154#define RPC2R 0x1588
155#define RPC3R 0x158C
156#define RPC4R 0x1590
157#define RPC13R 0x15B4
158#define RPC14R 0x15B8
159#define RPD0R 0x15C0
160#define RPD1R 0x15C4
161#define RPD2R 0x15C8
162#define RPD3R 0x15CC
163#define RPD4R 0x15D0
164#define RPD5R 0x15D4
165#define RPD6R 0x15D8
166#define RPD7R 0x15DC
167#define RPD9R 0x15E4
168#define RPD10R 0x15E8
169#define RPD11R 0x15EC
170#define RPD12R 0x15F0
171#define RPD14R 0x15F8
172#define RPD15R 0x15FC
173#define RPE3R 0x160C
174#define RPE5R 0x1614
175#define RPE8R 0x1620
176#define RPE9R 0x1624
177#define RPF0R 0x1640
178#define RPF1R 0x1644
179#define RPF2R 0x1648
180#define RPF3R 0x164C
181#define RPF4R 0x1650
182#define RPF5R 0x1654
183#define RPF8R 0x1660
184#define RPF12R 0x1670
185#define RPF13R 0x1674
186#define RPG0R 0x1680
187#define RPG1R 0x1684
188#define RPG6R 0x1698
189#define RPG7R 0x169C
190#define RPG8R 0x16A0
191#define RPG9R 0x16A4
192
193static const struct
194{
195 int pin;
196 int reg;
197} output_pin_reg[] = {
198 { OUT_RPD2, RPD2R },
199 { OUT_RPG8, RPG8R },
200 { OUT_RPF4, RPF4R },
201 { OUT_RPD10, RPD10R },
202 { OUT_RPF1, RPF1R },
203 { OUT_RPB9, RPB9R },
204 { OUT_RPB10, RPB10R },
205 { OUT_RPC14, RPC14R },
206 { OUT_RPB5, RPB5R },
207 { OUT_RPC1, RPC1R },
208 { OUT_RPD14, RPD14R },
209 { OUT_RPG1, RPG1R },
210 { OUT_RPA14, RPA14R },
211 { OUT_RPD6, RPD6R },
212 { OUT_RPD3, RPD3R },
213 { OUT_RPG7, RPG7R },
214 { OUT_RPF5, RPF5R },
215 { OUT_RPD11, RPD11R },
216 { OUT_RPF0, RPF0R },
217 { OUT_RPB1, RPB1R },
218 { OUT_RPE5, RPE5R },
219 { OUT_RPC13, RPC13R },
220 { OUT_RPB3, RPB3R },
221 { OUT_RPC4, RPC4R },
222 { OUT_RPD15, RPD15R },
223 { OUT_RPG0, RPG0R },
224 { OUT_RPA15, RPA15R },
225 { OUT_RPD7, RPD7R },
226 { OUT_RPD9, RPD9R },
227 { OUT_RPG6, RPG6R },
228 { OUT_RPB8, RPB8R },
229 { OUT_RPB15, RPB15R },
230 { OUT_RPD4, RPD4R },
231 { OUT_RPB0, RPB0R },
232 { OUT_RPE3, RPE3R },
233 { OUT_RPB7, RPB7R },
234 { OUT_RPF12, RPF12R },
235 { OUT_RPD12, RPD12R },
236 { OUT_RPF8, RPF8R },
237 { OUT_RPC3, RPC3R },
238 { OUT_RPE9, RPE9R },
239 { OUT_RPD1, RPD1R },
240 { OUT_RPG9, RPG9R },
241 { OUT_RPB14, RPB14R },
242 { OUT_RPD0, RPD0R },
243 { OUT_RPB6, RPB6R },
244 { OUT_RPD5, RPD5R },
245 { OUT_RPB2, RPB2R },
246 { OUT_RPF3, RPF3R },
247 { OUT_RPF13, RPF13R },
248 { OUT_RPC2, RPC2R },
249 { OUT_RPE8, RPE8R },
250 { OUT_RPF2, RPF2R },
251};
252
253void pic32_pps_output(int function, int pin)
254{
255 void __iomem *pps_base = ioremap(PPS_BASE, 0x170);
256 int i;
257
258 for (i = 0; i < ARRAY_SIZE(output_pin_reg); i++) {
259 if (output_pin_reg[i].pin == pin) {
260 __raw_writel(function,
261 pps_base + output_pin_reg[i].reg);
262 return;
263 }
264 }
265
266 iounmap(pps_base);
267}
diff --git a/arch/mips/pic32/pic32mzda/early_pin.h b/arch/mips/pic32/pic32mzda/early_pin.h
new file mode 100644
index 000000000..60e9c3210
--- /dev/null
+++ b/arch/mips/pic32/pic32mzda/early_pin.h
@@ -0,0 +1,233 @@
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Joshua Henderson <joshua.henderson@microchip.com>
4 * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
5 */
6#ifndef _PIC32MZDA_EARLY_PIN_H
7#define _PIC32MZDA_EARLY_PIN_H
8
9/*
10 * This is a complete, yet overly simplistic and unoptimized, PIC32MZDA PPS
11 * configuration only useful before we have full pinctrl initialized.
12 */
13
14/* Input PPS Functions */
15enum {
16 IN_FUNC_INT3,
17 IN_FUNC_T2CK,
18 IN_FUNC_T6CK,
19 IN_FUNC_IC3,
20 IN_FUNC_IC7,
21 IN_FUNC_U1RX,
22 IN_FUNC_U2CTS,
23 IN_FUNC_U5RX,
24 IN_FUNC_U6CTS,
25 IN_FUNC_SDI1,
26 IN_FUNC_SDI3,
27 IN_FUNC_SDI5,
28 IN_FUNC_SS6,
29 IN_FUNC_REFCLKI1,
30 IN_FUNC_INT4,
31 IN_FUNC_T5CK,
32 IN_FUNC_T7CK,
33 IN_FUNC_IC4,
34 IN_FUNC_IC8,
35 IN_FUNC_U3RX,
36 IN_FUNC_U4CTS,
37 IN_FUNC_SDI2,
38 IN_FUNC_SDI4,
39 IN_FUNC_C1RX,
40 IN_FUNC_REFCLKI4,
41 IN_FUNC_INT2,
42 IN_FUNC_T3CK,
43 IN_FUNC_T8CK,
44 IN_FUNC_IC2,
45 IN_FUNC_IC5,
46 IN_FUNC_IC9,
47 IN_FUNC_U1CTS,
48 IN_FUNC_U2RX,
49 IN_FUNC_U5CTS,
50 IN_FUNC_SS1,
51 IN_FUNC_SS3,
52 IN_FUNC_SS4,
53 IN_FUNC_SS5,
54 IN_FUNC_C2RX,
55 IN_FUNC_INT1,
56 IN_FUNC_T4CK,
57 IN_FUNC_T9CK,
58 IN_FUNC_IC1,
59 IN_FUNC_IC6,
60 IN_FUNC_U3CTS,
61 IN_FUNC_U4RX,
62 IN_FUNC_U6RX,
63 IN_FUNC_SS2,
64 IN_FUNC_SDI6,
65 IN_FUNC_OCFA,
66 IN_FUNC_REFCLKI3,
67};
68
69/* Input PPS Pins */
70#define IN_RPD2 0x00
71#define IN_RPG8 0x01
72#define IN_RPF4 0x02
73#define IN_RPD10 0x03
74#define IN_RPF1 0x04
75#define IN_RPB9 0x05
76#define IN_RPB10 0x06
77#define IN_RPC14 0x07
78#define IN_RPB5 0x08
79#define IN_RPC1 0x0A
80#define IN_RPD14 0x0B
81#define IN_RPG1 0x0C
82#define IN_RPA14 0x0D
83#define IN_RPD6 0x0E
84#define IN_RPD3 0x00
85#define IN_RPG7 0x01
86#define IN_RPF5 0x02
87#define IN_RPD11 0x03
88#define IN_RPF0 0x04
89#define IN_RPB1 0x05
90#define IN_RPE5 0x06
91#define IN_RPC13 0x07
92#define IN_RPB3 0x08
93#define IN_RPC4 0x0A
94#define IN_RPD15 0x0B
95#define IN_RPG0 0x0C
96#define IN_RPA15 0x0D
97#define IN_RPD7 0x0E
98#define IN_RPD9 0x00
99#define IN_RPG6 0x01
100#define IN_RPB8 0x02
101#define IN_RPB15 0x03
102#define IN_RPD4 0x04
103#define IN_RPB0 0x05
104#define IN_RPE3 0x06
105#define IN_RPB7 0x07
106#define IN_RPF12 0x09
107#define IN_RPD12 0x0A
108#define IN_RPF8 0x0B
109#define IN_RPC3 0x0C
110#define IN_RPE9 0x0D
111#define IN_RPD1 0x00
112#define IN_RPG9 0x01
113#define IN_RPB14 0x02
114#define IN_RPD0 0x03
115#define IN_RPB6 0x05
116#define IN_RPD5 0x06
117#define IN_RPB2 0x07
118#define IN_RPF3 0x08
119#define IN_RPF13 0x09
120#define IN_RPF2 0x0B
121#define IN_RPC2 0x0C
122#define IN_RPE8 0x0D
123
124/* Output PPS Pins */
125enum {
126 OUT_RPD2,
127 OUT_RPG8,
128 OUT_RPF4,
129 OUT_RPD10,
130 OUT_RPF1,
131 OUT_RPB9,
132 OUT_RPB10,
133 OUT_RPC14,
134 OUT_RPB5,
135 OUT_RPC1,
136 OUT_RPD14,
137 OUT_RPG1,
138 OUT_RPA14,
139 OUT_RPD6,
140 OUT_RPD3,
141 OUT_RPG7,
142 OUT_RPF5,
143 OUT_RPD11,
144 OUT_RPF0,
145 OUT_RPB1,
146 OUT_RPE5,
147 OUT_RPC13,
148 OUT_RPB3,
149 OUT_RPC4,
150 OUT_RPD15,
151 OUT_RPG0,
152 OUT_RPA15,
153 OUT_RPD7,
154 OUT_RPD9,
155 OUT_RPG6,
156 OUT_RPB8,
157 OUT_RPB15,
158 OUT_RPD4,
159 OUT_RPB0,
160 OUT_RPE3,
161 OUT_RPB7,
162 OUT_RPF12,
163 OUT_RPD12,
164 OUT_RPF8,
165 OUT_RPC3,
166 OUT_RPE9,
167 OUT_RPD1,
168 OUT_RPG9,
169 OUT_RPB14,
170 OUT_RPD0,
171 OUT_RPB6,
172 OUT_RPD5,
173 OUT_RPB2,
174 OUT_RPF3,
175 OUT_RPF13,
176 OUT_RPC2,
177 OUT_RPE8,
178 OUT_RPF2,
179};
180
181/* Output PPS Functions */
182#define OUT_FUNC_U3TX 0x01
183#define OUT_FUNC_U4RTS 0x02
184#define OUT_FUNC_SDO1 0x05
185#define OUT_FUNC_SDO2 0x06
186#define OUT_FUNC_SDO3 0x07
187#define OUT_FUNC_SDO5 0x09
188#define OUT_FUNC_SS6 0x0A
189#define OUT_FUNC_OC3 0x0B
190#define OUT_FUNC_OC6 0x0C
191#define OUT_FUNC_REFCLKO4 0x0D
192#define OUT_FUNC_C2OUT 0x0E
193#define OUT_FUNC_C1TX 0x0F
194#define OUT_FUNC_U1TX 0x01
195#define OUT_FUNC_U2RTS 0x02
196#define OUT_FUNC_U5TX 0x03
197#define OUT_FUNC_U6RTS 0x04
198#define OUT_FUNC_SDO1 0x05
199#define OUT_FUNC_SDO2 0x06
200#define OUT_FUNC_SDO3 0x07
201#define OUT_FUNC_SDO4 0x08
202#define OUT_FUNC_SDO5 0x09
203#define OUT_FUNC_OC4 0x0B
204#define OUT_FUNC_OC7 0x0C
205#define OUT_FUNC_REFCLKO1 0x0F
206#define OUT_FUNC_U3RTS 0x01
207#define OUT_FUNC_U4TX 0x02
208#define OUT_FUNC_U6TX 0x04
209#define OUT_FUNC_SS1 0x05
210#define OUT_FUNC_SS3 0x07
211#define OUT_FUNC_SS4 0x08
212#define OUT_FUNC_SS5 0x09
213#define OUT_FUNC_SDO6 0x0A
214#define OUT_FUNC_OC5 0x0B
215#define OUT_FUNC_OC8 0x0C
216#define OUT_FUNC_C1OUT 0x0E
217#define OUT_FUNC_REFCLKO3 0x0F
218#define OUT_FUNC_U1RTS 0x01
219#define OUT_FUNC_U2TX 0x02
220#define OUT_FUNC_U5RTS 0x03
221#define OUT_FUNC_U6TX 0x04
222#define OUT_FUNC_SS2 0x06
223#define OUT_FUNC_SDO4 0x08
224#define OUT_FUNC_SDO6 0x0A
225#define OUT_FUNC_OC2 0x0B
226#define OUT_FUNC_OC1 0x0C
227#define OUT_FUNC_OC9 0x0D
228#define OUT_FUNC_C2TX 0x0F
229
230void pic32_pps_input(int function, int pin);
231void pic32_pps_output(int function, int pin);
232
233#endif
diff --git a/arch/mips/pic32/pic32mzda/init.c b/arch/mips/pic32/pic32mzda/init.c
new file mode 100644
index 000000000..488c0bee7
--- /dev/null
+++ b/arch/mips/pic32/pic32mzda/init.c
@@ -0,0 +1,147 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Joshua Henderson, joshua.henderson@microchip.com
4 * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
5 */
6#include <linux/init.h>
7#include <linux/kernel.h>
8#include <linux/of_address.h>
9#include <linux/of_fdt.h>
10#include <linux/of_platform.h>
11#include <linux/platform_data/sdhci-pic32.h>
12
13#include <asm/fw/fw.h>
14#include <asm/mips-boards/generic.h>
15#include <asm/prom.h>
16
17#include "pic32mzda.h"
18
19const char *get_system_type(void)
20{
21 return "PIC32MZDA";
22}
23
24static ulong get_fdtaddr(void)
25{
26 ulong ftaddr = 0;
27
28 if (fw_passed_dtb && !fw_arg2 && !fw_arg3)
29 return (ulong)fw_passed_dtb;
30
31 if (&__dtb_start < &__dtb_end)
32 ftaddr = (ulong)__dtb_start;
33
34 return ftaddr;
35}
36
37void __init plat_mem_setup(void)
38{
39 void *dtb;
40
41 dtb = (void *)get_fdtaddr();
42 if (!dtb) {
43 pr_err("pic32: no DTB found.\n");
44 return;
45 }
46
47 /*
48 * Load the builtin device tree. This causes the chosen node to be
49 * parsed resulting in our memory appearing.
50 */
51 __dt_setup_arch(dtb);
52
53 pr_info("Found following command lines\n");
54 pr_info(" boot_command_line: %s\n", boot_command_line);
55 pr_info(" arcs_cmdline : %s\n", arcs_cmdline);
56#ifdef CONFIG_CMDLINE_BOOL
57 pr_info(" builtin_cmdline : %s\n", CONFIG_CMDLINE);
58#endif
59 if (dtb != __dtb_start)
60 strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
61
62#ifdef CONFIG_EARLY_PRINTK
63 fw_init_early_console();
64#endif
65 pic32_config_init();
66}
67
68static __init void pic32_init_cmdline(int argc, char *argv[])
69{
70 unsigned int count = COMMAND_LINE_SIZE - 1;
71 int i;
72 char *dst = &(arcs_cmdline[0]);
73 char *src;
74
75 for (i = 1; i < argc && count; ++i) {
76 src = argv[i];
77 while (*src && count) {
78 *dst++ = *src++;
79 --count;
80 }
81 *dst++ = ' ';
82 }
83 if (i > 1)
84 --dst;
85
86 *dst = 0;
87}
88
89void __init prom_init(void)
90{
91 pic32_init_cmdline((int)fw_arg0, (char **)fw_arg1);
92}
93
94void __init prom_free_prom_memory(void)
95{
96}
97
98void __init device_tree_init(void)
99{
100 if (!initial_boot_params)
101 return;
102
103 unflatten_and_copy_device_tree();
104}
105
106static struct pic32_sdhci_platform_data sdhci_data = {
107 .setup_dma = pic32_set_sdhci_adma_fifo_threshold,
108};
109
110static struct of_dev_auxdata pic32_auxdata_lookup[] __initdata = {
111 OF_DEV_AUXDATA("microchip,pic32mzda-sdhci", 0, "sdhci", &sdhci_data),
112 { /* sentinel */}
113};
114
115static int __init pic32_of_prepare_platform_data(struct of_dev_auxdata *lookup)
116{
117 struct device_node *root, *np;
118 struct resource res;
119
120 root = of_find_node_by_path("/");
121
122 for (; lookup->compatible; lookup++) {
123 np = of_find_compatible_node(NULL, NULL, lookup->compatible);
124 if (np) {
125 lookup->name = (char *)np->name;
126 if (lookup->phys_addr)
127 continue;
128 if (!of_address_to_resource(np, 0, &res))
129 lookup->phys_addr = res.start;
130 }
131 }
132
133 return 0;
134}
135
136static int __init plat_of_setup(void)
137{
138 if (!of_have_populated_dt())
139 panic("Device tree not present");
140
141 pic32_of_prepare_platform_data(pic32_auxdata_lookup);
142 if (of_platform_default_populate(NULL, pic32_auxdata_lookup, NULL))
143 panic("Failed to populate DT");
144
145 return 0;
146}
147arch_initcall(plat_of_setup);
diff --git a/arch/mips/pic32/pic32mzda/pic32mzda.h b/arch/mips/pic32/pic32mzda/pic32mzda.h
new file mode 100644
index 000000000..b7a93d8fe
--- /dev/null
+++ b/arch/mips/pic32/pic32mzda/pic32mzda.h
@@ -0,0 +1,21 @@
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Joshua Henderson <joshua.henderson@microchip.com>
4 * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
5 */
6#ifndef PIC32MZDA_COMMON_H
7#define PIC32MZDA_COMMON_H
8
9/* early clock */
10u32 pic32_get_pbclk(int bus);
11u32 pic32_get_sysclk(void);
12
13/* Device configuration */
14void __init pic32_config_init(void);
15int pic32_set_lcd_mode(int mode);
16int pic32_set_sdhci_adma_fifo_threshold(u32 rthrs, u32 wthrs);
17u32 pic32_get_boot_status(void);
18int pic32_disable_lcd(void);
19int pic32_enable_lcd(void);
20
21#endif
diff --git a/arch/mips/pic32/pic32mzda/time.c b/arch/mips/pic32/pic32mzda/time.c
new file mode 100644
index 000000000..7174e9abb
--- /dev/null
+++ b/arch/mips/pic32/pic32mzda/time.c
@@ -0,0 +1,60 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Joshua Henderson <joshua.henderson@microchip.com>
4 * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
5 */
6#include <linux/clocksource.h>
7#include <linux/init.h>
8#include <linux/irqdomain.h>
9#include <linux/of.h>
10#include <linux/of_clk.h>
11#include <linux/of_irq.h>
12
13#include <asm/time.h>
14
15#include "pic32mzda.h"
16
17static const struct of_device_id pic32_infra_match[] = {
18 { .compatible = "microchip,pic32mzda-infra", },
19 { },
20};
21
22#define DEFAULT_CORE_TIMER_INTERRUPT 0
23
24static unsigned int pic32_xlate_core_timer_irq(void)
25{
26 struct device_node *node;
27 unsigned int irq;
28
29 node = of_find_matching_node(NULL, pic32_infra_match);
30
31 if (WARN_ON(!node))
32 goto default_map;
33
34 irq = irq_of_parse_and_map(node, 0);
35 if (!irq)
36 goto default_map;
37
38 return irq;
39
40default_map:
41
42 return irq_create_mapping(NULL, DEFAULT_CORE_TIMER_INTERRUPT);
43}
44
45unsigned int get_c0_compare_int(void)
46{
47 return pic32_xlate_core_timer_irq();
48}
49
50void __init plat_time_init(void)
51{
52 unsigned long rate = pic32_get_pbclk(7);
53
54 of_clk_init(NULL);
55
56 pr_info("CPU Clock: %ldMHz\n", rate / 1000000);
57 mips_hpt_frequency = rate / 2;
58
59 timer_probe();
60}