| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * PMC-Sierra MSP board specific pci_ops | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright 2001 MontaVista Software Inc. | 
					
						
							|  |  |  |  * Copyright 2005-2007 PMC-Sierra, Inc | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Much of the code is derived from the original DDB5074 port by | 
					
						
							| 
									
										
										
										
											2014-04-22 12:51:13 +02:00
										 |  |  |  * Geert Uytterhoeven <geert@linux-m68k.org> | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  * This program is free software; you can redistribute	it and/or modify it | 
					
						
							|  |  |  |  * under  the terms of	the GNU General	 Public License as published by the | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * Free Software Foundation;  either version 2 of the  License, or (at your | 
					
						
							|  |  |  |  * option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define PCI_COUNTERS	1
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <linux/types.h>
 | 
					
						
							|  |  |  | #include <linux/pci.h>
 | 
					
						
							|  |  |  | #include <linux/interrupt.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS)
 | 
					
						
							|  |  |  | #include <linux/proc_fs.h>
 | 
					
						
							|  |  |  | #include <linux/seq_file.h>
 | 
					
						
							|  |  |  | #endif /* CONFIG_PROC_FS && PCI_COUNTERS */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <linux/kernel.h>
 | 
					
						
							|  |  |  | #include <linux/init.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <asm/byteorder.h>
 | 
					
						
							|  |  |  | #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
 | 
					
						
							|  |  |  | #include <asm/mipsmtregs.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <msp_prom.h>
 | 
					
						
							|  |  |  | #include <msp_cic_int.h>
 | 
					
						
							|  |  |  | #include <msp_pci.h>
 | 
					
						
							|  |  |  | #include <msp_regs.h>
 | 
					
						
							|  |  |  | #include <msp_regops.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define PCI_ACCESS_READ		0
 | 
					
						
							|  |  |  | #define PCI_ACCESS_WRITE	1
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS)
 | 
					
						
							|  |  |  | static char proc_init; | 
					
						
							|  |  |  | extern struct proc_dir_entry *proc_bus_pci_dir; | 
					
						
							|  |  |  | unsigned int pci_int_count[32]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void pci_proc_init(void); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*****************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-04-11 00:21:15 +01:00
										 |  |  |  *  FUNCTION: show_msp_pci_counts | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  *  _________________________________________________________________________ | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  DESCRIPTION: Prints the count of how many times each PCI | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *		 interrupt has asserted. Can be invoked by the | 
					
						
							|  |  |  |  *		 /proc filesystem. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-04-11 00:21:15 +01:00
										 |  |  |  *  INPUTS:	 m	 - synthetic file construction data | 
					
						
							|  |  |  |  *		 v	 - iterator | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-04-11 00:21:15 +01:00
										 |  |  |  *  RETURNS:	 0 or error | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							|  |  |  |  ****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2013-04-11 00:21:15 +01:00
										 |  |  | static int show_msp_pci_counts(struct seq_file *m, void *v) | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  | { | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	unsigned int intcount, total = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < 32; ++i) { | 
					
						
							|  |  |  | 		intcount = pci_int_count[i]; | 
					
						
							|  |  |  | 		if (intcount != 0) { | 
					
						
							| 
									
										
										
										
											2013-04-11 00:21:15 +01:00
										 |  |  | 			seq_printf(m, "[%d] = %u\n", i, intcount); | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  | 			total += intcount; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-11 00:21:15 +01:00
										 |  |  | 	seq_printf(m, "total = %u\n", total); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-11 00:21:15 +01:00
										 |  |  | static int msp_pci_rd_cnt_open(struct inode *inode, struct file *file) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return single_open(file, show_msp_pci_counts, NULL); | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-11 00:21:15 +01:00
										 |  |  | static const struct file_operations msp_pci_rd_cnt_fops = { | 
					
						
							|  |  |  | 	.open		= msp_pci_rd_cnt_open, | 
					
						
							|  |  |  | 	.read		= seq_read, | 
					
						
							|  |  |  | 	.llseek		= seq_lseek, | 
					
						
							| 
									
										
										
										
											2013-05-05 00:09:30 -04:00
										 |  |  | 	.release	= single_release, | 
					
						
							| 
									
										
										
										
											2013-04-11 00:21:15 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  | /*****************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-04-11 00:21:15 +01:00
										 |  |  |  *  FUNCTION: gen_pci_cfg_wr_show | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  *  _________________________________________________________________________ | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  DESCRIPTION: Generates a configuration write cycle for debug purposes. | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *		 The IDSEL line asserted and location and data written are | 
					
						
							|  |  |  |  *		 immaterial. Just want to be able to prove that a | 
					
						
							|  |  |  |  *		 configuration write can be correctly generated on the | 
					
						
							|  |  |  |  *		 PCI bus.  Intent is that this function by invocable from | 
					
						
							|  |  |  |  *		 the /proc filesystem. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-04-11 00:21:15 +01:00
										 |  |  |  *  INPUTS:	 m	 - synthetic file construction data | 
					
						
							|  |  |  |  *		 v	 - iterator | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-04-11 00:21:15 +01:00
										 |  |  |  *  RETURNS:	 0 or error | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							|  |  |  |  ****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2013-04-11 00:21:15 +01:00
										 |  |  | static int gen_pci_cfg_wr_show(struct seq_file *m, void *v) | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  | { | 
					
						
							|  |  |  | 	unsigned char where = 0; /* Write to static Device/Vendor ID */ | 
					
						
							|  |  |  | 	unsigned char bus_num = 0; /* Bus 0 */ | 
					
						
							|  |  |  | 	unsigned char dev_fn = 0xF; /* Arbitrary device number */ | 
					
						
							|  |  |  | 	u32 wr_data = 0xFF00AA00; /* Arbitrary data */ | 
					
						
							|  |  |  | 	struct msp_pci_regs *preg = (void *)PCI_BASE_REG; | 
					
						
							|  |  |  | 	unsigned long value; | 
					
						
							|  |  |  | 	int intr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-11 00:21:15 +01:00
										 |  |  | 	seq_puts(m, "PMC MSP PCI: Beginning\n"); | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (proc_init == 0) { | 
					
						
							|  |  |  | 		pci_proc_init(); | 
					
						
							|  |  |  | 		proc_init = ~0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-11 00:21:15 +01:00
										 |  |  | 	seq_puts(m, "PMC MSP PCI: Before Cfg Wr\n"); | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * Generate PCI Configuration Write Cycle | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Clear cause register bits */ | 
					
						
							|  |  |  | 	preg->if_status = ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Setup address that is to appear on PCI bus */ | 
					
						
							|  |  |  | 	preg->config_addr = BPCI_CFGADDR_ENABLE | | 
					
						
							|  |  |  | 		(bus_num << BPCI_CFGADDR_BUSNUM_SHF) | | 
					
						
							|  |  |  | 		(dev_fn << BPCI_CFGADDR_FUNCTNUM_SHF) | | 
					
						
							|  |  |  | 		(where & 0xFC); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	value = cpu_to_le32(wr_data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Launch the PCI configuration write cycle */ | 
					
						
							|  |  |  | 	*PCI_CONFIG_SPACE_REG = value; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * Check if the PCI configuration cycle (rd or wr) succeeded, by | 
					
						
							|  |  |  | 	 * checking the status bits for errors like master or target abort. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	intr = preg->if_status; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-11 00:21:15 +01:00
										 |  |  | 	seq_puts(m, "PMC MSP PCI: After Cfg Wr\n"); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-11 00:21:15 +01:00
										 |  |  | static int gen_pci_cfg_wr_open(struct inode *inode, struct file *file) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return single_open(file, gen_pci_cfg_wr_show, NULL); | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-11 00:21:15 +01:00
										 |  |  | static const struct file_operations gen_pci_cfg_wr_fops = { | 
					
						
							|  |  |  | 	.open		= gen_pci_cfg_wr_open, | 
					
						
							|  |  |  | 	.read		= seq_read, | 
					
						
							|  |  |  | 	.llseek		= seq_lseek, | 
					
						
							| 
									
										
										
										
											2013-05-05 00:09:30 -04:00
										 |  |  | 	.release	= single_release, | 
					
						
							| 
									
										
										
										
											2013-04-11 00:21:15 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  | /*****************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  FUNCTION: pci_proc_init | 
					
						
							|  |  |  |  *  _________________________________________________________________________ | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  DESCRIPTION: Create entries in the /proc filesystem for debug access. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  INPUTS:	 none | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  OUTPUTS:	 none | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  RETURNS:	 none | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							|  |  |  |  ****************************************************************************/ | 
					
						
							|  |  |  | static void pci_proc_init(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-04-11 00:21:15 +01:00
										 |  |  | 	proc_create("pmc_msp_pci_rd_cnt", 0, NULL, &msp_pci_rd_cnt_fops); | 
					
						
							|  |  |  | 	proc_create("pmc_msp_pci_cfg_wr", 0, NULL, &gen_pci_cfg_wr_fops); | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  | } | 
					
						
							|  |  |  | #endif /* CONFIG_PROC_FS && PCI_COUNTERS */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*****************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  STRUCT: pci_io_resource | 
					
						
							|  |  |  |  *  _________________________________________________________________________ | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  DESCRIPTION: Defines the address range that pciauto() will use to | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *		 assign to the I/O BARs of PCI devices. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *		 Use the start and end addresses of the MSP7120 PCI Host | 
					
						
							|  |  |  |  *		 Controller I/O space, in the form that they appear on the | 
					
						
							|  |  |  |  *		 PCI bus AFTER MSP7120 has performed address translation. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *		 For I/O accesses, MSP7120 ignores OATRAN and maps I/O | 
					
						
							|  |  |  |  *		 accesses into the bottom 0xFFF region of address space, | 
					
						
							|  |  |  |  *		 so that is the range to put into the pci_io_resource | 
					
						
							|  |  |  |  *		 struct. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *		 In MSP4200, the start address was 0x04 instead of the | 
					
						
							|  |  |  |  *		 expected 0x00. Will just assume there was a good reason | 
					
						
							|  |  |  |  *		 for this! | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  NOTES:	 Linux, by default, will assign I/O space to the lowest | 
					
						
							|  |  |  |  *		 region of address space. Since MSP7120 and Linux, | 
					
						
							|  |  |  |  *		 by default, have no offset in between how they map, the | 
					
						
							|  |  |  |  *		 io_offset element of pci_controller struct should be set | 
					
						
							|  |  |  |  *		 to zero. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  *  ELEMENTS: | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *    name	 - String used for a meaningful name. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *    start	 - Start address of MSP7120's I/O space, as MSP7120 presents | 
					
						
							|  |  |  |  *		   the address on the PCI bus. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *    end	 - End address of MSP7120's I/O space, as MSP7120 presents | 
					
						
							|  |  |  |  *		   the address on the PCI bus. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *    flags	 - Attributes indicating the type of resource. In this case, | 
					
						
							|  |  |  |  *		   indicate I/O space. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							|  |  |  |  ****************************************************************************/ | 
					
						
							|  |  |  | static struct resource pci_io_resource = { | 
					
						
							|  |  |  | 	.name	= "pci IO space", | 
					
						
							|  |  |  | 	.start	= 0x04, | 
					
						
							|  |  |  | 	.end	= 0x0FFF, | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  | 	.flags	= IORESOURCE_IO /* I/O space */ | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*****************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  STRUCT: pci_mem_resource | 
					
						
							|  |  |  |  *  _________________________________________________________________________ | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  DESCRIPTION: Defines the address range that pciauto() will use to | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *		 assign to the memory BARs of PCI devices. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *		 The .start and .end values are dependent upon how address | 
					
						
							|  |  |  |  *		 translation is performed by the OATRAN regiser. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *		 The values to use for .start and .end are the values | 
					
						
							|  |  |  |  *		 in the form they appear on the PCI bus AFTER MSP7120 has | 
					
						
							|  |  |  |  *		 performed OATRAN address translation. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							|  |  |  |  *  ELEMENTS: | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *    name	 - String used for a meaningful name. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *    start	 - Start address of MSP7120's memory space, as MSP7120 presents | 
					
						
							|  |  |  |  *		   the address on the PCI bus. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *    end	 - End address of MSP7120's memory space, as MSP7120 presents | 
					
						
							|  |  |  |  *		   the address on the PCI bus. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *    flags	 - Attributes indicating the type of resource. In this case, | 
					
						
							|  |  |  |  *		   indicate memory space. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							|  |  |  |  ****************************************************************************/ | 
					
						
							|  |  |  | static struct resource pci_mem_resource = { | 
					
						
							|  |  |  | 	.name	= "pci memory space", | 
					
						
							|  |  |  | 	.start	= MSP_PCI_SPACE_BASE, | 
					
						
							|  |  |  | 	.end	= MSP_PCI_SPACE_END, | 
					
						
							|  |  |  | 	.flags	= IORESOURCE_MEM	 /* memory space */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*****************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  FUNCTION: bpci_interrupt | 
					
						
							|  |  |  |  *  _________________________________________________________________________ | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  DESCRIPTION: PCI status interrupt handler. Updates the count of how | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *		 many times each status bit has been set, then clears | 
					
						
							|  |  |  |  *		 the status bits. If the appropriate macros are defined, | 
					
						
							|  |  |  |  *		 these counts can be viewed via the /proc filesystem. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  INPUTS:	 irq	 - unused | 
					
						
							|  |  |  |  *		 dev_id	 - unused | 
					
						
							|  |  |  |  *		 pt_regs - unused | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  OUTPUTS:	 none | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  RETURNS:	 PCIBIOS_SUCCESSFUL  - success | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							|  |  |  |  ****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2010-11-18 16:02:50 +05:30
										 |  |  | static irqreturn_t bpci_interrupt(int irq, void *dev_id) | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct msp_pci_regs *preg = (void *)PCI_BASE_REG; | 
					
						
							|  |  |  | 	unsigned int stat = preg->if_status; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS)
 | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	for (i = 0; i < 32; ++i) { | 
					
						
							|  |  |  | 		if ((1 << i) & stat) | 
					
						
							|  |  |  | 			++pci_int_count[i]; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif /* PROC_FS && PCI_COUNTERS */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* printk("PCI ISR: Status=%08X\n", stat); */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* write to clear all asserted interrupts */ | 
					
						
							|  |  |  | 	preg->if_status = stat; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-18 16:02:50 +05:30
										 |  |  | 	return IRQ_HANDLED; | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*****************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  FUNCTION: msp_pcibios_config_access | 
					
						
							|  |  |  |  *  _________________________________________________________________________ | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  DESCRIPTION: Performs a PCI configuration access (rd or wr), then | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *		 checks that the access succeeded by querying MSP7120's | 
					
						
							|  |  |  |  *		 PCI status bits. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							|  |  |  |  *  INPUTS: | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *		 access_type  - kind of PCI configuration cycle to perform | 
					
						
							|  |  |  |  *				(read or write). Legal values are | 
					
						
							|  |  |  |  *				PCI_ACCESS_WRITE and PCI_ACCESS_READ. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *		 bus	      - pointer to the bus number of the device to | 
					
						
							|  |  |  |  *				be targeted for the configuration cycle. | 
					
						
							|  |  |  |  *				The only element of the pci_bus structure | 
					
						
							|  |  |  |  *				used is bus->number. This argument determines | 
					
						
							|  |  |  |  *				if the configuration access will be Type 0 or | 
					
						
							|  |  |  |  *				Type 1. Since MSP7120 assumes itself to be the | 
					
						
							|  |  |  |  *				PCI Host, any non-zero bus->number generates | 
					
						
							|  |  |  |  *				a Type 1 access. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *		 devfn	      - this is an 8-bit field. The lower three bits | 
					
						
							|  |  |  |  *				specify the function number of the device to | 
					
						
							|  |  |  |  *				be targeted for the configuration cycle, with | 
					
						
							|  |  |  |  *				all three-bit combinations being legal. The | 
					
						
							|  |  |  |  *				upper five bits specify the device number, | 
					
						
							|  |  |  |  *				with legal values being 10 to 31. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *		 where	      - address within the Configuration Header | 
					
						
							|  |  |  |  *				space to access. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *		 data	      - for write accesses, contains the data to | 
					
						
							|  |  |  |  *				write. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							|  |  |  |  *  OUTPUTS: | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *		 data	      - for read accesses, contains the value read. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  RETURNS:	 PCIBIOS_SUCCESSFUL  - success | 
					
						
							|  |  |  |  *		 -1		     - access failure | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							|  |  |  |  ****************************************************************************/ | 
					
						
							|  |  |  | int msp_pcibios_config_access(unsigned char access_type, | 
					
						
							|  |  |  | 				struct pci_bus *bus, | 
					
						
							|  |  |  | 				unsigned int devfn, | 
					
						
							|  |  |  | 				unsigned char where, | 
					
						
							|  |  |  | 				u32 *data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct msp_pci_regs *preg = (void *)PCI_BASE_REG; | 
					
						
							|  |  |  | 	unsigned char bus_num = bus->number; | 
					
						
							|  |  |  | 	unsigned char dev_fn = (unsigned char)devfn; | 
					
						
							|  |  |  | 	unsigned long intr; | 
					
						
							|  |  |  | 	unsigned long value; | 
					
						
							|  |  |  | 	static char pciirqflag; | 
					
						
							| 
									
										
										
										
											2009-09-18 12:50:11 -07:00
										 |  |  | 	int ret; | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  | #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
 | 
					
						
							|  |  |  | 	unsigned int	vpe_status; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS)
 | 
					
						
							|  |  |  | 	if (proc_init == 0) { | 
					
						
							|  |  |  | 		pci_proc_init(); | 
					
						
							|  |  |  | 		proc_init = ~0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif /* CONFIG_PROC_FS && PCI_COUNTERS */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * Just the first time this function invokes, allocate | 
					
						
							|  |  |  | 	 * an interrupt line for PCI host status interrupts. The | 
					
						
							|  |  |  | 	 * allocation assigns an interrupt handler to the interrupt. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if (pciirqflag == 0) { | 
					
						
							| 
									
										
										
										
											2009-09-18 12:50:11 -07:00
										 |  |  | 		ret = request_irq(MSP_INT_PCI,/* Hardcoded internal MSP7120 wiring */ | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  | 				bpci_interrupt, | 
					
						
							| 
									
										
										
										
											2011-11-22 14:38:03 +00:00
										 |  |  | 				IRQF_SHARED, | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  | 				"PMC MSP PCI Host", | 
					
						
							|  |  |  | 				preg); | 
					
						
							| 
									
										
										
										
											2009-09-18 12:50:11 -07:00
										 |  |  | 		if (ret != 0) | 
					
						
							|  |  |  | 			return ret; | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  | 		pciirqflag = ~0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
 | 
					
						
							|  |  |  | 	vpe_status = dvpe(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * Clear PCI cause register bits. | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * In Polo, the PCI Host had a dedicated DMA called the | 
					
						
							|  |  |  | 	 * Block Copy (not to be confused with the general purpose Block | 
					
						
							|  |  |  | 	 * Copy Engine block). There appear to have been special interrupts | 
					
						
							|  |  |  | 	 * for this Block Copy, called Block Copy 0 Fault (BC0F) and | 
					
						
							|  |  |  | 	 * Block Copy 1 Fault (BC1F). MSP4200 and MSP7120 don't have this | 
					
						
							|  |  |  | 	 * dedicated Block Copy block, so these two interrupts are now | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  | 	 * marked reserved. In case the	 Block Copy is resurrected in a | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  | 	 * future design, maintain the code that treats these two interrupts | 
					
						
							|  |  |  | 	 * specially. | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * Write to clear all interrupts in the PCI status register, aside | 
					
						
							|  |  |  | 	 * from BC0F and BC1F. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	preg->if_status = ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Setup address that is to appear on PCI bus */ | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  | 	preg->config_addr = BPCI_CFGADDR_ENABLE | | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  | 		(bus_num << BPCI_CFGADDR_BUSNUM_SHF) | | 
					
						
							|  |  |  | 		(dev_fn << BPCI_CFGADDR_FUNCTNUM_SHF) | | 
					
						
							|  |  |  | 		(where & 0xFC); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* IF access is a PCI configuration write */ | 
					
						
							|  |  |  | 	if (access_type == PCI_ACCESS_WRITE) { | 
					
						
							|  |  |  | 		value = cpu_to_le32(*data); | 
					
						
							|  |  |  | 		*PCI_CONFIG_SPACE_REG = value; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		/* ELSE access is a PCI configuration read */ | 
					
						
							|  |  |  | 		value = le32_to_cpu(*PCI_CONFIG_SPACE_REG); | 
					
						
							|  |  |  | 		*data = value; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * Check if the PCI configuration cycle (rd or wr) succeeded, by | 
					
						
							|  |  |  | 	 * checking the status bits for errors like master or target abort. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	intr = preg->if_status; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Clear config access */ | 
					
						
							|  |  |  | 	preg->config_addr = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* IF error occurred */ | 
					
						
							|  |  |  | 	if (intr & ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F)) { | 
					
						
							|  |  |  | 		/* Clear status bits */ | 
					
						
							|  |  |  | 		preg->if_status = ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
 | 
					
						
							|  |  |  | 		evpe(vpe_status); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
 | 
					
						
							|  |  |  | 	evpe(vpe_status); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return PCIBIOS_SUCCESSFUL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*****************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  FUNCTION: msp_pcibios_read_config_byte | 
					
						
							|  |  |  |  *  _________________________________________________________________________ | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  DESCRIPTION: Read a byte from PCI configuration address spac | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *		 Since the hardware can't address 8 bit chunks | 
					
						
							|  |  |  |  *		 directly, read a 32-bit chunk, then mask off extraneous | 
					
						
							|  |  |  |  *		 bits. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  INPUTS	 bus	- structure containing attributes for the PCI bus | 
					
						
							|  |  |  |  *			  that the read is destined for. | 
					
						
							|  |  |  |  *		 devfn	- device/function combination that the read is | 
					
						
							|  |  |  |  *			  destined for. | 
					
						
							|  |  |  |  *		 where	- register within the Configuration Header space | 
					
						
							|  |  |  |  *			  to access. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  OUTPUTS	 val	- read data | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  RETURNS:	 PCIBIOS_SUCCESSFUL  - success | 
					
						
							|  |  |  |  *		 -1		     - read access failure | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							|  |  |  |  ****************************************************************************/ | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | msp_pcibios_read_config_byte(struct pci_bus *bus, | 
					
						
							|  |  |  | 				unsigned int devfn, | 
					
						
							|  |  |  | 				int where, | 
					
						
							|  |  |  | 				u32 *val) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u32 data = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * If the config access did not complete normally (e.g., underwent | 
					
						
							|  |  |  | 	 * master abort) do the PCI compliant thing, which is to supply an | 
					
						
							|  |  |  | 	 * all ones value. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, | 
					
						
							|  |  |  | 					where, &data)) { | 
					
						
							|  |  |  | 		*val = 0xFFFFFFFF; | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	*val = (data >> ((where & 3) << 3)) & 0x0ff; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return PCIBIOS_SUCCESSFUL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*****************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  FUNCTION: msp_pcibios_read_config_word | 
					
						
							|  |  |  |  *  _________________________________________________________________________ | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  DESCRIPTION: Read a word (16 bits) from PCI configuration address space. | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *		 Since the hardware can't address 16 bit chunks | 
					
						
							|  |  |  |  *		 directly, read a 32-bit chunk, then mask off extraneous | 
					
						
							|  |  |  |  *		 bits. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  INPUTS	 bus	- structure containing attributes for the PCI bus | 
					
						
							|  |  |  |  *			  that the read is destined for. | 
					
						
							|  |  |  |  *		 devfn	- device/function combination that the read is | 
					
						
							|  |  |  |  *			  destined for. | 
					
						
							|  |  |  |  *		 where	- register within the Configuration Header space | 
					
						
							|  |  |  |  *			  to access. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  OUTPUTS	 val	- read data | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  RETURNS:	 PCIBIOS_SUCCESSFUL	      - success | 
					
						
							|  |  |  |  *		 PCIBIOS_BAD_REGISTER_NUMBER  - bad register address | 
					
						
							|  |  |  |  *		 -1			      - read access failure | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							|  |  |  |  ****************************************************************************/ | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | msp_pcibios_read_config_word(struct pci_bus *bus, | 
					
						
							|  |  |  | 				unsigned int devfn, | 
					
						
							|  |  |  | 				int where, | 
					
						
							|  |  |  | 				u32 *val) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u32 data = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* if (where & 1) */	/* Commented out non-compliant code.
 | 
					
						
							|  |  |  | 				 * Should allow word access to configuration | 
					
						
							|  |  |  | 				 * registers, with only exception being when | 
					
						
							|  |  |  | 				 * the word access would wrap around into | 
					
						
							|  |  |  | 				 * the next dword. | 
					
						
							|  |  |  | 				 */ | 
					
						
							|  |  |  | 	if ((where & 3) == 3) { | 
					
						
							|  |  |  | 		*val = 0xFFFFFFFF; | 
					
						
							|  |  |  | 		return PCIBIOS_BAD_REGISTER_NUMBER; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * If the config access did not complete normally (e.g., underwent | 
					
						
							|  |  |  | 	 * master abort) do the PCI compliant thing, which is to supply an | 
					
						
							|  |  |  | 	 * all ones value. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, | 
					
						
							|  |  |  | 					where, &data)) { | 
					
						
							|  |  |  | 		*val = 0xFFFFFFFF; | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	*val = (data >> ((where & 3) << 3)) & 0x0ffff; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return PCIBIOS_SUCCESSFUL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*****************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  FUNCTION: msp_pcibios_read_config_dword | 
					
						
							|  |  |  |  *  _________________________________________________________________________ | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  DESCRIPTION: Read a double word (32 bits) from PCI configuration | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *		 address space. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  INPUTS	 bus	- structure containing attributes for the PCI bus | 
					
						
							|  |  |  |  *			  that the read is destined for. | 
					
						
							|  |  |  |  *		 devfn	- device/function combination that the read is | 
					
						
							|  |  |  |  *			  destined for. | 
					
						
							|  |  |  |  *		 where	- register within the Configuration Header space | 
					
						
							|  |  |  |  *			  to access. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  OUTPUTS	 val	- read data | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  RETURNS:	 PCIBIOS_SUCCESSFUL	      - success | 
					
						
							|  |  |  |  *		 PCIBIOS_BAD_REGISTER_NUMBER  - bad register address | 
					
						
							|  |  |  |  *		 -1			      - read access failure | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							|  |  |  |  ****************************************************************************/ | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | msp_pcibios_read_config_dword(struct pci_bus *bus, | 
					
						
							|  |  |  | 				unsigned int devfn, | 
					
						
							|  |  |  | 				int where, | 
					
						
							|  |  |  | 				u32 *val) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u32 data = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Address must be dword aligned. */ | 
					
						
							|  |  |  | 	if (where & 3) { | 
					
						
							|  |  |  | 		*val = 0xFFFFFFFF; | 
					
						
							|  |  |  | 		return PCIBIOS_BAD_REGISTER_NUMBER; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * If the config access did not complete normally (e.g., underwent | 
					
						
							|  |  |  | 	 * master abort) do the PCI compliant thing, which is to supply an | 
					
						
							|  |  |  | 	 * all ones value. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, | 
					
						
							|  |  |  | 					where, &data)) { | 
					
						
							|  |  |  | 		*val = 0xFFFFFFFF; | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	*val = data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return PCIBIOS_SUCCESSFUL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*****************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  FUNCTION: msp_pcibios_write_config_byte | 
					
						
							|  |  |  |  *  _________________________________________________________________________ | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  DESCRIPTION: Write a byte to PCI configuration address space. | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *		 Since the hardware can't address 8 bit chunks | 
					
						
							|  |  |  |  *		 directly, a read-modify-write is performed. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  INPUTS	 bus	- structure containing attributes for the PCI bus | 
					
						
							|  |  |  |  *			  that the write is destined for. | 
					
						
							|  |  |  |  *		 devfn	- device/function combination that the write is | 
					
						
							|  |  |  |  *			  destined for. | 
					
						
							|  |  |  |  *		 where	- register within the Configuration Header space | 
					
						
							|  |  |  |  *			  to access. | 
					
						
							|  |  |  |  *		 val	- value to write | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  OUTPUTS	 none | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  RETURNS:	 PCIBIOS_SUCCESSFUL  - success | 
					
						
							|  |  |  |  *		 -1		     - write access failure | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							|  |  |  |  ****************************************************************************/ | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | msp_pcibios_write_config_byte(struct pci_bus *bus, | 
					
						
							|  |  |  | 				unsigned int devfn, | 
					
						
							|  |  |  | 				int where, | 
					
						
							|  |  |  | 				u8 val) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u32 data = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* read config space */ | 
					
						
							|  |  |  | 	if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, | 
					
						
							|  |  |  | 					where, &data)) | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* modify the byte within the dword */ | 
					
						
							|  |  |  | 	data = (data & ~(0xff << ((where & 3) << 3))) | | 
					
						
							|  |  |  | 			(val << ((where & 3) << 3)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* write back the full dword */ | 
					
						
							|  |  |  | 	if (msp_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, | 
					
						
							|  |  |  | 					where, &data)) | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return PCIBIOS_SUCCESSFUL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*****************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  FUNCTION: msp_pcibios_write_config_word | 
					
						
							|  |  |  |  *  _________________________________________________________________________ | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  DESCRIPTION: Write a word (16-bits) to PCI configuration address space. | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *		 Since the hardware can't address 16 bit chunks | 
					
						
							|  |  |  |  *		 directly, a read-modify-write is performed. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  INPUTS	 bus	- structure containing attributes for the PCI bus | 
					
						
							|  |  |  |  *			  that the write is destined for. | 
					
						
							|  |  |  |  *		 devfn	- device/function combination that the write is | 
					
						
							|  |  |  |  *			  destined for. | 
					
						
							|  |  |  |  *		 where	- register within the Configuration Header space | 
					
						
							|  |  |  |  *			  to access. | 
					
						
							|  |  |  |  *		 val	- value to write | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  OUTPUTS	 none | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  RETURNS:	 PCIBIOS_SUCCESSFUL	      - success | 
					
						
							|  |  |  |  *		 PCIBIOS_BAD_REGISTER_NUMBER  - bad register address | 
					
						
							|  |  |  |  *		 -1			      - write access failure | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							|  |  |  |  ****************************************************************************/ | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | msp_pcibios_write_config_word(struct pci_bus *bus, | 
					
						
							|  |  |  | 				unsigned int devfn, | 
					
						
							|  |  |  | 				int where, | 
					
						
							|  |  |  | 				u16 val) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u32 data = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Fixed non-compliance: if (where & 1) */ | 
					
						
							|  |  |  | 	if ((where & 3) == 3) | 
					
						
							|  |  |  | 		return PCIBIOS_BAD_REGISTER_NUMBER; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* read config space */ | 
					
						
							|  |  |  | 	if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, | 
					
						
							|  |  |  | 					where, &data)) | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* modify the word within the dword */ | 
					
						
							|  |  |  | 	data = (data & ~(0xffff << ((where & 3) << 3))) | | 
					
						
							|  |  |  | 			(val << ((where & 3) << 3)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* write back the full dword */ | 
					
						
							|  |  |  | 	if (msp_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, | 
					
						
							|  |  |  | 					where, &data)) | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return PCIBIOS_SUCCESSFUL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*****************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  FUNCTION: msp_pcibios_write_config_dword | 
					
						
							|  |  |  |  *  _________________________________________________________________________ | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  DESCRIPTION: Write a double word (32-bits) to PCI configuration address | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *		 space. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  INPUTS	 bus	- structure containing attributes for the PCI bus | 
					
						
							|  |  |  |  *			  that the write is destined for. | 
					
						
							|  |  |  |  *		 devfn	- device/function combination that the write is | 
					
						
							|  |  |  |  *			  destined for. | 
					
						
							|  |  |  |  *		 where	- register within the Configuration Header space | 
					
						
							|  |  |  |  *			  to access. | 
					
						
							|  |  |  |  *		 val	- value to write | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  OUTPUTS	 none | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  RETURNS:	 PCIBIOS_SUCCESSFUL	      - success | 
					
						
							|  |  |  |  *		 PCIBIOS_BAD_REGISTER_NUMBER  - bad register address | 
					
						
							|  |  |  |  *		 -1			      - write access failure | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							|  |  |  |  ****************************************************************************/ | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | msp_pcibios_write_config_dword(struct pci_bus *bus, | 
					
						
							|  |  |  | 				unsigned int devfn, | 
					
						
							|  |  |  | 				int where, | 
					
						
							|  |  |  | 				u32 val) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* check that address is dword aligned */ | 
					
						
							|  |  |  | 	if (where & 3) | 
					
						
							|  |  |  | 		return PCIBIOS_BAD_REGISTER_NUMBER; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* perform write */ | 
					
						
							|  |  |  | 	if (msp_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, | 
					
						
							|  |  |  | 					where, &val)) | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return PCIBIOS_SUCCESSFUL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*****************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  FUNCTION: msp_pcibios_read_config | 
					
						
							|  |  |  |  *  _________________________________________________________________________ | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  DESCRIPTION: Interface the PCI configuration read request with | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *		 the appropriate function, based on how many bytes | 
					
						
							|  |  |  |  *		 the read request is. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  INPUTS	 bus	- structure containing attributes for the PCI bus | 
					
						
							|  |  |  |  *			  that the write is destined for. | 
					
						
							|  |  |  |  *		 devfn	- device/function combination that the write is | 
					
						
							|  |  |  |  *			  destined for. | 
					
						
							|  |  |  |  *		 where	- register within the Configuration Header space | 
					
						
							|  |  |  |  *			  to access. | 
					
						
							|  |  |  |  *		 size	- in units of bytes, should be 1, 2, or 4. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  OUTPUTS	 val	- value read, with any extraneous bytes masked | 
					
						
							|  |  |  |  *			  to zero. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  RETURNS:	 PCIBIOS_SUCCESSFUL   - success | 
					
						
							|  |  |  |  *		 -1		      - failure | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							|  |  |  |  ****************************************************************************/ | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | msp_pcibios_read_config(struct pci_bus *bus, | 
					
						
							|  |  |  | 			unsigned int	devfn, | 
					
						
							|  |  |  | 			int where, | 
					
						
							|  |  |  | 			int size, | 
					
						
							|  |  |  | 			u32 *val) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (size == 1) { | 
					
						
							|  |  |  | 		if (msp_pcibios_read_config_byte(bus, devfn, where, val)) { | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else if (size == 2) { | 
					
						
							|  |  |  | 		if (msp_pcibios_read_config_word(bus, devfn, where, val)) { | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else if (size == 4) { | 
					
						
							|  |  |  | 		if (msp_pcibios_read_config_dword(bus, devfn, where, val)) { | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		*val = 0xFFFFFFFF; | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return PCIBIOS_SUCCESSFUL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*****************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  FUNCTION: msp_pcibios_write_config | 
					
						
							|  |  |  |  *  _________________________________________________________________________ | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  DESCRIPTION: Interface the PCI configuration write request with | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *		 the appropriate function, based on how many bytes | 
					
						
							|  |  |  |  *		 the read request is. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  INPUTS	 bus	- structure containing attributes for the PCI bus | 
					
						
							|  |  |  |  *			  that the write is destined for. | 
					
						
							|  |  |  |  *		 devfn	- device/function combination that the write is | 
					
						
							|  |  |  |  *			  destined for. | 
					
						
							|  |  |  |  *		 where	- register within the Configuration Header space | 
					
						
							|  |  |  |  *			  to access. | 
					
						
							|  |  |  |  *		 size	- in units of bytes, should be 1, 2, or 4. | 
					
						
							|  |  |  |  *		 val	- value to write | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  OUTPUTS:	 none | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *  RETURNS:	 PCIBIOS_SUCCESSFUL   - success | 
					
						
							|  |  |  |  *		 -1		      - failure | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							|  |  |  |  ****************************************************************************/ | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | msp_pcibios_write_config(struct pci_bus *bus, | 
					
						
							|  |  |  | 			unsigned int devfn, | 
					
						
							|  |  |  | 			int where, | 
					
						
							|  |  |  | 			int size, | 
					
						
							|  |  |  | 			u32 val) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (size == 1) { | 
					
						
							|  |  |  | 		if (msp_pcibios_write_config_byte(bus, devfn, | 
					
						
							|  |  |  | 						where, (u8)(0xFF & val))) { | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else if (size == 2) { | 
					
						
							|  |  |  | 		if (msp_pcibios_write_config_word(bus, devfn, | 
					
						
							|  |  |  | 						where, (u16)(0xFFFF & val))) { | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else if (size == 4) { | 
					
						
							|  |  |  | 		if (msp_pcibios_write_config_dword(bus, devfn, where, val)) { | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return PCIBIOS_SUCCESSFUL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*****************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  STRUCTURE: msp_pci_ops | 
					
						
							|  |  |  |  *  _________________________________________________________________________ | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  DESCRIPTION: structure to abstract the hardware specific PCI | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *		 configuration accesses. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							|  |  |  |  *  ELEMENTS: | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *    read	- function for Linux to generate PCI Configuration reads. | 
					
						
							|  |  |  |  *    write	- function for Linux to generate PCI Configuration writes. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							|  |  |  |  ****************************************************************************/ | 
					
						
							|  |  |  | struct pci_ops msp_pci_ops = { | 
					
						
							|  |  |  | 	.read = msp_pcibios_read_config, | 
					
						
							|  |  |  | 	.write = msp_pcibios_write_config | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*****************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  STRUCTURE: msp_pci_controller | 
					
						
							|  |  |  |  *  _________________________________________________________________________ | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Describes the attributes of the MSP7120 PCI Host Controller | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  ELEMENTS: | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *    pci_ops	   - abstracts the hardware specific PCI configuration | 
					
						
							|  |  |  |  *		     accesses. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							|  |  |  |  *    mem_resource - address range pciauto() uses to assign to PCI device | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *		     memory BARs. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							|  |  |  |  *    mem_offset   - offset between how MSP7120 outbound PCI memory | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *		     transaction addresses appear on the PCI bus and how Linux | 
					
						
							|  |  |  |  *		     wants to configure memory BARs of the PCI devices. | 
					
						
							|  |  |  |  *		     MSP7120 does nothing funky, so just set to zero. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							|  |  |  |  *    io_resource  - address range pciauto() uses to assign to PCI device | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *		     I/O BARs. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *    io_offset	   - offset between how MSP7120 outbound PCI I/O | 
					
						
							|  |  |  |  *		     transaction addresses appear on the PCI bus and how | 
					
						
							|  |  |  |  *		     Linux defaults to configure I/O BARs of the PCI devices. | 
					
						
							|  |  |  |  *		     MSP7120 maps outbound I/O accesses into the bottom | 
					
						
							|  |  |  |  *		     bottom 4K of PCI address space (and ignores OATRAN). | 
					
						
							|  |  |  |  *		     Since the Linux default is to configure I/O BARs to the | 
					
						
							|  |  |  |  *		     bottom 4K, no special offset is needed. Just set to zero. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							|  |  |  |  ****************************************************************************/ | 
					
						
							|  |  |  | static struct pci_controller msp_pci_controller = { | 
					
						
							|  |  |  | 	.pci_ops	= &msp_pci_ops, | 
					
						
							|  |  |  | 	.mem_resource	= &pci_mem_resource, | 
					
						
							|  |  |  | 	.mem_offset	= 0, | 
					
						
							| 
									
										
										
										
											2010-06-13 22:22:59 +01:00
										 |  |  | 	.io_map_base	= MSP_PCI_IOSPACE_BASE, | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  | 	.io_resource	= &pci_io_resource, | 
					
						
							|  |  |  | 	.io_offset	= 0 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*****************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  FUNCTION: msp_pci_init | 
					
						
							|  |  |  |  *  _________________________________________________________________________ | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  DESCRIPTION: Initialize the PCI Host Controller and register it with | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  |  *		 Linux so Linux can seize control of the PCI bus. | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  |  * | 
					
						
							|  |  |  |  ****************************************************************************/ | 
					
						
							|  |  |  | void __init msp_pci_init(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct msp_pci_regs *preg = (void *)PCI_BASE_REG; | 
					
						
							|  |  |  | 	u32 id; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Extract Device ID */ | 
					
						
							|  |  |  | 	id = read_reg32(PCI_JTAG_DEVID_REG, 0xFFFF) >> 12; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Check if JTAG ID identifies MSP7120 */ | 
					
						
							|  |  |  | 	if (!MSP_HAS_PCI(id)) { | 
					
						
							|  |  |  | 		printk(KERN_WARNING "PCI: No PCI; id reads as %x\n", id); | 
					
						
							|  |  |  | 		goto no_pci; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * Enable flushing of the PCI-SDRAM queue upon a read | 
					
						
							|  |  |  | 	 * of the SDRAM's Memory Configuration Register. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	*(unsigned long *)QFLUSH_REG_1 = 3; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Configure PCI Host Controller. */ | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  | 	preg->if_status = ~0;		/* Clear cause register bits */ | 
					
						
							| 
									
										
										
										
											2007-06-14 15:56:23 -06:00
										 |  |  | 	preg->config_addr = 0;		/* Clear config access */ | 
					
						
							|  |  |  | 	preg->oatran	= MSP_PCI_OATRAN; /* PCI outbound addr translation */ | 
					
						
							|  |  |  | 	preg->if_mask	= 0xF8BF87C0;	/* Enable all PCI status interrupts */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* configure so inb(), outb(), and family are functional */ | 
					
						
							|  |  |  | 	set_io_port_base(MSP_PCI_IOSPACE_BASE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Tell Linux the details of the MSP7120 PCI Host Controller */ | 
					
						
							|  |  |  | 	register_pci_controller(&msp_pci_controller); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | no_pci: | 
					
						
							|  |  |  | 	/* Disable PCI channel */ | 
					
						
							|  |  |  | 	printk(KERN_WARNING "PCI: no host PCI bus detected\n"); | 
					
						
							|  |  |  | } |