sb_scd.c revision 195333
1195333Simp/*-
2195333Simp * Copyright (c) 2009 Neelkanth Natu
3195333Simp * All rights reserved.
4195333Simp *
5195333Simp * Redistribution and use in source and binary forms, with or without
6195333Simp * modification, are permitted provided that the following conditions
7195333Simp * are met:
8195333Simp * 1. Redistributions of source code must retain the above copyright
9195333Simp *    notice, this list of conditions and the following disclaimer.
10195333Simp * 2. Redistributions in binary form must reproduce the above copyright
11195333Simp *    notice, this list of conditions and the following disclaimer in the
12195333Simp *    documentation and/or other materials provided with the distribution.
13195333Simp *
14195333Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15195333Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16195333Simp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17195333Simp * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18195333Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19195333Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20195333Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21195333Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22195333Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23195333Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24195333Simp * SUCH DAMAGE.
25195333Simp */
26195333Simp#include <sys/param.h>
27195333Simp#include <sys/kernel.h>
28195333Simp#include <sys/systm.h>
29195333Simp#include <sys/module.h>
30195333Simp#include <sys/bus.h>
31195333Simp
32195333Simp#include <machine/resource.h>
33195333Simp
34195333Simp#include "sb_scd.h"
35195333Simp
36195333Simp__FBSDID("$FreeBSD: projects/mips/sys/mips/sibyte/sb_scd.c 195333 2009-07-04 03:05:48Z imp $");
37195333Simp
38195333Simp/*
39195333Simp * System Control and Debug (SCD) unit on the Sibyte ZBbus.
40195333Simp */
41195333Simp
42195333Simp/*
43195333Simp * Extract the value starting at bit position 'b' for 'n' bits from 'x'.
44195333Simp */
45195333Simp#define	GET_VAL_64(x, b, n)	(((x) >> (b)) & ((1ULL << (n)) - 1))
46195333Simp
47195333Simp#define SYSCFG_PLLDIV(x)	GET_VAL_64((x), 7, 5)
48195333Simp
49195333Simpuint64_t
50195333Simpsb_cpu_speed(void)
51195333Simp{
52195333Simp	int plldiv;
53195333Simp	const uint64_t MHZ = 1000000;
54195333Simp
55195333Simp	plldiv = SYSCFG_PLLDIV(sb_read_syscfg());
56195333Simp	if (plldiv == 0) {
57195333Simp		printf("PLL_DIV is 0 - assuming 6 (300MHz).\n");
58195333Simp		plldiv = 6;
59195333Simp	}
60195333Simp
61195333Simp	return (plldiv * 50 * MHZ);
62195333Simp}
63195333Simp
64195333Simpvoid
65195333Simpsb_system_reset(void)
66195333Simp{
67195333Simp	uint64_t syscfg;
68195333Simp
69195333Simp	const uint64_t SYSTEM_RESET = 1ULL << 60;
70195333Simp	const uint64_t EXT_RESET = 1ULL << 59;
71195333Simp	const uint64_t SOFT_RESET = 1ULL << 58;
72195333Simp
73195333Simp	syscfg = sb_read_syscfg();
74195333Simp	syscfg &= ~SOFT_RESET;
75195333Simp	syscfg |= SYSTEM_RESET | EXT_RESET;
76195333Simp	sb_write_syscfg(syscfg);
77195333Simp}
78195333Simp
79195333Simpint
80195333Simpsb_route_intsrc(int intsrc)
81195333Simp{
82195333Simp	int intrnum;
83195333Simp
84195333Simp	KASSERT(intsrc >= 0 && intsrc < NUM_INTSRC,
85195333Simp		("Invalid interrupt source number (%d)", intsrc));
86195333Simp
87195333Simp	/*
88195333Simp	 * Interrupt 5 is used by sources internal to the CPU (e.g. timer).
89195333Simp	 * Use a deterministic mapping for the remaining sources to map to
90195333Simp	 * interrupt numbers 0 through 4.
91195333Simp	 */
92195333Simp	intrnum = intsrc % 5;
93195333Simp
94195333Simp	/*
95195333Simp	 * Program the interrupt mapper while we are here.
96195333Simp	 */
97195333Simp	sb_write_intmap(intsrc, intrnum);
98195333Simp
99195333Simp	return (intrnum);
100195333Simp}
101195333Simp
102195333Simp#define	SCD_PHYSADDR	0x10000000
103195333Simp#define	SCD_SIZE	0x00060000
104195333Simp
105195333Simpstatic int
106195333Simpscd_probe(device_t dev)
107195333Simp{
108195333Simp
109195333Simp	device_set_desc(dev, "Broadcom/Sibyte System Control and Debug");
110195333Simp	return (0);
111195333Simp}
112195333Simp
113195333Simpstatic int
114195333Simpscd_attach(device_t dev)
115195333Simp{
116195333Simp	int rid;
117195333Simp	struct resource *res;
118195333Simp
119195333Simp	if (bootverbose) {
120195333Simp		device_printf(dev, "attached.\n");
121195333Simp	}
122195333Simp
123195333Simp	rid = 0;
124195333Simp	res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, SCD_PHYSADDR,
125195333Simp				 SCD_PHYSADDR + SCD_SIZE - 1, SCD_SIZE, 0);
126195333Simp	if (res == NULL) {
127195333Simp		panic("Cannot allocate resource for system control and debug.");
128195333Simp	}
129195333Simp
130195333Simp	return (0);
131195333Simp}
132195333Simp
133195333Simpstatic device_method_t scd_methods[] ={
134195333Simp	/* Device interface */
135195333Simp	DEVMETHOD(device_probe,		scd_probe),
136195333Simp	DEVMETHOD(device_attach,	scd_attach),
137195333Simp	DEVMETHOD(device_detach,	bus_generic_detach),
138195333Simp	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
139195333Simp	DEVMETHOD(device_suspend,	bus_generic_suspend),
140195333Simp	DEVMETHOD(device_resume,	bus_generic_resume),
141195333Simp
142195333Simp	{ 0, 0 }
143195333Simp};
144195333Simp
145195333Simpstatic driver_t scd_driver = {
146195333Simp	"scd",
147195333Simp	scd_methods
148195333Simp};
149195333Simp
150195333Simpstatic devclass_t scd_devclass;
151195333Simp
152195333SimpDRIVER_MODULE(scd, zbbus, scd_driver, scd_devclass, 0, 0);
153