Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Old U-boot compatibility for Acadia
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Author: Josh Boyer <jwboyer@linux.vnet.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Copyright 2008 IBM Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include "ops.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include "io.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include "dcr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include "stdio.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include "4xx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include "44x.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include "cuboot.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #define TARGET_4xx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include "ppcboot.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) static bd_t bd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define CPR_PERD0_SPIDV_MASK   0x000F0000     /* SPI Clock Divider */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define PLLC_SRC_MASK	       0x20000000     /* PLL feedback source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define PLLD_FBDV_MASK	       0x1F000000     /* PLL feedback divider value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define PLLD_FWDVA_MASK        0x000F0000     /* PLL forward divider A value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define PLLD_FWDVB_MASK        0x00000700     /* PLL forward divider B value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define PRIMAD_CPUDV_MASK      0x0F000000     /* CPU Clock Divisor Mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define PRIMAD_PLBDV_MASK      0x000F0000     /* PLB Clock Divisor Mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define PRIMAD_OPBDV_MASK      0x00000F00     /* OPB Clock Divisor Mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define PRIMAD_EBCDV_MASK      0x0000000F     /* EBC Clock Divisor Mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define PERD0_PWMDV_MASK       0xFF000000     /* PWM Divider Mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define PERD0_SPIDV_MASK       0x000F0000     /* SPI Divider Mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define PERD0_U0DV_MASK        0x0000FF00     /* UART 0 Divider Mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define PERD0_U1DV_MASK        0x000000FF     /* UART 1 Divider Mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) static void get_clocks(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	unsigned long sysclk, cpr_plld, cpr_pllc, cpr_primad, plloutb, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	unsigned long pllFwdDiv, pllFwdDivB, pllFbkDiv, pllPlbDiv, pllExtBusDiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	unsigned long pllOpbDiv, freqEBC, freqUART, freqOPB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	unsigned long div;		/* total divisor udiv * bdiv */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	unsigned long umin;		/* minimum udiv	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	unsigned short diff;		/* smallest diff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	unsigned long udiv;		/* best udiv */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	unsigned short idiff;		/* current diff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	unsigned short ibdiv;		/* current bdiv */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	unsigned long est;		/* current estimate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	unsigned long baud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	void *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	/* read the sysclk value from the CPLD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	sysclk = (in_8((unsigned char *)0x80000000) == 0xc) ? 66666666 : 33333000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	 * Read PLL Mode registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	cpr_plld = CPR0_READ(DCRN_CPR0_PLLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	cpr_pllc = CPR0_READ(DCRN_CPR0_PLLC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	 * Determine forward divider A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	pllFwdDiv = ((cpr_plld & PLLD_FWDVA_MASK) >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	 * Determine forward divider B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	pllFwdDivB = ((cpr_plld & PLLD_FWDVB_MASK) >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	if (pllFwdDivB == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		pllFwdDivB = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	 * Determine FBK_DIV.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	pllFbkDiv = ((cpr_plld & PLLD_FBDV_MASK) >> 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	if (pllFbkDiv == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		pllFbkDiv = 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	 * Read CPR_PRIMAD register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	cpr_primad = CPR0_READ(DCRN_CPR0_PRIMAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	 * Determine PLB_DIV.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	pllPlbDiv = ((cpr_primad & PRIMAD_PLBDV_MASK) >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	if (pllPlbDiv == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		pllPlbDiv = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	 * Determine EXTBUS_DIV.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	pllExtBusDiv = (cpr_primad & PRIMAD_EBCDV_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	if (pllExtBusDiv == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		pllExtBusDiv = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	 * Determine OPB_DIV.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	pllOpbDiv = ((cpr_primad & PRIMAD_OPBDV_MASK) >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	if (pllOpbDiv == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		pllOpbDiv = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	/* There is a bug in U-Boot that prevents us from using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	 * bd.bi_opbfreq because U-Boot doesn't populate it for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	 * 405EZ.  We get to calculate it, yay!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	freqOPB = (sysclk *pllFbkDiv) /pllOpbDiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	freqEBC = (sysclk * pllFbkDiv) / pllExtBusDiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	plloutb = ((sysclk * ((cpr_pllc & PLLC_SRC_MASK) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 					   pllFwdDivB : pllFwdDiv) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		    pllFbkDiv) / pllFwdDivB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	np = find_node_by_alias("serial0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	if (getprop(np, "current-speed", &baud, sizeof(baud)) != sizeof(baud))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		fatal("no current-speed property\n\r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	udiv = 256;			/* Assume lowest possible serial clk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	div = plloutb / (16 * baud); /* total divisor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	umin = (plloutb / freqOPB) << 1;	/* 2 x OPB divisor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	diff = 256;			/* highest possible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	/* i is the test udiv value -- start with the largest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	 * possible (256) to minimize serial clock and constrain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	 * search to umin.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	for (i = 256; i > umin; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		ibdiv = div / i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		est = i * ibdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		idiff = (est > div) ? (est-div) : (div-est);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		if (idiff == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 			udiv = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 			break;      /* can't do better */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		} else if (idiff < diff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 			udiv = i;       /* best so far */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 			diff = idiff;   /* update lowest diff*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	freqUART = plloutb / udiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	dt_fixup_cpu_clocks(bd.bi_procfreq, bd.bi_intfreq, bd.bi_plb_busfreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	dt_fixup_clock("/plb/ebc", freqEBC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	dt_fixup_clock("/plb/opb", freqOPB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	dt_fixup_clock("/plb/opb/serial@ef600300", freqUART);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	dt_fixup_clock("/plb/opb/serial@ef600400", freqUART);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static void acadia_fixups(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	dt_fixup_memory(bd.bi_memstart, bd.bi_memsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	get_clocks();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		unsigned long r6, unsigned long r7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	CUBOOT_INIT();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	platform_ops.fixups = acadia_fixups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	platform_ops.exit = ibm40x_dbcr_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	fdt_init(_dtb_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	serial_console_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }