LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* RE: [PATCH/2.6.17-rc4 1/10] Powerpc: Add general support for mpc7 448h pc2 (Taiga) platform
From: Zang Roy-r61911 @ 2006-05-18  4:12 UTC (permalink / raw)
  To: Kumar Gala
  Cc: linuxppc-dev list, Yang Xin-Xin-r48390, Paul Mackerras,
	Alexandre.Bounine



On May 17, 2006, at 5:13 AM, Zang Roy-r61911 wrote:

> Add support for Freescale mpcc7448 (Taiga) board support
>
> Signed-off-by: Roy Zang  <tie-fei.zang@freescale.com>
>
> ---
>
>  arch/powerpc/Kconfig                       |   24 +++
>  arch/powerpc/kernel/legacy_serial.c        |   39 ++++

These board port should live in platforms/embedded6xx.

Kumar, what does you mean? 
All my board support code should be live in platforms/embedded6xx? 
How about the legacy serial support?

>  arch/powerpc/platforms/74xx/Makefile       |    4
>  arch/powerpc/platforms/74xx/misc.c         |   38 ++++
>  arch/powerpc/platforms/74xx/mpc7448_hpc2.c |  257 +++++++++++++++++ 
> +++++++++++
>  arch/powerpc/platforms/74xx/mpc7448_hpc2.h |   80 +++++++++
>  arch/powerpc/platforms/74xx/pci.c          |  103 +++++++++++
>  arch/powerpc/platforms/Makefile            |    1
>  8 files changed, 545 insertions(+), 1 deletions(-)
>  create mode 100644 arch/powerpc/platforms/74xx/Makefile
>  create mode 100644 arch/powerpc/platforms/74xx/misc.c
>  create mode 100644 arch/powerpc/platforms/74xx/mpc7448_hpc2.c
>  create mode 100644 arch/powerpc/platforms/74xx/mpc7448_hpc2.h
>  create mode 100644 arch/powerpc/platforms/74xx/pci.c
>
> 13c16416da4fa51ec771bd4863d94344d139b2f5
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index 6729c98..abeac1f 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -332,6 +332,27 @@ config APUS
>  	  Select APUS if configuring for a PowerUP Amiga.
>  	  More information is available at:
>  	  <http://linux-apus.sourceforge.net/>.
> +
> +config MPC7448HPC2
> +	bool "Freescale MPC7448HPC2(Taiga)"
> +	select DEFAULT_UIMAGE
> +	select PPC_UDBG_16550
> +	help
> +	  Select MPC7448HPC2 if configuring for Freescale MPC7448HPC2  
> (Taiga)
> +	  platform
> +
> +config 74xx
> +	bool
> +	depends on MPC7448HPC2
> +	default y
> +	help
> +	  Select 74xx support
> +

What is the config option used for?  We should get ride of.

> +config TSI108_BRIDGE
> +	bool
> +	depends on MPC7448HPC2
> +	default y
> +	
>  endchoice
>
>  config PPC_PSERIES
> @@ -798,7 +819,8 @@ config MCA
>  	bool
>
>  config PCI
> -	bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx ||  
> PPC_MPC52xx || (EMBEDDED && PPC_ISERIES)
> +	bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx ||  
> PPC_MPC52xx || (EMBEDDED && PPC_ISERIES) \
> +				  || MPC7448HPC2
>  	default y if !40x && !CPM2 && !8xx && !APUS && !PPC_83xx && ! 
> PPC_85xx
>  	default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS
>  	default PCI_QSPAN if !4xx && !CPM2 && 8xx
> diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/ 
> kernel/legacy_serial.c
> index 6e67b5b..f99238d 100644
> --- a/arch/powerpc/kernel/legacy_serial.c
> +++ b/arch/powerpc/kernel/legacy_serial.c
> @@ -134,6 +134,34 @@ static int __init add_legacy_soc_port(st
>  	return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags);
>  }
>
> +static int __init add_legacy_tsi_port(struct device_node *np,
> +				      struct device_node *tsi_dev)
> +{
> +	phys_addr_t addr;
> +	u32 *addrp;
> +	upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
> +
> +	/* We only support ports that have a clock frequency properly
> +	 * encoded in the device-tree.
> +	 */
> +	if (get_property(np, "clock-frequency", NULL) == NULL)
> +		return -1;
> +
> +	/* Get the address */
> +	addrp = of_get_address(tsi_dev, 0, NULL, NULL);
> +	if (addrp == NULL)
> +		return -1;
> +
> +	addr = of_translate_address(tsi_dev, addrp);
> +
> +	/* Add port, irq will be dealt with later. We passed a translated
> +	 * IO port value. It will be fixed up later along with the irq
> +	 */
> +	return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags);
> +}
> +

This looks like its duplicating add_legacy_soc_port, why not use that  
instead?

> +
> +
>  static int __init add_legacy_isa_port(struct device_node *np,
>  				      struct device_node *isa_brg)
>  {
> @@ -302,6 +330,17 @@ void __init find_legacy_serial_ports(voi
>  		of_node_put(isa);
>  	}
>
> +	/* First fill our array with tsi-bridge ports */
> +	for (np = NULL; (np = of_find_compatible_node(np, "serial",  
> "ns16550")) != NULL;) {
> +		struct device_node *tsi = of_get_parent(np);
> +		if (tsi && !strcmp(tsi->type, "tsi-bridge")) {
> +			index = add_legacy_tsi_port(np, np);
> +			if (index >= 0 && np == stdout)
> +				legacy_serial_console = index;
> +		}
> +		of_node_put(tsi);
> +	}
> +	
>  #ifdef CONFIG_PCI
>  	/* Next, try to locate PCI ports */
>  	for (np = NULL; (np = of_find_all_nodes(np));) {
> diff --git a/arch/powerpc/platforms/74xx/Makefile b/arch/powerpc/ 
> platforms/74xx/Makefile
> new file mode 100644
> index 0000000..ed5648c
> --- /dev/null
> +++ b/arch/powerpc/platforms/74xx/Makefile
> @@ -0,0 +1,4 @@
> +#
> +# Makefile for the PowerPC 74xx linux kernel.
> +#
> +obj-$(CONFIG_MPC7448HPC2)	+= mpc7448_hpc2.o pci.o misc.o
> diff --git a/arch/powerpc/platforms/74xx/misc.c b/arch/powerpc/ 
> platforms/74xx/misc.c
> new file mode 100644
> index 0000000..6228875
> --- /dev/null
> +++ b/arch/powerpc/platforms/74xx/misc.c
> @@ -0,0 +1,38 @@
> +
> +/*
> + * MPC74xx generic code.
> + *
> + * Maintained by Roy Zang
> + *
> + * Copyright 2006 Freescale Semiconductor Inc.
> + *
> + * 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
> + * Free Software Foundation;  either version 2 of the  License, or  
> (at your
> + * option) any later version.
> + */
> +#include <linux/irq.h>
> +#include <linux/module.h>
> +#include <asm/irq.h>
> +extern void _nmask_and_or_msr(unsigned long nmask, unsigned long  
> or_val);
> +
> +void mpc7448_hpc2_restart(char *cmd)
> +{
> +	local_irq_disable();
> +
> +	/* Set exception prefix high - to the firmware */
> +	_nmask_and_or_msr(0, MSR_IP);
> +
> +	for (;;) ;		/* Spin until reset happens */
> +}
> +
> +void mpc7448_hpc2_power_off(void)
> +{
> +	local_irq_disable();
> +	for (;;) ;		/* No way to shut power off with software */
> +}
> +
> +void mpc7448_hpc2_halt(void)
> +{
> +	mpc7448_hpc2_power_off();
> +}

Move these back into mpc7448_hpc2.c.  They are to specific to hpc2.

> diff --git a/arch/powerpc/platforms/74xx/mpc7448_hpc2.c b/arch/ 
> powerpc/platforms/74xx/mpc7448_hpc2.c
> new file mode 100644
> index 0000000..b060ae1
> --- /dev/null
> +++ b/arch/powerpc/platforms/74xx/mpc7448_hpc2.c
> @@ -0,0 +1,257 @@
> +/*
> + * mpc7448_hpc2.c
> + *
> + * Board setup routines for the Freescale Taiga platform
> + *
> + * Author: Jacob Pan
> + *	 jacob.pan@freescale.com
> + * Author: Xianghua Xiao
> + *       updated for taiga board from emulation platform 2005.5
> + *       x.xiao@freescale.com
> + * Maintainer: Roy Zang <tie-fei.zang@freescale.com>
> + *
> + * Copyright 2004-2006 Freescale Semiconductor, Inc.
> + *
> + * This file is licensed under
> + * the terms of the GNU General Public License version 2.  This  
> program
> + * is licensed "as is" without any warranty of any kind, whether  
> express
> + * or implied.
> + */
> +
> +#include <linux/config.h>
> +#include <linux/stddef.h>
> +#include <linux/kernel.h>
> +#include <linux/pci.h>
> +#include <linux/kdev_t.h>
> +#include <linux/console.h>
> +#include <linux/delay.h>
> +#include <linux/irq.h>
> +#include <linux/ide.h>
> +#include <linux/seq_file.h>
> +#include <linux/root_dev.h>
> +#include <linux/serial.h>
> +#include <linux/tty.h>
> +#include <linux/serial_core.h>
> +
> +#include <asm/system.h>
> +#include <asm/time.h>
> +#include <asm/machdep.h>
> +#include <asm/prom.h>
> +#include <asm/udbg.h>
> +#include <asm/tsi108.h>
> +#include <asm/pci-bridge.h>
> +#include <asm/reg.h>
> +#include <mm/mmu_decl.h>
> +#include "mpc7448_hpc2.h"
> +#include <asm/tsi108_pic.h>
> +
> +#ifndef CONFIG_PCI
> +isa_io_base = MPC7448_HPC2_ISA_IO_BASE;
> +isa_mem_base = MPC7448_HPC2_ISA_MEM_BASE;
> +pci_dram_offset = MPC7448_HPC2_PCI_MEM_OFFSET;
> +#endif
> +
> +extern int add_bridge(struct device_node *dev);
> +extern void mpc7448_hpc2_restart(char *cmd);
> +extern void mpc7448_hpc2_power_off(void);
> +extern void mpc7448_hpc2_halt(void);
> +
> +#ifdef TSI108_ETH
> +hw_info hw_info_table[TSI108_ETH_MAX_PORTS + 1] = {
> +	{TSI108_CSR_ADDR_PHYS + TSI108_ETH_OFFSET,
> +	 TSI108_CSR_ADDR_PHYS + TSI108_ETH_OFFSET,
> +	 TSI108_PHY0_ADDR, IRQ_TSI108_GIGE0},
> +
> +	{TSI108_CSR_ADDR_PHYS + TSI108_ETH_OFFSET + 0x400,
> +	 TSI108_CSR_ADDR_PHYS + TSI108_ETH_OFFSET,
> +	 TSI108_PHY1_ADDR, IRQ_TSI108_GIGE1},
> +
> +	{TBL_END, TBL_END, TBL_END, TBL_END}
> +};
> +#endif

This table looks problematic.  Look at using something like a  
platform device.

> +
> +/*
> + * Define all of the IRQ senses and polarities.  Taken from the
> + * mpc7448hpc  manual.
> + * Note:  Likely, this table and the following function should be
> + *        obtained and derived from the OF Device Tree.
> + */
> +
> +static u_char mpc7448_hpc2_pic_initsenses[] __initdata = {
> +	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* INT[0] XINT0 from  
> FPGA */
> +	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* INT[1] XINT1 from  
> FPGA */
> +	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* INT[2] PHY_INT from  
> both GIGE */
> +	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* INT[3] RESERVED */
> +};
> +
> +/*
> + * mpc7448hpc2 PCI interrupt routing. all PCI interrupt comes from
> + * external PCI source at 23. need to program pci interrupt  
> control registers
> + * to route per slot IRQs.
> + */
> +
> +static inline int
> +mpc7448_hpc2_map_irq(struct pci_dev *dev, unsigned char idsel,
> +		     unsigned char pin)
> +{
> +	static char pci_irq_table[][4] =
> +	    /*
> +	     *      PCI IDSEL/INTPIN->INTLINE
> +	     *         A     B     C     D
> +	     */
> +	{
> +		{IRQ_PCI_INTA, IRQ_PCI_INTB, IRQ_PCI_INTC, IRQ_PCI_INTD},	/* A  
> SLOT 1 IDSEL 17 */
> +		{IRQ_PCI_INTB, IRQ_PCI_INTC, IRQ_PCI_INTD, IRQ_PCI_INTA},	/* B  
> SLOT 2 IDSEL 18 */
> +		{IRQ_PCI_INTC, IRQ_PCI_INTD, IRQ_PCI_INTA, IRQ_PCI_INTB},	/* C  
> SATA IDSEL 19 */
> +		{IRQ_PCI_INTD, IRQ_PCI_INTA, IRQ_PCI_INTB, IRQ_PCI_INTC},	/* D  
> USB IDSEL 20 */
> +	};
> +
> +	const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4;
> +	return PCI_IRQ_TABLE_LOOKUP;
> +}
> +
> +int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn)
> +{
> +	if (bus == 0 && PCI_SLOT(devfn) == 0)
> +		return PCIBIOS_DEVICE_NOT_FOUND;
> +	else
> +		return PCIBIOS_SUCCESSFUL;
> +}
> +
> +static __inline__ void mpc7448_hpc2_l2cr_prefetch_enable(void)
> +{
> +	unsigned long msscr0;
> +	__asm__ __volatile__("mfspr %0, 0x3f6\n \
> +		ori %0,%0,0x3\n	         \
> +		sync \n                  \
> +		mtspr 0x3f6,%0\n   \
> +		sync\n			 \
> +		isync ":"=r"(msscr0));
> +}
> +
> +static void __init mpc7448_hpc2_setup_arch(void)
> +{
> +	struct device_node *cpu;
> +	struct device_node *np;
> +	if (ppc_md.progress)
> +		ppc_md.progress("mpc7448_hpc2_setup_arch():set_bridge", 0);
> +
> +	cpu = of_find_node_by_type(NULL, "cpu");
> +	if (cpu != 0) {
> +		unsigned int *fp;
> +
> +		fp = (int *)get_property(cpu, "clock-frequency", NULL);
> +		if (fp != 0)
> +			loops_per_jiffy = *fp / HZ;
> +		else
> +			loops_per_jiffy = 50000000 / HZ;
> +		of_node_put(cpu);
> +	}
> +
> +#ifdef	CONFIG_ROOT_NFS
> +	ROOT_DEV = Root_NFS;
> +#else
> +	ROOT_DEV = Root_HDA1;
> +#endif
> +
> +#ifdef CONFIG_BLK_DEV_INITRD
> +	ROOT_DEV = Root_RAM0;
> +#endif
> +
> +	/* setup PCI host bridge */
> +
> +#ifdef CONFIG_PCI
> +
> +	for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
> +		add_bridge(np);
> +
> +	ppc_md.pci_swizzle = common_swizzle;
> +	ppc_md.pci_map_irq = mpc7448_hpc2_map_irq;
> +	ppc_md.pci_exclude_device = mpc7448_hpc2_exclude_device;
> +	if (ppc_md.progress)
> +		ppc_md.progress("tsi108: resources set", 0x100);
> +#endif
> +
> +#ifdef CONFIG_DUMMY_CONSOLE
> +	conswitchp = &dummy_con;
> +#endif
> +
> +	printk(KERN_INFO "MPC7448HPC2 (TAIGA) Platform\n");
> +	printk(KERN_INFO
> +	       "Jointly ported by Freescale and Tundra Semiconductor\n");
> +	printk(KERN_INFO
> +	       "Enabling L2 cache then enabling the HID0 prefetch engine. 
> \n");
> +	_set_L2CR(L2CR_L2E);
> +	mpc7448_hpc2_l2cr_prefetch_enable();

Hmm, can't remember what happens with the L2 setup on 74xx.

> +}
> +
> +/*
> + * Interrupt setup and service.  Interrrupts on the mpc7448_hpc2 come
> + * from the four external INT pins, PCI interrupts are routed via
> + * PCI interrupt control registers, it generates internal IRQ23
> + *
> + * Interrupt routing on the Taiga Board:
> + * TSI108:PB_INT[0] -> CPU0:INT#
> + * TSI108:PB_INT[1] -> CPU0:MCP#
> + * TSI108:PB_INT[2] -> N/C
> + * TSI108:PB_INT[3] -> N/C
> + */
> +static void __init mpc7448_hpc2_init_IRQ(void)
> +{
> +
> +	tsi108_pic_init(mpc7448_hpc2_pic_initsenses);
> +
> +	/* Configure MPIC outputs to CPU0 */
> +	tsi108_pic_set_output(0, IRQ_SENSE_EDGE, IRQ_POLARITY_NEGATIVE);
> +}
> +
> +static void __init mpc7448_hpc2_map_io(void)
> +{
> +	/* PCI IO  mapping */
> +	io_block_mapping(MPC7448_HPC2_PCI_IO_BASE_VIRT,
> +			 MPC7448_HPC2_PCI_IO_BASE_PHYS, 0x00800000, _PAGE_IO);
> +	/* Tsi108 CSR mapping */
> +	io_block_mapping(TSI108_CSR_ADDR_VIRT, TSI108_CSR_ADDR_PHYS,
> +			 0x100000, _PAGE_IO);
> +
> +	/* PCI Config mapping */
> +	io_block_mapping(MPC7448_HPC2_PCI_CFG_BASE_VIRT,
> +			 MPC7448_HPC2_PCI_CFG_BASE_PHYS,
> +			 MPC7448_HPC2_PCI_CFG_SIZE, _PAGE_IO);
> +
> +	tsi108_pci_cfg_base = MPC7448_HPC2_PCI_CFG_BASE_VIRT;
> +	/* NVRAM mapping */
> +	io_block_mapping(MPC7448_HPC2_NVRAM_BASE_ADDR,
> +			 MPC7448_HPC2_NVRAM_BASE_ADDR, MPC7448_HPC2_NVRAM_SIZE,
> +			 _PAGE_IO);
> +}

You need to do this another way, we are trying to avoid using  
io_block_mapping()

> +
> +void mpc7448_hpc2_show_cpuinfo(struct seq_file *m)
> +{
> +	seq_printf(m, "vendor\t\t: Freescale Semiconductor\n");
> +	seq_printf(m, "machine\t\t: MPC7448hpc2\n");
> +}
> +
> +/*
> + * Called very early, device-tree isn't unflattened
> + */
> +static int __init mpc7448_hpc2_probe(void)
> +{
> +	/* We always match for now, eventually we should look at the flat
> +	   dev tree to ensure this is the board we are suppose to run on
> +	 */
> +	return 1;
> +}
> +
> +define_machine(mpc7448_hpc2){
> +	.name 			= "MPC7448 HPC2",
> +	.probe 			= mpc7448_hpc2_probe,
> +	.setup_arch 		= mpc7448_hpc2_setup_arch,
> +	.init_IRQ 		= mpc7448_hpc2_init_IRQ,
> +	.show_cpuinfo 		= mpc7448_hpc2_show_cpuinfo,
> +	.get_irq 		= tsi108_pic_get_irq,
> +	.restart 		= mpc7448_hpc2_restart,
> +	.calibrate_decr 	= generic_calibrate_decr,
> +	.setup_io_mappings 	= mpc7448_hpc2_map_io,
> +	.progress 		= udbg_progress,
> +};
> diff --git a/arch/powerpc/platforms/74xx/mpc7448_hpc2.h b/arch/ 
> powerpc/platforms/74xx/mpc7448_hpc2.h
> new file mode 100644
> index 0000000..8833520
> --- /dev/null
> +++ b/arch/powerpc/platforms/74xx/mpc7448_hpc2.h
> @@ -0,0 +1,80 @@
> +/*
> + * mpc7448_hpc2.h
> + *
> + * Definitions for Freescale MPC7448_HPC2 platform
> + *
> + * Author: Jacob Pan
> + *         jacob.pan@freescale.com
> + * Maintainer: Roy Zang <roy.zang@freescale.com>
> + *
> + * 2006 (c) Freescale Semiconductor, Inc.  This file is licensed  
> under
> + * the terms of the GNU General Public License version 2.  This  
> program
> + * is licensed "as is" without any warranty of any kind, whether  
> express
> + * or implied.
> + */
> +
> +#ifndef __PPC_PLATFORMS_MPC7448_HPC2_H
> +#define __PPC_PLATFORMS_MPC7448_HPC2_H
> +
> +#include <asm/ppcboot.h>
> +
> +/* Ethernet defines
> + */
> +#define TSI108_ETH
> +#define TSI108_ETH_MAX_PORTS	(2)	/* TSI108 Ethernet block has 2  
> ports */
> +#define TSI108_PHY0_ADDR	(8)	/* PHY address for GIGE port 0 */
> +#define TSI108_PHY1_ADDR	(9)	/* PHY address for GIGE port 1 */
> +
> +/* Base Addresses for the PCI bus
> + * HOST_PCI initiator (outbound) window to PCI bus
> + */
> +#define MPC7448_HPC2_PCI_MEM_OFFSET	(0x00000000)
> +#define MPC7448_HPC2_PCI_IO_BASE_PHYS	(0xfa000000)
> +#define MPC7448_HPC2_PCI_IO_BASE_VIRT	(MPC7448_HPC2_PCI_IO_BASE_PHYS)
> +#define MPC7448_HPC2_PCI_MEM_BASE	(0xe0000000)
> +#define MPC7448_HPC2_ISA_IO_BASE	(0x00000000)
> +#define MPC7448_HPC2_ISA_MEM_BASE	(0x00000000)
> +
> +#define MPC7448_HPC2_PCI_CFG_BASE_PHYS	(0xfb000000)
> +#define MPC7448_HPC2_PCI_CFG_BASE_VIRT	 
> (MPC7448_HPC2_PCI_CFG_BASE_PHYS)
> +#define MPC7448_HPC2_PCI_CFG_SIZE	(0x01000000)
> +
> +#define MPC7448_HPC2_PCI_MEM_START	(0xE0000000)
> +#define MPC7448_HPC2_PCI_MEM_END	(0xF9FFFFFF)
> +
> +#define MPC7448_HPC2_PCI_IO_START	(0xFA000000)
> +#define MPC7448_HPC2_PCI_IO_END	(0xFA00FFFF)
> +
> +#define MPC7448_HPC2_PCI_CFG_OFFSET	(0xFB000000)
> +#define MPC7448_HPC2_PCI_IO_OFFSET	(0xFA000000)
> +
> +#define MPC7448_HPC2_PCI_MEM32_OFFSET	0x00000000	/* PCI MEM32  
> space offset within
> +							   the PCI window */
> +#define MPC7448_HPC2_PCI_PFM_OFFSET	0x10000000	/* PCI PFM1 space  
> offset within
> +							   the PCI window */

Can you not determine these from your flat device tree?

> +
> +/* Memory-mapped CIU resources (CPU view)
> + * The memory map is set by initialization code in monitor
> + */
> +
> +#define TSI108_CSR_ADDR_PHYS	(0xC0000000)	/* Physical Tsi108 CSR  
> Base Address */
> +#define TSI108_CSR_ADDR_VIRT	(0xF0000000)	/* Virtual Tsi108 CSR  
> Base Address */

Don't use hard coded VIRT addresses.

> +
> +#define FLASH_BASE_ADDR		(0xFF000000)	/* Boot FLASH Base Address */
> +
> +#define SDRAM_BASE_ADDR		0x00000000	/* SDRAM base address */
> +#define BOARD_SDRAM_SIZE	0x20000000	/* Default value: 512MB */
> +
> +/* Size of SDRAM space reserved for user space. This limits space  
> available
> + * for dynamic allocation.
> + */
> +#define USER_RESERVED_MEM	(BOARD_SDRAM_SIZE - 0x02000000)
> +
> +#define USER_RESERVED_BASE  \
> +  (SDRAM_BASE_ADDR + (BOARD_SDRAM_SIZE - USER_RESERVED_MEM)
> +
> +/* Memory mapped NVRAM/RTC */
> +#define MPC7448_HPC2_NVRAM_BASE_ADDR	(0xFC000000)
> +#define MPC7448_HPC2_NVRAM_SIZE	(0x8000)
> +
> +#endif				/* __PPC_PLATFORMS_MPC7448_HPC2_H */
> diff --git a/arch/powerpc/platforms/74xx/pci.c b/arch/powerpc/ 
> platforms/74xx/pci.c
> new file mode 100644
> index 0000000..fd822ed
> --- /dev/null
> +++ b/arch/powerpc/platforms/74xx/pci.c

If this is generic to the tsi108 rename to something like  
tsi108_pci.c as its not generic to 74xx or embedded6xx.

> @@ -0,0 +1,103 @@
> +/*
> + * TSI 108 PCI hose setup up code
> + *
> + * Maintained by Roy Zang
> + *
> + * 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
> + * Free Software Foundation;  either version 2 of the  License, or  
> (at your
> + * option) any later version.
> + */
> +
> +#include <linux/config.h>
> +#include <linux/stddef.h>
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/errno.h>
> +#include <linux/pci.h>
> +#include <linux/delay.h>
> +#include <linux/irq.h>
> +#include <linux/module.h>
> +
> +#include <asm/system.h>
> +#include <asm/atomic.h>
> +#include <asm/io.h>
> +#include <asm/pci-bridge.h>
> +#include <asm/prom.h>
> +#include <asm/tsi108.h>
> +#include "mpc7448_hpc2.h"

What's this included needed for?

> +
> +#undef DEBUG
> +
> +#ifdef DEBUG
> +#define DBG(x...) printk(x)
> +#else
> +#define DBG(x...)
> +#endif
> +
> +extern int tsi108_direct_write_config(struct pci_bus *bus,  
> unsigned int devfn,
> +				      int offset, int len, u32 val);
> +extern int tsi108_direct_read_config(struct pci_bus *bus, unsigned  
> int devfn,
> +				     int offset, int len, u32 * val);
> +

Can you not use indirect pci support that already exists?

> +void tsi108_clear_pci_error(u32 pci_cfg_base);
> +
> +extern int
> +tsi108_read_config(int bus, unsigned int devfn, int offset, int  
> len, u32 * val);
> +#ifdef CONFIG_PCI
> +static struct pci_ops direct_pci_ops = {
> +	tsi108_direct_read_config,
> +	tsi108_direct_write_config
> +};
> +
> +void tsi108_clear_pci_cfg_error(void)
> +{
> +	tsi108_clear_pci_error(MPC7448_HPC2_PCI_CFG_BASE_PHYS);
> +}
> +
> +int __init add_bridge(struct device_node *dev)
> +{
> +	int len;
> +	struct pci_controller *hose;
> +	struct resource rsrc;
> +	int *bus_range;
> +	int primary = 0, has_address = 0;
> +
> +	DBG("TSI_PCI: %s tsi108_pci_cfg_base=0x%x\n", __FUNCTION__,
> +	    tsi108_pci_cfg_base);
> +
> +	/* Fetch host bridge registers address */
> +	has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
> +
> +	/* Get bus range if any */
> +	bus_range = (int *)get_property(dev, "bus-range", &len);
> +	if (bus_range == NULL || len < 2 * sizeof(int)) {
> +		printk(KERN_WARNING "Can't get bus-range for %s, assume"
> +		       " bus 0\n", dev->full_name);
> +	}
> +
> +	hose = pcibios_alloc_controller();
> +
> +	if (!hose) {
> +		printk("PCI Host bridge init failed\n");
> +		return -ENOMEM;
> +	}
> +	hose->arch_data = dev;
> +	hose->set_cfg_type = 1;
> +
> +	hose->first_busno = bus_range ? bus_range[0] : 0;
> +	hose->last_busno = bus_range ? bus_range[1] : 0xff;
> +
> +	(hose)->ops = &direct_pci_ops;
> +
> +	printk(KERN_INFO "Found tsi108 PCI host bridge at 0x%08lx. "
> +	       "Firmware bus number: %d->%d\n",
> +	       rsrc.start, hose->first_busno, hose->last_busno);
> +
> +	/* Interpret the "ranges" property */
> +	/* This also maps the I/O region and sets isa_io/mem_base */
> +	pci_process_bridge_OF_ranges(hose, dev, primary);
> +	return 0;
> +
> +}
> +#endif
> diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/ 
> platforms/Makefile
> index c4f6b0d..71ca0e0 100644
> --- a/arch/powerpc/platforms/Makefile
> +++ b/arch/powerpc/platforms/Makefile
> @@ -9,6 +9,7 @@ obj-$(CONFIG_PPC_CHRP)		+= chrp/
>  obj-$(CONFIG_4xx)		+= 4xx/
>  obj-$(CONFIG_PPC_83xx)		+= 83xx/
>  obj-$(CONFIG_PPC_85xx)		+= 85xx/
> +obj-$(CONFIG_74xx)		+= 74xx/
>  obj-$(CONFIG_PPC_PSERIES)	+= pseries/
>  obj-$(CONFIG_PPC_ISERIES)	+= iseries/
>  obj-$(CONFIG_PPC_MAPLE)		+= maple/
> -- 
> 1.3.0
>
>
>
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev

^ permalink raw reply

* RE: [PATCH/2.6.17-rc4 6/10]  Add  Tundra pci vendor and device ID
From: Zang Roy-r61911 @ 2006-05-18  4:50 UTC (permalink / raw)
  To: Kumar Gala
  Cc: linuxppc-dev list, Yang Xin-Xin-r48390, Paul Mackerras,
	Alexandre.Bounine


VENDOR_ID_TUNDRA and PCI_DEVICE_ID_TUNDRA_CA91C042 have been
in pciids list. 
we will summit PCI_DEVICE_ID_TUNDRA_TSI108 and
PCI_DEVICE_ID_TUNDRA_TSI109.
Dose the pci.ids file there will appear in the new kernel release?

Roy

On May 17, 2006, at 5:14 AM, Zang Roy-r61911 wrote:

> Add Tundra Semiconductor pci host bridge vendor ID and device ID
>
> Signed-off-by: Alexandre Bounine <alexandreb@tundra.com>
> Signed-off-by: Roy Zang	<tie-fei.zang@freescale.com>

Did you guys submit http://pciids.sourceforge.net/ ?

- k

> ---
>
>  include/linux/pci_ids.h |    4 ++++
>  1 files changed, 4 insertions(+), 0 deletions(-)
>
> 14bddf6670ca982d5cee57afa472d2199e2170fc
> diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
> index d6fe048..c39fcfc 100644
> --- a/include/linux/pci_ids.h
> +++ b/include/linux/pci_ids.h
> @@ -2276,3 +2276,7 @@ #define PCI_DEVICE_ID_RME_DIGI32	0x9896
>  #define PCI_DEVICE_ID_RME_DIGI32_PRO	0x9897
>  #define PCI_DEVICE_ID_RME_DIGI32_8	0x9898
>
> +#define PCI_VENDOR_ID_TUNDRA		0x10e3
> +#define PCI_DEVICE_ID_TUNDRA_CA91C042	0x0000
> +#define PCI_DEVICE_ID_TUNDRA_TSI108	0x0108
> +#define PCI_DEVICE_ID_TUNDRA_TSI109	0xA108
> -- 
> 1.3.0
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev

^ permalink raw reply

* Re: [HACK] add sandpoint + flattened dt support to arch/powerpc/boot
From: Benjamin Herrenschmidt @ 2006-05-18  5:32 UTC (permalink / raw)
  To: Mark A. Greer; +Cc: linuxppc-dev
In-Reply-To: <20060518002142.GA23182@mag.az.mvista.com>

On Wed, 2006-05-17 at 17:21 -0700, Mark A. Greer wrote:
> Hi,
> 
> This is a patch with some very rough code that adds support for the
> sandpoint to arch/powerpc.  I'm posting it now in the hope that it
> will spark a deeper discussion on exactly how we're going to support
> flattened device tree code in the bootwrapper for non-OF platforms.
> I'm also hoping that it will help others that are working on the same
> sort of thing so we can help each other.
> 
> Again, the code is rough with lots of hacks but it boots and is
> something we can point to during this discussion.
> 
> So...I am on the right path?

Well, we'll see, let's have a look :)

> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index 6729c98..de09eac 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -323,7 +323,10 @@ config PPC_ISERIES
>  
>  config EMBEDDED6xx
>  	bool "Embedded 6xx/7xx/7xxx-based board"
> -	depends on PPC32 && BROKEN
> +	depends on PPC32
> +	select PPC_UDBG_16550
> +	select MPIC
> +	select MPIC_SERIAL

Not totally related to your patch but I'm tempted to turn that into a
"Generic 6xx/7xx/7xxx" rather than "embedded" if we manage to always
avoid board specific code most of the time, but instead add necessary
bits in the device-tree. We still need a per-board Kconfig option I
think that will just select the necessary bits and pieces (and more than
one can be selected at one time). Also, I think right now, the embedded
stuff is +/- exclusive from the MULTIPLATFORM stuff, that must be fixed
asap. We are all living in the same kernel now :)
 
> +
> +config MPIC_SERIAL
> +	depends on EMBEDDED6xx
> +	bool
> +	default n

Not sure what the above is, I'll have a look further in the patch but I
can already tell you that it should be your per-board
CONFIG_PPC_SANDPOINT for example that "selects" the various bits you
need, and thus the above should depend on it, not EMBEDDED6xx... In fact
I'm wondering wether we should kill EMBEDDED6xx :) Unless it's purely a
reference to arch/powerpc/platforms/embedded6xx/ as a storage place for
board setup_xxx.c files which is useful for platforms that really don't
need more than one or 2 files in there.
 
> +ifeq ($(CONFIG_EMBEDDED6xx),y)
> +src-boot += prom_embedded.c ns16550.c dts/sandpoint.S \
> +	dt_utils.c sandpoint.c mpc10x.c
> +else
> +src-boot += prom.c
> +endif

Again, I think CONFIG_EMBEDDED6xx is the wrong approach. I'd like to
avoid the word "embedded" altogether anyway :) Thing is, it would be
good if ultimately, embedded boards firmware was capable of passing a
device-tree. Thus, embedded a device-tree in the zImage wrapper is more
like a "fallback" solution which has the side effect of creating machine
specific zImage's.

That is why, I think, what we should do is have rules for building
separate zImage wrappers. The basic OF one (which exists in both real
and virtual mode versions and that I'd like to make capable of also
working if a flat device-tree is passed in), the zImage.sandpoint, the
zImage.prep, and whatever...

Thus enabling CONFIG_PPC_MYBOARD should trigger the build of the
board-flavored version of the wrapper in addition to all the other ones
for the other boards built as part of a given config.

I know it's a bit difficult because the current boot Kbuild rules aren't
really design for multiple targets but I think that's the way to go.
 
 .../...

About the .dts file, we should look into "shipping" a pre-built one so
that dtc is not required for building a kernel. I think we already have
a mecanism for providing "shipped" versions of files and having the
option of rebuilding them from source (though I don't have the details
in mind at the moment) 

> diff --git a/arch/powerpc/boot/io.h b/arch/powerpc/boot/io.h

 .../.. io stuffs ...

Well... io accessors in here can't harm, the question is more how they
are used ;)

> +#define	PCI_DEVFN(slot,func)	((((slot) & 0x1f) << 3) | ((func) & 0x07))
> +
> +/* Indirect PCI config space access routines */
> +static inline void
> +pci_indirect_read_config_byte(u32 *cfg_addr, u32 *cfg_data, int devfn,
> +		int offset, u8 *val)
> +{
> +	out_be32(cfg_addr,
> +		((offset & 0xfc) << 24) | (devfn << 16) | (0 << 8) | 0x80);
> +	*val = in_8((u8 *)(cfg_data + (offset & 3)));
> +	return;
> +}
> +
> +static inline void
> +pci_indirect_read_config_dword(u32 *cfg_addr, u32 *cfg_data, int devfn,
> +		int offset, u32 *val)
> +{
> +	out_be32(cfg_addr,
> +		((offset & 0xfc) << 24) | (devfn << 16) | (0 << 8) | 0x80);
> +	*val = in_le32(cfg_data + (offset & 3));
> +	return;
> +}

That's more annoying... if we start having PCI config space access in
the boot wrapper how far will it stop ? I'd rather keep that sort of
stuff local to myboard.c file unless it's really worth sharing... Unless
we end up with really common need for them in which case those should be
in separate files, possibly in a separate dir (thinking about it, prep
will probably need that too)

The main problem is how do we do printf kind of things from such a
bootloader. That needs IO, thus uart drivers etc... possibly parsing
from the device-tree etc... I'm tempted to just have a global
"boot_puts" function pointer set by the board and/or OF code to use
through the bootloader, maybe a shared uart.c file with various uart
bits and keep the gory implementation details of mapping the uart and
using those uart bits in the myboard.c file...
 
> +#ifdef CONFIG_PPC_OF
>  typedef void (*kernel_entry_t)( unsigned long,
>                                  unsigned long,
>                                  void *,
>  				void *);
> +#else
> +void platform_fixups(void *dt_blob);
> +extern void *dt_blob_start;
> +extern void *dt_blob_end;
> +void edit_cmdline(void *dt_blob_start);
> +typedef void (*kernel_entry_t)(void *dtb_addr, void *kernel_entry_paddr,
> +		void *must_be_null);
> +#endif

Why 2 different prototypes for kernel_entry ?

I think we need something like CONFIG_PPC_BOOT_HAS_BUILTIN_DT that
enables various DT related stuff in a clean way and have a builtin_dt.h
file with related prototypes & definitions.
 
>  #undef DEBUG
> @@ -218,7 +227,7 @@ void start(unsigned long a1, unsigned lo
>  	if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4)
>  		exit();
>  
> -	printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", _start, sp);
> +	printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", _start,sp);

Gratuituous uglyfication :)

>  	/*
>  	 * The first available claim_base must be above the end of the
> @@ -238,7 +247,7 @@ void start(unsigned long a1, unsigned lo
>  		gunzip(elfheader, sizeof(elfheader),
>  				(unsigned char *)vmlinuz.addr, &len);
>  	} else
> -		memcpy(elfheader, (const void *)vmlinuz.addr, sizeof(elfheader));
> +		memcpy(elfheader, (const void *)vmlinuz.addr,sizeof(elfheader));

Gratuituous uglyfication (bis) :)
 
>  	if (!is_elf64(elfheader) && !is_elf32(elfheader)) {
>  		printf("Error: not a valid PPC32 or PPC64 ELF file!\n\r");
> @@ -263,18 +272,21 @@ void start(unsigned long a1, unsigned lo
>  	initrd.size = (unsigned long)(_initrd_end - _initrd_start);
>  	initrd.memsize = initrd.size;
>  	if ( initrd.size > 0 ) {
> -		printf("Allocating 0x%lx bytes for initrd ...\n\r", initrd.size);
> +		printf("Allocating 0x%lx bytes for initrd ...\n\r",initrd.size);

Gratuituous uglyfication (ter) :)

>  		initrd.addr = try_claim(initrd.size);
>  		if (initrd.addr == 0) {
> -			printf("Can't allocate memory for initial ramdisk !\n\r");
> +			printf("Can't allocate memory for initial "
> +					"ramdisk !\n\r");
>  			exit();
>  		}
>  		a1 = initrd.addr;
>  		a2 = initrd.size;
> -		printf("initial ramdisk moving 0x%lx <- 0x%lx (0x%lx bytes)\n\r",
> -		       initrd.addr, (unsigned long)_initrd_start, initrd.size);
> -		memmove((void *)initrd.addr, (void *)_initrd_start, initrd.size);
> -		printf("initrd head: 0x%lx\n\r", *((unsigned long *)initrd.addr));
> +		printf("initial ramdisk moving 0x%lx <- 0x%lx "
> +			"(0x%lx bytes)\n\r", initrd.addr,
> +			(unsigned long)_initrd_start, initrd.size);
> +		memmove((void *)initrd.addr, (void *)_initrd_start,initrd.size);
> +		printf("initrd head: 0x%lx\n\r",
> +				*((unsigned long *)initrd.addr));
>  	}
>  
>  	/* Eventually gunzip the kernel */
> @@ -299,6 +311,7 @@ #endif
>  	flush_cache((void *)vmlinux.addr, vmlinux.size);
>  
>  	kernel_entry = (kernel_entry_t)vmlinux.addr;
> +#ifdef CONFIG_PPC_OF
>  #ifdef DEBUG
>  	printf( "kernel:\n\r"
>  		"        entry addr = 0x%lx\n\r"
> @@ -311,9 +324,20 @@ #ifdef DEBUG
>  #endif

>  	kernel_entry(a1, a2, prom, NULL);
> +#else /* !CONFIG_PPC_OF ==> flattened device tree */
> +#ifdef DEBUG
> +	printf("kernel:\n\r"
> +		"        entry addr   = 0x%lx\n\r"
> +		"        flattened dt = 0x%lx\n\r",
> +		(unsigned long)kernel_entry, &dt_blob_start);
> +#endif
> +	edit_cmdline(&dt_blob_start);
> +	platform_fixups(&dt_blob_start);
>  
> +	kernel_entry(&dt_blob_start, (void *)vmlinux.addr, NULL);
> +#endif

Let's avoid #ifdef's if we can... provide function pointers where it
matter setup by the board/OF init code maybe but not ifdef's. Afaik,
only WD actually _likes_ ifdef's :)

> +++ b/arch/powerpc/boot/mpc10x.c

We'll need some subdirs here or it will get messy quick...

> diff --git a/arch/powerpc/boot/ns16550.c b/arch/powerpc/boot/ns16550.c

Same comment as above

> +/* XXXX Get info from dt instead */
> +static struct {
> +	int baud_base;
> +	unsigned long com_port;
> +	u16 iomem_reg_shift;
> +} rs_table[RS_TABLE_SIZE] = {
> +        { BASE_BAUD, SANDPOINT_SERIAL_0, 0 },
> +        { BASE_BAUD, SANDPOINT_SERIAL_1, 0 },
> +};

Well, your own comment says it all :) I think we might need an
equivalent of prom_parse.c in the bootloader
+
> +/* #ifndef CONFIG_PPC_OF XXXX */
> +
> +/* Definitions used by the flattened device tree */
> +#define OF_DT_HEADER		0xd00dfeed	/* marker */
> +#define OF_DT_BEGIN_NODE	0x1		/* Start of node, full name */
> +#define OF_DT_END_NODE		0x2		/* End node */
> +#define OF_DT_PROP		0x3		/* Property: name off, size,
> +						 * content */
> +#define OF_DT_NOP		0x4		/* nop */
> +#define OF_DT_END		0x9
> +
> +#define OF_DT_VERSION		0x10

   .../... (flat DT definitions)

Can't we share the kernel definition here ? Maybe split the kenrel one
in two if necessary ? I don't like that sort of duplication...

> +unsigned long serial_init(int chan, void *ignored);
> +void serial_putc(unsigned long com_port, unsigned char c);
> +unsigned char serial_getc(unsigned long com_port);
> +int serial_tstc(unsigned long com_port);

Forgot to mention that earlier, but those should be uart_* imho (or even
16550_*) since we'll surely have different species of serial ports to
deal with and I don't like name mixup. Unless we consider that only ever
one of those serial files get built in a given zImage wrapper in which
case it makes some sense...

> +call_prom(const char *service, int nargs, int nret, ...)
> +{
> +
> +	static struct {
> +		char	*service;
> +		int	((*rtn)(int nargs, int nret, va_list args));
> +	} services[] = {
> +		{ "exit", service_exit },
> +		{ "finddevice", service_finddevice },
> +		{ "getprop", service_getprop },
> +		/* { "write", service_write }, */
> +	};
> +	va_list args;
> +	int i, rc = 0;
> +
> +	for (i=0; i<ARRAY_SIZE(services); i++)
> +		if (!strcmp(service, services[i].service)) {
> +			va_start(args, nret);
> +			rc = services[i].rtn(nargs, nret, args);
> +			va_end(args);
> +		}
> +
> +	return (nret > 0)? rc : 0;
> +}

I don't think call_prom is the right abstraction :) We have to decide
here, we have two choices:

 - Either a given zImage wrapper can be booted from both a real OF and
have an embedded flat DT, in which case we need function pointers and I
think the right abstraction is for individual prom functions to have
their function pointer rathaer than "multiplex" through call_prom

 - Or a given zImage wrapper is a single board thingy. That is it is
either the OF wrapper _or_ it can contain an embedded DT. Probably
easier that way and no need for funciton pointers nor mux at all... I
tend to think that might be the right way to go at this point...
Especially since as I wrote before, I'm tempted to think we should just
in that case build multiple zImage wrappers. The only thing there is
that if we go that route, I'd like the "OF" one to also be able to boot
with a flat DT passed on entry to it so it will be useable as a generic
zImage for firmwares that have a flat DT to pass to the kernel. The only
"issue" with that is it might be difficult to have console output unless
we do the putc function pointer thing I described earlier and have
several "uart" impleentations with differnet names and enough
device-tree parsing to be able to instanciate them (almost a copy of
kernel's legacy serial stuff). Another option if we want console output
is to add something to the DT header specifically for use by such early
boot code that specifies a function that can be called back for
displaying thing as long as a given memory range isn't overriden (the FW
itself)

Comments are welcome here, this is I think the most tricky point and
where we need to make a decision...

> diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
> index 6e67b5b..2feca55 100644
> --- a/arch/powerpc/kernel/legacy_serial.c
> +++ b/arch/powerpc/kernel/legacy_serial.c
> @@ -147,9 +147,11 @@ static int __init add_legacy_isa_port(st
>  	if (reg == NULL)
>  		return -1;
>  
> +#if 0 /* XXXX */
>  	/* Verify it's an IO port, we don't support anything else */
>  	if (!(reg[0] & 0x00000001))
>  		return -1;
> +#endif

Gack ? Care to explain ?

> +obj-$(CONFIG_EMBEDDED6xx)	+= embedded6xx/

Hrmph.... (random noises)


> +/*
> + * Define all of the IRQ senses and polarities.  Taken from the
> + * Sandpoint X3 User's manual.
> + */
> +static u_char sandpoint_openpic_initsenses[] __initdata = {
> +	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 0: SIOINT */
> +	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 1: XXXX FILL?? */
> +	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 2: PCI Slot 1 */
> +	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 3: PCI Slot 2 */
> +	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 4: PCI Slot 3 */
> +	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 5: PCI Slot 4 */
> +	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 6: XXXX FILL?? */
> +	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 7: XXXX FILL?? */
> +	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 8: IDE (INT C) */
> +	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 9: IDE (INT D) */
> +	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 10: */
> +	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 11: */
> +	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 12: */
> +	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 13: */
> +	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 14: */
> +	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 15: */
> +};

Of course you already know that this has to go into the device-tree :)

> +/*
> + * Interrupt setup and service.  Interrrupts on the Sandpoint come
> + * from the four PCI slots plus the 8259 in the Winbond Super I/O (SIO).
> + * The 8259 is cascaded from EPIC IRQ0, IRQ1-4 map to PCI slots 1-4,
> + * IDE is on EPIC 7 and 8.
> + */
> +static void __init
> +sandpoint_init_IRQ(void)
> +{
> +	struct mpic *mpic;
> +	phys_addr_t openpic_paddr = 0xfc000000 + /* XXXX */
> +		MPC10X_EUMB_EPIC_OFFSET;
> +
> +	/* This doesn't handle i2c, dma, i2o, or timer intrs right now XXXX */
> +	mpic = mpic_alloc(openpic_paddr, MPIC_PRIMARY,
> +			16 /* XXXX otherwise num_sources used */ ,
> +			NUM_8259_INTERRUPTS,
> +			0, /* was 16 */
> +			NR_IRQS - 4 /* XXXX */,
> +			sandpoint_openpic_initsenses,
> +			sizeof(sandpoint_openpic_initsenses), " EPIC     ");
> +
> +	BUG_ON(mpic == NULL); /* XXXX */
> +	mpic_assign_isu(mpic,  0, openpic_paddr + 0x10200);
> +	mpic_init(mpic);
> +	mpic_setup_cascade(NUM_8259_INTERRUPTS, i8259_irq_cascade, NULL);
> +	i8259_init(0xfef00000, 0); /* pci iack addr */
> +}

It would be really nice if we could define properties to put in the
"mpic" node that defines the various attributes to pass to it and that
sort of thing so that we can have a generic "mpic_init_IRQ" that walks
all MPICs and instanciate & link them in cascade when necessary... Oh
well, food for thought, no high priority there.

> +/*
> + * Freescale Sandpoint interrupt routing.
> + */
> +static inline int
> +x3_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
> +{
> +	static char pci_irq_table[][4] =
> +	/*
> +	 *	PCI IDSEL/INTPIN->INTLINE
> +	 * 	   A   B   C   D
> +	 */
> +	{
> +		{ 16,  0,  0,  0 },	/* IDSEL 11 - i8259 on Winbond */
> +		{  0,  0,  0,  0 },	/* IDSEL 12 - unused */
> +		{ 18, 21, 20, 19 },	/* IDSEL 13 - PCI slot 1 */
> +		{ 19, 18, 21, 20 },	/* IDSEL 14 - PCI slot 2 */
> +		{ 20, 19, 18, 21 },	/* IDSEL 15 - PCI slot 3 */
> +		{ 21, 20, 19, 18 },	/* IDSEL 16 - PCI slot 4 */
> +	};
> +
> +	const long min_idsel = 11, max_idsel = 16, irqs_per_slot = 4;
> +	return PCI_IRQ_TABLE_LOOKUP;
> +}

Of course you also know that the above has to go into the device-tree as
well :)

> +static void __init
> +sandpoint_setup_winbond_83553(struct pci_controller *hose)
> +{
> +	int		devfn;
> +
> +	/*
> +	 * Route IDE interrupts directly to the 8259's IRQ 14 & 15.
> +	 * We can't route the IDE interrupt to PCI INTC# or INTD# because those
> +	 * woule interfere with the PMC's INTC# and INTD# lines.
> +	 */
> +	/*
> +	 * Winbond Fcn 0
> +	 */
> +	devfn = PCI_DEVFN(11,0);
> +
> +	early_write_config_byte(hose,
> +				0,
> +				devfn,
> +				0x43, /* IDE Interrupt Routing Control */
> +				0xef);
> +	early_write_config_word(hose,
> +				0,
> +				devfn,
> +				0x44, /* PCI Interrupt Routing Control */
> +				0x0000);
> +
> +	/* Want ISA memory cycles to be forwarded to PCI bus */
> +	early_write_config_byte(hose,
> +				0,
> +				devfn,
> +				0x48, /* ISA-to-PCI Addr Decoder Control */
> +				0xf0);
> +
> +	/* Enable Port 92.  */
> +	early_write_config_byte(hose,
> +				0,
> +				devfn,
> +				0x4e,	/* AT System Control Register */
> +				0x06);
> +	/*
> +	 * Winbond Fcn 1
> +	 */
> +	devfn = PCI_DEVFN(11,1);
> +
> +	/* Put IDE controller into native mode. */
> +	early_write_config_byte(hose,
> +				0,
> +				devfn,
> +				0x09,	/* Programming interface Register */
> +				0x8f);
> +
> +	/* Init IRQ routing, enable both ports, disable fast 16 */
> +	early_write_config_dword(hose,
> +				0,
> +				devfn,
> +				0x40,	/* IDE Control/Status Register */
> +				0x00ff0011);
> +	return;
> +}

How much of the above could/should be done by the wrapper since it does
config space access hacks ? My idea is that we might be able to remove
pretty much _everything_ from this sandpoint.c file ... My dream would
be to have a generic board support that matches a list of known boards
for which no special code is needed, only the device-tree (and possibly
the zImage wrapper).

The main things preventing us from doing that at the moment is that we
need to define enough standard nodes/properties to have the ability to
the setup interrupt controller tree entirely from it, and the PCI host
bridges as well. For the later, that means encoding enough of the bridge
type and config access method to allow having a generic device-tree
based piece of code that does what add_bridges() does in a generic way. 

> +static int
> +x3_exclude_device(u_char bus, u_char devfn)
> +{
> +	if ((bus == 0) && (PCI_SLOT(devfn) == 0))
> +		return PCIBIOS_DEVICE_NOT_FOUND;
> +	else
> +		return PCIBIOS_SUCCESSFUL;
> +}

If we need to exclude devices in a generic way, we could define a
specific exclude list property... or use what I think has already been
defined by OF for indicating which slots should be probed :)
 
> +static int __init
> +add_bridge(struct device_node *dev)
> +{
> +	int len;
> +	struct pci_controller *hose;
> +	int *bus_range;
> +
> +	printk("Adding PCI host bridge %s\n", dev->full_name);
> +
> +	bus_range = (int *) get_property(dev, "bus-range", &len);
> +	if (bus_range == NULL || len < 2 * sizeof(int))
> +		printk(KERN_WARNING "Can't get bus-range for %s, assume"
> +				" bus 0\n", dev->full_name);
> +
> +	hose = pcibios_alloc_controller();
> +	if (hose == NULL)
> +		return -ENOMEM;
> +	hose->first_busno = bus_range ? bus_range[0] : 0;
> +	hose->last_busno = bus_range ? bus_range[1] : 0xff;
> +	setup_indirect_pci(hose, 0xfec00000, 0xfee00000);
> +
> +	/* Interpret the "ranges" property */
> +	/* This also maps the I/O region and sets isa_io/mem_base */
> +	pci_process_bridge_OF_ranges(hose, dev, 1);
> +
> +	return 0;
> +}

See above comments.... Looks ok but how many boards will end up having
very small variations of that same code and thus can we find a way to
make that totally generic...
 
> +u32 mag_dbg = 0;
> +
> +static void __init
> +sandpoint_setup_arch(void)
> +{
> +	loops_per_jiffy = 100000000 / HZ;
> +	isa_io_base = 0xfe000000;
> +	isa_mem_base = 0x80000000;
> +	pci_dram_offset = 0;

The isa stuff should probably be deduced from the device-tree, the
default LPJ too, probably not even useful anymore since we are using the
timebase nowadays.

> +#ifdef CONFIG_BLK_DEV_INITRD
> +	if (initrd_start)
> +		ROOT_DEV = Root_RAM0;
> +	else
> +#endif
> +#ifdef	CONFIG_ROOT_NFS
> +		ROOT_DEV = Root_NFS;
> +#else
> +		ROOT_DEV = Root_HDA1;
> +#endif

Same comment as above, this is fairly generic and we could even imagine
something like a linux,default-boot-device thing in the DT...

> +#if 1 /* XXXX NEW */
> +	{
> +		struct device_node *np;
> +
> +		mag_dbg = 1;
> +		for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
> +			add_bridge(np);
> +		mag_dbg = 0;
> +
> +		ppc_md.pci_swizzle = common_swizzle;
> +		ppc_md.pci_map_irq = x3_map_irq;
> +		ppc_md.pci_exclude_device = x3_exclude_device; /* XXXX */
> +	}
> +#endif

The problem of IRQ mapping & swizzling will be solved real soon
(hopefully early 2.6.18) so that we can completely rely on the
device-tree without needing device_node's for every PCI device. Only P2P
bridges that don't do standard swizzling (typically bridges soldered on
the motherboard) will require device nodes. I'm working on it :)

The idea is that the host bridge will need the standard interrupt-map &
interrupt-map-mask which will indicate the interrupt mapping for every
line of every slot/device in the standard way handled by OF (that
already works). And I'll add code that will be able to handle PCI
devices without a node by artificially building their "interrupts"
property based on the interrupt pin config space entry and walking up
the PCI tree, doing standard swizzling when encountering a P2P bridge
until we hit something with a device-node in which case we hook our
result to the interrupt-map of that device-node.
 
> +	if (cpu_has_feature(CPU_FTR_SPEC7450))
> +		/* 745x is different.  We only want to pass along enable. */
> +		_set_L2CR(L2CR_L2E);
> +	else if (cpu_has_feature(CPU_FTR_L2CR))
> +		/* All modules have 1MB of L2.  We also assume that an
> +		 * L2 divisor of 3 will work.
> +		 */
> +		_set_L2CR(L2CR_L2E | L2CR_L2SIZ_1MB | L2CR_L2CLK_DIV3
> +				| L2CR_L2RAM_PIPE | L2CR_L2OH_1_0 | L2CR_L2DF);

Keeping in mind my idea of having as much generic code as possible,
whould we do the above in the boot wrapper or if not, should we provide
some DT entries indicating that L2CR should be reset and to which
values ?

> +#if 0
> +	/* Untested right now. */
> +	if (cpu_has_feature(CPU_FTR_L3CR)) {
> +		/* Magic value. */
> +		_set_L3CR(0x8f032000);
> +	}
> +#endif
> +}

Same comment as above but for L3CR

 .../...

> +/*
> + * Fix IDE interrupts.
> + */
> +static int __init
> +sandpoint_fix_winbond_83553(void)
> +{
> +	/* Make some 8259 interrupt level sensitive */
> +	outb(0xe0, 0x4d0);
> +	outb(0xde, 0x4d1);
> +
> +	return 0;
> +}
> +
> +arch_initcall(sandpoint_fix_winbond_83553);
> +
> +/*
> + * Initialize the ISA devices on the Nat'l PC87308VUL SuperIO chip.
> + */
> +static int __init
> +sandpoint_setup_natl_87308(void)
> +{
> +	u_char	reg;
> +
> +	/*
> +	 * Enable all the devices on the Super I/O chip.
> +	 */
> +	SANDPOINT_87308_SELECT_DEV(0x00); /* Select kbd logical device */
> +	SANDPOINT_87308_CFG_OUTB(0xf0, 0x00); /* Set KBC clock to 8 Mhz */
> +	SANDPOINT_87308_DEV_ENABLE(0x00); /* Enable keyboard */
> +	SANDPOINT_87308_DEV_ENABLE(0x01); /* Enable mouse */
> +	SANDPOINT_87308_DEV_ENABLE(0x02); /* Enable rtc */
> +	SANDPOINT_87308_DEV_ENABLE(0x03); /* Enable fdc (floppy) */
> +	SANDPOINT_87308_DEV_ENABLE(0x04); /* Enable parallel */
> +	SANDPOINT_87308_DEV_ENABLE(0x05); /* Enable UART 2 */
> +	SANDPOINT_87308_CFG_OUTB(0xf0, 0x82); /* Enable bank select regs */
> +	SANDPOINT_87308_DEV_ENABLE(0x06); /* Enable UART 1 */
> +	SANDPOINT_87308_CFG_OUTB(0xf0, 0x82); /* Enable bank select regs */
> +
> +	/* Set up floppy in PS/2 mode */
> +	outb(0x09, SIO_CONFIG_RA);
> +	reg = inb(SIO_CONFIG_RD);
> +	reg = (reg & 0x3F) | 0x40;
> +	outb(reg, SIO_CONFIG_RD);
> +	outb(reg, SIO_CONFIG_RD);	/* Have to write twice to change! */
> +
> +	return 0;
> +}

Looks like zImage wrapper work to me... Unless we ever get booted by a
firmware that both provides a flat DT and doesn't do the above....

Ok, I'm not _ABSOLUTELY_ trying to remove the need for a myboar.c file
here ... but it might be worth doing something generic enough so that
it's either reduced to the strict minimum in many cases _or_ made
completely unnecessary if we can...
 
> +arch_initcall(sandpoint_setup_natl_87308);
> +
> +static int __init
> +sandpoint_request_io(void)
> +{
> +	request_region(0x00,0x20,"dma1");
> +	request_region(0x20,0x20,"pic1");
> +	request_region(0x40,0x20,"timer");
> +	request_region(0x80,0x10,"dma page reg");
> +	request_region(0xa0,0x20,"pic2");
> +	request_region(0xc0,0x20,"dma2");
> +
> +	return 0;
> +}

The above has to go... not sure yet what is the best way but it's just a
pain... Could be made dependent on the OFDT too

> +arch_initcall(sandpoint_request_io);
> +#endif
> +
> +static void __init
> +sandpoint_map_io(void)
> +{
> +	io_block_mapping(0xfe000000, 0xfe000000, 0x02000000, _PAGE_IO);
> +}

To kill absolutely. What is it there for ? At the very least, make
io_block_mapping allocate virtual space as discussed earlier. I'd like
to keep BATs for RAM anyway

> +static void
> +sandpoint_restart(char *cmd)
> +{
> +	local_irq_disable();
> +
> +	/* Set exception prefix high - to the firmware */
> +	_nmask_and_or_msr(0, MSR_IP);
> +
> +	/* Reset system via Port 92 */
> +	outb(0x00, 0x92);
> +	outb(0x01, 0x92);
> +
> +	for(;;);	/* Spin until reset happens */
> +}

The above is fairly common. (Or variations of it). In the context of a
"generic" board, we could imagine having a list of known "reboot
methods" and have a DT node indicating which one to use...

> +static void
> +sandpoint_power_off(void)
> +{
> +	local_irq_disable();
> +	for(;;);	/* No way to shut power off with software */
> +	/* NOTREACHED */
> +}

The above is _VERY_ commmon :) probably worth just not having a callback
in ppc_md. at all...

> +static void
> +sandpoint_halt(void)
> +{
> +	sandpoint_power_off();
> +	/* NOTREACHED */
> +}

Same comment as before.

> +static void
> +sandpoint_show_cpuinfo(struct seq_file *m)
> +{
> +	seq_printf(m, "vendor\t\t: Freescale\n");
> +	seq_printf(m, "machine\t\t: Sandpoint\n");
> +}

Do we need that ? We could define standard DT properties that get
printed in cpuinfo and have that in setup-common.c ...

 .../... (commented out IDE code)

This is a windbond ? Can't it just be probed/detected using normal PCI
probing ?

> +
> +/*
> + * Set BAT 3 to map 0xf8000000 to end of physical memory space 1-to-1.
> + */
> +static __inline__ void
> +sandpoint_set_bat(void)
> +{
> +	unsigned long bat3u, bat3l;
> +
> +	__asm__ __volatile__(
> +			" lis %0,0xf800\n	\
> +			ori %1,%0,0x002a\n	\
> +			ori %0,%0,0x0ffe\n	\
> +			mtspr 0x21e,%0\n	\
> +			mtspr 0x21f,%1\n	\
> +			isync\n			\
> +			sync "
> +			: "=r" (bat3u), "=r" (bat3l));
> +}

WTF ?

> +TODC_ALLOC();
> +
> +static int __init
> +sandpoint_probe(void)
> +{
> +	return 1;
> +}

WTF (bis) ? :)

> +define_machine(sandpoint) {
> +	.name			= "Sandpoint",
> +	.probe			= sandpoint_probe,
> +	.setup_arch		= sandpoint_setup_arch,
> +	.setup_io_mappings	= sandpoint_map_io,
> +	.init_IRQ		= sandpoint_init_IRQ,
> +	.show_cpuinfo		= sandpoint_show_cpuinfo,
> +	.get_irq		= mpic_get_irq,
> +	.restart		= sandpoint_restart,
> +	.power_off		= sandpoint_power_off,
> +	.halt			= sandpoint_halt,
> +	.calibrate_decr		= generic_calibrate_decr,
> +	/*
> +	.progress		= udbg_progress,
> +	*/
> +};

So on the TODO list, replace as much as we can of the above with
generic_* equivalents until nothing remains :)
 
> diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
> index 7dcdfcb..1badbec 100644
> --- a/arch/powerpc/sysdev/mpic.c
> +++ b/arch/powerpc/sysdev/mpic.c
> @@ -629,6 +629,13 @@ #endif /* CONFIG_SMP */
>  			mb();
>  	}
>  
> +#ifdef CONFIG_MPIC_SERIAL
> +	/* For serial interrupts & set clock ratio */
> +	mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1,
> +		mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1)
> +			| (1<<27) | (0x7<<28));
> +#endif

This should not be an #ifdef.... this should be an MPIC init flag passed
when initializing it. (and if we do generic device-tree instanciation of
PIC's, we could define standard properties to put in the MPIC node to
enable those flags).

Keep up the good work ! :)

Cheers,
Ben.

^ permalink raw reply

* RE: [PATCH/2.6.17-rc4 7/10]  Powerpc: workaround for tsi108 pci c onfi g read exception
From: Zang Roy-r61911 @ 2006-05-18  5:56 UTC (permalink / raw)
  To: Kumar Gala
  Cc: linuxppc-dev list, Yang Xin-Xin-r48390, Paul Mackerras,
	Alexandre.Bounine


PB and PCI error flags will be set when issuing a PCI/X configuration 
read request. The error flags should be cleared or the system will be
halt.

Alex, is it right?
Roy

On May 17, 2006, at 5:14 AM, Zang Roy-r61911 wrote:

> Workaround for Tundra Semiconductor tsi108 host bridge pci config read
> exception

Can you explain further why this is needed?


>
> Signed-off-by: Alexandre Bounine <alexandreb@tundra.com>
> Signed-off-by: Roy Zang	<tie-fei.zang@freescale.com>
>
> ---
>
>  arch/powerpc/kernel/traps.c |   13 +++++++++++++
>  1 files changed, 13 insertions(+), 0 deletions(-)
>
> 0575fbe21e4f1045528bb91ec4b34bb7955c4a92
> diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
> index 064a525..7468d76 100644
> --- a/arch/powerpc/kernel/traps.c
> +++ b/arch/powerpc/kernel/traps.c
> @@ -262,6 +262,19 @@ #if defined(CONFIG_PPC_PMAC) && defined(
>  		}
>  	}
>  #endif /* CONFIG_PPC_PMAC && CONFIG_PPC32 */
> +
> +#ifdef CONFIG_TSI108_BRIDGE
> +	extern void tsi108_clear_pci_cfg_error(void);
> +	const struct exception_table_entry *entry;
> +
> +	/* Are we prepared to handle this fault?  */
> +	if ((entry = search_exception_tables(regs->nip)) != NULL) {
> +		tsi108_clear_pci_cfg_error();
> +		regs->msr |= MSR_RI;
> +		regs->nip = entry->fixup;
> +		return 1;
> +	}
> +#endif /* CONFIG_TSI108_BRIDGE */
>  	return 0;
>  }
>
> -- 
> 1.3.0
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev

^ permalink raw reply

* [PATCH 1/2] powerpc: Add of_parse_dma_window()
From: Jeremy Kerr @ 2006-05-18  6:20 UTC (permalink / raw)
  To: linuxppc-dev

Add a function for generic parsing of dma-window properties (ie,
ibm,dma-window and ibm,my-dma-window) of pci and virtual device nodes.

This function will also be used by cell.

Signed-off-by: Jeremy Kerr <jk@ozlabs.org>

 arch/powerpc/kernel/prom_parse.c |   23 +++++++++++++++++++++++
 include/asm-powerpc/prom.h       |    6 ++++++
 2 files changed, 29 insertions(+)

Index: linux-2.6/arch/powerpc/kernel/prom_parse.c
===================================================================
--- linux-2.6.orig/arch/powerpc/kernel/prom_parse.c
+++ linux-2.6/arch/powerpc/kernel/prom_parse.c
@@ -548,3 +548,26 @@ int of_pci_address_to_resource(struct de
 	return __of_address_to_resource(dev, addrp, size, flags, r);
 }
 EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
+
+void of_parse_dma_window(struct device_node *dn, unsigned char *dma_window_prop,
+		unsigned long *busno, unsigned long *phys, unsigned long *size)
+{
+	u32 *dma_window, cells;
+	unsigned char *prop;
+
+	dma_window = (u32 *)dma_window_prop;
+
+	/* busno is always one cell */
+	*busno = *(dma_window++);
+
+	prop = get_property(dn, "ibm,#dma-address-cells", NULL);
+	cells = prop ? *(u32 *)prop : prom_n_addr_cells(dn);
+	*phys = of_read_addr(dma_window, cells);
+
+	dma_window += cells;
+
+	prop = get_property(dn, "ibm,#dma-size-cells", NULL);
+	cells = prop ? *(u32 *)prop : prom_n_size_cells(dn);
+	*size = of_read_addr(dma_window, cells);
+}
+EXPORT_SYMBOL_GPL(of_parse_dma_window);
Index: linux-2.6/include/asm-powerpc/prom.h
===================================================================
--- linux-2.6.orig/include/asm-powerpc/prom.h
+++ linux-2.6/include/asm-powerpc/prom.h
@@ -230,6 +230,12 @@ extern int of_address_to_resource(struct
 extern int of_pci_address_to_resource(struct device_node *dev, int bar,
 				      struct resource *r);
 
+/* Parse the ibm,dma-window property of an OF node into the busno, phys and
+ * size parameters.
+ */
+void of_parse_dma_window(struct device_node *dn, unsigned char *dma_window_prop,
+		unsigned long *busno, unsigned long *phys, unsigned long *size);
+
 extern void kdump_move_device_tree(void);
 
 #endif /* __KERNEL__ */

To: linuxppc-dev@ozlabs.org
From: Jeremy Kerr <jk@ozlabs.org>
Date: Thu, 18 May 2006 16:20:51 +1000
Subject: [PATCH 2/2] powerpc: pseries: Use generic dma-window parsing function
Message-Id: <1147933251.472945.297063284077.qpush@pokey>

Change the pseries iommu init code to use the new of_parse_dma_window()
to parse the ibm,dma-window and ibm,my-dma-window properties of pci and
virtual device nodes.

Also, clean up vio_build_iommu_table() a little.

Tested on pseries, with both vio and pci devices.

Signed-off-by: Jeremy Kerr <jk@ozlabs.org>

 arch/powerpc/platforms/pseries/iommu.c |   29 ++++++++++-------------------
 arch/powerpc/platforms/pseries/vio.c   |   32 ++++++++++++++------------------
 2 files changed, 24 insertions(+), 37 deletions(-)

Index: linux-2.6/arch/powerpc/platforms/pseries/iommu.c
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/pseries/iommu.c
+++ linux-2.6/arch/powerpc/platforms/pseries/iommu.c
@@ -299,30 +299,22 @@ static void iommu_table_setparms(struct 
  * iommu_table_setparms_lpar
  *
  * Function: On pSeries LPAR systems, return TCE table info, given a pci bus.
- *
- * ToDo: properly interpret the ibm,dma-window property.  The definition is:
- *	logical-bus-number	(1 word)
- *	phys-address		(#address-cells words)
- *	size			(#cell-size words)
- *
- * Currently we hard code these sizes (more or less).
  */
 static void iommu_table_setparms_lpar(struct pci_controller *phb,
 				      struct device_node *dn,
 				      struct iommu_table *tbl,
-				      unsigned int *dma_window)
+				      unsigned char *dma_window)
 {
+	unsigned long offset, size;
+
 	tbl->it_busno  = PCI_DN(dn)->bussubno;
+	of_parse_dma_window(dn, dma_window, &tbl->it_index, &offset, &size);
 
-	/* TODO: Parse field size properties properly. */
-	tbl->it_size   = (((unsigned long)dma_window[4] << 32) |
-			   (unsigned long)dma_window[5]) >> PAGE_SHIFT;
-	tbl->it_offset = (((unsigned long)dma_window[2] << 32) |
-			   (unsigned long)dma_window[3]) >> PAGE_SHIFT;
 	tbl->it_base   = 0;
-	tbl->it_index  = dma_window[0];
 	tbl->it_blocksize  = 16;
 	tbl->it_type = TCE_PCI;
+	tbl->it_offset = offset >> PAGE_SHIFT;
+	tbl->it_size = size >> PAGE_SHIFT;
 }
 
 static void iommu_bus_setup_pSeries(struct pci_bus *bus)
@@ -414,7 +406,7 @@ static void iommu_bus_setup_pSeriesLP(st
 	struct iommu_table *tbl;
 	struct device_node *dn, *pdn;
 	struct pci_dn *ppci;
-	unsigned int *dma_window = NULL;
+	unsigned char *dma_window = NULL;
 
 	DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self);
 
@@ -422,7 +414,7 @@ static void iommu_bus_setup_pSeriesLP(st
 
 	/* Find nearest ibm,dma-window, walking up the device tree */
 	for (pdn = dn; pdn != NULL; pdn = pdn->parent) {
-		dma_window = (unsigned int *)get_property(pdn, "ibm,dma-window", NULL);
+		dma_window = get_property(pdn, "ibm,dma-window", NULL);
 		if (dma_window != NULL)
 			break;
 	}
@@ -516,7 +508,7 @@ static void iommu_dev_setup_pSeriesLP(st
 {
 	struct device_node *pdn, *dn;
 	struct iommu_table *tbl;
-	int *dma_window = NULL;
+	unsigned char *dma_window = NULL;
 	struct pci_dn *pci;
 
 	DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev));
@@ -531,8 +523,7 @@ static void iommu_dev_setup_pSeriesLP(st
 
 	for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table;
 	     pdn = pdn->parent) {
-		dma_window = (unsigned int *)
-			get_property(pdn, "ibm,dma-window", NULL);
+		dma_window = get_property(pdn, "ibm,dma-window", NULL);
 		if (dma_window)
 			break;
 	}
Index: linux-2.6/arch/powerpc/platforms/pseries/vio.c
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/pseries/vio.c
+++ linux-2.6/arch/powerpc/platforms/pseries/vio.c
@@ -108,32 +108,28 @@ __initcall(vio_bus_init_pseries);
 */
 static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
 {
-	unsigned int *dma_window;
-	struct iommu_table *newTceTable;
-	unsigned long offset;
-	int dma_window_property_size;
+	unsigned char *dma_window;
+	struct iommu_table *tbl;
+	unsigned long offset, size;
 
-	dma_window = (unsigned int *) get_property(dev->dev.platform_data, "ibm,my-dma-window", &dma_window_property_size);
-	if(!dma_window) {
+	dma_window = get_property(dev->dev.platform_data,
+			"ibm,my-dma-window", NULL);
+	if (!dma_window)
 		return NULL;
-	}
 
-	newTceTable = (struct iommu_table *) kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
+	tbl = (struct iommu_table *)kmalloc(sizeof(*tbl), GFP_KERNEL);
 
-	/*  There should be some code to extract the phys-encoded offset
-		using prom_n_addr_cells(). However, according to a comment
-		on earlier versions, it's always zero, so we don't bother */
-	offset = dma_window[1] >>  PAGE_SHIFT;
+	of_parse_dma_window(dev->dev.platform_data, dma_window,
+			&tbl->it_index, &offset, &size);
 
 	/* TCE table size - measured in tce entries */
-	newTceTable->it_size		= dma_window[4] >> PAGE_SHIFT;
+	tbl->it_size	= size >> PAGE_SHIFT;
 	/* offset for VIO should always be 0 */
-	newTceTable->it_offset		= offset;
-	newTceTable->it_busno		= 0;
-	newTceTable->it_index		= (unsigned long)dma_window[0];
-	newTceTable->it_type		= TCE_VB;
+	tbl->it_offset	= offset >> PAGE_SHIFT;
+	tbl->it_busno	= 0;
+	tbl->it_type	= TCE_VB;
 
-	return iommu_init_table(newTceTable);
+	return iommu_init_table(tbl);
 }
 
 /**

^ permalink raw reply

* Re: [PATCH 1/2] powerpc: Add of_parse_dma_window()
From: Jeremy Kerr @ 2006-05-18  6:28 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1147933251.463191.267166640873.qpush@pokey>

Whoa, looks like two mails got merged into one. A re-send is coming..


Jeremy

^ permalink raw reply

* [PATCH 1/2] powerpc: Add of_parse_dma_window()
From: Jeremy Kerr @ 2006-05-18  6:32 UTC (permalink / raw)
  To: linuxppc-dev

Add a function for generic parsing of dma-window properties (ie,
ibm,dma-window and ibm,my-dma-window) of pci and virtual device nodes.

This function will also be used by cell.

Signed-off-by: Jeremy Kerr <jk@ozlabs.org>

 arch/powerpc/kernel/prom_parse.c |   23 +++++++++++++++++++++++
 include/asm-powerpc/prom.h       |    6 ++++++
 2 files changed, 29 insertions(+)

Index: linux-2.6/arch/powerpc/kernel/prom_parse.c
===================================================================
--- linux-2.6.orig/arch/powerpc/kernel/prom_parse.c
+++ linux-2.6/arch/powerpc/kernel/prom_parse.c
@@ -548,3 +548,26 @@ int of_pci_address_to_resource(struct de
 	return __of_address_to_resource(dev, addrp, size, flags, r);
 }
 EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
+
+void of_parse_dma_window(struct device_node *dn, unsigned char *dma_window_prop,
+		unsigned long *busno, unsigned long *phys, unsigned long *size)
+{
+	u32 *dma_window, cells;
+	unsigned char *prop;
+
+	dma_window = (u32 *)dma_window_prop;
+
+	/* busno is always one cell */
+	*busno = *(dma_window++);
+
+	prop = get_property(dn, "ibm,#dma-address-cells", NULL);
+	cells = prop ? *(u32 *)prop : prom_n_addr_cells(dn);
+	*phys = of_read_addr(dma_window, cells);
+
+	dma_window += cells;
+
+	prop = get_property(dn, "ibm,#dma-size-cells", NULL);
+	cells = prop ? *(u32 *)prop : prom_n_size_cells(dn);
+	*size = of_read_addr(dma_window, cells);
+}
+EXPORT_SYMBOL_GPL(of_parse_dma_window);
Index: linux-2.6/include/asm-powerpc/prom.h
===================================================================
--- linux-2.6.orig/include/asm-powerpc/prom.h
+++ linux-2.6/include/asm-powerpc/prom.h
@@ -230,6 +230,12 @@ extern int of_address_to_resource(struct
 extern int of_pci_address_to_resource(struct device_node *dev, int bar,
 				      struct resource *r);
 
+/* Parse the ibm,dma-window property of an OF node into the busno, phys and
+ * size parameters.
+ */
+void of_parse_dma_window(struct device_node *dn, unsigned char *dma_window_prop,
+		unsigned long *busno, unsigned long *phys, unsigned long *size);
+
 extern void kdump_move_device_tree(void);
 
 #endif /* __KERNEL__ */

^ permalink raw reply

* [PATCH 2/2] powerpc: pseries: Use generic dma-window parsing function
From: Jeremy Kerr @ 2006-05-18  6:32 UTC (permalink / raw)
  To: linuxppc-dev

Change the pseries iommu init code to use the new of_parse_dma_window()
to parse the ibm,dma-window and ibm,my-dma-window properties of pci and
virtual device nodes.

Also, clean up vio_build_iommu_table() a little.

Tested on pseries, with both vio and pci devices.

Signed-off-by: Jeremy Kerr <jk@ozlabs.org>

 arch/powerpc/platforms/pseries/iommu.c |   29 ++++++++++-------------------
 arch/powerpc/platforms/pseries/vio.c   |   32 ++++++++++++++------------------
 2 files changed, 24 insertions(+), 37 deletions(-)

Index: linux-2.6/arch/powerpc/platforms/pseries/iommu.c
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/pseries/iommu.c
+++ linux-2.6/arch/powerpc/platforms/pseries/iommu.c
@@ -299,30 +299,22 @@ static void iommu_table_setparms(struct 
  * iommu_table_setparms_lpar
  *
  * Function: On pSeries LPAR systems, return TCE table info, given a pci bus.
- *
- * ToDo: properly interpret the ibm,dma-window property.  The definition is:
- *	logical-bus-number	(1 word)
- *	phys-address		(#address-cells words)
- *	size			(#cell-size words)
- *
- * Currently we hard code these sizes (more or less).
  */
 static void iommu_table_setparms_lpar(struct pci_controller *phb,
 				      struct device_node *dn,
 				      struct iommu_table *tbl,
-				      unsigned int *dma_window)
+				      unsigned char *dma_window)
 {
+	unsigned long offset, size;
+
 	tbl->it_busno  = PCI_DN(dn)->bussubno;
+	of_parse_dma_window(dn, dma_window, &tbl->it_index, &offset, &size);
 
-	/* TODO: Parse field size properties properly. */
-	tbl->it_size   = (((unsigned long)dma_window[4] << 32) |
-			   (unsigned long)dma_window[5]) >> PAGE_SHIFT;
-	tbl->it_offset = (((unsigned long)dma_window[2] << 32) |
-			   (unsigned long)dma_window[3]) >> PAGE_SHIFT;
 	tbl->it_base   = 0;
-	tbl->it_index  = dma_window[0];
 	tbl->it_blocksize  = 16;
 	tbl->it_type = TCE_PCI;
+	tbl->it_offset = offset >> PAGE_SHIFT;
+	tbl->it_size = size >> PAGE_SHIFT;
 }
 
 static void iommu_bus_setup_pSeries(struct pci_bus *bus)
@@ -414,7 +406,7 @@ static void iommu_bus_setup_pSeriesLP(st
 	struct iommu_table *tbl;
 	struct device_node *dn, *pdn;
 	struct pci_dn *ppci;
-	unsigned int *dma_window = NULL;
+	unsigned char *dma_window = NULL;
 
 	DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self);
 
@@ -422,7 +414,7 @@ static void iommu_bus_setup_pSeriesLP(st
 
 	/* Find nearest ibm,dma-window, walking up the device tree */
 	for (pdn = dn; pdn != NULL; pdn = pdn->parent) {
-		dma_window = (unsigned int *)get_property(pdn, "ibm,dma-window", NULL);
+		dma_window = get_property(pdn, "ibm,dma-window", NULL);
 		if (dma_window != NULL)
 			break;
 	}
@@ -516,7 +508,7 @@ static void iommu_dev_setup_pSeriesLP(st
 {
 	struct device_node *pdn, *dn;
 	struct iommu_table *tbl;
-	int *dma_window = NULL;
+	unsigned char *dma_window = NULL;
 	struct pci_dn *pci;
 
 	DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev));
@@ -531,8 +523,7 @@ static void iommu_dev_setup_pSeriesLP(st
 
 	for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table;
 	     pdn = pdn->parent) {
-		dma_window = (unsigned int *)
-			get_property(pdn, "ibm,dma-window", NULL);
+		dma_window = get_property(pdn, "ibm,dma-window", NULL);
 		if (dma_window)
 			break;
 	}
Index: linux-2.6/arch/powerpc/platforms/pseries/vio.c
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/pseries/vio.c
+++ linux-2.6/arch/powerpc/platforms/pseries/vio.c
@@ -108,32 +108,28 @@ __initcall(vio_bus_init_pseries);
 */
 static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
 {
-	unsigned int *dma_window;
-	struct iommu_table *newTceTable;
-	unsigned long offset;
-	int dma_window_property_size;
+	unsigned char *dma_window;
+	struct iommu_table *tbl;
+	unsigned long offset, size;
 
-	dma_window = (unsigned int *) get_property(dev->dev.platform_data, "ibm,my-dma-window", &dma_window_property_size);
-	if(!dma_window) {
+	dma_window = get_property(dev->dev.platform_data,
+			"ibm,my-dma-window", NULL);
+	if (!dma_window)
 		return NULL;
-	}
 
-	newTceTable = (struct iommu_table *) kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
+	tbl = (struct iommu_table *)kmalloc(sizeof(*tbl), GFP_KERNEL);
 
-	/*  There should be some code to extract the phys-encoded offset
-		using prom_n_addr_cells(). However, according to a comment
-		on earlier versions, it's always zero, so we don't bother */
-	offset = dma_window[1] >>  PAGE_SHIFT;
+	of_parse_dma_window(dev->dev.platform_data, dma_window,
+			&tbl->it_index, &offset, &size);
 
 	/* TCE table size - measured in tce entries */
-	newTceTable->it_size		= dma_window[4] >> PAGE_SHIFT;
+	tbl->it_size	= size >> PAGE_SHIFT;
 	/* offset for VIO should always be 0 */
-	newTceTable->it_offset		= offset;
-	newTceTable->it_busno		= 0;
-	newTceTable->it_index		= (unsigned long)dma_window[0];
-	newTceTable->it_type		= TCE_VB;
+	tbl->it_offset	= offset >> PAGE_SHIFT;
+	tbl->it_busno	= 0;
+	tbl->it_type	= TCE_VB;
 
-	return iommu_init_table(newTceTable);
+	return iommu_init_table(tbl);
 }
 
 /**

^ permalink raw reply

* RE: [PATCH/2.6.17-rc4 1/10] Powerpc: Add general support for mpc7 448h pc2 (Taiga) platform
From: Zang Roy-r61911 @ 2006-05-18  6:46 UTC (permalink / raw)
  To: Kumar Gala
  Cc: linuxppc-dev list, Yang Xin-Xin-r48390, Paul Mackerras,
	Alexandre.Bounine

 
> 
> On May 17, 2006, at 5:13 AM, Zang Roy-r61911 wrote:
> 
> > Add support for Freescale mpcc7448 (Taiga) board support
> >
> > Signed-off-by: Roy Zang  <tie-fei.zang@freescale.com>
> >
> > ---
> >
> >  arch/powerpc/Kconfig                       |   24 +++
> >  arch/powerpc/kernel/legacy_serial.c        |   39 ++++
> 
> These board port should live in platforms/embedded6xx.

Should the mpc7448hpc2 board support code be moved to
embedded6xx?

> 
> >  arch/powerpc/platforms/74xx/Makefile       |    4
> >  arch/powerpc/platforms/74xx/misc.c         |   38 ++++
> >  arch/powerpc/platforms/74xx/mpc7448_hpc2.c |  257 
> +++++++++++++++++ 
> > +++++++++++
> >  arch/powerpc/platforms/74xx/mpc7448_hpc2.h |   80 +++++++++
> >  arch/powerpc/platforms/74xx/pci.c          |  103 +++++++++++
> >  arch/powerpc/platforms/Makefile            |    1
> >  8 files changed, 545 insertions(+), 1 deletions(-)
> >  create mode 100644 arch/powerpc/platforms/74xx/Makefile
> >  create mode 100644 arch/powerpc/platforms/74xx/misc.c
> >  create mode 100644 arch/powerpc/platforms/74xx/mpc7448_hpc2.c
> >  create mode 100644 arch/powerpc/platforms/74xx/mpc7448_hpc2.h
> >  create mode 100644 arch/powerpc/platforms/74xx/pci.c
> >
> > 13c16416da4fa51ec771bd4863d94344d139b2f5
> > diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> > index 6729c98..abeac1f 100644
> > --- a/arch/powerpc/Kconfig
> > +++ b/arch/powerpc/Kconfig
> > @@ -332,6 +332,27 @@ config APUS
> >  	  Select APUS if configuring for a PowerUP Amiga.
> >  	  More information is available at:
> >  	  <http://linux-apus.sourceforge.net/>.
> > +
> > +config MPC7448HPC2
> > +	bool "Freescale MPC7448HPC2(Taiga)"
> > +	select DEFAULT_UIMAGE
> > +	select PPC_UDBG_16550
> > +	help
> > +	  Select MPC7448HPC2 if configuring for Freescale MPC7448HPC2  
> > (Taiga)
> > +	  platform
> > +
> > +config 74xx
> > +	bool
> > +	depends on MPC7448HPC2
> > +	default y
> > +	help
> > +	  Select 74xx support
> > +
> 
> What is the config option used for?  We should get ride of.

This config option is used to build the directory arch/powerpc/platforms/74xx
If the board support code will move to embedded6xx, this option can be removed.

> 
> > +config TSI108_BRIDGE
> > +	bool
> > +	depends on MPC7448HPC2
> > +	default y
> > +	
> >  endchoice
> >
> >  config PPC_PSERIES
> > @@ -798,7 +819,8 @@ config MCA
> >  	bool
> >
> >  config PCI
> > -	bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx ||  
> > PPC_MPC52xx || (EMBEDDED && PPC_ISERIES)
> > +	bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx ||  
> > PPC_MPC52xx || (EMBEDDED && PPC_ISERIES) \
> > +				  || MPC7448HPC2
> >  	default y if !40x && !CPM2 && !8xx && !APUS && !PPC_83xx && ! 
> > PPC_85xx
> >  	default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS
> >  	default PCI_QSPAN if !4xx && !CPM2 && 8xx
> > diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/ 
> > kernel/legacy_serial.c
> > index 6e67b5b..f99238d 100644
> > --- a/arch/powerpc/kernel/legacy_serial.c
> > +++ b/arch/powerpc/kernel/legacy_serial.c
> > @@ -134,6 +134,34 @@ static int __init add_legacy_soc_port(st
> >  	return add_legacy_port(np, -1, UPIO_MEM, addr, addr, 
> NO_IRQ, flags);
> >  }
> >
> > +static int __init add_legacy_tsi_port(struct device_node *np,
> > +				      struct device_node *tsi_dev)
> > +{
> > +	phys_addr_t addr;
> > +	u32 *addrp;
> > +	upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
> > +
> > +	/* We only support ports that have a clock frequency properly
> > +	 * encoded in the device-tree.
> > +	 */
> > +	if (get_property(np, "clock-frequency", NULL) == NULL)
> > +		return -1;
> > +
> > +	/* Get the address */
> > +	addrp = of_get_address(tsi_dev, 0, NULL, NULL);
> > +	if (addrp == NULL)
> > +		return -1;
> > +
> > +	addr = of_translate_address(tsi_dev, addrp);
> > +
> > +	/* Add port, irq will be dealt with later. We passed a 
> translated
> > +	 * IO port value. It will be fixed up later along with the irq
> > +	 */
> > +	return add_legacy_port(np, -1, UPIO_MEM, addr, addr, 
> NO_IRQ, flags);
> > +}
> > +
> 
> This looks like its duplicating add_legacy_soc_port, why not 
> use that  
> instead?

The tsi108 serial port is not a sub node of "soc".  well, any way,
I can try soc!

> 
> > +
> > +
> >  static int __init add_legacy_isa_port(struct device_node *np,
> >  				      struct device_node *isa_brg)
> >  {
> > @@ -302,6 +330,17 @@ void __init find_legacy_serial_ports(voi
> >  		of_node_put(isa);
> >  	}
> >
> > +	/* First fill our array with tsi-bridge ports */
> > +	for (np = NULL; (np = of_find_compatible_node(np, "serial",  
> > "ns16550")) != NULL;) {
> > +		struct device_node *tsi = of_get_parent(np);
> > +		if (tsi && !strcmp(tsi->type, "tsi-bridge")) {
> > +			index = add_legacy_tsi_port(np, np);
> > +			if (index >= 0 && np == stdout)
> > +				legacy_serial_console = index;
> > +		}
> > +		of_node_put(tsi);
> > +	}
> > +	
> >  #ifdef CONFIG_PCI
> >  	/* Next, try to locate PCI ports */
> >  	for (np = NULL; (np = of_find_all_nodes(np));) {
> > diff --git a/arch/powerpc/platforms/74xx/Makefile b/arch/powerpc/ 
> > platforms/74xx/Makefile
> > new file mode 100644
> > index 0000000..ed5648c
> > --- /dev/null
> > +++ b/arch/powerpc/platforms/74xx/Makefile
> > @@ -0,0 +1,4 @@
> > +#
> > +# Makefile for the PowerPC 74xx linux kernel.
> > +#
> > +obj-$(CONFIG_MPC7448HPC2)	+= mpc7448_hpc2.o pci.o misc.o
> > diff --git a/arch/powerpc/platforms/74xx/misc.c b/arch/powerpc/ 
> > platforms/74xx/misc.c
> > new file mode 100644
> > index 0000000..6228875
> > --- /dev/null
> > +++ b/arch/powerpc/platforms/74xx/misc.c
> > @@ -0,0 +1,38 @@
> > +
> > +/*
> > + * MPC74xx generic code.
> > + *
> > + * Maintained by Roy Zang
> > + *
> > + * Copyright 2006 Freescale Semiconductor Inc.
> > + *
> > + * 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
> > + * Free Software Foundation;  either version 2 of the  
> License, or  
> > (at your
> > + * option) any later version.
> > + */
> > +#include <linux/irq.h>
> > +#include <linux/module.h>
> > +#include <asm/irq.h>
> > +extern void _nmask_and_or_msr(unsigned long nmask, unsigned long  
> > or_val);
> > +
> > +void mpc7448_hpc2_restart(char *cmd)
> > +{
> > +	local_irq_disable();
> > +
> > +	/* Set exception prefix high - to the firmware */
> > +	_nmask_and_or_msr(0, MSR_IP);
> > +
> > +	for (;;) ;		/* Spin until reset happens */
> > +}
> > +
> > +void mpc7448_hpc2_power_off(void)
> > +{
> > +	local_irq_disable();
> > +	for (;;) ;		/* No way to shut power off 
> with software */
> > +}
> > +
> > +void mpc7448_hpc2_halt(void)
> > +{
> > +	mpc7448_hpc2_power_off();
> > +}
> 
> Move these back into mpc7448_hpc2.c.  They are to specific to hpc2.
 
OK!

> 
> > diff --git a/arch/powerpc/platforms/74xx/mpc7448_hpc2.c b/arch/ 
> > powerpc/platforms/74xx/mpc7448_hpc2.c
> > new file mode 100644
> > index 0000000..b060ae1
> > --- /dev/null
> > +++ b/arch/powerpc/platforms/74xx/mpc7448_hpc2.c
> > @@ -0,0 +1,257 @@
> > +/*
> > + * mpc7448_hpc2.c
> > + *
> > + * Board setup routines for the Freescale Taiga platform
> > + *
> > + * Author: Jacob Pan
> > + *	 jacob.pan@freescale.com
> > + * Author: Xianghua Xiao
> > + *       updated for taiga board from emulation platform 2005.5
> > + *       x.xiao@freescale.com
> > + * Maintainer: Roy Zang <tie-fei.zang@freescale.com>
> > + *
> > + * Copyright 2004-2006 Freescale Semiconductor, Inc.
> > + *
> > + * This file is licensed under
> > + * the terms of the GNU General Public License version 2.  This  
> > program
> > + * is licensed "as is" without any warranty of any kind, whether  
> > express
> > + * or implied.
> > + */
> > +
> > +#include <linux/config.h>
> > +#include <linux/stddef.h>
> > +#include <linux/kernel.h>
> > +#include <linux/pci.h>
> > +#include <linux/kdev_t.h>
> > +#include <linux/console.h>
> > +#include <linux/delay.h>
> > +#include <linux/irq.h>
> > +#include <linux/ide.h>
> > +#include <linux/seq_file.h>
> > +#include <linux/root_dev.h>
> > +#include <linux/serial.h>
> > +#include <linux/tty.h>
> > +#include <linux/serial_core.h>
> > +
> > +#include <asm/system.h>
> > +#include <asm/time.h>
> > +#include <asm/machdep.h>
> > +#include <asm/prom.h>
> > +#include <asm/udbg.h>
> > +#include <asm/tsi108.h>
> > +#include <asm/pci-bridge.h>
> > +#include <asm/reg.h>
> > +#include <mm/mmu_decl.h>
> > +#include "mpc7448_hpc2.h"
> > +#include <asm/tsi108_pic.h>
> > +
> > +#ifndef CONFIG_PCI
> > +isa_io_base = MPC7448_HPC2_ISA_IO_BASE;
> > +isa_mem_base = MPC7448_HPC2_ISA_MEM_BASE;
> > +pci_dram_offset = MPC7448_HPC2_PCI_MEM_OFFSET;
> > +#endif
> > +
> > +extern int add_bridge(struct device_node *dev);
> > +extern void mpc7448_hpc2_restart(char *cmd);
> > +extern void mpc7448_hpc2_power_off(void);
> > +extern void mpc7448_hpc2_halt(void);
> > +
> > +#ifdef TSI108_ETH
> > +hw_info hw_info_table[TSI108_ETH_MAX_PORTS + 1] = {
> > +	{TSI108_CSR_ADDR_PHYS + TSI108_ETH_OFFSET,
> > +	 TSI108_CSR_ADDR_PHYS + TSI108_ETH_OFFSET,
> > +	 TSI108_PHY0_ADDR, IRQ_TSI108_GIGE0},
> > +
> > +	{TSI108_CSR_ADDR_PHYS + TSI108_ETH_OFFSET + 0x400,
> > +	 TSI108_CSR_ADDR_PHYS + TSI108_ETH_OFFSET,
> > +	 TSI108_PHY1_ADDR, IRQ_TSI108_GIGE1},
> > +
> > +	{TBL_END, TBL_END, TBL_END, TBL_END}
> > +};
> > +#endif
> 
> This table looks problematic.  Look at using something like a  
> platform device.

I will try it! 

> 
> > +
> > +/*
> > + * Define all of the IRQ senses and polarities.  Taken from the
> > + * mpc7448hpc  manual.
> > + * Note:  Likely, this table and the following function should be
> > + *        obtained and derived from the OF Device Tree.
> > + */
> > +
> > +static u_char mpc7448_hpc2_pic_initsenses[] __initdata = {
> > +	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 
> INT[0] XINT0 from  
> > FPGA */
> > +	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 
> INT[1] XINT1 from  
> > FPGA */
> > +	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 
> INT[2] PHY_INT from  
> > both GIGE */
> > +	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 
> INT[3] RESERVED */
> > +};
> > +
> > +/*
> > + * mpc7448hpc2 PCI interrupt routing. all PCI interrupt comes from
> > + * external PCI source at 23. need to program pci interrupt  
> > control registers
> > + * to route per slot IRQs.
> > + */
> > +
> > +static inline int
> > +mpc7448_hpc2_map_irq(struct pci_dev *dev, unsigned char idsel,
> > +		     unsigned char pin)
> > +{
> > +	static char pci_irq_table[][4] =
> > +	    /*
> > +	     *      PCI IDSEL/INTPIN->INTLINE
> > +	     *         A     B     C     D
> > +	     */
> > +	{
> > +		{IRQ_PCI_INTA, IRQ_PCI_INTB, IRQ_PCI_INTC, 
> IRQ_PCI_INTD},	/* A  
> > SLOT 1 IDSEL 17 */
> > +		{IRQ_PCI_INTB, IRQ_PCI_INTC, IRQ_PCI_INTD, 
> IRQ_PCI_INTA},	/* B  
> > SLOT 2 IDSEL 18 */
> > +		{IRQ_PCI_INTC, IRQ_PCI_INTD, IRQ_PCI_INTA, 
> IRQ_PCI_INTB},	/* C  
> > SATA IDSEL 19 */
> > +		{IRQ_PCI_INTD, IRQ_PCI_INTA, IRQ_PCI_INTB, 
> IRQ_PCI_INTC},	/* D  
> > USB IDSEL 20 */
> > +	};
> > +
> > +	const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4;
> > +	return PCI_IRQ_TABLE_LOOKUP;
> > +}
> > +
> > +int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn)
> > +{
> > +	if (bus == 0 && PCI_SLOT(devfn) == 0)
> > +		return PCIBIOS_DEVICE_NOT_FOUND;
> > +	else
> > +		return PCIBIOS_SUCCESSFUL;
> > +}
> > +
> > +static __inline__ void mpc7448_hpc2_l2cr_prefetch_enable(void)
> > +{
> > +	unsigned long msscr0;
> > +	__asm__ __volatile__("mfspr %0, 0x3f6\n \
> > +		ori %0,%0,0x3\n	         \
> > +		sync \n                  \
> > +		mtspr 0x3f6,%0\n   \
> > +		sync\n			 \
> > +		isync ":"=r"(msscr0));
> > +}
> > +
> > +static void __init mpc7448_hpc2_setup_arch(void)
> > +{
> > +	struct device_node *cpu;
> > +	struct device_node *np;
> > +	if (ppc_md.progress)
> > +		
> ppc_md.progress("mpc7448_hpc2_setup_arch():set_bridge", 0);
> > +
> > +	cpu = of_find_node_by_type(NULL, "cpu");
> > +	if (cpu != 0) {
> > +		unsigned int *fp;
> > +
> > +		fp = (int *)get_property(cpu, "clock-frequency", NULL);
> > +		if (fp != 0)
> > +			loops_per_jiffy = *fp / HZ;
> > +		else
> > +			loops_per_jiffy = 50000000 / HZ;
> > +		of_node_put(cpu);
> > +	}
> > +
> > +#ifdef	CONFIG_ROOT_NFS
> > +	ROOT_DEV = Root_NFS;
> > +#else
> > +	ROOT_DEV = Root_HDA1;
> > +#endif
> > +
> > +#ifdef CONFIG_BLK_DEV_INITRD
> > +	ROOT_DEV = Root_RAM0;
> > +#endif
> > +
> > +	/* setup PCI host bridge */
> > +
> > +#ifdef CONFIG_PCI
> > +
> > +	for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
> > +		add_bridge(np);
> > +
> > +	ppc_md.pci_swizzle = common_swizzle;
> > +	ppc_md.pci_map_irq = mpc7448_hpc2_map_irq;
> > +	ppc_md.pci_exclude_device = mpc7448_hpc2_exclude_device;
> > +	if (ppc_md.progress)
> > +		ppc_md.progress("tsi108: resources set", 0x100);
> > +#endif
> > +
> > +#ifdef CONFIG_DUMMY_CONSOLE
> > +	conswitchp = &dummy_con;
> > +#endif
> > +
> > +	printk(KERN_INFO "MPC7448HPC2 (TAIGA) Platform\n");
> > +	printk(KERN_INFO
> > +	       "Jointly ported by Freescale and Tundra 
> Semiconductor\n");
> > +	printk(KERN_INFO
> > +	       "Enabling L2 cache then enabling the HID0 
> prefetch engine. 
> > \n");
> > +	_set_L2CR(L2CR_L2E);
> > +	mpc7448_hpc2_l2cr_prefetch_enable();
> 
> Hmm, can't remember what happens with the L2 setup on 74xx.

I will check it!

> 
> > +}
> > +
> > +/*
> > + * Interrupt setup and service.  Interrrupts on the 
> mpc7448_hpc2 come
> > + * from the four external INT pins, PCI interrupts are routed via
> > + * PCI interrupt control registers, it generates internal IRQ23
> > + *
> > + * Interrupt routing on the Taiga Board:
> > + * TSI108:PB_INT[0] -> CPU0:INT#
> > + * TSI108:PB_INT[1] -> CPU0:MCP#
> > + * TSI108:PB_INT[2] -> N/C
> > + * TSI108:PB_INT[3] -> N/C
> > + */
> > +static void __init mpc7448_hpc2_init_IRQ(void)
> > +{
> > +
> > +	tsi108_pic_init(mpc7448_hpc2_pic_initsenses);
> > +
> > +	/* Configure MPIC outputs to CPU0 */
> > +	tsi108_pic_set_output(0, IRQ_SENSE_EDGE, IRQ_POLARITY_NEGATIVE);
> > +}
> > +
> > +static void __init mpc7448_hpc2_map_io(void)
> > +{
> > +	/* PCI IO  mapping */
> > +	io_block_mapping(MPC7448_HPC2_PCI_IO_BASE_VIRT,
> > +			 MPC7448_HPC2_PCI_IO_BASE_PHYS, 
> 0x00800000, _PAGE_IO);
> > +	/* Tsi108 CSR mapping */
> > +	io_block_mapping(TSI108_CSR_ADDR_VIRT, TSI108_CSR_ADDR_PHYS,
> > +			 0x100000, _PAGE_IO);
> > +
> > +	/* PCI Config mapping */
> > +	io_block_mapping(MPC7448_HPC2_PCI_CFG_BASE_VIRT,
> > +			 MPC7448_HPC2_PCI_CFG_BASE_PHYS,
> > +			 MPC7448_HPC2_PCI_CFG_SIZE, _PAGE_IO);
> > +
> > +	tsi108_pci_cfg_base = MPC7448_HPC2_PCI_CFG_BASE_VIRT;
> > +	/* NVRAM mapping */
> > +	io_block_mapping(MPC7448_HPC2_NVRAM_BASE_ADDR,
> > +			 MPC7448_HPC2_NVRAM_BASE_ADDR, 
> MPC7448_HPC2_NVRAM_SIZE,
> > +			 _PAGE_IO);
> > +}
> 
> You need to do this another way, we are trying to avoid using  
> io_block_mapping()

OK! I will abandon io_block_mapping() :).

> 
> > +
> > +void mpc7448_hpc2_show_cpuinfo(struct seq_file *m)
> > +{
> > +	seq_printf(m, "vendor\t\t: Freescale Semiconductor\n");
> > +	seq_printf(m, "machine\t\t: MPC7448hpc2\n");
> > +}
> > +
> > +/*
> > + * Called very early, device-tree isn't unflattened
> > + */
> > +static int __init mpc7448_hpc2_probe(void)
> > +{
> > +	/* We always match for now, eventually we should look 
> at the flat
> > +	   dev tree to ensure this is the board we are suppose to run on
> > +	 */
> > +	return 1;
> > +}
> > +
> > +define_machine(mpc7448_hpc2){
> > +	.name 			= "MPC7448 HPC2",
> > +	.probe 			= mpc7448_hpc2_probe,
> > +	.setup_arch 		= mpc7448_hpc2_setup_arch,
> > +	.init_IRQ 		= mpc7448_hpc2_init_IRQ,
> > +	.show_cpuinfo 		= mpc7448_hpc2_show_cpuinfo,
> > +	.get_irq 		= tsi108_pic_get_irq,
> > +	.restart 		= mpc7448_hpc2_restart,
> > +	.calibrate_decr 	= generic_calibrate_decr,
> > +	.setup_io_mappings 	= mpc7448_hpc2_map_io,
> > +	.progress 		= udbg_progress,
> > +};
> > diff --git a/arch/powerpc/platforms/74xx/mpc7448_hpc2.h b/arch/ 
> > powerpc/platforms/74xx/mpc7448_hpc2.h
> > new file mode 100644
> > index 0000000..8833520
> > --- /dev/null
> > +++ b/arch/powerpc/platforms/74xx/mpc7448_hpc2.h
> > @@ -0,0 +1,80 @@
> > +/*
> > + * mpc7448_hpc2.h
> > + *
> > + * Definitions for Freescale MPC7448_HPC2 platform
> > + *
> > + * Author: Jacob Pan
> > + *         jacob.pan@freescale.com
> > + * Maintainer: Roy Zang <roy.zang@freescale.com>
> > + *
> > + * 2006 (c) Freescale Semiconductor, Inc.  This file is licensed  
> > under
> > + * the terms of the GNU General Public License version 2.  This  
> > program
> > + * is licensed "as is" without any warranty of any kind, whether  
> > express
> > + * or implied.
> > + */
> > +
> > +#ifndef __PPC_PLATFORMS_MPC7448_HPC2_H
> > +#define __PPC_PLATFORMS_MPC7448_HPC2_H
> > +
> > +#include <asm/ppcboot.h>
> > +
> > +/* Ethernet defines
> > + */
> > +#define TSI108_ETH
> > +#define TSI108_ETH_MAX_PORTS	(2)	/* TSI108 
> Ethernet block has 2  
> > ports */
> > +#define TSI108_PHY0_ADDR	(8)	/* PHY address for GIGE 
> port 0 */
> > +#define TSI108_PHY1_ADDR	(9)	/* PHY address for GIGE 
> port 1 */
> > +
> > +/* Base Addresses for the PCI bus
> > + * HOST_PCI initiator (outbound) window to PCI bus
> > + */
> > +#define MPC7448_HPC2_PCI_MEM_OFFSET	(0x00000000)
> > +#define MPC7448_HPC2_PCI_IO_BASE_PHYS	(0xfa000000)
> > +#define MPC7448_HPC2_PCI_IO_BASE_VIRT	
> (MPC7448_HPC2_PCI_IO_BASE_PHYS)
> > +#define MPC7448_HPC2_PCI_MEM_BASE	(0xe0000000)
> > +#define MPC7448_HPC2_ISA_IO_BASE	(0x00000000)
> > +#define MPC7448_HPC2_ISA_MEM_BASE	(0x00000000)
> > +
> > +#define MPC7448_HPC2_PCI_CFG_BASE_PHYS	(0xfb000000)
> > +#define MPC7448_HPC2_PCI_CFG_BASE_VIRT	 
> > (MPC7448_HPC2_PCI_CFG_BASE_PHYS)
> > +#define MPC7448_HPC2_PCI_CFG_SIZE	(0x01000000)
> > +
> > +#define MPC7448_HPC2_PCI_MEM_START	(0xE0000000)
> > +#define MPC7448_HPC2_PCI_MEM_END	(0xF9FFFFFF)
> > +
> > +#define MPC7448_HPC2_PCI_IO_START	(0xFA000000)
> > +#define MPC7448_HPC2_PCI_IO_END	(0xFA00FFFF)
> > +
> > +#define MPC7448_HPC2_PCI_CFG_OFFSET	(0xFB000000)
> > +#define MPC7448_HPC2_PCI_IO_OFFSET	(0xFA000000)
> > +
> > +#define MPC7448_HPC2_PCI_MEM32_OFFSET	0x00000000	
> /* PCI MEM32  
> > space offset within
> > +							   the 
> PCI window */
> > +#define MPC7448_HPC2_PCI_PFM_OFFSET	0x10000000	
> /* PCI PFM1 space  
> > offset within
> > +							   the 
> PCI window */
> 
> Can you not determine these from your flat device tree?

I can !

> 
> > +
> > +/* Memory-mapped CIU resources (CPU view)
> > + * The memory map is set by initialization code in monitor
> > + */
> > +
> > +#define TSI108_CSR_ADDR_PHYS	(0xC0000000)	/* 
> Physical Tsi108 CSR  
> > Base Address */
> > +#define TSI108_CSR_ADDR_VIRT	(0xF0000000)	/* 
> Virtual Tsi108 CSR  
> > Base Address */
> 
> Don't use hard coded VIRT addresses.

OK!

> 
> > +
> > +#define FLASH_BASE_ADDR		(0xFF000000)	/* Boot 
> FLASH Base Address */
> > +
> > +#define SDRAM_BASE_ADDR		0x00000000	/* 
> SDRAM base address */
> > +#define BOARD_SDRAM_SIZE	0x20000000	/* Default 
> value: 512MB */
> > +
> > +/* Size of SDRAM space reserved for user space. This limits space  
> > available
> > + * for dynamic allocation.
> > + */
> > +#define USER_RESERVED_MEM	(BOARD_SDRAM_SIZE - 0x02000000)
> > +
> > +#define USER_RESERVED_BASE  \
> > +  (SDRAM_BASE_ADDR + (BOARD_SDRAM_SIZE - USER_RESERVED_MEM)
> > +
> > +/* Memory mapped NVRAM/RTC */
> > +#define MPC7448_HPC2_NVRAM_BASE_ADDR	(0xFC000000)
> > +#define MPC7448_HPC2_NVRAM_SIZE	(0x8000)
> > +
> > +#endif				/* 
> __PPC_PLATFORMS_MPC7448_HPC2_H */
> > diff --git a/arch/powerpc/platforms/74xx/pci.c b/arch/powerpc/ 
> > platforms/74xx/pci.c
> > new file mode 100644
> > index 0000000..fd822ed
> > --- /dev/null
> > +++ b/arch/powerpc/platforms/74xx/pci.c
> 
> If this is generic to the tsi108 rename to something like  
> tsi108_pci.c as its not generic to 74xx or embedded6xx.

OK!

> 
> > @@ -0,0 +1,103 @@
> > +/*
> > + * TSI 108 PCI hose setup up code
> > + *
> > + * Maintained by Roy Zang
> > + *
> > + * 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
> > + * Free Software Foundation;  either version 2 of the  
> License, or  
> > (at your
> > + * option) any later version.
> > + */
> > +
> > +#include <linux/config.h>
> > +#include <linux/stddef.h>
> > +#include <linux/kernel.h>
> > +#include <linux/init.h>
> > +#include <linux/errno.h>
> > +#include <linux/pci.h>
> > +#include <linux/delay.h>
> > +#include <linux/irq.h>
> > +#include <linux/module.h>
> > +
> > +#include <asm/system.h>
> > +#include <asm/atomic.h>
> > +#include <asm/io.h>
> > +#include <asm/pci-bridge.h>
> > +#include <asm/prom.h>
> > +#include <asm/tsi108.h>
> > +#include "mpc7448_hpc2.h"
> 
> What's this included needed for?
> 
> > +
> > +#undef DEBUG
> > +
> > +#ifdef DEBUG
> > +#define DBG(x...) printk(x)
> > +#else
> > +#define DBG(x...)
> > +#endif
> > +
> > +extern int tsi108_direct_write_config(struct pci_bus *bus,  
> > unsigned int devfn,
> > +				      int offset, int len, u32 val);
> > +extern int tsi108_direct_read_config(struct pci_bus *bus, 
> unsigned  
> > int devfn,
> > +				     int offset, int len, u32 * val);
> > +
> 
> Can you not use indirect pci support that already exists?

I am not sure, I will  have a try.

> 
> > +void tsi108_clear_pci_error(u32 pci_cfg_base);
> > +
> > +extern int
> > +tsi108_read_config(int bus, unsigned int devfn, int offset, int  
> > len, u32 * val);
> > +#ifdef CONFIG_PCI
> > +static struct pci_ops direct_pci_ops = {
> > +	tsi108_direct_read_config,
> > +	tsi108_direct_write_config
> > +};
> > +
> > +void tsi108_clear_pci_cfg_error(void)
> > +{
> > +	tsi108_clear_pci_error(MPC7448_HPC2_PCI_CFG_BASE_PHYS);
> > +}
> > +
> > +int __init add_bridge(struct device_node *dev)
> > +{
> > +	int len;
> > +	struct pci_controller *hose;
> > +	struct resource rsrc;
> > +	int *bus_range;
> > +	int primary = 0, has_address = 0;
> > +
> > +	DBG("TSI_PCI: %s tsi108_pci_cfg_base=0x%x\n", __FUNCTION__,
> > +	    tsi108_pci_cfg_base);
> > +
> > +	/* Fetch host bridge registers address */
> > +	has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
> > +
> > +	/* Get bus range if any */
> > +	bus_range = (int *)get_property(dev, "bus-range", &len);
> > +	if (bus_range == NULL || len < 2 * sizeof(int)) {
> > +		printk(KERN_WARNING "Can't get bus-range for %s, assume"
> > +		       " bus 0\n", dev->full_name);
> > +	}
> > +
> > +	hose = pcibios_alloc_controller();
> > +
> > +	if (!hose) {
> > +		printk("PCI Host bridge init failed\n");
> > +		return -ENOMEM;
> > +	}
> > +	hose->arch_data = dev;
> > +	hose->set_cfg_type = 1;
> > +
> > +	hose->first_busno = bus_range ? bus_range[0] : 0;
> > +	hose->last_busno = bus_range ? bus_range[1] : 0xff;
> > +
> > +	(hose)->ops = &direct_pci_ops;
> > +
> > +	printk(KERN_INFO "Found tsi108 PCI host bridge at 0x%08lx. "
> > +	       "Firmware bus number: %d->%d\n",
> > +	       rsrc.start, hose->first_busno, hose->last_busno);
> > +
> > +	/* Interpret the "ranges" property */
> > +	/* This also maps the I/O region and sets isa_io/mem_base */
> > +	pci_process_bridge_OF_ranges(hose, dev, primary);
> > +	return 0;
> > +
> > +}
> > +#endif
> > diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/ 
> > platforms/Makefile
> > index c4f6b0d..71ca0e0 100644
> > --- a/arch/powerpc/platforms/Makefile
> > +++ b/arch/powerpc/platforms/Makefile
> > @@ -9,6 +9,7 @@ obj-$(CONFIG_PPC_CHRP)		+= chrp/
> >  obj-$(CONFIG_4xx)		+= 4xx/
> >  obj-$(CONFIG_PPC_83xx)		+= 83xx/
> >  obj-$(CONFIG_PPC_85xx)		+= 85xx/
> > +obj-$(CONFIG_74xx)		+= 74xx/
> >  obj-$(CONFIG_PPC_PSERIES)	+= pseries/
> >  obj-$(CONFIG_PPC_ISERIES)	+= iseries/
> >  obj-$(CONFIG_PPC_MAPLE)		+= maple/
> > -- 
> > 1.3.0
> >
> >
> >
> >
> > _______________________________________________
> > Linuxppc-dev mailing list
> > Linuxppc-dev@ozlabs.org
> > https://ozlabs.org/mailman/listinfo/linuxppc-dev
> 

^ permalink raw reply

* RE: [PATCH/2.6.17-rc4 3/10] Powerpc: Add tsi108 common function
From: Zang Roy-r61911 @ 2006-05-18  6:49 UTC (permalink / raw)
  To: Kumar Gala
  Cc: linuxppc-dev list, Yang Xin-Xin-r48390, Paul Mackerras,
	Alexandre.Bounine



> -----Original Message-----
> From: Kumar Gala [mailto:galak@kernel.crashing.org]

> 
> Can the PCI use indirect like used on most other PPC platforms.

I am not sure. I will have a try!

> 
> > +int
> > +tsi108_direct_write_config(struct pci_bus *bus, unsigned 
> int devfunc,
> > +			   int offset, int len, u32 val)
> > +{
> > +	volatile unsigned char *cfg_addr;
> > +
> > +	cfg_addr = (unsigned char *)(tsi_mk_config_addr(bus->number,
> > +							
> devfunc, offset) |
> > +				     (offset & 0x03));
> > +
> > +#ifdef TSI108_PCI_DEBUG
> > +	printk("PCI CFG write : ");
> > +	printk("%d:0x%x:0x%x ", bus->number, devfunc, offset);
> > +	printk("%d ADDR=0x%08x ", len, (uint) cfg_addr);
> > +	printk("data = 0x%08x\n", val);
> > +#endif
> > +
> > +	switch (len) {
> > +	case 1:
> > +		out_8((u8 *) cfg_addr, val);
> > +		break;
> > +	case 2:
> > +		out_le16((u16 *) cfg_addr, val);
> > +		break;
> > +	default:
> > +		out_le32((u32 *) cfg_addr, val);
> > +		break;
> > +	}
> > +
> 

^ permalink raw reply

* RE: [PATCH/2.6.17-rc4 1/10] Powerpc: Add general support for mpc7 448h pc2 (Taiga) platform
From: Zang Roy-r61911 @ 2006-05-18  6:57 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Kumar Gala
  Cc: linuxppc-dev list, Paul Mackerras, Alexandre.Bounine,
	Yang Xin-Xin-r48390

 
> On Wed, 2006-05-17 at 08:45 -0500, Kumar Gala wrote:
> 
> > > +#ifdef TSI108_ETH
> > > +hw_info hw_info_table[TSI108_ETH_MAX_PORTS + 1] = {
> > > +	{TSI108_CSR_ADDR_PHYS + TSI108_ETH_OFFSET,
> > > +	 TSI108_CSR_ADDR_PHYS + TSI108_ETH_OFFSET,
> > > +	 TSI108_PHY0_ADDR, IRQ_TSI108_GIGE0},
> > > +
> > > +	{TSI108_CSR_ADDR_PHYS + TSI108_ETH_OFFSET + 0x400,
> > > +	 TSI108_CSR_ADDR_PHYS + TSI108_ETH_OFFSET,
> > > +	 TSI108_PHY1_ADDR, IRQ_TSI108_GIGE1},
> > > +
> > > +	{TBL_END, TBL_END, TBL_END, TBL_END}
> > > +};
> > > +#endif
> > 
> > This table looks problematic.  Look at using something like a  
> > platform device.
> 
> Bzzzt ... wrong answer :) That's a textbook example of stuff 
> that should
> be provided via the device-tree.
> 
> 

Well , should I register this data to a platform device or the Ethernet 
driver get the information from device-tree directly?
Roy

^ permalink raw reply

* RE: [PATCH/2.6.17-rc4 1/10] Powerpc: Add general support for mpc7 448h pc2 (Taiga) platform
From: Benjamin Herrenschmidt @ 2006-05-18  6:59 UTC (permalink / raw)
  To: Zang Roy-r61911
  Cc: linuxppc-dev list, Paul Mackerras, Alexandre.Bounine,
	Yang Xin-Xin-r48390
In-Reply-To: <9FCDBA58F226D911B202000BDBAD4673062C0563@zch01exm40.ap.freescale.net>


> The tsi108 serial port is not a sub node of "soc".  well, any way,
> I can try soc!

What is it ? Where is it ? "soc" is a bit of a generic name for
something in the device-tree in fact... we might want to define a way to
expose any bus via some kind of soc mecanism even if it's not a root
bus.

^ permalink raw reply

* Re: [RFC PATCH 00/09] robust VM per_cpu variables
From: Steven Rostedt @ 2006-05-18  7:00 UTC (permalink / raw)
  To: Christoph Lameter
  Cc: Andrew Morton, linux-mips, David Mosberger-Tang, linux-ia64,
	Martin Mares, spyro, Joe Taylor, Andi Kleen, linuxppc-dev,
	Paul Mackerras, benedict.gaster, sam, bjornw, kenneth.w.chen,
	Ingo Molnar, kiran, Nick Piggin, grundler, arnd, Rusty Russell,
	starvik, Linus Torvalds, Thomas Gleixner, rth, Chris Zankel,
	tony.luck, LKML, ralf, Marc Gauthier, lethal, schwidefsky,
	linux390, davem, parisc-linux
In-Reply-To: <Pine.LNX.4.64.0605171038160.13767@schroedinger.engr.sgi.com>


On Wed, 17 May 2006, Christoph Lameter wrote:

> On Wed, 17 May 2006, Steven Rostedt wrote:
>
> > > Well I'd like to see a comprehensive solution including a fix for the
> > > problems with allocper_cpu() allocations (allocper_cpu has to allocate
> > > memory for potential processors... which could be a lot on
> > > some types of systems and its allocated somewhere not on the nodes of the
> > > processor since they may not yet be online).
> >
> > OK, now you're beyond what I'm working with ;)  No hot plug CPUs for me.
> > Well, at least not yet!
>
> You need to at least consider how this could be handled by the per_cpu
> memory manangement. The VM thingie with dynamic per cpu memory would allow
> a fixup of allocpercpu.
>

Last night, while aimlessly wondering the streets of Karlsruhe, I thought
of some ideas.  Maybe not very good ideas, but ideas never-the-less.

How about a hybrid?  Have the normal in kernel code use what is there
today, with the indirection.  Have modules and add on CPUs use an
allocated vm area.

Here's the thought:

  Have the boot time per_cpu variables (BTPCV) allocated like it is today.
  But make sure that they are paged align.

  Store away the initial values of per_cpu variables (PCV), for systems
  with hot pluggable CPUs.

  For modules, have a VM dedicated area. The assumption is that the
  modules will not have more PCVs than the kernel. Hopefully the PCVs
  of a module will not strain the TLB too much.  As long as the modules
  PCVs are separated per cpu the same as the BTPCV then this will work.
  We can even use the extra space that was added in the alignment,
  if the modules PCV section is small enough to fit.

  Now for allocated PCV for a hot plugged CPU.  We can dynamically
  allocate them when the CPU is loaded, and copy in the saved BTPCV.

The hotplug CPU handling might be hard to work with the module handling,
but both should be simple by themselves.  So if we concentrate on just the
hotplug first, then this might actually benefit you.

So, Allocate a page alligned BTPCV for each online CPU and copy the
section into them.  Keep the initial section around.

When a CPU comes on line, allocate the memory for the PCV in VM and copy
the saved BTPCV into it.  Then have the indirect pointer array (or CPU
private register/variable) point to this section.  It only puts strain on
the TLB of the newly online CPU, but it gives us the option of placing the
PCV into memory that we want (NUMA friendly).

So I should forget about the modules for now, and get a hotplug PCV
solution working.  All the archs would need to do is to give a VM address
where to store these variables. Hmm...

Thoughts?

-- Steve

^ permalink raw reply

* RE: [PATCH/2.6.17-rc4 10/10]  bugs fix for marvell SATA on powerp c pl atform
From: Benjamin Herrenschmidt @ 2006-05-18  7:02 UTC (permalink / raw)
  To: Zang Roy-r61911
  Cc: Alexandre.Bounine, linuxppc-dev list, linux-kernel, linux-ide,
	Paul Mackerras, Yang Xin-Xin-r48390, jgarzik
In-Reply-To: <9FCDBA58F226D911B202000BDBAD46730626DE6E@zch01exm40.ap.freescale.net>

On Thu, 2006-05-18 at 12:03 +0800, Zang Roy-r61911 wrote:
> -----Original Message-----
> From: Kumar Gala [mailto:galak@kernel.crashing.org]
> Sent: 2006年5月17日 21:28
> To: Zang Roy-r61911
> Cc: Paul Mackerras; linuxppc-dev list; Alexandre.Bounine@tundra.com; Yang Xin-Xin-r48390
> Subject: Re: [PATCH/2.6.17-rc4 10/10] bugs fix for marvell SATA on powerpc pl atform

Copying here the comments I already made so Jeff gets them...

> @@ -1032,6 +1032,9 @@ static inline void mv_crqb_pack_cmd(u16 
>  {
>       *cmdw = data | (addr << CRQB_CMD_ADDR_SHIFT) | CRQB_CMD_CS |
>               (last ? CRQB_CMD_LAST : 0);
> +#ifdef CONFIG_PPC
> +     *cmdw = cpu_to_le16(*cmdw);
> +#endif
>  }

Why an ifdef here ? The cpu_to_le16 should probably be unconditional.
And even if for some weird reason you wanted to ifdef it, why PPC ? and
what about other BE architectures ?
 
>  /**
> @@ -1567,13 +1570,18 @@ static void mv5_read_preamp(struct mv_ho
>  static void mv5_enable_leds(struct mv_host_priv *hpriv, void __iomem
*mmio)
>  {
>       u32 tmp;
> -
> +#ifndef CONFIG_PPC
>       writel(0, mmio + MV_GPIO_PORT_CTL);
> +#endif

You'll have to do better here too... I don't wee why when compiled on
PPC, this driver should "magically" not clear those bits... At the very
least, you should test the machine type if you want to do something
specific to your platform, but first, you'll have to convince Jeff why
this change has to be done in the first place and if there is a better
way to handle it.

>       /* FIXME: handle MV_HP_ERRATA_50XXB2 errata */
>  
>       tmp = readl(mmio + MV_PCI_EXP_ROM_BAR_CTL);
> +#ifdef CONFIG_PPC
> +     tmp &= ~(1 << 0);
> +#else        
>       tmp |= ~(1 << 0);
> +#endif
>       writel(tmp, mmio + MV_PCI_EXP_ROM_BAR_CTL);
>  }

Looks to me like the initial code was bogus, thus the #ifdef shouldn't
be necessary neither, and even if it was, an ifdef CONFIG_PPC would be
the wrong approach for what I think should be ovious enough reasons...

Ben.

^ permalink raw reply

* RE: [PATCH/2.6.17-rc4 1/10] Powerpc: Add general support for mpc7 448h pc2 (Taiga) platform
From: Zang Roy-r61911 @ 2006-05-18  7:12 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: linuxppc-dev list, Yang Xin-Xin-r48390, Paul Mackerras,
	Alexandre.Bounine


> I'm not repeating Kumar's comments about that CONFIG_7xxx 
> thing and that
> 7xxx/ directory, it should all go.
> 

Should I move my code to embedded6xx?

> Some more bits:
> 
> > +static u_char mpc7448_hpc2_pic_initsenses[] __initdata = {
> > +	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 
> INT[0] XINT0 from FPGA */
> > +	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 
> INT[1] XINT1 from FPGA */
> > +	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 
> INT[2] PHY_INT from both GIGE */
> > +	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 
> INT[3] RESERVED */
> > +};
> > +
> > +/*
> > + * mpc7448hpc2 PCI interrupt routing. all PCI interrupt comes from
> > + * external PCI source at 23. need to program pci 
> interrupt control registers
> > + * to route per slot IRQs.
> > + */
> > +
> > +static inline int
> > +mpc7448_hpc2_map_irq(struct pci_dev *dev, unsigned char idsel,
> > +		     unsigned char pin)
> > +{
> > +	static char pci_irq_table[][4] =
> > +	    /*
> > +	     *      PCI IDSEL/INTPIN->INTLINE
> > +	     *         A     B     C     D
> > +	     */
> > +	{
> > +		{IRQ_PCI_INTA, IRQ_PCI_INTB, IRQ_PCI_INTC, 
> IRQ_PCI_INTD},	/* A SLOT 1 IDSEL 17 */
> > +		{IRQ_PCI_INTB, IRQ_PCI_INTC, IRQ_PCI_INTD, 
> IRQ_PCI_INTA},	/* B SLOT 2 IDSEL 18 */
> > +		{IRQ_PCI_INTC, IRQ_PCI_INTD, IRQ_PCI_INTA, 
> IRQ_PCI_INTB},	/* C SATA IDSEL 19 */
> > +		{IRQ_PCI_INTD, IRQ_PCI_INTA, IRQ_PCI_INTB, 
> IRQ_PCI_INTC},	/* D USB IDSEL 20 */
> > +	};
> > +
> > +	const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4;
> > +	return PCI_IRQ_TABLE_LOOKUP;
> > +}
> 
> This whole irq map stuff is excactly what the device-tree is 
> there for .
> Please implement proper interrupt maps in the device-tree and 
> get rid of
> those tables.

I will get rid of those tables.  I can see that in file
 arch/powerpc/platforms/85xx/mpc85xx_ads.c (2.6.17-rc4), there is
a similar table. Should it be removed in future :)?

> 
> > +static void __init mpc7448_hpc2_map_io(void)
> > +{
> > +	/* PCI IO  mapping */
> > +	io_block_mapping(MPC7448_HPC2_PCI_IO_BASE_VIRT,
> > +			 MPC7448_HPC2_PCI_IO_BASE_PHYS, 
> 0x00800000, _PAGE_IO);
> > +	/* Tsi108 CSR mapping */
> > +	io_block_mapping(TSI108_CSR_ADDR_VIRT, TSI108_CSR_ADDR_PHYS,
> > +			 0x100000, _PAGE_IO);
> > +
> > +	/* PCI Config mapping */
> > +	io_block_mapping(MPC7448_HPC2_PCI_CFG_BASE_VIRT,
> > +			 MPC7448_HPC2_PCI_CFG_BASE_PHYS,
> > +			 MPC7448_HPC2_PCI_CFG_SIZE, _PAGE_IO);
> > +
> > +	tsi108_pci_cfg_base = MPC7448_HPC2_PCI_CFG_BASE_VIRT;
> > +	/* NVRAM mapping */
> > +	io_block_mapping(MPC7448_HPC2_NVRAM_BASE_ADDR,
> > +			 MPC7448_HPC2_NVRAM_BASE_ADDR, 
> MPC7448_HPC2_NVRAM_SIZE,
> > +			 _PAGE_IO);
> > +}
> 
> io_block_mapping is bad ! see endless discussions in the archives of
> why ... Use ioremap.

OK!

> 
> > +static int __init mpc7448_hpc2_probe(void)
> > +{
> > +	/* We always match for now, eventually we should look 
> at the flat
> > +	   dev tree to ensure this is the board we are suppose to run on
> > +	 */
> > +	return 1;
> > +}
> 
> Yes, please do so, we will not accept a board that does the above :)

I just do the same thing as 85xx :).

> 
> > +extern int tsi108_direct_write_config(struct pci_bus *bus, 
> unsigned int devfn,
> > +				      int offset, int len, u32 val);
> > +extern int tsi108_direct_read_config(struct pci_bus *bus, 
> unsigned int devfn,
> > +				     int offset, int len, u32 * val);
> >
> > +void tsi108_clear_pci_error(u32 pci_cfg_base);
> > +
> > +extern int
> > +tsi108_read_config(int bus, unsigned int devfn, int 
> offset, int len, u32 * val);
> > +#ifdef CONFIG_PCI
> > +static struct pci_ops direct_pci_ops = {
> > +	tsi108_direct_read_config,
> > +	tsi108_direct_write_config
> > +};
> 
> That sounds bogus. You should instead have a tsi108_pci.c file that
> contains all of the functions _and_ the pci_ops structure 
> (with a better
> name please) and exports some kind of setup_tsi108_pci(device_node *).
> 

OK!

> > +void tsi108_clear_pci_cfg_error(void)
> > +{
> > +	tsi108_clear_pci_error(MPC7448_HPC2_PCI_CFG_BASE_PHYS);
> > +}
> > +
> > +int __init add_bridge(struct device_node *dev)
> > +{
> > +	int len;
> > +	struct pci_controller *hose;
> > +	struct resource rsrc;
> > +	int *bus_range;
> > +	int primary = 0, has_address = 0;
> > +
> > +	DBG("TSI_PCI: %s tsi108_pci_cfg_base=0x%x\n", __FUNCTION__,
> > +	    tsi108_pci_cfg_base);
> > +
> > +	/* Fetch host bridge registers address */
> > +	has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
> > +
> > +	/* Get bus range if any */
> > +	bus_range = (int *)get_property(dev, "bus-range", &len);
> > +	if (bus_range == NULL || len < 2 * sizeof(int)) {
> > +		printk(KERN_WARNING "Can't get bus-range for %s, assume"
> > +		       " bus 0\n", dev->full_name);
> > +	}
> > +
> > +	hose = pcibios_alloc_controller();
> > +
> > +	if (!hose) {
> > +		printk("PCI Host bridge init failed\n");
> > +		return -ENOMEM;
> > +	}
> > +	hose->arch_data = dev;
> > +	hose->set_cfg_type = 1;
> > +
> > +	hose->first_busno = bus_range ? bus_range[0] : 0;
> > +	hose->last_busno = bus_range ? bus_range[1] : 0xff;
> > +
> > +	(hose)->ops = &direct_pci_ops;
> > +
> > +	printk(KERN_INFO "Found tsi108 PCI host bridge at 0x%08lx. "
> > +	       "Firmware bus number: %d->%d\n",
> > +	       rsrc.start, hose->first_busno, hose->last_busno);
> > +
> > +	/* Interpret the "ranges" property */
> > +	/* This also maps the I/O region and sets isa_io/mem_base */
> > +	pci_process_bridge_OF_ranges(hose, dev, primary);
> > +	return 0;
> > +
> > +}
> 
> We need a generic add_bridge that goes through PCI bridges and
> instanciate based on their type as provided by the device-tree. You
> should try to work in that direction...
OK!

 
 

^ permalink raw reply

* RE: [PATCH/2.6.17-rc4 2/10] Powerpc: Add Tundra Semiconductor tsi 108  macro define
From: Zang Roy-r61911 @ 2006-05-18  7:16 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: linuxppc-dev list, Yang Xin-Xin-r48390, Paul Mackerras,
	Alexandre.Bounine

> 
> > +/* Error codes */
> > +
> > +#define MPIC_OK		0
> > +#define MPIC_ERROR	1
> 
> What the heck are these for ?
> 
> Ben.
I will remove them.
Roy
> 
> 

^ permalink raw reply

* RE: [PATCH/2.6.17-rc4 1/10] Powerpc: Add general support for mpc7 448h pc2 (Taiga) platform
From: Benjamin Herrenschmidt @ 2006-05-18  7:19 UTC (permalink / raw)
  To: Zang Roy-r61911
  Cc: linuxppc-dev list, Paul Mackerras, Alexandre.Bounine,
	Yang Xin-Xin-r48390
In-Reply-To: <9FCDBA58F226D911B202000BDBAD4673062C05CC@zch01exm40.ap.freescale.net>


> Well , should I register this data to a platform device or the Ethernet 
> driver get the information from device-tree directly?

You probably want to define a bus structure (/soc might work even if
it's not strictly a /soc) or use of_platform device to link a
device-tree node to a driver instance. You can create as many nodes as
you have devices and provide all the additional infos you need including
interrupt routing via the device-tree.

Ben.

^ permalink raw reply

* [PATCH] powerpc: the iSeries vio lan driver changed device type
From: Stephen Rothwell @ 2006-05-18  7:21 UTC (permalink / raw)
  To: paulus; +Cc: ppc-dev

So the IOMMU table building code needs to match.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---

 arch/powerpc/kernel/vio.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

This patch is relative to the four iSeries vio patches I sent on Moday.
-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

af5dbd2219106b6ce52b075485fca3c2a08cec58
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index ac5c7bf..b559cbd 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -71,7 +71,7 @@ static struct iommu_table *vio_build_iom
 {
 #ifdef CONFIG_PPC_ISERIES
 	if (firmware_has_feature(FW_FEATURE_ISERIES)) {
-		if (strcmp(dev->type, "vlan") == 0)
+		if (strcmp(dev->type, "network") == 0)
 			return &veth_iommu_table;
 		return &vio_iommu_table;
 	} else
-- 
1.3.1.ge923

^ permalink raw reply related

* RE: [PATCH/2.6.17-rc4 1/10] Powerpc: Add general support for mpc7 448h pc2 (Taiga) platform
From: Benjamin Herrenschmidt @ 2006-05-18  7:22 UTC (permalink / raw)
  To: Zang Roy-r61911
  Cc: linuxppc-dev list, Yang Xin-Xin-r48390, Paul Mackerras,
	Alexandre.Bounine
In-Reply-To: <9FCDBA58F226D911B202000BDBAD4673062C064E@zch01exm40.ap.freescale.net>

On Thu, 2006-05-18 at 15:12 +0800, Zang Roy-r61911 wrote:
> > I'm not repeating Kumar's comments about that CONFIG_7xxx 
> > thing and that
> > 7xxx/ directory, it should all go.
> > 
> 
> Should I move my code to embedded6xx?

Probably for now yes.

> I will get rid of those tables.  I can see that in file
>  arch/powerpc/platforms/85xx/mpc85xx_ads.c (2.6.17-rc4), there is
> a similar table. Should it be removed in future :)?

Yes. And somebody beaten up for letting that stuff leak into
arch/powerpc :)

> > Yes, please do so, we will not accept a board that does the above :)
> 
> I just do the same thing as 85xx :).

Yes and I intend to LART Kumar seriously for that next time I meet
him :)

> > We need a generic add_bridge that goes through PCI bridges and
> > instanciate based on their type as provided by the device-tree. You
> > should try to work in that direction...

I suggest you also read my comments to Mark A. Greer as most of that
stuff overlaps... I wish I had more times to work myself on that but I'm
fairly overflowed at the moment...

Ben

^ permalink raw reply

* Re: snd-aoa status update / automatic driver loading
From: Eddy Petrişor @ 2006-05-18  7:25 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linuxppc-dev list, debian-powerpc
In-Reply-To: <1147860564.14395.6.camel@johannes>

T24gNS8xNy8wNiwgSm9oYW5uZXMgQmVyZyA8am9oYW5uZXNAc2lwc29sdXRpb25zLm5ldD4gd3Jv
dGU6Cj4gSGV5LAo+Cj4gQ3VycmVudGx5IHNuZC1hb2EgaXMga25vd24gdG8gd29yayBvbiB0aGUg
Zm9sbG93aW5nIG1hY2hpbmVzOgo+ICogUG93ZXJCb29rNSw4Cj4gKiBQb3dlckJvb2s1LDcKPiAq
IFBvd2VyTWFjOCwxCj4gKiBQb3dlck1hYzgsMgo+ICogMTciIE9jdG9iZXIgMjAwNSBQb3dlckJv
b2sgKGRvbid0IGtub3cgdGhlIG51bWJlcikKPiAqIFBvd2VyTWFjMTEsMgo+ICogUG93ZXJCb29r
Niw4Cj4gYW5kIG15Cj4gKiBQb3dlckJvb2s1LDYKCkFueSBjaGFuY2UgZm9yIDUsMiA/IFdoYXQg
aXMgbmVlZGVkIGZvciBpdD8gQ29kZWMgb25seT8KCi0tIApSZWdhcmRzLApFZGR5UAo9PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KIkltYWdpbmF0aW9uIGlzIG1v
cmUgaW1wb3J0YW50IHRoYW4ga25vd2xlZGdlIiBBLkVpbnN0ZWluCg==

^ permalink raw reply

* mm/rmap.c incompatible with ppc/kernel/dma-mapping.c?
From: Gerhard Pircher @ 2006-05-18  8:03 UTC (permalink / raw)
  To: linuxppc-dev

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="us-ascii", Size: 2037 bytes --]

Hi,

Since I managed to compile in not cache coherent DMA support in the AmigaOne
Linux kernel, the system crashes whenever I try to view a movie for example
in totem or VLC. The following log snipped is the only debug information I
could extract, because most of the time the system hard locks  and can only
be reactivated with a hardware reset.

May 12 00:04:17 localhost kernel: kernel BUG in page_add_file_rmap at
mm/rmap.c:387!
May 12 00:04:17 localhost kernel: Oops: Exception in kernel mode, sig: 5
[#1]
May 12 00:04:17 localhost kernel: NIP: C004968C LR: C0044CB8 SP: D2C77E20
REGS: d2c77d70 TRAP: 0700    Not tainted
May 12 00:04:17 localhost kernel: MSR: 00029032 EE: 1 PR: 0 FP: 0 ME: 1
IR/DR: 11
May 12 00:04:17 localhost kernel: TASK = d4918000[2900] 'totem' THREAD:
d2c76000Last syscall: 246
May 12 00:04:17 localhost kernel: GPR00: 00000001 D2C77E20 D4918000 C0D02720
00000000 D27B02A0 02000000 D4FE4400
May 12 00:04:17 localhost kernel: GPR08: C03D0000 38139785 00000000 38139785
24048444 10054698 00000000 10171158
May 12 00:04:17 localhost kernel: GPR16: 00000000 00000000 0EADDD7C 00015F90
000001F6 315B1970 33CA8000 D4D6BBA0
May 12 00:04:17 localhost kernel: GPR24: 00000000 00000000 02000000 D4B7D33C
33CA8000 C0D02720 38139785 D2888220
May 12 00:04:17 localhost kernel: NIP [c004968c] page_add_file_rmap+0x8/0x78
May 12 00:04:17 localhost kernel: LR [c0044cb8] do_no_page+0x1cc/0x37c
May 12 00:04:17 localhost kernel: Call trace:
May 12 00:04:17 localhost kernel:  [c004503c] handle_mm_fault+0xf4/0x174
May 12 00:04:17 localhost kernel:  [c0012100] do_page_fault+0x140/0x398
May 12 00:04:17 localhost kernel:  [c0008178] handle_page_fault+0xc/0x80

I tested this with kernel 2.6.8 and 2.6.14.2. Both show the same behavior.
Is this a known problem on PPC systems with desktop CPUs? What about others 
PPC boards that have 6xx/7xxx cpus and not cache coherent northbridges?

Thanks in advance!

regards,

Gerhard

-- 
Echte DSL-Flatrate dauerhaft für 0,- Euro*!
"Feel free" mit GMX DSL! http://www.gmx.net/de/go/dsl

^ permalink raw reply

* [PATCH] powerpc: Add of_parse_dma_window()
From: Jeremy Kerr @ 2006-05-18  8:05 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1147933975.484840.681634501201.qpush@pokey>

Add a function for generic parsing of dma-window properties (ie,
ibm,dma-window and ibm,my-dma-window) of pci and virtual device nodes.

This function will also be used by cell.

Signed-off-by: Jeremy Kerr <jk@ozlabs.org>

---
Update: don't EXPORT_SYMBOL - dma-window won't be needed by a module

 arch/powerpc/kernel/prom_parse.c |   22 ++++++++++++++++++++++
 include/asm-powerpc/prom.h       |    6 ++++++
 2 files changed, 28 insertions(+)

Index: linux-2.6/arch/powerpc/kernel/prom_parse.c
===================================================================
--- linux-2.6.orig/arch/powerpc/kernel/prom_parse.c
+++ linux-2.6/arch/powerpc/kernel/prom_parse.c
@@ -548,3 +548,25 @@ int of_pci_address_to_resource(struct de
 	return __of_address_to_resource(dev, addrp, size, flags, r);
 }
 EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
+
+void of_parse_dma_window(struct device_node *dn, unsigned char *dma_window_prop,
+		unsigned long *busno, unsigned long *phys, unsigned long *size)
+{
+	u32 *dma_window, cells;
+	unsigned char *prop;
+
+	dma_window = (u32 *)dma_window_prop;
+
+	/* busno is always one cell */
+	*busno = *(dma_window++);
+
+	prop = get_property(dn, "ibm,#dma-address-cells", NULL);
+	cells = prop ? *(u32 *)prop : prom_n_addr_cells(dn);
+	*phys = of_read_addr(dma_window, cells);
+
+	dma_window += cells;
+
+	prop = get_property(dn, "ibm,#dma-size-cells", NULL);
+	cells = prop ? *(u32 *)prop : prom_n_size_cells(dn);
+	*size = of_read_addr(dma_window, cells);
+}
Index: linux-2.6/include/asm-powerpc/prom.h
===================================================================
--- linux-2.6.orig/include/asm-powerpc/prom.h
+++ linux-2.6/include/asm-powerpc/prom.h
@@ -230,6 +230,12 @@ extern int of_address_to_resource(struct
 extern int of_pci_address_to_resource(struct device_node *dev, int bar,
 				      struct resource *r);
 
+/* Parse the ibm,dma-window property of an OF node into the busno, phys and
+ * size parameters.
+ */
+void of_parse_dma_window(struct device_node *dn, unsigned char *dma_window_prop,
+		unsigned long *busno, unsigned long *phys, unsigned long *size);
+
 extern void kdump_move_device_tree(void);
 
 #endif /* __KERNEL__ */

^ permalink raw reply

* RE: [PATCH/2.6.17-rc4 1/10] Powerpc: Add general support for mpc7 448h pc2 (Taiga) platform
From: Zang Roy-r61911 @ 2006-05-18  8:05 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: linuxppc-dev list, Paul Mackerras, Alexandre.Bounine,
	Yang Xin-Xin-r48390

> 
> > The tsi108 serial port is not a sub node of "soc".  well, any way,
> > I can try soc!
> 
> What is it ? Where is it ? "soc" is a bit of a generic name for
> something in the device-tree in fact... we might want to 
> define a way to
> expose any bus via some kind of soc mecanism even if it's not a root
> bus.
> 
> 
Should I just use add_legacy_soc_port() instead of a new function
add_legacy_tsi_port()?
--- arch/powerpc/kernel/legacy_serial.c.orig	Thu May 18 15:35:19 2006
+++ arch/powerpc/kernel/legacy_serial.c	Thu May 18 15:50:38 2006
@@ -302,6 +302,17 @@ void __init find_legacy_serial_ports(voi
 		of_node_put(isa);
 	}
 
+	/* First fill our array with tsi-bridge ports */
+	for (np = NULL; (np = of_find_compatible_node(np, "serial", "ns16550")) != NULL;) {
+		struct device_node *tsi = of_get_parent(np);
+		if (tsi && !strcmp(tsi->type, "tsi-bridge")) {
+			index = add_legacy_soc_port(np, np);
+			if (index >= 0 && np == stdout)
+				legacy_serial_console = index;
+		}
+		of_node_put(tsi);
+	}
+	
 #ifdef CONFIG_PCI
 	/* Next, try to locate PCI ports */
 	for (np = NULL; (np = of_find_all_nodes(np));) 

^ permalink raw reply

* [PATCH] powerpc: pseries: Use generic dma-window parsing function
From: Jeremy Kerr @ 2006-05-18  8:06 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1147933975.516311.850847048300.qpush@pokey>

Change the pseries iommu init code to use the new of_parse_dma_window()
to parse the ibm,dma-window and ibm,my-dma-window properties of pci and
virtual device nodes.

Also, clean up vio_build_iommu_table() a little.

Tested on pseries, with both vio and pci devices.

Signed-off-by: Jeremy Kerr <jk@ozlabs.org>

---
Update: rebase to current powerpc head: vio driver has been merged

 arch/powerpc/kernel/vio.c              |   36 ++++++++++++---------------------
 arch/powerpc/platforms/pseries/iommu.c |   29 +++++++++-----------------
 2 files changed, 24 insertions(+), 41 deletions(-)

Index: linux-2.6/arch/powerpc/platforms/pseries/iommu.c
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/pseries/iommu.c
+++ linux-2.6/arch/powerpc/platforms/pseries/iommu.c
@@ -281,30 +281,22 @@ static void iommu_table_setparms(struct 
  * iommu_table_setparms_lpar
  *
  * Function: On pSeries LPAR systems, return TCE table info, given a pci bus.
- *
- * ToDo: properly interpret the ibm,dma-window property.  The definition is:
- *	logical-bus-number	(1 word)
- *	phys-address		(#address-cells words)
- *	size			(#cell-size words)
- *
- * Currently we hard code these sizes (more or less).
  */
 static void iommu_table_setparms_lpar(struct pci_controller *phb,
 				      struct device_node *dn,
 				      struct iommu_table *tbl,
-				      unsigned int *dma_window)
+				      unsigned char *dma_window)
 {
+	unsigned long offset, size;
+
 	tbl->it_busno  = PCI_DN(dn)->bussubno;
+	of_parse_dma_window(dn, dma_window, &tbl->it_index, &offset, &size);
 
-	/* TODO: Parse field size properties properly. */
-	tbl->it_size   = (((unsigned long)dma_window[4] << 32) |
-			   (unsigned long)dma_window[5]) >> PAGE_SHIFT;
-	tbl->it_offset = (((unsigned long)dma_window[2] << 32) |
-			   (unsigned long)dma_window[3]) >> PAGE_SHIFT;
 	tbl->it_base   = 0;
-	tbl->it_index  = dma_window[0];
 	tbl->it_blocksize  = 16;
 	tbl->it_type = TCE_PCI;
+	tbl->it_offset = offset >> PAGE_SHIFT;
+	tbl->it_size = size >> PAGE_SHIFT;
 }
 
 static void iommu_bus_setup_pSeries(struct pci_bus *bus)
@@ -396,7 +388,7 @@ static void iommu_bus_setup_pSeriesLP(st
 	struct iommu_table *tbl;
 	struct device_node *dn, *pdn;
 	struct pci_dn *ppci;
-	unsigned int *dma_window = NULL;
+	unsigned char *dma_window = NULL;
 
 	DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self);
 
@@ -404,7 +396,7 @@ static void iommu_bus_setup_pSeriesLP(st
 
 	/* Find nearest ibm,dma-window, walking up the device tree */
 	for (pdn = dn; pdn != NULL; pdn = pdn->parent) {
-		dma_window = (unsigned int *)get_property(pdn, "ibm,dma-window", NULL);
+		dma_window = get_property(pdn, "ibm,dma-window", NULL);
 		if (dma_window != NULL)
 			break;
 	}
@@ -498,7 +490,7 @@ static void iommu_dev_setup_pSeriesLP(st
 {
 	struct device_node *pdn, *dn;
 	struct iommu_table *tbl;
-	int *dma_window = NULL;
+	unsigned char *dma_window = NULL;
 	struct pci_dn *pci;
 
 	DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev));
@@ -513,8 +505,7 @@ static void iommu_dev_setup_pSeriesLP(st
 
 	for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table;
 	     pdn = pdn->parent) {
-		dma_window = (unsigned int *)
-			get_property(pdn, "ibm,dma-window", NULL);
+		dma_window = get_property(pdn, "ibm,dma-window", NULL);
 		if (dma_window)
 			break;
 	}
Index: linux-2.6/arch/powerpc/kernel/vio.c
===================================================================
--- linux-2.6.orig/arch/powerpc/kernel/vio.c
+++ linux-2.6/arch/powerpc/kernel/vio.c
@@ -77,36 +77,28 @@ static struct iommu_table *vio_build_iom
 	} else
 #endif
 	{
-		unsigned int *dma_window;
-		struct iommu_table *newTceTable;
-		unsigned long offset;
-		int dma_window_property_size;
-
-		dma_window = (unsigned int *)get_property(
-				dev->dev.platform_data, "ibm,my-dma-window",
-				&dma_window_property_size);
+		unsigned char *dma_window;
+		struct iommu_table *tbl;
+		unsigned long offset, size;
+
+		dma_window = get_property(dev->dev.platform_data,
+				"ibm,my-dma-window", NULL);
 		if (!dma_window)
 			return NULL;
 
-		newTceTable = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
+		tbl = kmalloc(sizeof(*tbl), GFP_KERNEL);
 
-		/*
-		 * There should be some code to extract the phys-encoded
-		 * offset using prom_n_addr_cells(). However, according to
-		 * a comment on earlier versions, it's always zero, so we
-		 * don't bother
-		 */
-		offset = dma_window[1] >>  PAGE_SHIFT;
+		of_parse_dma_window(dev->dev.platform_data, dma_window,
+				&tbl->it_index, &offset, &size);
 
 		/* TCE table size - measured in tce entries */
-		newTceTable->it_size = dma_window[4] >> PAGE_SHIFT;
+		tbl->it_size = size >> PAGE_SHIFT;
 		/* offset for VIO should always be 0 */
-		newTceTable->it_offset = offset;
-		newTceTable->it_busno = 0;
-		newTceTable->it_index = (unsigned long)dma_window[0];
-		newTceTable->it_type = TCE_VB;
+		tbl->it_offset = offset >> PAGE_SHIFT;
+		tbl->it_busno = 0;
+		tbl->it_type = TCE_VB;
 
-		return iommu_init_table(newTceTable);
+		return iommu_init_table(tbl);
 	}
 }
 

^ permalink raw reply

* Re: snd-aoa status update / automatic driver loading
From: Rene Rebe @ 2006-05-18  8:56 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Johannes Berg
In-Reply-To: <1147860564.14395.6.camel@johannes>

Hi,

thanks for the update. Is record/capture supost to work now?

Yours,

=2D-=20
Ren=E9 Rebe - Rubensstr. 64 - 12157 Berlin (Europe / Germany)
            http://exactcode.de | http://t2-project.org | http://rebe.name
            +49 (0)30 / 255 897 45

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox