xref: /freebsd/sys/arm/mv/armada38x/armada38x.c (revision b0b1dbdd)
1 /*-
2  * Copyright (c) 2015 Semihalf.
3  * Copyright (c) 2015 Stormshield.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30 
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/bus.h>
34 
35 #include <machine/fdt.h>
36 
37 #include <arm/mv/mvwin.h>
38 #include <arm/mv/mvreg.h>
39 #include <arm/mv/mvvar.h>
40 
41 int armada38x_open_bootrom_win(void);
42 int armada38x_scu_enable(void);
43 int armada38x_win_set_iosync_barrier(void);
44 
45 uint32_t
46 get_tclk(void)
47 {
48 	uint32_t sar;
49 
50 	/*
51 	 * On Armada38x TCLK can be configured to 250 MHz or 200 MHz.
52 	 * Current setting is read from Sample At Reset register.
53 	 */
54 	sar = (uint32_t)get_sar_value();
55 	sar = (sar & TCLK_MASK) >> TCLK_SHIFT;
56 	if (sar == 0)
57 		return (TCLK_250MHZ);
58 	else
59 		return (TCLK_200MHZ);
60 }
61 
62 int
63 armada38x_win_set_iosync_barrier(void)
64 {
65 	bus_space_handle_t vaddr_iowind;
66 	int rv;
67 
68 	rv = bus_space_map(fdtbus_bs_tag, (bus_addr_t)MV_MBUS_BRIDGE_BASE,
69 	    MV_CPU_SUBSYS_REGS_LEN, 0, &vaddr_iowind);
70 	if (rv != 0)
71 		return (rv);
72 
73 	/* Set Sync Barrier flags for all Mbus internal units */
74 	bus_space_write_4(fdtbus_bs_tag, vaddr_iowind, MV_SYNC_BARRIER_CTRL,
75 	    MV_SYNC_BARRIER_CTRL_ALL);
76 
77 	bus_space_barrier(fdtbus_bs_tag, vaddr_iowind, 0,
78 	    MV_CPU_SUBSYS_REGS_LEN, BUS_SPACE_BARRIER_WRITE);
79 	bus_space_unmap(fdtbus_bs_tag, vaddr_iowind, MV_CPU_SUBSYS_REGS_LEN);
80 
81 	return (rv);
82 }
83 
84 int
85 armada38x_open_bootrom_win(void)
86 {
87 	bus_space_handle_t vaddr_iowind;
88 	uint32_t val;
89 	int rv;
90 
91 	rv = bus_space_map(fdtbus_bs_tag, (bus_addr_t)MV_MBUS_BRIDGE_BASE,
92 	    MV_CPU_SUBSYS_REGS_LEN, 0, &vaddr_iowind);
93 	if (rv != 0)
94 		return (rv);
95 
96 	val = (MV_BOOTROM_WIN_SIZE & IO_WIN_SIZE_MASK) << IO_WIN_SIZE_SHIFT;
97 	val |= (MBUS_BOOTROM_ATTR & IO_WIN_ATTR_MASK) << IO_WIN_ATTR_SHIFT;
98 	val |= (MBUS_BOOTROM_TGT_ID & IO_WIN_TGT_MASK) << IO_WIN_TGT_SHIFT;
99 	/* Enable window and Sync Barrier */
100 	val |= (0x1 & IO_WIN_SYNC_MASK) << IO_WIN_SYNC_SHIFT;
101 	val |= (0x1 & IO_WIN_ENA_MASK) << IO_WIN_ENA_SHIFT;
102 
103 	/* Configure IO Window Control Register */
104 	bus_space_write_4(fdtbus_bs_tag, vaddr_iowind, IO_WIN_9_CTRL_OFFSET,
105 	    val);
106 	/* Configure IO Window Base Register */
107 	bus_space_write_4(fdtbus_bs_tag, vaddr_iowind, IO_WIN_9_BASE_OFFSET,
108 	    MV_BOOTROM_MEM_ADDR);
109 
110 	bus_space_barrier(fdtbus_bs_tag, vaddr_iowind, 0, MV_CPU_SUBSYS_REGS_LEN,
111 	    BUS_SPACE_BARRIER_WRITE);
112 	bus_space_unmap(fdtbus_bs_tag, vaddr_iowind, MV_CPU_SUBSYS_REGS_LEN);
113 
114 	return (rv);
115 }
116 
117 int
118 armada38x_scu_enable(void)
119 {
120 	bus_space_handle_t vaddr_scu;
121 	int rv;
122 	uint32_t val;
123 
124 	rv = bus_space_map(fdtbus_bs_tag, (bus_addr_t)MV_SCU_BASE,
125 	    MV_SCU_REGS_LEN, 0, &vaddr_scu);
126 	if (rv != 0)
127 		return (rv);
128 
129 	/* Enable SCU */
130 	val = bus_space_read_4(fdtbus_bs_tag, vaddr_scu, MV_SCU_REG_CTRL);
131 	if (!(val & MV_SCU_ENABLE))
132 		bus_space_write_4(fdtbus_bs_tag, vaddr_scu, 0,
133 		    val | MV_SCU_ENABLE);
134 
135 	bus_space_unmap(fdtbus_bs_tag, vaddr_scu, MV_SCU_REGS_LEN);
136 	return (0);
137 }
138