sb_scd.c revision 195333
1/*-
2 * Copyright (c) 2009 Neelkanth Natu
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26#include <sys/param.h>
27#include <sys/kernel.h>
28#include <sys/systm.h>
29#include <sys/module.h>
30#include <sys/bus.h>
31
32#include <machine/resource.h>
33
34#include "sb_scd.h"
35
36__FBSDID("$FreeBSD: projects/mips/sys/mips/sibyte/sb_scd.c 195333 2009-07-04 03:05:48Z imp $");
37
38/*
39 * System Control and Debug (SCD) unit on the Sibyte ZBbus.
40 */
41
42/*
43 * Extract the value starting at bit position 'b' for 'n' bits from 'x'.
44 */
45#define	GET_VAL_64(x, b, n)	(((x) >> (b)) & ((1ULL << (n)) - 1))
46
47#define SYSCFG_PLLDIV(x)	GET_VAL_64((x), 7, 5)
48
49uint64_t
50sb_cpu_speed(void)
51{
52	int plldiv;
53	const uint64_t MHZ = 1000000;
54
55	plldiv = SYSCFG_PLLDIV(sb_read_syscfg());
56	if (plldiv == 0) {
57		printf("PLL_DIV is 0 - assuming 6 (300MHz).\n");
58		plldiv = 6;
59	}
60
61	return (plldiv * 50 * MHZ);
62}
63
64void
65sb_system_reset(void)
66{
67	uint64_t syscfg;
68
69	const uint64_t SYSTEM_RESET = 1ULL << 60;
70	const uint64_t EXT_RESET = 1ULL << 59;
71	const uint64_t SOFT_RESET = 1ULL << 58;
72
73	syscfg = sb_read_syscfg();
74	syscfg &= ~SOFT_RESET;
75	syscfg |= SYSTEM_RESET | EXT_RESET;
76	sb_write_syscfg(syscfg);
77}
78
79int
80sb_route_intsrc(int intsrc)
81{
82	int intrnum;
83
84	KASSERT(intsrc >= 0 && intsrc < NUM_INTSRC,
85		("Invalid interrupt source number (%d)", intsrc));
86
87	/*
88	 * Interrupt 5 is used by sources internal to the CPU (e.g. timer).
89	 * Use a deterministic mapping for the remaining sources to map to
90	 * interrupt numbers 0 through 4.
91	 */
92	intrnum = intsrc % 5;
93
94	/*
95	 * Program the interrupt mapper while we are here.
96	 */
97	sb_write_intmap(intsrc, intrnum);
98
99	return (intrnum);
100}
101
102#define	SCD_PHYSADDR	0x10000000
103#define	SCD_SIZE	0x00060000
104
105static int
106scd_probe(device_t dev)
107{
108
109	device_set_desc(dev, "Broadcom/Sibyte System Control and Debug");
110	return (0);
111}
112
113static int
114scd_attach(device_t dev)
115{
116	int rid;
117	struct resource *res;
118
119	if (bootverbose) {
120		device_printf(dev, "attached.\n");
121	}
122
123	rid = 0;
124	res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, SCD_PHYSADDR,
125				 SCD_PHYSADDR + SCD_SIZE - 1, SCD_SIZE, 0);
126	if (res == NULL) {
127		panic("Cannot allocate resource for system control and debug.");
128	}
129
130	return (0);
131}
132
133static device_method_t scd_methods[] ={
134	/* Device interface */
135	DEVMETHOD(device_probe,		scd_probe),
136	DEVMETHOD(device_attach,	scd_attach),
137	DEVMETHOD(device_detach,	bus_generic_detach),
138	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
139	DEVMETHOD(device_suspend,	bus_generic_suspend),
140	DEVMETHOD(device_resume,	bus_generic_resume),
141
142	{ 0, 0 }
143};
144
145static driver_t scd_driver = {
146	"scd",
147	scd_methods
148};
149
150static devclass_t scd_devclass;
151
152DRIVER_MODULE(scd, zbbus, scd_driver, scd_devclass, 0, 0);
153