1/*-
2 * Copyright 2015 John Wehle <john@feith.com>
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 */
27
28/*
29 * Amlogic aml8726 SoC identification.
30 *
31 * The SoC identification is used by some of the drivers in order to
32 * handle hardware differences so the identification needs to happen
33 * early in the boot process (e.g. before SMP startup).
34 *
35 * It's expected that the register addresses for identifying the SoC
36 * are set in stone.
37 *
38 * Currently missing an entry for the aml8726-m and doesn't distinguish
39 * between the m801, m802, m805, s802, s805, and s812 which are all
40 * variations of the aml8726-m8.
41 */
42
43#include <sys/cdefs.h>
44__FBSDID("$FreeBSD: stable/11/sys/arm/amlogic/aml8726/aml8726_identsoc.c 314506 2017-03-01 19:55:04Z ian $");
45
46#include <sys/param.h>
47#include <sys/systm.h>
48#include <sys/bus.h>
49#include <sys/clock.h>
50#include <sys/kernel.h>
51#include <sys/module.h>
52#include <sys/lock.h>
53#include <sys/mutex.h>
54#include <sys/resource.h>
55#include <sys/rman.h>
56
57#include <machine/bus.h>
58#include <machine/fdt.h>
59
60#include <arm/amlogic/aml8726/aml8726_soc.h>
61
62uint32_t aml8726_soc_hw_rev = AML_SOC_HW_REV_UNKNOWN;
63uint32_t aml8726_soc_metal_rev = AML_SOC_METAL_REV_UNKNOWN;
64
65static const struct {
66	uint32_t hw_rev;
67	char *desc;
68} aml8726_soc_desc[] = {
69	{ AML_SOC_HW_REV_M3,	"aml8726-m3" },
70	{ AML_SOC_HW_REV_M6,	"aml8726-m6" },
71	{ AML_SOC_HW_REV_M6TV,	"aml8726-m6tv" },
72	{ AML_SOC_HW_REV_M6TVL,	"aml8726-m6tvl" },
73	{ AML_SOC_HW_REV_M8,	"aml8726-m8" },
74	{ AML_SOC_HW_REV_M8B,	"aml8726-m8b" },
75	{ 0xff, NULL }
76};
77
78static const struct {
79	uint32_t metal_rev;
80	char *desc;
81} aml8726_m8_soc_rev[] = {
82	{ AML_SOC_M8_METAL_REV_A,	"A" },
83	{ AML_SOC_M8_METAL_REV_M2_A,	"MarkII A" },
84	{ AML_SOC_M8_METAL_REV_B,	"B" },
85	{ AML_SOC_M8_METAL_REV_C,	"C" },
86	{ 0xff, NULL }
87};
88
89void
90aml8726_identify_soc(void)
91{
92	int err;
93	struct resource res;
94
95	memset(&res, 0, sizeof(res));
96
97	res.r_bustag = fdtbus_bs_tag;
98
99	err = bus_space_map(res.r_bustag, AML_SOC_CBUS_BASE_ADDR, 0x100000,
100	    0, &res.r_bushandle);
101
102	if (err)
103		panic("Could not allocate resource for SoC identification\n");
104
105	aml8726_soc_hw_rev = bus_read_4(&res, AML_SOC_HW_REV_REG);
106
107	aml8726_soc_metal_rev = bus_read_4(&res, AML_SOC_METAL_REV_REG);
108
109	bus_space_unmap(res.r_bustag, res.r_bushandle, 0x100000);
110}
111
112static void
113aml8726_identify_announce_soc(void *dummy)
114{
115	int i;
116
117	for (i = 0; aml8726_soc_desc[i].desc; i++)
118		if (aml8726_soc_desc[i].hw_rev == aml8726_soc_hw_rev)
119			break;
120
121	if (aml8726_soc_desc[i].desc == NULL)
122		panic("Amlogic unknown aml8726 SoC %#x\n", aml8726_soc_hw_rev);
123
124	printf("Amlogic %s SoC", aml8726_soc_desc[i].desc);
125
126	if (aml8726_soc_hw_rev == AML_SOC_HW_REV_M8) {
127		for (i = 0; aml8726_m8_soc_rev[i].desc; i++)
128			if (aml8726_m8_soc_rev[i].metal_rev ==
129			    aml8726_soc_metal_rev)
130				break;
131
132		if (aml8726_m8_soc_rev[i].desc == NULL)
133			printf(", unknown rev %#x", aml8726_soc_metal_rev);
134		else
135			printf(", rev %s", aml8726_m8_soc_rev[i].desc);
136	}
137
138	printf("\n");
139}
140
141SYSINIT(aml8726_identify_announce_soc, SI_SUB_CPU, SI_ORDER_SECOND,
142    aml8726_identify_announce_soc, NULL);
143