⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pmac_feature.c

📁 ARM 嵌入式 系统 设计与实例开发 实验教材 二源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	{ PMAC_FTR_IDE_RESET,		core99_ide_reset },	{ PMAC_FTR_GMAC_ENABLE,		core99_gmac_enable },	{ PMAC_FTR_GMAC_PHY_RESET,	core99_gmac_phy_reset },	{ PMAC_FTR_SOUND_CHIP_ENABLE,	core99_sound_chip_enable },	{ PMAC_FTR_AIRPORT_ENABLE,	core99_airport_enable },	{ PMAC_FTR_USB_ENABLE,		core99_usb_enable },	{ PMAC_FTR_1394_ENABLE,		core99_firewire_enable },	{ PMAC_FTR_1394_CABLE_POWER,	core99_firewire_cable_power },	{ PMAC_FTR_SLEEP_STATE,		core99_sleep_state },	{ PMAC_FTR_READ_GPIO,		core99_read_gpio },	{ PMAC_FTR_WRITE_GPIO,		core99_write_gpio },	{ 0, NULL }};	static struct pmac_mb_def pmac_mb_defs[] __pmacdata = {	/* Warning: ordering is important as some models may claim	 * beeing compatible with several types	 */	{	"AAPL,8500",			"PowerMac 8500/8600",		PMAC_TYPE_PSURGE,		NULL,		0	},	{	"AAPL,9500",			"PowerMac 9500/9600",		PMAC_TYPE_PSURGE,		NULL,		0	},	{	"AAPL,7500",			"PowerMac 7500",		PMAC_TYPE_PSURGE,		NULL,		0	},	{	"AAPL,e407",			"Alchemy",		PMAC_TYPE_ALCHEMY,		NULL,		0	},	{	"AAPL,e411",			"Gazelle",		PMAC_TYPE_GAZELLE,		NULL,		0	},	{	"AAPL,3400/2400",		"PowerBook 3400",		PMAC_TYPE_HOOPER,		ohare_features,		PMAC_MB_CAN_SLEEP	},	{	"AAPL,3500",			"PowerBook 3500",		PMAC_TYPE_KANGA,		ohare_features,		PMAC_MB_CAN_SLEEP	},	{	"AAPL,Gossamer",		"PowerMac G3 (Gossamer)",		PMAC_TYPE_GOSSAMER,		heathrow_desktop_features,		0	},	{	"AAPL,PowerMac G3",		"PowerMac G3 (Silk)",		PMAC_TYPE_SILK,			heathrow_desktop_features,		0	},	{	"AAPL,PowerBook1998",		"PowerBook Wallstreet",		PMAC_TYPE_WALLSTREET,		heathrow_laptop_features,		PMAC_MB_CAN_SLEEP	},	{	"AAPL,PowerBook1,1",		"PowerBook 101 (Lombard)",		PMAC_TYPE_101_PBOOK,		paddington_features,		PMAC_MB_CAN_SLEEP	},	{	"iMac,1",			"iMac (first generation)",		PMAC_TYPE_ORIG_IMAC,		paddington_features,		0	},	{	"PowerMac4,1",			"iMac \"Flower Power\"",		PMAC_TYPE_PANGEA_IMAC,		pangea_features,		PMAC_MB_CAN_SLEEP	},	{	"PowerBook4,1",			"iBook 2",		PMAC_TYPE_IBOOK2,		pangea_features,		PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER	},	{	"PowerMac1,1",			"Blue&White G3",		PMAC_TYPE_YOSEMITE,		paddington_features,		0	},	{	"PowerMac1,2",			"PowerMac G4 PCI Graphics",		PMAC_TYPE_YIKES,		paddington_features,		0	},	{	"PowerBook2,1",			"iBook (first generation)",		PMAC_TYPE_ORIG_IBOOK,		core99_features,		PMAC_MB_CAN_SLEEP	},	{	"PowerMac3,1",			"PowerMac G4 AGP Graphics",		PMAC_TYPE_SAWTOOTH,		core99_features,		0	},	{	"PowerMac3,2",			"PowerMac G4 AGP Graphics",		PMAC_TYPE_SAWTOOTH,		core99_features,		0	},	{	"PowerMac3,3",			"PowerMac G4 AGP Graphics",		PMAC_TYPE_SAWTOOTH,		core99_features,		0	},	{	"PowerMac2,1",			"iMac FireWire",		PMAC_TYPE_FW_IMAC,		core99_features,		PMAC_MB_CAN_SLEEP	},	{	"PowerMac2,2",			"iMac FireWire",		PMAC_TYPE_FW_IMAC,		core99_features,		PMAC_MB_CAN_SLEEP	},	{	"PowerBook2,2",			"iBook FireWire",		PMAC_TYPE_FW_IBOOK,		core99_features,		PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER	},	{	"PowerMac5,1",			"PowerMac G4 Cube",		PMAC_TYPE_CUBE,			core99_features,	},	{	"PowerMac3,4",			"PowerMac G4 Silver",		PMAC_TYPE_QUICKSILVER,		core99_features,		0	},	{	"PowerMac3,5",			"PowerMac G4 Silver",		PMAC_TYPE_QUICKSILVER,		core99_features,		0	},	{	"PowerBook3,1",			"PowerBook Pismo",		PMAC_TYPE_PISMO,		core99_features,		PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER	},	{	"PowerBook3,2",			"PowerBook Titanium",		PMAC_TYPE_TITANIUM,		core99_features,		PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER	},	{	"PowerBook3,3",			"PowerBook Titanium II",		PMAC_TYPE_TITANIUM2,		core99_features,		PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER	},};/* * The toplevel feature_call callback */int __pmacpmac_do_feature_call(unsigned int selector, ...){	struct device_node* node;	int param, value, i;	feature_call func = NULL;	va_list args;		if (!pmac_mb.features)		return -ENODEV;	for (i=0; pmac_mb.features[i].function; i++)		if (pmac_mb.features[i].selector == selector) {			func = pmac_mb.features[i].function;			break;		}	if (!func)		for (i=0; any_features[i].function; i++)			if (any_features[i].selector == selector) {				func = any_features[i].function;				break;			}	if (!func)		return -ENODEV;	va_start(args, selector);	node = (struct device_node*)va_arg(args, void*);	param = va_arg(args, int);	value = va_arg(args, int);	va_end(args);	return func(node, param, value);}static int __initprobe_motherboard(void){	int i;	struct macio_chip* macio = &macio_chips[0];	/* Lookup known motherboard type in device-tree */	for(i=0; i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) {	    if (machine_is_compatible(pmac_mb_defs[i].model_string)) {		pmac_mb = pmac_mb_defs[i];		goto found;	    }	}	/* Fallback to selection depending on mac-io chip type */	switch(macio->type) {	    case macio_grand_central:		pmac_mb.model_id = PMAC_TYPE_PSURGE;		pmac_mb.model_name = "Unknown PowerSurge";		break;	    case macio_ohare:		pmac_mb.model_id = PMAC_TYPE_UNKNOWN_OHARE;		pmac_mb.model_name = "Unknown OHare-based";	    	break;	    case macio_heathrow:		pmac_mb.model_id = PMAC_TYPE_UNKNOWN_HEATHROW;		pmac_mb.model_name = "Unknown Heathrow-based";		pmac_mb.features = heathrow_desktop_features;		break;	    case macio_paddington:		pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PADDINGTON;		pmac_mb.model_name = "Unknown Paddington-based";	    	pmac_mb.features = paddington_features;		break;	    case macio_keylargo:		pmac_mb.model_id = PMAC_TYPE_UNKNOWN_CORE99;		pmac_mb.model_name = "Unknown Keylargo-based";	    	pmac_mb.features = core99_features;		break;	    case macio_pangea:		pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PANGEA;		pmac_mb.model_name = "Unknown Pangea-based";	    	pmac_mb.features = pangea_features;		break;	    default:	    	return -ENODEV;	}found:	/* Fixup Hooper vs. Comet */	if (pmac_mb.model_id == PMAC_TYPE_HOOPER) {		u32* mach_id_ptr = (u32*)ioremap(0xf3000034, 4);		if (!mach_id_ptr)			return -ENODEV;		/* Here, I used to disable the media-bay on comet. It		 * appears this is wrong, the floppy connector is actually		 * a kind of media-bay and works with the current driver.		 */		if ((*mach_id_ptr) & 0x20000000UL)			pmac_mb.model_id = PMAC_TYPE_COMET;		iounmap(mach_id_ptr);	}	/* Set default value of powersave_nap on machines that support it.	 * It appears that uninorth rev 3 has a problem with it, we don't	 * enable it on those. In theory, the flush-on-lock property is	 * supposed to be set when not supported, but I'm not very confident	 * that all Apple OF revs did it properly, I do it the paranoid way.	 */	while (uninorth_base && uninorth_rev > 3) {		struct device_node* np = find_path_device("/cpus");		u32 pvr = mfspr(PVR);		if (!np || !np->child) {			printk(KERN_WARNING "Can't find CPU(s) in device tree !\n");			break;		}		np = np->child;		/* Nap mode not supported on SMP */		if (np->sibling)			break;		/* Nap mode not supported if flush-on-lock property is present */		if (get_property(np, "flush-on-lock", NULL))			break;		/* Some 7450 may have problem with NAP mode too ... */		if (((pvr >> 16) == 0x8000) && ((pvr & 0xffff) < 0x0201))			break;		powersave_nap = 1;		printk(KERN_INFO "Processor NAP mode on idle enabled.\n");		break;	}	printk(KERN_INFO "PowerMac motherboard: %s\n", pmac_mb.model_name);	return 0;}/* Initialize the Core99 UniNorth host bridge and memory controller */static void __initprobe_uninorth(void){	unsigned long actrl;		/* Locate core99 Uni-N */	uninorth_node = find_devices("uni-n");	if (uninorth_node && uninorth_node->n_addrs > 0) {		uninorth_base = ioremap(uninorth_node->addrs[0].address, 0x1000);		uninorth_rev = in_be32(UN_REG(UNI_N_VERSION));	} else		uninorth_node = NULL;			if (!uninorth_node)		return;		printk(KERN_INFO "Found Uninorth memory controller & host bridge, revision: %d\n",			uninorth_rev);	/* Set the arbitrer QAck delay according to what Apple does	 */	if (uninorth_rev < 0x10) {		actrl = UN_IN(UNI_N_ARB_CTRL) & ~UNI_N_ARB_CTRL_QACK_DELAY_MASK;		actrl |= ((uninorth_rev < 3) ? UNI_N_ARB_CTRL_QACK_DELAY105 :			UNI_N_ARB_CTRL_QACK_DELAY) << UNI_N_ARB_CTRL_QACK_DELAY_SHIFT;		UN_OUT(UNI_N_ARB_CTRL, actrl);	}}	static void __initprobe_one_macio(const char* name, const char* compat, int type){	struct device_node*	node;	int			i;	volatile u32*		base;	u32*			revp;		node = find_devices(name);	if (!node || !node->n_addrs)		return;	if (compat)		do {			if (device_is_compatible(node, compat))				break;			node = node->next;		} while (node);	if (!node)		return;	for(i=0; i<MAX_MACIO_CHIPS; i++) {		if (!macio_chips[i].of_node)			break;		if (macio_chips[i].of_node == node)			return;	}	if (i >= MAX_MACIO_CHIPS) {		printk(KERN_ERR "pmac_feature: Please increase MAX_MACIO_CHIPS !\n");		printk(KERN_ERR "pmac_feature: %s skipped\n", node->full_name);		return;	}	base = (volatile u32*)ioremap(node->addrs[0].address, node->addrs[0].size);	if (!base) {		printk(KERN_ERR "pmac_feature: Can't map mac-io chip !\n");		return;	}	if (type == macio_keylargo) {		u32* did = (u32 *)get_property(node, "device-id", NULL);		if (*did == 0x00000025)			type = macio_pangea;	}	macio_chips[i].of_node	= node;	macio_chips[i].type	= type;	macio_chips[i].base	= base;	macio_chips[i].flags	= MACIO_FLAG_SCCB_ON | MACIO_FLAG_SCCB_ON;	revp = (u32 *)get_property(node, "revision-id", NULL);	if (revp)		macio_chips[i].rev = *revp;	printk(KERN_INFO "Found a %s mac-io controller, rev: %d, mapped at 0x%p\n",		macio_names[type], macio_chips[i].rev, macio_chips[i].base);}static int __initprobe_macios(void){	/* Warning, ordering is important */	probe_one_macio("gc", NULL, macio_grand_central);	probe_one_macio("ohare", NULL, macio_ohare);	probe_one_macio("pci106b,7", NULL, macio_ohareII);	probe_one_macio("mac-io", "keylargo", macio_keylargo);	probe_one_macio("mac-io", "paddington", macio_paddington);	probe_one_macio("mac-io", "gatwick", macio_gatwick);	probe_one_macio("mac-io", "heathrow", macio_heathrow);	/* Make sure the "main" macio chip appear first */	if (macio_chips[0].type == macio_gatwick	    && macio_chips[1].type == macio_heathrow) {		struct macio_chip temp = macio_chips[0];		macio_chips[0] = macio_chips[1];		macio_chips[1] = temp;	}	if (macio_chips[0].type == macio_ohareII	    && macio_chips[1].type == macio_ohare) {		struct macio_chip temp = macio_chips[0];		macio_chips[0] = macio_chips[1];		macio_chips[1] = temp;	}	return (macio_chips[0].of_node == NULL) ? -ENODEV : 0;}static void __initinitial_serial_shutdown(struct device_node* np){	int len;	struct slot_names_prop {		int	count;		char	name[1];	} *slots;	char *conn;	int port_type = PMAC_SCC_ASYNC;	int modem = 0;		slots = (struct slot_names_prop *)get_property(np, "slot-names", &len);	conn = get_property(np, "AAPL,connector", &len);	if (conn && (strcmp(conn, "infrared") == 0))		port_type = PMAC_SCC_IRDA;	else if (device_is_compatible(np, "cobalt"))		modem = 1;	else if (slots && slots->count > 0) {		if (strcmp(slots->name, "IrDA") == 0)			port_type = PMAC_SCC_IRDA;		else if (strcmp(slots->name, "Modem") == 0)			modem = 1;	}	if (modem)		pmac_call_feature(PMAC_FTR_MODEM_ENABLE, np, 0, 0);	pmac_call_feature(PMAC_FTR_SCC_ENABLE, np, port_type, 0);}static void __initset_initial_features(void){	struct device_node* np;		/* That hack appears to be necessary for some StarMax motherboards	 * but I'm not too sure it was audited for side-effects on other	 * ohare based machines...	 * Since I still have difficulties figuring the right way to	 * differenciate them all and since that hack was there for a long	 * time, I'll keep it around	 */	if (macio_chips[0].type == macio_ohare && !find_devices("via-pmu")) {		struct macio_chip* macio = &macio_chips[0];		MACIO_OUT32(OHARE_FCR, STARMAX_FEATURES);	} else if (macio_chips[0].type == macio_ohare) {		struct macio_chip* macio = &macio_chips[0];		MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);	} else if (macio_chips[1].type == macio_ohare) {		struct macio_chip* macio = &macio_chips[1];		MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);	}	if (macio_chips[0].type == macio_keylargo ||	    macio_chips[0].type == macio_pangea) {		/* Enable GMAC for now for PCI probing. It will be disabled		 * later on after PCI probe		 */		np = find_devices("ethernet");		while(np) {			if (np->parent			    && device_is_compatible(np->parent, "uni-north")			    && device_is_compatible(np, "gmac"))				core99_gmac_enable(np, 0, 1);			np = np->next;		}		/* Enable FW before PCI probe. Will be disabled later on		 * Note: We should have a batter way to check that we are		 * dealing with uninorth internal cell and not a PCI cell		 * on the external PCI. The code below works though.		 */		np = find_devices("firewire");		while(np) {			if (np->parent			    && device_is_compatible(np->parent, "uni-north")			    && (device_is_compatible(np, "pci106b,18") || 	     		        device_is_compatible(np, "pci106b,30") ||	     		        device_is_compatible(np, "pci11c1,5811"))) {				macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED;				core99_firewire_enable(np, 0, 1);			}			np = np->next;		}				/* Switch airport off */		np = find_devices("radio");		while(np) {			if (np && np->parent == macio_chips[0].of_node) {				macio_chips[0].flags |= MACIO_FLAG_AIRPORT_ON;				core99_airport_enable(np, 0, 0);			}			np = np->next;		}	}	/* On all machines, switch sound off */	if (macio_chips[0].of_node)		pmac_do_feature_call(PMAC_FTR_SOUND_CHIP_ENABLE,			macio_chips[0].of_node, 0, 0);	/* On all machines, switch modem & serial ports off */	np = find_devices("ch-a");	while(np) {		initial_serial_shutdown(np);		np = np->next;	}	np = find_devices("ch-b");	while(np) {		initial_serial_shutdown(np);		np = np->next;	}		/* Let hardware settle down */	mdelay(10);}void __initpmac_feature_init(void){	/* Detect the UniNorth memory controller */	probe_uninorth();	/* Probe mac-io controllers */	if (probe_macios()) {		printk(KERN_WARNING "No mac-io chip found\n");		return;	}	/* Probe machine type */	if (probe_motherboard())		printk(KERN_WARNING "Unknown PowerMac !\n");	/* Set some initial features (turn off some chips that will	 * be later turned on)	 */	set_initial_features();}void __initpmac_feature_late_init(void){	struct device_node* np;		/* Request some resources late */	if (uninorth_node)		request_OF_resource(uninorth_node, 0, NULL);	np = find_devices("hammerhead");	if (np)		request_OF_resource(np, 0, NULL);	np = find_devices("interrupt-controller");	if (np)		request_OF_resource(np, 0, NULL);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -