Add PCI support for TQM834x Boards

Kumar Gala kumar.gala at freescale.com
Tue Oct 25 01:20:24 EST 2005


Two comments:
* The comment in mpc83xx_setup_hose() may not be 100% correct (see  
inline)
* Updating of pci_ids.h should be done via http:// 
pciids.sourceforge.net/.  I can handle doing this for 834x if you  
want me to.

- kumar

On Oct 22, 2005, at 5:36 PM, Wolfgang Denk wrote:

> The following patch (against latest 2.6 tree) adds  PCI  support  for
> the TQ Systems TQM834x Boards. Verified on TQM8349L.
>
> Note: for TQM834x board support actually to compile and  work,  three
> previously submitted patches are required. See postings:
>
> Sat, 22 Oct 2005   [PATCH 2.6] Add generic support for DS1377 RTC
> Sat, 22 Oct 2005   [PATCH] Cleanup mpc83xx_restart() code
> Sat, 22 Oct 2005   [Patch] Add support for TQM834x Boards
>
>
> ---
> PCI support for the TQM834x boards.
>
> Signed-off-by: Rafal Jaworowski <raj at semihalf.com>
> Signed-off-by: Wolfgang Denk <wd at denx.de>
>
>
> ---
> commit 5108607a56824e025fda5efe9f68ff310545adb9
> tree 4e3b67d3e9f4188f69de9715da68781fb7eebc84
> parent 0af38510e829b6d397128269fe194898924ab534
> author Rafal Jaworowski <raj at pollux.denx.de> Wed, 19 Oct 2005  
> 12:32:42 +0200
> committer Rafal Jaworowski <raj at pollux.denx.de> Wed, 19 Oct 2005  
> 12:32:42 +0200
>
>  arch/ppc/platforms/83xx/mpc834x_sys.c |    7 +++
>  arch/ppc/platforms/83xx/tqm834x.c     |   37 ++++++++++-----
>  arch/ppc/platforms/83xx/tqm834x.h     |   10 ++--
>  arch/ppc/syslib/ppc83xx_pci.h         |   41 +++++++++++++++++
>  arch/ppc/syslib/ppc83xx_setup.c       |   79 ++++++++++++++++++++++ 
> ++++++-----
>  arch/ppc/syslib/ppc83xx_setup.h       |    1
>  include/linux/pci_ids.h               |   10 ++++
>  7 files changed, 157 insertions(+), 28 deletions(-)
>
> diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/ 
> platforms/83xx/mpc834x_sys.c
> --- a/arch/ppc/platforms/83xx/mpc834x_sys.c
> +++ b/arch/ppc/platforms/83xx/mpc834x_sys.c
> @@ -364,6 +364,13 @@ platform_init(unsigned long r3, unsigned
>      ppc_md.progress = gen550_progress;
>  #endif    /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
>
> +#ifdef CONFIG_PCI
> +    ppc_md.pci_swizzle = common_swizzle;
> +    ppc_md.pci_map_irq = mpc83xx_map_irq;
> +    ppc_md.pci_exclude_device = mpc83xx_exclude_device;
> +    ppc_md.pcibios_fixup = mpc834x_pcibios_fixup;
> +#endif /* CONFIG_PCI */
> +
>      if (ppc_md.progress)
>          ppc_md.progress("mpc834x_sys_init(): exit", 0);
>
> diff --git a/arch/ppc/platforms/83xx/tqm834x.c b/arch/ppc/platforms/ 
> 83xx/tqm834x.c
> --- a/arch/ppc/platforms/83xx/tqm834x.c
> +++ b/arch/ppc/platforms/83xx/tqm834x.c
> @@ -61,28 +61,33 @@ unsigned char __res[sizeof (bd_t)];
>
>  #ifdef CONFIG_PCI
>  int
> -mpc83xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned  
> char pin)
> +tqm834x_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned  
> char pin)
>  {
> +    int irq;
>      static char pci_irq_table[][4] =
>          /*
>           *      PCI IDSEL/INTPIN->INTLINE
>           *       A      B      C      D
>           */
>      {
> -        {PIRQA, PIRQB,  PIRQC,  PIRQD}, /* idsel 0x11 */
> -        {PIRQC, PIRQD,  PIRQA,  PIRQB}, /* idsel 0x12 */
> -        {PIRQD, PIRQA,  PIRQB,  PIRQC}  /* idsel 0x13 */
> +        {PIRQA, PIRQB,  PIRQC,  PIRQD}, /* idsel 0x1c */
> +        {PIRQB, PIRQC,  PIRQD,  PIRQA}, /* idsel 0x1d */
> +        {PIRQC, PIRQD,  0,  0}      /* idsel 0x1e */
>      };
>
> -    const long min_idsel = 0x11, max_idsel = 0x13, irqs_per_slot = 4;
> -    return PCI_IRQ_TABLE_LOOKUP;
> +    const long min_idsel = 0x1c, max_idsel = 0x1e, irqs_per_slot = 4;
> +    irq = PCI_IRQ_TABLE_LOOKUP;
> +    if (!irq)
> +        irq = 0;
> +    return (irq);
>  }
>
>  int
> -mpc83xx_exclude_device(u_char bus, u_char devfn)
> +tqm834x_exclude_device(u_char bus, u_char devfn)
>  {
>      return PCIBIOS_SUCCESSFUL;
>  }
> +
>  #endif /* CONFIG_PCI */
>
>  /*  
> ********************************************************************** 
> **
> @@ -190,19 +195,20 @@ tqm834x_init_IRQ(void)
>      u8 senses[8] = {
>          0,            /* EXT 0 */
>          0,            /* EXT 1 */
> -        0,            /* EXT 2 */
> -        0,            /* EXT 3 */
>  #ifdef CONFIG_PCI
> -        IRQ_SENSE_LEVEL,    /* EXT 4 */
> +        IRQ_SENSE_LEVEL,    /* EXT 2 */
> +        IRQ_SENSE_LEVEL,    /* EXT 3 */
> +        0,            /* EXT 4 */
>          IRQ_SENSE_LEVEL,    /* EXT 5 */
>          IRQ_SENSE_LEVEL,    /* EXT 6 */
> -        IRQ_SENSE_LEVEL,    /* EXT 7 */
>  #else
> +        0,            /* EXT 2 */
> +        0,            /* EXT 3 */
>          0,            /* EXT 4 */
>          0,            /* EXT 5 */
>          0,            /* EXT 6 */
> -        0,            /* EXT 7 */
>  #endif
> +        IRQ_SENSE_LEVEL,    /* EXT 7 */
>      };
>
>      ipic_init(binfo->bi_immr_base + 0x00700, 0,  
> MPC83xx_IPIC_IRQ_OFFSET, senses, 8);
> @@ -329,6 +335,13 @@ platform_init(unsigned long r3, unsigned
>      ppc_md.progress = gen550_progress;
>  #endif    /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
>
> +#ifdef CONFIG_PCI
> +    ppc_md.pci_swizzle = common_swizzle;
> +    ppc_md.pci_map_irq = tqm834x_map_irq;
> +    ppc_md.pci_exclude_device = tqm834x_exclude_device;
> +    ppc_md.pcibios_fixup = mpc834x_pcibios_fixup;
> +#endif /* CONFIG_PCI */
> +
>      if (ppc_md.progress)
>          ppc_md.progress("tqm834x_init(): exit", 0);
>
> diff --git a/arch/ppc/platforms/83xx/tqm834x.h b/arch/ppc/platforms/ 
> 83xx/tqm834x.h
> --- a/arch/ppc/platforms/83xx/tqm834x.h
> +++ b/arch/ppc/platforms/83xx/tqm834x.h
> @@ -24,15 +24,15 @@
>
>  #define VIRT_IMMRBAR        ((uint)0xfe000000)
>
> -#define PIRQA    MPC83xx_IRQ_EXT4
> -#define PIRQB    MPC83xx_IRQ_EXT5
> +#define PIRQA    MPC83xx_IRQ_EXT2
> +#define PIRQB    MPC83xx_IRQ_EXT3
>  #define PIRQC    MPC83xx_IRQ_EXT6
> -#define PIRQD    MPC83xx_IRQ_EXT7
> +#define PIRQD    MPC83xx_IRQ_EXT5
>
>  #define MPC83xx_PCI1_LOWER_IO    0x00000000
>  #define MPC83xx_PCI1_UPPER_IO    0x00ffffff
> -#define MPC83xx_PCI1_LOWER_MEM    0x80000000
> -#define MPC83xx_PCI1_UPPER_MEM    0x9fffffff
> +#define MPC83xx_PCI1_LOWER_MEM    0xc0000000
> +#define MPC83xx_PCI1_UPPER_MEM    0xdfffffff
>  #define MPC83xx_PCI1_IO_BASE    0xe2000000
>  #define MPC83xx_PCI1_MEM_OFFSET    0x00000000
>  #define MPC83xx_PCI1_IO_SIZE    0x01000000
> diff --git a/arch/ppc/syslib/ppc83xx_pci.h b/arch/ppc/syslib/ 
> ppc83xx_pci.h
> --- a/arch/ppc/syslib/ppc83xx_pci.h
> +++ b/arch/ppc/syslib/ppc83xx_pci.h
> @@ -25,6 +25,47 @@ typedef struct immr_clk {
>      u32 sccr; /* system clock control Register  */
>      u8 res0[0xF4];
>  } immr_clk_t;
> +#define SPMR_LBIUCM  0x80000000 /* LBIUCM  */
> +#define SPMR_DDRCM   0x40000000 /* DDRCM  */
> +#define SPMR_SVCOD   0x30000000 /* SVCOD  */
> +#define SPMR_SPMF    0x0F000000 /* SPMF  */
> +#define SPMR_CKID    0x00800000 /* CKID  */
> +#define SPMR_CKID_SHIFT 23
> +#define SPMR_COREPLL 0x007F0000 /* COREPLL  */
> +#define SPMR_CEVCOD  0x000000C0 /* CEVCOD  */
> +#define SPMR_CEPDF   0x00000020 /* CEPDF  */
> +#define SPMR_CEPMF   0x0000001F /* CEPMF  */
> +
> +#define OCCR_PCICOE0 0x80000000 /* PCICOE0  */
> +#define OCCR_PCICOE1 0x40000000 /* PCICOE1  */
> +#define OCCR_PCICOE2 0x20000000 /* PCICOE2  */
> +#define OCCR_PCICOE3 0x10000000 /* PCICOE3  */
> +#define OCCR_PCICOE4 0x08000000 /* PCICOE4  */
> +#define OCCR_PCICOE5 0x04000000 /* PCICOE5  */
> +#define OCCR_PCICOE6 0x02000000 /* PCICOE6  */
> +#define OCCR_PCICOE7 0x01000000 /* PCICOE7  */
> +#define OCCR_PCICD0  0x00800000 /* PCICD0  */
> +#define OCCR_PCICD1  0x00400000 /* PCICD1  */
> +#define OCCR_PCICD2  0x00200000 /* PCICD2  */
> +#define OCCR_PCICD3  0x00100000 /* PCICD3  */
> +#define OCCR_PCICD4  0x00080000 /* PCICD4  */
> +#define OCCR_PCICD5  0x00040000 /* PCICD5  */
> +#define OCCR_PCICD6  0x00020000 /* PCICD6  */
> +#define OCCR_PCICD7  0x00010000 /* PCICD7  */
> +#define OCCR_PCI1CR  0x00000002 /* PCI1CR  */
> +#define OCCR_PCI2CR  0x00000001 /* PCI2CR  */
> +
> +#define SCCR_TSEC1CM  0xc0000000 /* TSEC1CM  */
> +#define SCCR_TSEC1CM_SHIFT 30
> +#define SCCR_TSEC2CM  0x30000000 /* TSEC2CM  */
> +#define SCCR_TSEC2CM_SHIFT 28
> +#define SCCR_ENCCM    0x03000000 /* ENCCM  */
> +#define SCCR_ENCCM_SHIFT 24
> +#define SCCR_USBMPHCM 0x00c00000 /* USBMPHCM  */
> +#define SCCR_USBMPHCM_SHIFT 22
> +#define SCCR_USBDRCM  0x00300000 /* USBDRCM  */
> +#define SCCR_USBDRCM_SHIFT 20
> +#define SCCR_PCICM    0x00010000 /* PCICM  */
>
>  /*
>   * Sequencer
> diff --git a/arch/ppc/syslib/ppc83xx_setup.c b/arch/ppc/syslib/ 
> ppc83xx_setup.c
> --- a/arch/ppc/syslib/ppc83xx_setup.c
> +++ b/arch/ppc/syslib/ppc83xx_setup.c
> @@ -221,6 +221,7 @@ mpc83xx_setup_pci1(struct pci_controller
>      iounmap(ios);
>  }
>
> +#ifdef CONFIG_MPC83xx_PCI2
>  void __init
>  mpc83xx_setup_pci2(struct pci_controller *hose)
>  {
> @@ -278,8 +279,11 @@ mpc83xx_setup_pci2(struct pci_controller
>      iounmap(pci_ctrl);
>      iounmap(ios);
>  }
> +#endif
>
>  /*
> + * NOTICE for the MPC83xx SYS Freescale evaluation board:
> + *
>   * PCI buses can be enabled only if SYS board combinates with PIB
>   * (Platform IO Board) board which provide 3 PCI slots. There is 2  
> PCI buses
>   * and 3 PCI slots, so people must configure the routes between  
> them before
> @@ -287,10 +291,6 @@ mpc83xx_setup_pci2(struct pci_controller
>   * can be accessed via I2C bus 2 and are configured by firmware.  
> Refer to
>   * Freescale to get more information about firmware configuration.
>   */
> -
> -extern int mpc83xx_exclude_device(u_char bus, u_char devfn);
> -extern int mpc83xx_map_irq(struct pci_dev *dev, unsigned char idsel,
> -        unsigned char pin);
>  void __init
>  mpc83xx_setup_hose(void)
>  {
> @@ -306,22 +306,46 @@ mpc83xx_setup_hose(void)
>              sizeof(immr_clk_t));
>
>      /*
> -     * Configure PCI controller and PCI_CLK_OUTPUT both in 66M mode
> +     * Configure PCI_CLK_OUTPUT
>       */
>      val32 = clk->occr;
>      udelay(2000);
> -    clk->occr = 0xff000000;
> +
> +#ifdef CONFIG_TQM834x

Is the following comment 100% correct?  I'm not sure I follow the  
STK85xx reference.

> +    /*
> +     * WARNING! only PCI_CLK_OUTPUT1 is enabled for the TQM834x as  
> this is
> +     * the one line actually used for clocking all external PCI  
> devices in
> +     * current setup of the STK85xx.  Enabling other  
> PCI_CLK_OUTPUT lines
> +     * may lead to board's hang for unknown reasons - particularly
> +     * PCI_CLK_OUTPUT6 and PCI_CLK_OUTPUT7 are known to hang the  
> board;
> +     * this issue is under investigation (18 oct 05)
> +     */
> +    val32 = OCCR_PCICOE1;
> +#else
> +    /* enable all PCI_CLK_OUTs */
> +    val32 = (OCCR_PCICOE0 | OCCR_PCICOE1 | OCCR_PCICOE2 |  
> OCCR_PCICOE3 \
> +         | OCCR_PCICOE4 | OCCR_PCICOE5 | OCCR_PCICOE6 |  
> OCCR_PCICOE7);
> +#endif
> +    /* set frequency of the PCI and clock outputs for external  
> devicesc
> +     * according to system clocking settings */
> +    if (clk->spmr & SPMR_CKID) {
> +        /* PCI Clock is 1/2 of CONFIG_83XX_CLKIN so need to set up  
> OCCR
> +         * fields accordingly */
> +        val32 |= (OCCR_PCI1CR | OCCR_PCI2CR);
> +
> +        val32 |= (OCCR_PCICD0 | OCCR_PCICD1 | OCCR_PCICD2 \
> +              | OCCR_PCICD3 | OCCR_PCICD4 | OCCR_PCICD5 \
> +              | OCCR_PCICD6 | OCCR_PCICD7);
> +    }
> +
> +    clk->occr = val32;
>      udelay(2000);
> -
>      iounmap(clk);
>
>      hose1 = pcibios_alloc_controller();
>      if(!hose1)
>          return;
>
> -    ppc_md.pci_swizzle = common_swizzle;
> -    ppc_md.pci_map_irq = mpc83xx_map_irq;
> -
>      hose1->bus_offset = 0;
>      hose1->first_busno = 0;
>      hose1->last_busno = 0xff;
> @@ -357,7 +381,6 @@ mpc83xx_setup_hose(void)
>              MPC83xx_PCI1_UPPER_MEM,
>              IORESOURCE_MEM, "PCI host bridge 1");
>
> -    ppc_md.pci_exclude_device = mpc83xx_exclude_device;
>      hose1->last_busno = pciauto_bus_scan(hose1, hose1->first_busno);
>
>  #ifdef CONFIG_MPC83xx_PCI2
> @@ -395,4 +418,38 @@ mpc83xx_setup_hose(void)
>      hose2->last_busno = pciauto_bus_scan(hose2, hose2->first_busno);
>  #endif /* CONFIG_MPC83xx_PCI2 */
>  }
> +
> +
> +void __init
> +mpc834x_pcibios_fixup(void)
> +{
> +    struct pci_dev *dev = NULL;
> +    unsigned int class;
> +    int i;
> +
> +    if ((dev = pci_find_device(PCI_VENDOR_ID_FREESCALE,
> +                   PCI_DEVICE_ID_FREESCALE_MPC8349E, NULL))) {
> +        class = dev->class >> 8;
> +        if (class == PCI_CLASS_BRIDGE_OTHER) {
> +            /*
> +             * at least rev 1.1 of the MPC8349E chip has the class
> +             * wrongly set in the host/PCI bridge config space
> +             * register; this leads to the host/PCI bridge being
> +             * treated as a regular client device, trying to assign
> +             * PCI resources to it etc.
> +             *
> +             */
> +            dev->class = (PCI_CLASS_BRIDGE_HOST << 8) & ~0xf;
> +
> +            /* for some odd reasons the host/PCI bridge behaves
> +             * like an agent device and would claim PCI mem/io/irq
> +             * resources, so we make these resources inactive (i.e.
> +             * the bridge will not claim resources from itself)
> +             */
> +            for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
> +                dev->resource[i].flags = IORESOURCE_UNSET;
> +        }
> +    }
> +
> +}
>  #endif /*CONFIG_PCI*/
> diff --git a/arch/ppc/syslib/ppc83xx_setup.h b/arch/ppc/syslib/ 
> ppc83xx_setup.h
> --- a/arch/ppc/syslib/ppc83xx_setup.h
> +++ b/arch/ppc/syslib/ppc83xx_setup.h
> @@ -36,6 +36,7 @@ extern void mpc83xx_restart(char *cmd);
>  extern void mpc83xx_power_off(void);
>  extern void mpc83xx_halt(void);
>  extern void mpc83xx_setup_hose(void) __init;
> +extern void mpc834x_pcibios_fixup(void);
>
>  /* PCI config */
>  #define PCI1_CFG_ADDR_OFFSET (0x8300)
> diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
> --- a/include/linux/pci_ids.h
> +++ b/include/linux/pci_ids.h
> @@ -2278,6 +2278,16 @@
>  #define PCI_VENDOR_ID_TDI               0x192E
>  #define PCI_DEVICE_ID_TDI_EHCI          0x0101
>
> +#define PCI_VENDOR_ID_FREESCALE            0x1957
> +#define PCI_DEVICE_ID_FREESCALE_MPC8349E    0x0080
> +#define PCI_DEVICE_ID_FREESCALE_MPC8349        0x0081
> +#define PCI_DEVICE_ID_FREESCALE_MPC8347E_1    0x0082
> +#define PCI_DEVICE_ID_FREESCALE_MPC8347_1    0x0083
> +#define PCI_DEVICE_ID_FREESCALE_MPC8347E_2    0x0084
> +#define PCI_DEVICE_ID_FREESCALE_MPC8347_2    0x0085
> +#define PCI_DEVICE_ID_FREESCALE_MPC8343E    0x0086
> +#define PCI_DEVICE_ID_FREESCALE_MPC8343        0x0087
> +
>  #define PCI_VENDOR_ID_SYMPHONY        0x1c1c
>  #define PCI_DEVICE_ID_SYMPHONY_101    0x0001
>
>
>
> !-------------------------------------------------------------flip-
>
>
>
> Best regards,
>
> Wolfgang Denk
>
> -- 
> Software Engineering:  Embedded and Realtime Systems,  Embedded Linux
> Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
> The first 90% of a project takes 90% of the time, the last 10%  takes
> the other 90% of the time.
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev at ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
>




More information about the Linuxppc-dev mailing list