Commit 2b9d7467 authored by Zang Roy-r61911's avatar Zang Roy-r61911 Committed by Paul Mackerras

[POWERPC] Add tsi108 pci and platform device data register function

Add Tundra Semiconductor tsi108 pci and platform device data register
function support.
Signed-off-by: default avatarAlexandre Bounine <alexandreb@tundra.com>
Signed-off-by: default avatarRoy Zang <tie-fei.zang@freescale.com>

 ---
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent c5d56332
...@@ -12,3 +12,4 @@ obj-$(CONFIG_U3_DART) += dart_iommu.o ...@@ -12,3 +12,4 @@ obj-$(CONFIG_U3_DART) += dart_iommu.o
obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o
obj-$(CONFIG_PPC_83xx) += ipic.o obj-$(CONFIG_PPC_83xx) += ipic.o
obj-$(CONFIG_FSL_SOC) += fsl_soc.o obj-$(CONFIG_FSL_SOC) += fsl_soc.o
obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o
/*
* tsi108/109 device setup code
*
* Maintained by Roy Zang < tie-fei.zang@freescale.com >
*
* 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/major.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <asm/tsi108.h>
#include <asm/system.h>
#include <asm/atomic.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/prom.h>
#include <mm/mmu_decl.h>
#undef DEBUG
#ifdef DEBUG
#define DBG(fmt...) do { printk(fmt); } while(0)
#else
#define DBG(fmt...) do { } while(0)
#endif
static phys_addr_t tsi108_csr_base = -1;
phys_addr_t get_csrbase(void)
{
struct device_node *tsi;
if (tsi108_csr_base != -1)
return tsi108_csr_base;
tsi = of_find_node_by_type(NULL, "tsi-bridge");
if (tsi) {
unsigned int size;
void *prop = get_property(tsi, "reg", &size);
tsi108_csr_base = of_translate_address(tsi, prop);
of_node_put(tsi);
};
return tsi108_csr_base;
}
u32 get_vir_csrbase(void)
{
return (u32) (ioremap(get_csrbase(), 0x10000));
}
EXPORT_SYMBOL(get_csrbase);
EXPORT_SYMBOL(get_vir_csrbase);
static int __init tsi108_eth_of_init(void)
{
struct device_node *np;
unsigned int i;
struct platform_device *tsi_eth_dev;
struct resource res;
int ret;
for (np = NULL, i = 0;
(np = of_find_compatible_node(np, "network", "tsi-ethernet")) != NULL;
i++) {
struct resource r[2];
struct device_node *phy;
hw_info tsi_eth_data;
unsigned int *id;
unsigned int *phy_id;
void *mac_addr;
phandle *ph;
memset(r, 0, sizeof(r));
memset(&tsi_eth_data, 0, sizeof(tsi_eth_data));
ret = of_address_to_resource(np, 0, &r[0]);
DBG("%s: name:start->end = %s:0x%lx-> 0x%lx\n",
__FUNCTION__,r[0].name, r[0].start, r[0].end);
if (ret)
goto err;
r[1].name = "tx";
r[1].start = np->intrs[0].line;
r[1].end = np->intrs[0].line;
r[1].flags = IORESOURCE_IRQ;
tsi_eth_dev =
platform_device_register_simple("tsi-ethernet", i, &r[0],
np->n_intrs + 1);
if (IS_ERR(tsi_eth_dev)) {
ret = PTR_ERR(tsi_eth_dev);
goto err;
}
mac_addr = get_property(np, "address", NULL);
memcpy(tsi_eth_data.mac_addr, mac_addr, 6);
ph = (phandle *) get_property(np, "phy-handle", NULL);
phy = of_find_node_by_phandle(*ph);
if (phy == NULL) {
ret = -ENODEV;
goto unreg;
}
id = (u32 *) get_property(phy, "reg", NULL);
phy_id = (u32 *) get_property(phy, "phy-id", NULL);
ret = of_address_to_resource(phy, 0, &res);
if (ret) {
of_node_put(phy);
goto unreg;
}
tsi_eth_data.regs = r[0].start;
tsi_eth_data.phyregs = res.start;
tsi_eth_data.phy = *phy_id;
tsi_eth_data.irq_num = np->intrs[0].line;
of_node_put(phy);
ret =
platform_device_add_data(tsi_eth_dev, &tsi_eth_data,
sizeof(hw_info));
if (ret)
goto unreg;
}
return 0;
unreg:
platform_device_unregister(tsi_eth_dev);
err:
return ret;
}
arch_initcall(tsi108_eth_of_init);
This diff is collapsed.
/*
* include/asm-ppc/tsi108.h
*
* common routine and memory layout for Tundra TSI108(Grendel) host bridge
* memory controller.
*
* Author: Jacob Pan (jacob.pan@freescale.com)
* Alex Bounine (alexandreb@tundra.com)
* 2004 (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_KERNEL_TSI108_H
#define __PPC_KERNEL_TSI108_H
#include <asm/pci-bridge.h>
/* Size of entire register space */
#define TSI108_REG_SIZE (0x10000)
/* Sizes of register spaces for individual blocks */
#define TSI108_HLP_SIZE 0x1000
#define TSI108_PCI_SIZE 0x1000
#define TSI108_CLK_SIZE 0x1000
#define TSI108_PB_SIZE 0x1000
#define TSI108_SD_SIZE 0x1000
#define TSI108_DMA_SIZE 0x1000
#define TSI108_ETH_SIZE 0x1000
#define TSI108_I2C_SIZE 0x400
#define TSI108_MPIC_SIZE 0x400
#define TSI108_UART0_SIZE 0x200
#define TSI108_GPIO_SIZE 0x200
#define TSI108_UART1_SIZE 0x200
/* Offsets within Tsi108(A) CSR space for individual blocks */
#define TSI108_HLP_OFFSET 0x0000
#define TSI108_PCI_OFFSET 0x1000
#define TSI108_CLK_OFFSET 0x2000
#define TSI108_PB_OFFSET 0x3000
#define TSI108_SD_OFFSET 0x4000
#define TSI108_DMA_OFFSET 0x5000
#define TSI108_ETH_OFFSET 0x6000
#define TSI108_I2C_OFFSET 0x7000
#define TSI108_MPIC_OFFSET 0x7400
#define TSI108_UART0_OFFSET 0x7800
#define TSI108_GPIO_OFFSET 0x7A00
#define TSI108_UART1_OFFSET 0x7C00
/* Tsi108 registers used by common code components */
#define TSI108_PCI_CSR (0x004)
#define TSI108_PCI_IRP_CFG_CTL (0x180)
#define TSI108_PCI_IRP_STAT (0x184)
#define TSI108_PCI_IRP_ENABLE (0x188)
#define TSI108_PCI_IRP_INTAD (0x18C)
#define TSI108_PCI_IRP_STAT_P_INT (0x00400000)
#define TSI108_PCI_IRP_ENABLE_P_INT (0x00400000)
#define TSI108_CG_PWRUP_STATUS (0x234)
#define TSI108_PB_ISR (0x00C)
#define TSI108_PB_ERRCS (0x404)
#define TSI108_PB_AERR (0x408)
#define TSI108_PB_ERRCS_ES (1 << 1)
#define TSI108_PB_ISR_PBS_RD_ERR (1 << 8)
#define TSI108_PCI_CFG_BASE_PHYS (0xfb000000)
#define TSI108_PCI_CFG_SIZE (0x01000000)
/* Global variables */
extern u32 tsi108_pci_cfg_base;
/* Exported functions */
extern int tsi108_bridge_init(struct pci_controller *hose, uint phys_csr_base);
extern unsigned long tsi108_get_mem_size(void);
extern unsigned long tsi108_get_cpu_clk(void);
extern unsigned long tsi108_get_sdc_clk(void);
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);
extern void tsi108_clear_pci_error(u32 pci_cfg_base);
extern phys_addr_t get_csrbase(void);
typedef struct {
u32 regs; /* hw registers base address */
u32 phyregs; /* phy registers base address */
u16 phy; /* phy address */
u16 irq_num; /* irq number */
u8 mac_addr[6]; /* phy mac address */
} hw_info;
extern u32 get_vir_csrbase(void);
extern u32 tsi108_csr_vir_base;
extern inline u32 tsi108_read_reg(u32 reg_offset)
{
return in_be32((volatile u32 *)(tsi108_csr_vir_base + reg_offset));
}
extern inline void tsi108_write_reg(u32 reg_offset, u32 val)
{
out_be32((volatile u32 *)(tsi108_csr_vir_base + reg_offset), val);
}
#endif /* __PPC_KERNEL_TSI108_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment