xref: /openbmc/linux/arch/mips/generic/board-ocelot.c (revision 4d2ee1be)
16bce3deaSAlexandre Belloni // SPDX-License-Identifier: (GPL-2.0 OR MIT)
26bce3deaSAlexandre Belloni /*
36bce3deaSAlexandre Belloni  * Microsemi MIPS SoC support
46bce3deaSAlexandre Belloni  *
56bce3deaSAlexandre Belloni  * Copyright (c) 2017 Microsemi Corporation
66bce3deaSAlexandre Belloni  */
76bce3deaSAlexandre Belloni #include <asm/machine.h>
86bce3deaSAlexandre Belloni #include <asm/prom.h>
96bce3deaSAlexandre Belloni 
106bce3deaSAlexandre Belloni #define DEVCPU_GCB_CHIP_REGS_CHIP_ID	0x71070000
116bce3deaSAlexandre Belloni #define CHIP_ID_PART_ID			GENMASK(27, 12)
126bce3deaSAlexandre Belloni 
136bce3deaSAlexandre Belloni #define OCELOT_PART_ID			(0x7514 << 12)
146bce3deaSAlexandre Belloni 
156bce3deaSAlexandre Belloni #define UART_UART			0x70100000
166bce3deaSAlexandre Belloni 
ocelot_detect(void)176bce3deaSAlexandre Belloni static __init bool ocelot_detect(void)
186bce3deaSAlexandre Belloni {
196bce3deaSAlexandre Belloni 	u32 rev;
206bce3deaSAlexandre Belloni 	int idx;
216bce3deaSAlexandre Belloni 
226bce3deaSAlexandre Belloni 	/* Look for the TLB entry set up by redboot before trying to use it */
236bce3deaSAlexandre Belloni 	write_c0_entryhi(DEVCPU_GCB_CHIP_REGS_CHIP_ID);
246bce3deaSAlexandre Belloni 	mtc0_tlbw_hazard();
256bce3deaSAlexandre Belloni 	tlb_probe();
266bce3deaSAlexandre Belloni 	tlb_probe_hazard();
276bce3deaSAlexandre Belloni 	idx = read_c0_index();
286bce3deaSAlexandre Belloni 	if (idx < 0)
29*4d2ee1beSHuilong Deng 		return false;
306bce3deaSAlexandre Belloni 
316bce3deaSAlexandre Belloni 	/* A TLB entry exists, lets assume its usable and check the CHIP ID */
326bce3deaSAlexandre Belloni 	rev = __raw_readl((void __iomem *)DEVCPU_GCB_CHIP_REGS_CHIP_ID);
336bce3deaSAlexandre Belloni 
346bce3deaSAlexandre Belloni 	if ((rev & CHIP_ID_PART_ID) != OCELOT_PART_ID)
35*4d2ee1beSHuilong Deng 		return false;
366bce3deaSAlexandre Belloni 
376bce3deaSAlexandre Belloni 	/* Copy command line from bootloader early for Initrd detection */
386bce3deaSAlexandre Belloni 	if (fw_arg0 < 10 && (fw_arg1 & 0xFFF00000) == 0x80000000) {
396bce3deaSAlexandre Belloni 		unsigned int prom_argc = fw_arg0;
406bce3deaSAlexandre Belloni 		const char **prom_argv = (const char **)fw_arg1;
416bce3deaSAlexandre Belloni 
426bce3deaSAlexandre Belloni 		if (prom_argc > 1 && strlen(prom_argv[1]) > 0)
436bce3deaSAlexandre Belloni 			/* ignore all built-in args if any f/w args given */
446bce3deaSAlexandre Belloni 			strcpy(arcs_cmdline, prom_argv[1]);
456bce3deaSAlexandre Belloni 	}
466bce3deaSAlexandre Belloni 
47*4d2ee1beSHuilong Deng 	return true;
486bce3deaSAlexandre Belloni }
496bce3deaSAlexandre Belloni 
ocelot_earlyprintk_init(void)506bce3deaSAlexandre Belloni static void __init ocelot_earlyprintk_init(void)
516bce3deaSAlexandre Belloni {
526bce3deaSAlexandre Belloni 	void __iomem *uart_base;
536bce3deaSAlexandre Belloni 
544bdc0d67SChristoph Hellwig 	uart_base = ioremap(UART_UART, 0x20);
556bce3deaSAlexandre Belloni 	setup_8250_early_printk_port((unsigned long)uart_base, 2, 50000);
566bce3deaSAlexandre Belloni }
576bce3deaSAlexandre Belloni 
ocelot_late_init(void)586bce3deaSAlexandre Belloni static void __init ocelot_late_init(void)
596bce3deaSAlexandre Belloni {
606bce3deaSAlexandre Belloni 	ocelot_earlyprintk_init();
616bce3deaSAlexandre Belloni }
626bce3deaSAlexandre Belloni 
ocelot_fixup_fdt(const void * fdt,const void * match_data)636bce3deaSAlexandre Belloni static __init const void *ocelot_fixup_fdt(const void *fdt,
646bce3deaSAlexandre Belloni 					   const void *match_data)
656bce3deaSAlexandre Belloni {
666bce3deaSAlexandre Belloni 	/* This has to be done so late because ioremap needs to work */
676bce3deaSAlexandre Belloni 	late_time_init = ocelot_late_init;
686bce3deaSAlexandre Belloni 
696bce3deaSAlexandre Belloni 	return fdt;
706bce3deaSAlexandre Belloni }
716bce3deaSAlexandre Belloni 
726bce3deaSAlexandre Belloni extern char __dtb_ocelot_pcb123_begin[];
736bce3deaSAlexandre Belloni 
746bce3deaSAlexandre Belloni MIPS_MACHINE(ocelot) = {
756bce3deaSAlexandre Belloni 	.fdt = __dtb_ocelot_pcb123_begin,
766bce3deaSAlexandre Belloni 	.fixup_fdt = ocelot_fixup_fdt,
776bce3deaSAlexandre Belloni 	.detect = ocelot_detect,
786bce3deaSAlexandre Belloni };
79