xref: /freebsd/sys/arm/annapurna/alpine/alpine_machdep.c (revision 781a630db6fecfb26ab5e3ee97b4d9b4c87de406)
14d892e4fSZbigniew Bodek /*-
24d892e4fSZbigniew Bodek  * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
34d892e4fSZbigniew Bodek  * Copyright (c) 2015 Semihalf
44d892e4fSZbigniew Bodek  * All rights reserved.
54d892e4fSZbigniew Bodek  *
64d892e4fSZbigniew Bodek  * Redistribution and use in source and binary forms, with or without
74d892e4fSZbigniew Bodek  * modification, are permitted provided that the following conditions
84d892e4fSZbigniew Bodek  * are met:
94d892e4fSZbigniew Bodek  * 1. Redistributions of source code must retain the above copyright
104d892e4fSZbigniew Bodek  *    notice, this list of conditions and the following disclaimer.
114d892e4fSZbigniew Bodek  * 2. Redistributions in binary form must reproduce the above copyright
124d892e4fSZbigniew Bodek  *    notice, this list of conditions and the following disclaimer in the
134d892e4fSZbigniew Bodek  *    documentation and/or other materials provided with the distribution.
144d892e4fSZbigniew Bodek  *
154d892e4fSZbigniew Bodek  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
164d892e4fSZbigniew Bodek  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
174d892e4fSZbigniew Bodek  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
184d892e4fSZbigniew Bodek  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
194d892e4fSZbigniew Bodek  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
204d892e4fSZbigniew Bodek  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
214d892e4fSZbigniew Bodek  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
224d892e4fSZbigniew Bodek  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
234d892e4fSZbigniew Bodek  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
244d892e4fSZbigniew Bodek  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
254d892e4fSZbigniew Bodek  * SUCH DAMAGE.
264d892e4fSZbigniew Bodek  *
274d892e4fSZbigniew Bodek  */
284d892e4fSZbigniew Bodek 
29c20963adSAndrew Turner #include "opt_ddb.h"
30c20963adSAndrew Turner #include "opt_platform.h"
31c20963adSAndrew Turner 
324d892e4fSZbigniew Bodek #include <sys/param.h>
334d892e4fSZbigniew Bodek #include <sys/systm.h>
344d892e4fSZbigniew Bodek #include <sys/bus.h>
35*781a630dSOskar Holmlund #include <sys/devmap.h>
364d892e4fSZbigniew Bodek 
374d892e4fSZbigniew Bodek #include <vm/vm.h>
384d892e4fSZbigniew Bodek #include <vm/pmap.h>
394d892e4fSZbigniew Bodek 
404d892e4fSZbigniew Bodek #include <machine/bus.h>
414d892e4fSZbigniew Bodek #include <machine/fdt.h>
42c20963adSAndrew Turner #include <machine/platformvar.h>
434d892e4fSZbigniew Bodek 
44c20963adSAndrew Turner #include <dev/fdt/fdt_common.h>
45c20963adSAndrew Turner #include <dev/ofw/openfirm.h>
464d892e4fSZbigniew Bodek 
47c20963adSAndrew Turner #include <arm/annapurna/alpine/alpine_mp.h>
48c20963adSAndrew Turner 
49c20963adSAndrew Turner #include "platform_if.h"
50c20963adSAndrew Turner 
51c20963adSAndrew Turner #define	WDTLOAD		0x000
52c20963adSAndrew Turner #define	LOAD_MIN	0x00000001
53c20963adSAndrew Turner #define	LOAD_MAX	0xFFFFFFFF
54c20963adSAndrew Turner #define	WDTVALUE	0x004
55c20963adSAndrew Turner #define	WDTCONTROL	0x008
56c20963adSAndrew Turner /* control register masks */
57c20963adSAndrew Turner #define	INT_ENABLE	(1 << 0)
58c20963adSAndrew Turner #define	RESET_ENABLE	(1 << 1)
59c20963adSAndrew Turner #define	WDTLOCK		0xC00
60c20963adSAndrew Turner #define	UNLOCK		0x1ACCE551
61c20963adSAndrew Turner #define	LOCK		0x00000001
62c20963adSAndrew Turner 
634d892e4fSZbigniew Bodek bus_addr_t al_devmap_pa;
644d892e4fSZbigniew Bodek bus_addr_t al_devmap_size;
654d892e4fSZbigniew Bodek 
66c20963adSAndrew Turner static int
alpine_get_devmap_base(bus_addr_t * pa,bus_addr_t * size)67c20963adSAndrew Turner alpine_get_devmap_base(bus_addr_t *pa, bus_addr_t *size)
684d892e4fSZbigniew Bodek {
69c20963adSAndrew Turner 	phandle_t node;
704d892e4fSZbigniew Bodek 
71108117ccSOleksandr Tymoshenko 	if ((node = OF_finddevice("/")) == -1)
72c20963adSAndrew Turner 		return (ENXIO);
73c20963adSAndrew Turner 
74c20963adSAndrew Turner 	if ((node = fdt_find_compatible(node, "simple-bus", 1)) == 0)
75c20963adSAndrew Turner 		return (ENXIO);
76c20963adSAndrew Turner 
77c20963adSAndrew Turner 	return fdt_get_range(node, 0, pa, size);
784d892e4fSZbigniew Bodek }
794d892e4fSZbigniew Bodek 
80c20963adSAndrew Turner static int
alpine_get_wdt_base(uint32_t * pbase,uint32_t * psize)81c20963adSAndrew Turner alpine_get_wdt_base(uint32_t *pbase, uint32_t *psize)
824d892e4fSZbigniew Bodek {
83c20963adSAndrew Turner 	phandle_t node;
84c20963adSAndrew Turner 	u_long base = 0;
85c20963adSAndrew Turner 	u_long size = 0;
864d892e4fSZbigniew Bodek 
87c20963adSAndrew Turner 	if (pbase == NULL || psize == NULL)
88c20963adSAndrew Turner 		return (EINVAL);
894d892e4fSZbigniew Bodek 
90c20963adSAndrew Turner 	if ((node = OF_finddevice("/")) == -1)
91c20963adSAndrew Turner 		return (EFAULT);
924d892e4fSZbigniew Bodek 
93c20963adSAndrew Turner 	if ((node = fdt_find_compatible(node, "simple-bus", 1)) == 0)
94c20963adSAndrew Turner 		return (EFAULT);
954d892e4fSZbigniew Bodek 
96c20963adSAndrew Turner 	if ((node =
97c20963adSAndrew Turner 	    fdt_find_compatible(node, "arm,sp805", 1)) == 0)
98c20963adSAndrew Turner 		return (EFAULT);
994d892e4fSZbigniew Bodek 
100c20963adSAndrew Turner 	if (fdt_regsize(node, &base, &size))
101c20963adSAndrew Turner 		return (EFAULT);
102c20963adSAndrew Turner 
103c20963adSAndrew Turner 	*pbase = base;
104c20963adSAndrew Turner 	*psize = size;
105c20963adSAndrew Turner 
106c20963adSAndrew Turner 	return (0);
1074d892e4fSZbigniew Bodek }
1084d892e4fSZbigniew Bodek 
1094d892e4fSZbigniew Bodek /*
110e81df523SSvatopluk Kraus  * Construct devmap table with DT-derived config data.
1114d892e4fSZbigniew Bodek  */
112c20963adSAndrew Turner static int
alpine_devmap_init(platform_t plat)113c20963adSAndrew Turner alpine_devmap_init(platform_t plat)
1144d892e4fSZbigniew Bodek {
1154d892e4fSZbigniew Bodek 	alpine_get_devmap_base(&al_devmap_pa, &al_devmap_size);
11630b72b68SRuslan Bukin 	devmap_add_entry(al_devmap_pa, al_devmap_size);
1174d892e4fSZbigniew Bodek 	return (0);
1184d892e4fSZbigniew Bodek }
119c20963adSAndrew Turner 
120c20963adSAndrew Turner static void
alpine_cpu_reset(platform_t plat)121c20963adSAndrew Turner alpine_cpu_reset(platform_t plat)
122c20963adSAndrew Turner {
123c20963adSAndrew Turner 	uint32_t wdbase, wdsize;
124c20963adSAndrew Turner 	bus_addr_t wdbaddr;
125c20963adSAndrew Turner 	int ret;
126c20963adSAndrew Turner 
127c20963adSAndrew Turner 	ret = alpine_get_wdt_base(&wdbase, &wdsize);
128c20963adSAndrew Turner 	if (ret) {
129c20963adSAndrew Turner 		printf("Unable to get WDT base, do power down manually...");
130c20963adSAndrew Turner 		goto infinite;
131c20963adSAndrew Turner 	}
132c20963adSAndrew Turner 
133c20963adSAndrew Turner 	ret = bus_space_map(fdtbus_bs_tag, al_devmap_pa + wdbase,
134c20963adSAndrew Turner 	    wdsize, 0, &wdbaddr);
135c20963adSAndrew Turner 	if (ret) {
136c20963adSAndrew Turner 		printf("Unable to map WDT base, do power down manually...");
137c20963adSAndrew Turner 		goto infinite;
138c20963adSAndrew Turner 	}
139c20963adSAndrew Turner 
140c20963adSAndrew Turner 	bus_space_write_4(fdtbus_bs_tag, wdbaddr, WDTLOCK, UNLOCK);
141c20963adSAndrew Turner 	bus_space_write_4(fdtbus_bs_tag, wdbaddr, WDTLOAD, LOAD_MIN);
142c20963adSAndrew Turner 	bus_space_write_4(fdtbus_bs_tag, wdbaddr, WDTCONTROL,
143c20963adSAndrew Turner 	    INT_ENABLE | RESET_ENABLE);
144c20963adSAndrew Turner 
145c20963adSAndrew Turner infinite:
146c20963adSAndrew Turner 	while (1) {}
147c20963adSAndrew Turner }
148c20963adSAndrew Turner 
149c20963adSAndrew Turner static platform_method_t alpine_methods[] = {
150c20963adSAndrew Turner 	PLATFORMMETHOD(platform_devmap_init,	alpine_devmap_init),
151c20963adSAndrew Turner 	PLATFORMMETHOD(platform_cpu_reset,	alpine_cpu_reset),
152c20963adSAndrew Turner 
153c20963adSAndrew Turner #ifdef SMP
154c20963adSAndrew Turner 	PLATFORMMETHOD(platform_mp_start_ap,	alpine_mp_start_ap),
155c20963adSAndrew Turner 	PLATFORMMETHOD(platform_mp_setmaxid,	alpine_mp_setmaxid),
156c20963adSAndrew Turner #endif
157c20963adSAndrew Turner 	PLATFORMMETHOD_END,
158c20963adSAndrew Turner };
159c20963adSAndrew Turner FDT_PLATFORM_DEF(alpine, "alpine", 0, "annapurna,alpine", 200);
160