xref: /netbsd-src/sys/arch/mips/atheros/ar_conf.c (revision 97627a755de6688e3779397891de0a51dd226e2f)
1*97627a75Smatt /*	$NetBSD: ar_conf.c,v 1.3 2015/06/09 22:50:50 matt Exp $	*/
281d18a2fSmatt /*-
381d18a2fSmatt  * Copyright (c) 2011 The NetBSD Foundation, Inc.
481d18a2fSmatt  * All rights reserved.
581d18a2fSmatt  *
681d18a2fSmatt  * This code is derived from software contributed to The NetBSD Foundation
781d18a2fSmatt  * by Matt Thomas of 3am Software Foundry.
881d18a2fSmatt  *
981d18a2fSmatt  * Redistribution and use in source and binary forms, with or without
1081d18a2fSmatt  * modification, are permitted provided that the following conditions
1181d18a2fSmatt  * are met:
1281d18a2fSmatt  * 1. Redistributions of source code must retain the above copyright
1381d18a2fSmatt  *    notice, this list of conditions and the following disclaimer.
1481d18a2fSmatt  * 2. Redistributions in binary form must reproduce the above copyright
1581d18a2fSmatt  *    notice, this list of conditions and the following disclaimer in the
1681d18a2fSmatt  *    documentation and/or other materials provided with the distribution.
1781d18a2fSmatt  *
1881d18a2fSmatt  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
1981d18a2fSmatt  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2081d18a2fSmatt  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2181d18a2fSmatt  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2281d18a2fSmatt  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2381d18a2fSmatt  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2481d18a2fSmatt  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2581d18a2fSmatt  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2681d18a2fSmatt  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2781d18a2fSmatt  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2881d18a2fSmatt  * POSSIBILITY OF SUCH DAMAGE.
2981d18a2fSmatt  */
3081d18a2fSmatt 
3181d18a2fSmatt #include <sys/cdefs.h>
3281d18a2fSmatt 
33*97627a75Smatt __KERNEL_RCSID(0, "$NetBSD: ar_conf.c,v 1.3 2015/06/09 22:50:50 matt Exp $");
3481d18a2fSmatt 
3581d18a2fSmatt #include <sys/param.h>
36*97627a75Smatt #include <sys/cpu.h>
3781d18a2fSmatt 
3881d18a2fSmatt #include "opt_wisoc.h"
3981d18a2fSmatt 
4081d18a2fSmatt #include <mips/cpuregs.h>
4181d18a2fSmatt #include <mips/locore.h>
4281d18a2fSmatt 
4381d18a2fSmatt #include <mips/atheros/include/platform.h>
4481d18a2fSmatt #include <mips/atheros/include/ar9344reg.h>
4581d18a2fSmatt 
4681d18a2fSmatt struct atheros_chip {
4781d18a2fSmatt 	const struct atheros_platformsw *ac_platformsw;
4881d18a2fSmatt 	const struct atheros_boardsw *ac_boardsw;
4981d18a2fSmatt 	uint8_t ac_chipid;
5081d18a2fSmatt 	uint8_t ac_chipmask;
5181d18a2fSmatt 	uint8_t ac_cid;
5281d18a2fSmatt 	uint8_t ac_pid;
5381d18a2fSmatt 	const char ac_name[8];
5481d18a2fSmatt };
5581d18a2fSmatt 
5681d18a2fSmatt static const struct atheros_chip chips[] = {
5781d18a2fSmatt #ifdef WISOC_AR5312
5881d18a2fSmatt 	{
5981d18a2fSmatt 		.ac_platformsw =	&ar5312_platformsw,
6081d18a2fSmatt 		.ac_boardsw =		&ar5312_boardsw,
6181d18a2fSmatt 		.ac_chipid =		ARCHIP_AR5312,
6281d18a2fSmatt 		.ac_chipmask =		0xff,
6381d18a2fSmatt 		.ac_cid =		MIPS_PRID_CID_MTI,
6481d18a2fSmatt 		.ac_pid =		MIPS_4Kc,
6581d18a2fSmatt 		.ac_name =		"AR5312"
6681d18a2fSmatt 	},
6781d18a2fSmatt #endif
6881d18a2fSmatt #ifdef WISOC_AR5315
6981d18a2fSmatt 	{
7081d18a2fSmatt 		.ac_platformsw =	&ar5315_platformsw,
7181d18a2fSmatt 		.ac_boardsw =		&ar5315_boardsw,
7281d18a2fSmatt 		.ac_chipid =		ARCHIP_AR5315,
7381d18a2fSmatt 		.ac_chipmask =		0xf0,
7481d18a2fSmatt 		.ac_cid =		MIPS_PRID_CID_MTI,
7581d18a2fSmatt 		.ac_pid =		MIPS_4Kc,
7681d18a2fSmatt 		.ac_name =		"AR5315"
7781d18a2fSmatt 	},
7881d18a2fSmatt #endif
7981d18a2fSmatt #ifdef WISOC_AR7100
8081d18a2fSmatt 	{
8181d18a2fSmatt 		.ac_platformsw =	&ar7100_platformsw,
8281d18a2fSmatt 		.ac_chipid =		ARCHIP_AR7130,
8381d18a2fSmatt 		.ac_chipmask =		0xf3,
8481d18a2fSmatt 		.ac_cid =		MIPS_PRID_CID_MTI,
8581d18a2fSmatt 		.ac_pid =		MIPS_24K,
8681d18a2fSmatt 		.ac_name =		"AR7130"
8781d18a2fSmatt 	}, {
8881d18a2fSmatt 		.ac_platformsw =	&ar7100_platformsw,
8981d18a2fSmatt 		.ac_chipid =		ARCHIP_AR7141,
9081d18a2fSmatt 		.ac_chipmask =		0xf3,
9181d18a2fSmatt 		.ac_cid =		MIPS_PRID_CID_MTI,
9281d18a2fSmatt 		.ac_pid =		MIPS_24K,
9381d18a2fSmatt 		.ac_name =		"AR7141"
9481d18a2fSmatt 	}, {
9581d18a2fSmatt 		.ac_platformsw =	&ar7100_platformsw,
9681d18a2fSmatt 		.ac_chipid =		ARCHIP_AR7161,
9781d18a2fSmatt 		.ac_chipmask =		0xf3,
9881d18a2fSmatt 		.ac_cid =		MIPS_PRID_CID_MTI,
9981d18a2fSmatt 		.ac_pid =		MIPS_24K,
10081d18a2fSmatt 		.ac_name =		"AR7161"
10181d18a2fSmatt 	},
10281d18a2fSmatt #endif
10381d18a2fSmatt #ifdef WISOC_AR9344
10481d18a2fSmatt 	{
10581d18a2fSmatt 		.ac_platformsw =	&ar9344_platformsw,
10631586d2cSmatt 		.ac_chipid =		0x20,	/* 7240? */
10731586d2cSmatt 		.ac_chipmask =		0xff,
10831586d2cSmatt 		.ac_cid =		MIPS_PRID_CID_MTI,
10931586d2cSmatt 		.ac_pid =		MIPS_74K,
11031586d2cSmatt 		.ac_name =		"AR7240"
11131586d2cSmatt 	}, {
11231586d2cSmatt 		.ac_platformsw =	&ar9344_platformsw,
11381d18a2fSmatt 		.ac_chipid =		ARCHIP_AR9344,
11481d18a2fSmatt 		.ac_chipmask =		0xff,
11581d18a2fSmatt 		.ac_cid =		MIPS_PRID_CID_MTI,
11681d18a2fSmatt 		.ac_pid =		MIPS_74K,
11781d18a2fSmatt 		.ac_name =		"AR9344"
11881d18a2fSmatt 	},
11981d18a2fSmatt #endif
12081d18a2fSmatt };
12181d18a2fSmatt 
12281d18a2fSmatt __CTASSERT(__arraycount(chips) > 0);
12381d18a2fSmatt 
12481d18a2fSmatt const struct atheros_platformsw *platformsw;
12581d18a2fSmatt 
12681d18a2fSmatt static const struct atheros_chip *my_chip;
12781d18a2fSmatt 
12881d18a2fSmatt static struct arfreqs chip_freqs;
12981d18a2fSmatt 
13081d18a2fSmatt const char *
atheros_get_cpuname(void)13181d18a2fSmatt atheros_get_cpuname(void)
13281d18a2fSmatt {
13381d18a2fSmatt 	return my_chip->ac_name;
13481d18a2fSmatt }
13581d18a2fSmatt 
13681d18a2fSmatt u_int
atheros_get_chipid(void)13781d18a2fSmatt atheros_get_chipid(void)
13881d18a2fSmatt {
13981d18a2fSmatt 	return my_chip->ac_chipid;
14081d18a2fSmatt }
14181d18a2fSmatt 
14281d18a2fSmatt uint32_t
atheros_get_uart_freq(void)14331586d2cSmatt atheros_get_uart_freq(void)
14431586d2cSmatt {
14531586d2cSmatt 	if (chip_freqs.freq_uart)
14631586d2cSmatt 		return chip_freqs.freq_uart;
14731586d2cSmatt 
14831586d2cSmatt 	return chip_freqs.freq_bus;
14931586d2cSmatt }
15031586d2cSmatt 
15131586d2cSmatt uint32_t
atheros_get_bus_freq(void)15281d18a2fSmatt atheros_get_bus_freq(void)
15381d18a2fSmatt {
15481d18a2fSmatt 	return chip_freqs.freq_bus;
15581d18a2fSmatt }
15681d18a2fSmatt 
15781d18a2fSmatt uint32_t
atheros_get_cpu_freq(void)15881d18a2fSmatt atheros_get_cpu_freq(void)
15981d18a2fSmatt {
16081d18a2fSmatt 	return chip_freqs.freq_cpu;
16181d18a2fSmatt }
16281d18a2fSmatt 
16381d18a2fSmatt uint32_t
atheros_get_mem_freq(void)16481d18a2fSmatt atheros_get_mem_freq(void)
16581d18a2fSmatt {
16681d18a2fSmatt 	return chip_freqs.freq_mem;
16781d18a2fSmatt }
16881d18a2fSmatt 
16981d18a2fSmatt void
atheros_set_platformsw(void)17081d18a2fSmatt atheros_set_platformsw(void)
17181d18a2fSmatt {
17281d18a2fSmatt 	const u_int cid = MIPS_PRID_CID(mips_options.mips_cpu_id);
17381d18a2fSmatt 	const u_int pid = MIPS_PRID_IMPL(mips_options.mips_cpu_id);
17481d18a2fSmatt 
17581d18a2fSmatt 	for (const struct atheros_chip *ac = chips;
17681d18a2fSmatt 	    ac < chips + __arraycount(chips);
17781d18a2fSmatt 	    ac++) {
17881d18a2fSmatt 		const struct atheros_platformsw * const apsw = ac->ac_platformsw;
17981d18a2fSmatt                 if (cid != ac->ac_cid || pid != ac->ac_pid)
18081d18a2fSmatt 			continue;
18181d18a2fSmatt 
18281d18a2fSmatt 		const uint32_t revision_id = *(volatile uint32_t *)
18381d18a2fSmatt 		    MIPS_PHYS_TO_KSEG1(apsw->apsw_revision_id_addr);
18481d18a2fSmatt 		const uint32_t chipid = AR9344_REVISION_CHIPID(revision_id);
18581d18a2fSmatt 
18681d18a2fSmatt 		if ((chipid & ac->ac_chipmask) == ac->ac_chipid) {
18781d18a2fSmatt 			platformsw = apsw;
18881d18a2fSmatt 			my_chip = ac;
18981d18a2fSmatt 			atheros_early_consinit();
19081d18a2fSmatt 			printf("Early console started!\n");
19181d18a2fSmatt 			(*apsw->apsw_get_freqs)(&chip_freqs);
19231586d2cSmatt 			printf("freqs: cpu=%u bus=%u mem=%u ref=%u pll=%u\n",
19331586d2cSmatt 			     chip_freqs.freq_cpu,
19431586d2cSmatt 			     chip_freqs.freq_bus,
19531586d2cSmatt 			     chip_freqs.freq_mem,
19631586d2cSmatt 			     chip_freqs.freq_ref,
19731586d2cSmatt 			     chip_freqs.freq_pll);
19881d18a2fSmatt 			return;
19981d18a2fSmatt 		}
20081d18a2fSmatt 	}
20181d18a2fSmatt 	panic("%s: unrecognized platform", __func__);
20281d18a2fSmatt }
20381d18a2fSmatt 
20481d18a2fSmatt #include "ath_arbus.h"
20581d18a2fSmatt #if NATH_ARBUS > 0
20681d18a2fSmatt #include <ah_soc.h>
20781d18a2fSmatt 
20881d18a2fSmatt const struct ar531x_boarddata *
atheros_get_board_info(void)20981d18a2fSmatt atheros_get_board_info(void)
21081d18a2fSmatt {
21181d18a2fSmatt 	const struct atheros_boardsw * const boardsw = my_chip->ac_boardsw;
21281d18a2fSmatt 	if (boardsw == NULL)
21381d18a2fSmatt 		return NULL;
21481d18a2fSmatt 	return (*boardsw->absw_get_board_info)();
21581d18a2fSmatt }
21681d18a2fSmatt 
21781d18a2fSmatt /*
21881d18a2fSmatt  * Locate board and radio configuration data in flash.
21981d18a2fSmatt  */
22081d18a2fSmatt int
atheros_get_board_config(struct ar531x_config * config)22181d18a2fSmatt atheros_get_board_config(struct ar531x_config *config)
22281d18a2fSmatt {
22381d18a2fSmatt 	const struct atheros_boardsw * const boardsw = my_chip->ac_boardsw;
22481d18a2fSmatt 	if (boardsw == NULL)
22581d18a2fSmatt 		return ENOENT;
22681d18a2fSmatt 
22781d18a2fSmatt 	config->board = (*boardsw->absw_get_board_info)();
22881d18a2fSmatt 	if (config->board == NULL)
22981d18a2fSmatt 		return ENOENT;
23081d18a2fSmatt 
23181d18a2fSmatt 	config->radio = (*boardsw->absw_get_radio_info)();
23281d18a2fSmatt 	if (config->radio == NULL)
23381d18a2fSmatt 		return ENOENT;		/* XXX distinct code */
23481d18a2fSmatt 
23581d18a2fSmatt 	return 0;
23681d18a2fSmatt }
23781d18a2fSmatt #endif /* NATH_ARBUS > 0 */
238