1280905Sganbold/*-
2280905Sganbold * Copyright 2015 John Wehle <john@feith.com>
3280905Sganbold * All rights reserved.
4280905Sganbold *
5280905Sganbold * Redistribution and use in source and binary forms, with or without
6280905Sganbold * modification, are permitted provided that the following conditions
7280905Sganbold * are met:
8280905Sganbold * 1. Redistributions of source code must retain the above copyright
9280905Sganbold *    notice, this list of conditions and the following disclaimer.
10280905Sganbold * 2. Redistributions in binary form must reproduce the above copyright
11280905Sganbold *    notice, this list of conditions and the following disclaimer in the
12280905Sganbold *    documentation and/or other materials provided with the distribution.
13280905Sganbold *
14280905Sganbold * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15280905Sganbold * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16280905Sganbold * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17280905Sganbold * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18280905Sganbold * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19280905Sganbold * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20280905Sganbold * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21280905Sganbold * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22280905Sganbold * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23280905Sganbold * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24280905Sganbold * SUCH DAMAGE.
25280905Sganbold *
26280905Sganbold */
27280905Sganbold
28280905Sganbold/*
29280905Sganbold * Amlogic aml8726 SoC identification.
30280905Sganbold *
31280905Sganbold * The SoC identification is used by some of the drivers in order to
32280905Sganbold * handle hardware differences so the identification needs to happen
33280905Sganbold * early in the boot process (e.g. before SMP startup).
34280905Sganbold *
35280905Sganbold * It's expected that the register addresses for identifying the SoC
36280905Sganbold * are set in stone.
37280905Sganbold *
38280905Sganbold * Currently missing an entry for the aml8726-m and doesn't distinguish
39280905Sganbold * between the m801, m802, m805, s802, s805, and s812 which are all
40280905Sganbold * variations of the aml8726-m8.
41280905Sganbold */
42280905Sganbold
43280905Sganbold#include <sys/cdefs.h>
44280905Sganbold__FBSDID("$FreeBSD: stable/11/sys/arm/amlogic/aml8726/aml8726_identsoc.c 314506 2017-03-01 19:55:04Z ian $");
45280905Sganbold
46280905Sganbold#include <sys/param.h>
47280905Sganbold#include <sys/systm.h>
48280905Sganbold#include <sys/bus.h>
49280905Sganbold#include <sys/clock.h>
50280905Sganbold#include <sys/kernel.h>
51280905Sganbold#include <sys/module.h>
52280905Sganbold#include <sys/lock.h>
53280905Sganbold#include <sys/mutex.h>
54280905Sganbold#include <sys/resource.h>
55280905Sganbold#include <sys/rman.h>
56280905Sganbold
57280905Sganbold#include <machine/bus.h>
58280905Sganbold#include <machine/fdt.h>
59280905Sganbold
60280905Sganbold#include <arm/amlogic/aml8726/aml8726_soc.h>
61280905Sganbold
62281418Sganbolduint32_t aml8726_soc_hw_rev = AML_SOC_HW_REV_UNKNOWN;
63281418Sganbolduint32_t aml8726_soc_metal_rev = AML_SOC_METAL_REV_UNKNOWN;
64280905Sganbold
65280905Sganboldstatic const struct {
66280905Sganbold	uint32_t hw_rev;
67280905Sganbold	char *desc;
68280905Sganbold} aml8726_soc_desc[] = {
69280905Sganbold	{ AML_SOC_HW_REV_M3,	"aml8726-m3" },
70280905Sganbold	{ AML_SOC_HW_REV_M6,	"aml8726-m6" },
71280905Sganbold	{ AML_SOC_HW_REV_M6TV,	"aml8726-m6tv" },
72280905Sganbold	{ AML_SOC_HW_REV_M6TVL,	"aml8726-m6tvl" },
73280905Sganbold	{ AML_SOC_HW_REV_M8,	"aml8726-m8" },
74280905Sganbold	{ AML_SOC_HW_REV_M8B,	"aml8726-m8b" },
75280905Sganbold	{ 0xff, NULL }
76280905Sganbold};
77280905Sganbold
78280905Sganboldstatic const struct {
79280905Sganbold	uint32_t metal_rev;
80280905Sganbold	char *desc;
81280905Sganbold} aml8726_m8_soc_rev[] = {
82280905Sganbold	{ AML_SOC_M8_METAL_REV_A,	"A" },
83280905Sganbold	{ AML_SOC_M8_METAL_REV_M2_A,	"MarkII A" },
84280905Sganbold	{ AML_SOC_M8_METAL_REV_B,	"B" },
85280905Sganbold	{ AML_SOC_M8_METAL_REV_C,	"C" },
86280905Sganbold	{ 0xff, NULL }
87280905Sganbold};
88280905Sganbold
89281418Sganboldvoid
90314506Sianaml8726_identify_soc(void)
91280905Sganbold{
92280905Sganbold	int err;
93280905Sganbold	struct resource res;
94280905Sganbold
95280905Sganbold	memset(&res, 0, sizeof(res));
96280905Sganbold
97280905Sganbold	res.r_bustag = fdtbus_bs_tag;
98280905Sganbold
99280905Sganbold	err = bus_space_map(res.r_bustag, AML_SOC_CBUS_BASE_ADDR, 0x100000,
100280905Sganbold	    0, &res.r_bushandle);
101280905Sganbold
102280905Sganbold	if (err)
103280905Sganbold		panic("Could not allocate resource for SoC identification\n");
104280905Sganbold
105280905Sganbold	aml8726_soc_hw_rev = bus_read_4(&res, AML_SOC_HW_REV_REG);
106280905Sganbold
107280905Sganbold	aml8726_soc_metal_rev = bus_read_4(&res, AML_SOC_METAL_REV_REG);
108280905Sganbold
109280905Sganbold	bus_space_unmap(res.r_bustag, res.r_bushandle, 0x100000);
110281418Sganbold}
111280905Sganbold
112281418Sganboldstatic void
113281418Sganboldaml8726_identify_announce_soc(void *dummy)
114281418Sganbold{
115281418Sganbold	int i;
116281418Sganbold
117280905Sganbold	for (i = 0; aml8726_soc_desc[i].desc; i++)
118280905Sganbold		if (aml8726_soc_desc[i].hw_rev == aml8726_soc_hw_rev)
119280905Sganbold			break;
120280905Sganbold
121280905Sganbold	if (aml8726_soc_desc[i].desc == NULL)
122280905Sganbold		panic("Amlogic unknown aml8726 SoC %#x\n", aml8726_soc_hw_rev);
123280905Sganbold
124280905Sganbold	printf("Amlogic %s SoC", aml8726_soc_desc[i].desc);
125280905Sganbold
126280905Sganbold	if (aml8726_soc_hw_rev == AML_SOC_HW_REV_M8) {
127280905Sganbold		for (i = 0; aml8726_m8_soc_rev[i].desc; i++)
128280905Sganbold			if (aml8726_m8_soc_rev[i].metal_rev ==
129280905Sganbold			    aml8726_soc_metal_rev)
130280905Sganbold				break;
131280905Sganbold
132280905Sganbold		if (aml8726_m8_soc_rev[i].desc == NULL)
133280905Sganbold			printf(", unknown rev %#x", aml8726_soc_metal_rev);
134280905Sganbold		else
135280905Sganbold			printf(", rev %s", aml8726_m8_soc_rev[i].desc);
136280905Sganbold	}
137280905Sganbold
138280905Sganbold	printf("\n");
139280905Sganbold}
140280905Sganbold
141281418SganboldSYSINIT(aml8726_identify_announce_soc, SI_SUB_CPU, SI_ORDER_SECOND,
142281418Sganbold    aml8726_identify_announce_soc, NULL);
143