mirror of
				https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
				synced 2025-10-31 08:08:51 +01:00 
			
		
		
		
	Fixed MTP to work with TWRP
This commit is contained in:
		
						commit
						f6dfaef42e
					
				
					 50820 changed files with 20846062 additions and 0 deletions
				
			
		
							
								
								
									
										409
									
								
								arch/mips/cavium-octeon/executive/octeon-model.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										409
									
								
								arch/mips/cavium-octeon/executive/octeon-model.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,409 @@ | |||
| /***********************license start***************
 | ||||
|  * Author: Cavium Networks | ||||
|  * | ||||
|  * Contact: support@caviumnetworks.com | ||||
|  * This file is part of the OCTEON SDK | ||||
|  * | ||||
|  * Copyright (c) 2003-2010 Cavium Networks | ||||
|  * | ||||
|  * This file is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License, Version 2, as | ||||
|  * published by the Free Software Foundation. | ||||
|  * | ||||
|  * This file is distributed in the hope that it will be useful, but | ||||
|  * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty | ||||
|  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or | ||||
|  * NONINFRINGEMENT.  See the GNU General Public License for more | ||||
|  * details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this file; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||||
|  * or visit http://www.gnu.org/licenses/.
 | ||||
|  * | ||||
|  * This file may also be available under a different license from Cavium. | ||||
|  * Contact Cavium Networks for more information | ||||
|  ***********************license end**************************************/ | ||||
| 
 | ||||
| #include <asm/octeon/octeon.h> | ||||
| 
 | ||||
| /**
 | ||||
|  * Given the chip processor ID from COP0, this function returns a | ||||
|  * string representing the chip model number. The string is of the | ||||
|  * form CNXXXXpX.X-FREQ-SUFFIX. | ||||
|  * - XXXX = The chip model number | ||||
|  * - X.X = Chip pass number | ||||
|  * - FREQ = Current frequency in Mhz | ||||
|  * - SUFFIX = NSP, EXP, SCP, SSP, or CP | ||||
|  * | ||||
|  * @chip_id: Chip ID | ||||
|  * | ||||
|  * Returns Model string | ||||
|  */ | ||||
| const char *octeon_model_get_string(uint32_t chip_id) | ||||
| { | ||||
| 	static char buffer[32]; | ||||
| 	return octeon_model_get_string_buffer(chip_id, buffer); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Version of octeon_model_get_string() that takes buffer as argument, | ||||
|  * as running early in u-boot static/global variables don't work when | ||||
|  * running from flash. | ||||
|  */ | ||||
| const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer) | ||||
| { | ||||
| 	const char *family; | ||||
| 	const char *core_model; | ||||
| 	char pass[4]; | ||||
| 	int clock_mhz; | ||||
| 	const char *suffix; | ||||
| 	union cvmx_l2d_fus3 fus3; | ||||
| 	int num_cores; | ||||
| 	union cvmx_mio_fus_dat2 fus_dat2; | ||||
| 	union cvmx_mio_fus_dat3 fus_dat3; | ||||
| 	char fuse_model[10]; | ||||
| 	uint32_t fuse_data = 0; | ||||
| 
 | ||||
| 	fus3.u64 = 0; | ||||
| 	if (!OCTEON_IS_MODEL(OCTEON_CN6XXX)) | ||||
| 		fus3.u64 = cvmx_read_csr(CVMX_L2D_FUS3); | ||||
| 	fus_dat2.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT2); | ||||
| 	fus_dat3.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT3); | ||||
| 	num_cores = cvmx_pop(cvmx_read_csr(CVMX_CIU_FUSE)); | ||||
| 
 | ||||
| 	/* Make sure the non existent devices look disabled */ | ||||
| 	switch ((chip_id >> 8) & 0xff) { | ||||
| 	case 6:		/* CN50XX */ | ||||
| 	case 2:		/* CN30XX */ | ||||
| 		fus_dat3.s.nodfa_dte = 1; | ||||
| 		fus_dat3.s.nozip = 1; | ||||
| 		break; | ||||
| 	case 4:		/* CN57XX or CN56XX */ | ||||
| 		fus_dat3.s.nodfa_dte = 1; | ||||
| 		break; | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Make a guess at the suffix */ | ||||
| 	/* NSP = everything */ | ||||
| 	/* EXP = No crypto */ | ||||
| 	/* SCP = No DFA, No zip */ | ||||
| 	/* CP = No DFA, No crypto, No zip */ | ||||
| 	if (fus_dat3.s.nodfa_dte) { | ||||
| 		if (fus_dat2.s.nocrypto) | ||||
| 			suffix = "CP"; | ||||
| 		else | ||||
| 			suffix = "SCP"; | ||||
| 	} else if (fus_dat2.s.nocrypto) | ||||
| 		suffix = "EXP"; | ||||
| 	else | ||||
| 		suffix = "NSP"; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Assume pass number is encoded using <5:3><2:0>. Exceptions | ||||
| 	 * will be fixed later. | ||||
| 	 */ | ||||
| 	sprintf(pass, "%d.%d", (int)((chip_id >> 3) & 7) + 1, (int)chip_id & 7); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Use the number of cores to determine the last 2 digits of | ||||
| 	 * the model number. There are some exceptions that are fixed | ||||
| 	 * later. | ||||
| 	 */ | ||||
| 	switch (num_cores) { | ||||
| 	case 32: | ||||
| 		core_model = "80"; | ||||
| 		break; | ||||
| 	case 24: | ||||
| 		core_model = "70"; | ||||
| 		break; | ||||
| 	case 16: | ||||
| 		core_model = "60"; | ||||
| 		break; | ||||
| 	case 15: | ||||
| 		core_model = "58"; | ||||
| 		break; | ||||
| 	case 14: | ||||
| 		core_model = "55"; | ||||
| 		break; | ||||
| 	case 13: | ||||
| 		core_model = "52"; | ||||
| 		break; | ||||
| 	case 12: | ||||
| 		core_model = "50"; | ||||
| 		break; | ||||
| 	case 11: | ||||
| 		core_model = "48"; | ||||
| 		break; | ||||
| 	case 10: | ||||
| 		core_model = "45"; | ||||
| 		break; | ||||
| 	case 9: | ||||
| 		core_model = "42"; | ||||
| 		break; | ||||
| 	case 8: | ||||
| 		core_model = "40"; | ||||
| 		break; | ||||
| 	case 7: | ||||
| 		core_model = "38"; | ||||
| 		break; | ||||
| 	case 6: | ||||
| 		core_model = "34"; | ||||
| 		break; | ||||
| 	case 5: | ||||
| 		core_model = "32"; | ||||
| 		break; | ||||
| 	case 4: | ||||
| 		core_model = "30"; | ||||
| 		break; | ||||
| 	case 3: | ||||
| 		core_model = "25"; | ||||
| 		break; | ||||
| 	case 2: | ||||
| 		core_model = "20"; | ||||
| 		break; | ||||
| 	case 1: | ||||
| 		core_model = "10"; | ||||
| 		break; | ||||
| 	default: | ||||
| 		core_model = "XX"; | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Now figure out the family, the first two digits */ | ||||
| 	switch ((chip_id >> 8) & 0xff) { | ||||
| 	case 0:		/* CN38XX, CN37XX or CN36XX */ | ||||
| 		if (fus3.cn38xx.crip_512k) { | ||||
| 			/*
 | ||||
| 			 * For some unknown reason, the 16 core one is | ||||
| 			 * called 37 instead of 36. | ||||
| 			 */ | ||||
| 			if (num_cores >= 16) | ||||
| 				family = "37"; | ||||
| 			else | ||||
| 				family = "36"; | ||||
| 		} else | ||||
| 			family = "38"; | ||||
| 		/*
 | ||||
| 		 * This series of chips didn't follow the standard | ||||
| 		 * pass numbering. | ||||
| 		 */ | ||||
| 		switch (chip_id & 0xf) { | ||||
| 		case 0: | ||||
| 			strcpy(pass, "1.X"); | ||||
| 			break; | ||||
| 		case 1: | ||||
| 			strcpy(pass, "2.X"); | ||||
| 			break; | ||||
| 		case 3: | ||||
| 			strcpy(pass, "3.X"); | ||||
| 			break; | ||||
| 		default: | ||||
| 			strcpy(pass, "X.X"); | ||||
| 			break; | ||||
| 		} | ||||
| 		break; | ||||
| 	case 1:		/* CN31XX or CN3020 */ | ||||
| 		if ((chip_id & 0x10) || fus3.cn31xx.crip_128k) | ||||
| 			family = "30"; | ||||
| 		else | ||||
| 			family = "31"; | ||||
| 		/*
 | ||||
| 		 * This series of chips didn't follow the standard | ||||
| 		 * pass numbering. | ||||
| 		 */ | ||||
| 		switch (chip_id & 0xf) { | ||||
| 		case 0: | ||||
| 			strcpy(pass, "1.0"); | ||||
| 			break; | ||||
| 		case 2: | ||||
| 			strcpy(pass, "1.1"); | ||||
| 			break; | ||||
| 		default: | ||||
| 			strcpy(pass, "X.X"); | ||||
| 			break; | ||||
| 		} | ||||
| 		break; | ||||
| 	case 2:		/* CN3010 or CN3005 */ | ||||
| 		family = "30"; | ||||
| 		/* A chip with half cache is an 05 */ | ||||
| 		if (fus3.cn30xx.crip_64k) | ||||
| 			core_model = "05"; | ||||
| 		/*
 | ||||
| 		 * This series of chips didn't follow the standard | ||||
| 		 * pass numbering. | ||||
| 		 */ | ||||
| 		switch (chip_id & 0xf) { | ||||
| 		case 0: | ||||
| 			strcpy(pass, "1.0"); | ||||
| 			break; | ||||
| 		case 2: | ||||
| 			strcpy(pass, "1.1"); | ||||
| 			break; | ||||
| 		default: | ||||
| 			strcpy(pass, "X.X"); | ||||
| 			break; | ||||
| 		} | ||||
| 		break; | ||||
| 	case 3:		/* CN58XX */ | ||||
| 		family = "58"; | ||||
| 		/* Special case. 4 core, half cache (CP with half cache) */ | ||||
| 		if ((num_cores == 4) && fus3.cn58xx.crip_1024k && !strncmp(suffix, "CP", 2)) | ||||
| 			core_model = "29"; | ||||
| 
 | ||||
| 		/* Pass 1 uses different encodings for pass numbers */ | ||||
| 		if ((chip_id & 0xFF) < 0x8) { | ||||
| 			switch (chip_id & 0x3) { | ||||
| 			case 0: | ||||
| 				strcpy(pass, "1.0"); | ||||
| 				break; | ||||
| 			case 1: | ||||
| 				strcpy(pass, "1.1"); | ||||
| 				break; | ||||
| 			case 3: | ||||
| 				strcpy(pass, "1.2"); | ||||
| 				break; | ||||
| 			default: | ||||
| 				strcpy(pass, "1.X"); | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 		break; | ||||
| 	case 4:		/* CN57XX, CN56XX, CN55XX, CN54XX */ | ||||
| 		if (fus_dat2.cn56xx.raid_en) { | ||||
| 			if (fus3.cn56xx.crip_1024k) | ||||
| 				family = "55"; | ||||
| 			else | ||||
| 				family = "57"; | ||||
| 			if (fus_dat2.cn56xx.nocrypto) | ||||
| 				suffix = "SP"; | ||||
| 			else | ||||
| 				suffix = "SSP"; | ||||
| 		} else { | ||||
| 			if (fus_dat2.cn56xx.nocrypto) | ||||
| 				suffix = "CP"; | ||||
| 			else { | ||||
| 				suffix = "NSP"; | ||||
| 				if (fus_dat3.s.nozip) | ||||
| 					suffix = "SCP"; | ||||
| 
 | ||||
| 				if (fus_dat3.s.bar2_en) | ||||
| 					suffix = "NSPB2"; | ||||
| 			} | ||||
| 			if (fus3.cn56xx.crip_1024k) | ||||
| 				family = "54"; | ||||
| 			else | ||||
| 				family = "56"; | ||||
| 		} | ||||
| 		break; | ||||
| 	case 6:		/* CN50XX */ | ||||
| 		family = "50"; | ||||
| 		break; | ||||
| 	case 7:		/* CN52XX */ | ||||
| 		if (fus3.cn52xx.crip_256k) | ||||
| 			family = "51"; | ||||
| 		else | ||||
| 			family = "52"; | ||||
| 		break; | ||||
| 	case 0x93:		/* CN61XX */ | ||||
| 		family = "61"; | ||||
| 		if (fus_dat2.cn61xx.nocrypto && fus_dat2.cn61xx.dorm_crypto) | ||||
| 			suffix = "AP"; | ||||
| 		if (fus_dat2.cn61xx.nocrypto) | ||||
| 			suffix = "CP"; | ||||
| 		else if (fus_dat2.cn61xx.dorm_crypto) | ||||
| 			suffix = "DAP"; | ||||
| 		else if (fus_dat3.cn61xx.nozip) | ||||
| 			suffix = "SCP"; | ||||
| 		break; | ||||
| 	case 0x90:		/* CN63XX */ | ||||
| 		family = "63"; | ||||
| 		if (fus_dat3.s.l2c_crip == 2) | ||||
| 			family = "62"; | ||||
| 		if (num_cores == 6)	/* Other core counts match generic */ | ||||
| 			core_model = "35"; | ||||
| 		if (fus_dat2.cn63xx.nocrypto) | ||||
| 			suffix = "CP"; | ||||
| 		else if (fus_dat2.cn63xx.dorm_crypto) | ||||
| 			suffix = "DAP"; | ||||
| 		else if (fus_dat3.cn63xx.nozip) | ||||
| 			suffix = "SCP"; | ||||
| 		else | ||||
| 			suffix = "AAP"; | ||||
| 		break; | ||||
| 	case 0x92:		/* CN66XX */ | ||||
| 		family = "66"; | ||||
| 		if (num_cores == 6)	/* Other core counts match generic */ | ||||
| 			core_model = "35"; | ||||
| 		if (fus_dat2.cn66xx.nocrypto && fus_dat2.cn66xx.dorm_crypto) | ||||
| 			suffix = "AP"; | ||||
| 		if (fus_dat2.cn66xx.nocrypto) | ||||
| 			suffix = "CP"; | ||||
| 		else if (fus_dat2.cn66xx.dorm_crypto) | ||||
| 			suffix = "DAP"; | ||||
| 		else if (fus_dat3.cn66xx.nozip) | ||||
| 			suffix = "SCP"; | ||||
| 		else | ||||
| 			suffix = "AAP"; | ||||
| 		break; | ||||
| 	case 0x91:		/* CN68XX */ | ||||
| 		family = "68"; | ||||
| 		if (fus_dat2.cn68xx.nocrypto && fus_dat3.cn68xx.nozip) | ||||
| 			suffix = "CP"; | ||||
| 		else if (fus_dat2.cn68xx.dorm_crypto) | ||||
| 			suffix = "DAP"; | ||||
| 		else if (fus_dat3.cn68xx.nozip) | ||||
| 			suffix = "SCP"; | ||||
| 		else if (fus_dat2.cn68xx.nocrypto) | ||||
| 			suffix = "SP"; | ||||
| 		else | ||||
| 			suffix = "AAP"; | ||||
| 		break; | ||||
| 	default: | ||||
| 		family = "XX"; | ||||
| 		core_model = "XX"; | ||||
| 		strcpy(pass, "X.X"); | ||||
| 		suffix = "XXX"; | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	clock_mhz = octeon_get_clock_rate() / 1000000; | ||||
| 	if (family[0] != '3') { | ||||
| 		int fuse_base = 384 / 8; | ||||
| 		if (family[0] == '6') | ||||
| 			fuse_base = 832 / 8; | ||||
| 
 | ||||
| 		/* Check for model in fuses, overrides normal decode */ | ||||
| 		/* This is _not_ valid for Octeon CN3XXX models */ | ||||
| 		fuse_data |= cvmx_fuse_read_byte(fuse_base + 3); | ||||
| 		fuse_data = fuse_data << 8; | ||||
| 		fuse_data |= cvmx_fuse_read_byte(fuse_base + 2); | ||||
| 		fuse_data = fuse_data << 8; | ||||
| 		fuse_data |= cvmx_fuse_read_byte(fuse_base + 1); | ||||
| 		fuse_data = fuse_data << 8; | ||||
| 		fuse_data |= cvmx_fuse_read_byte(fuse_base); | ||||
| 		if (fuse_data & 0x7ffff) { | ||||
| 			int model = fuse_data & 0x3fff; | ||||
| 			int suffix = (fuse_data >> 14) & 0x1f; | ||||
| 			if (suffix && model) { | ||||
| 				/* Have both number and suffix in fuses, so both */ | ||||
| 				sprintf(fuse_model, "%d%c", model, 'A' + suffix - 1); | ||||
| 				core_model = ""; | ||||
| 				family = fuse_model; | ||||
| 			} else if (suffix && !model) { | ||||
| 				/* Only have suffix, so add suffix to 'normal' model number */ | ||||
| 				sprintf(fuse_model, "%s%c", core_model, 'A' + suffix - 1); | ||||
| 				core_model = fuse_model; | ||||
| 			} else { | ||||
| 				/* Don't have suffix, so just use model from fuses */ | ||||
| 				sprintf(fuse_model, "%d", model); | ||||
| 				core_model = ""; | ||||
| 				family = fuse_model; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	sprintf(buffer, "CN%s%sp%s-%d-%s", family, core_model, pass, clock_mhz, suffix); | ||||
| 	return buffer; | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 awab228
						awab228