You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
280 lines
8.2 KiB
280 lines
8.2 KiB
/**\file
|
|
* This file encapsulates all the PCI dependent initialization and resource allocation
|
|
* on Linux
|
|
*/
|
|
|
|
/* sw
|
|
#include <linux/config.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/module.h>
|
|
#include <linux/pci.h>
|
|
#include <linux/init.h>
|
|
#include <linux/dma-mapping.h>
|
|
#include <linux/netdevice.h>
|
|
#include <linux/etherdevice.h>
|
|
*/
|
|
|
|
#include "synopGMAC_plat.h"
|
|
#include "synopGMAC_pci_bus_interface.h"
|
|
|
|
|
|
|
|
#if 0 //sw
|
|
#include "GMAC_Pmon.h"
|
|
|
|
|
|
/**********************************************************************************/
|
|
|
|
|
|
#define SYNOPGMAC_VENDOR_ID 0x0700
|
|
#define SYNOPGMAC_DEVICE_ID 0x1108
|
|
|
|
#define BAR0 0
|
|
#define BAR1 1
|
|
#define BAR2 2
|
|
#define BAR3 3
|
|
#define BAR4 4
|
|
#define BAR5 5
|
|
static u8 synopGMAC_driver_name[] = "synopGMAC_pci_driver";
|
|
static struct pci_device_id ids[] = {
|
|
{PCI_DEVICE (SYNOPGMAC_VENDOR_ID, SYNOPGMAC_DEVICE_ID),}, {0,}
|
|
};
|
|
|
|
u32 synop_pci_using_dac;
|
|
|
|
/**********************************************************************************/
|
|
extern u8 *synopGMACMappedAddr;
|
|
extern u32 synopGMACMappedAddrSize;
|
|
extern struct pci_dev *synopGMACpcidev;
|
|
|
|
/* Get the pci revision id */
|
|
static unsigned char
|
|
get_revision (struct pci_dev *dev)
|
|
{
|
|
u8 revision;
|
|
pci_read_config_byte (dev, PCI_REVISION_ID, &revision);
|
|
return revision;
|
|
}
|
|
|
|
|
|
/**
|
|
* probe function of Linux pci driver.
|
|
* - Ioremap the BARx memory (It is BAR0 here)
|
|
* - lock the memory for the device
|
|
* \return Returns 0 on success and Error code on failure.
|
|
*/
|
|
static int probe (struct pci_dev *pdev, const struct pci_device_id *my_pci_id)
|
|
{
|
|
s32 retval;
|
|
u16 word_data = 0;
|
|
u32 double_word_data = 0;
|
|
u32 the_register_resource_base, the_register_resource_size;
|
|
|
|
/* Do probing type stuff here.
|
|
* Like calling request_region();
|
|
*/
|
|
TR ("ENABLING PCI DEVICE\n");
|
|
|
|
/* Enable the device */
|
|
if (pci_enable_device (pdev))
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
if (!(retval = pci_set_dma_mask (pdev, DMA_64BIT_MASK))
|
|
&& !(retval = pci_set_consistent_dma_mask (pdev, DMA_64BIT_MASK)))
|
|
{
|
|
synop_pci_using_dac = 1;
|
|
}
|
|
|
|
else
|
|
{
|
|
if ((pci_set_dma_mask (pdev, DMA_32BIT_MASK))
|
|
&& (retval = pci_set_consistent_dma_mask (pdev, DMA_32BIT_MASK)))
|
|
{
|
|
TR0 ("NO usable DMA Configuration, aborting\n");
|
|
return retval;
|
|
}
|
|
synop_pci_using_dac = 0;
|
|
}
|
|
if (synop_pci_using_dac)
|
|
TR ("64 bit double-address cycle Supported with this device\n");
|
|
|
|
else
|
|
TR ("32 bit double-address cycle Supported with this device\n");
|
|
|
|
//Setting the pci as master
|
|
pci_set_master (pdev);
|
|
|
|
/* Get the pci revision id */
|
|
if (get_revision (pdev) == 0x42)
|
|
return -ENODEV;
|
|
|
|
TR ("synopGMAC device found at slot %d, func %d\n",PCI_SLOT (pdev->devfn), PCI_FUNC (pdev->devfn));
|
|
|
|
{
|
|
|
|
//u16 w = 0, dw = 0;
|
|
TR ("****************************************************\n");
|
|
pci_read_config_word (pdev, PCI_COMMAND, &word_data);
|
|
TR ("COMMAND = %04x\n", word_data);
|
|
pci_read_config_word (pdev, PCI_STATUS, &word_data);
|
|
TR ("STATUS = %04x\n", word_data);
|
|
pci_read_config_dword (pdev, PCI_CLASS_REVISION, &double_word_data);
|
|
TR ("CLASS_REVISION = %08x\n", double_word_data);
|
|
pci_read_config_dword (pdev, PCI_BASE_ADDRESS_0, &double_word_data);
|
|
TR ("BASE_ADDRESS_0 = %08x\n", double_word_data);
|
|
pci_read_config_dword (pdev, PCI_BASE_ADDRESS_1, &double_word_data);
|
|
TR ("BASE_ADDRESS_1 = %08x\n", double_word_data);
|
|
pci_read_config_dword (pdev, PCI_BASE_ADDRESS_2, &double_word_data);
|
|
TR ("BASE_ADDRESS_2 = %08x\n", double_word_data);
|
|
pci_read_config_dword (pdev, PCI_BASE_ADDRESS_3, &double_word_data);
|
|
TR ("BASE_ADDRESS_3 = %08x\n", double_word_data);
|
|
pci_read_config_dword (pdev, PCI_BASE_ADDRESS_4, &double_word_data);
|
|
TR ("BASE_ADDRESS_4 = %08x\n", double_word_data);
|
|
pci_read_config_dword (pdev, PCI_BASE_ADDRESS_5, &double_word_data);
|
|
TR ("BASE_ADDRESS_5 = %08x\n", double_word_data);
|
|
TR ("****************************************************\n");
|
|
|
|
/*These are the retry counts without which driver fais to run movies :) */
|
|
pci_write_config_byte (pdev, 0x40, 0xff);
|
|
pci_write_config_byte (pdev, 0x41, 0xff);
|
|
}
|
|
|
|
/* Get the resource start address and the size for BARx in question In this case BAR0 */
|
|
the_register_resource_base = pci_resource_start (pdev, BAR0);
|
|
the_register_resource_size = pci_resource_len (pdev, BAR0);
|
|
TR ("BAR0 Base is %x size is %d\n", the_register_resource_base,the_register_resource_size);
|
|
|
|
/*
|
|
Get the iomapped address which is nothing but the physical to virtual mapped address
|
|
ioremap_nocahe is similare to ioremap on most of the architectures. But The pci-ahb bridge
|
|
BAR0 is mapped to 16M address space. If we ask for this much memory, Kernel refuses to
|
|
give the same.
|
|
|
|
Note that 16M is too much of memory to request from kernel.
|
|
Lets ask for less memory so that kernel is happy giving it :)
|
|
*/
|
|
synopGMACMappedAddr = (u8 *) ioremap_nocache ((u32) the_register_resource_base, (size_t) (128 * 1024));
|
|
synopGMACMappedAddrSize = (128 * 1024); // this is needed for remove function
|
|
|
|
if (!synopGMACMappedAddr){
|
|
TR0 ("ioremap_nocache failed with addrrss %08x\n", (u32) synopGMACMappedAddr);
|
|
}
|
|
|
|
TR ("Physical address = %08x\n", the_register_resource_base);
|
|
TR ("Remapped address = %08x\n", (u32) synopGMACMappedAddr);
|
|
|
|
/*Check if region is already locked by any other driver ? */
|
|
if (check_mem_region ((u32) synopGMACMappedAddr, synopGMACMappedAddrSize))
|
|
{
|
|
synopGMACMappedAddr = 0; // Errored in checking memory region
|
|
TR0("Memory Already Locked !!\n");
|
|
iounmap (synopGMACMappedAddr);
|
|
return -EBUSY;
|
|
}
|
|
|
|
/*Great We have free memory of required size.. Lets Lock it... */
|
|
request_mem_region ((u32) synopGMACMappedAddr, synopGMACMappedAddrSize,"synopGMACmemory");
|
|
TR ("Requested memory region for synopGMACMappedAddr = 0x%x\n", (u32) synopGMACMappedAddr);
|
|
|
|
/*Now pci interface is ready. Let give this information the the HOST module */
|
|
synopGMACpcidev = pdev;
|
|
return 0; // Everything is fine. So return 0.
|
|
}
|
|
|
|
|
|
/**
|
|
* remove function of Linux pci driver.
|
|
*
|
|
* - Releases the memory allocated by probe function
|
|
* - Unmaps the memory region
|
|
*
|
|
* \return Returns 0 on success and Error code on failure.
|
|
*/
|
|
static void remove (struct pci_dev *dev)
|
|
{
|
|
|
|
/* Do the reverse of what probe does */
|
|
if (synopGMACMappedAddr)
|
|
{
|
|
TR0 ("Releaseing synopGMACMappedAddr 0x%x whose size is %d\n", (u32) synopGMACMappedAddr, synopGMACMappedAddrSize);
|
|
|
|
/*release the memory region which we locked using request_mem_region */
|
|
release_mem_region ((u32) synopGMACMappedAddr, synopGMACMappedAddrSize);
|
|
}
|
|
TR0 ("Unmapping synopGMACMappedAddr =0x%x\n", (u32) synopGMACMappedAddr);
|
|
iounmap (synopGMACMappedAddr);
|
|
}
|
|
|
|
static struct pci_driver pci_driver =
|
|
{ .name = synopGMAC_driver_name,
|
|
.id_table = ids,
|
|
.probe = probe,
|
|
.remove = remove,
|
|
};
|
|
|
|
|
|
/**
|
|
* Function to initialize the Linux Pci Bus Interface.
|
|
* Registers the pci_driver
|
|
* \return Returns 0 on success and Error code on failure.
|
|
*/
|
|
|
|
/* sw we do nothing in gs232
|
|
s32 __init synopGMAC_init_pci_bus_interface (void)
|
|
{
|
|
s32 retval;
|
|
TR ("Now Going to Call pci_register_driver\n");
|
|
if (synopGMACMappedAddr)
|
|
return -EBUSY;
|
|
if ((retval = pci_register_driver (&pci_driver)))
|
|
{
|
|
return retval;
|
|
}
|
|
if (!synopGMACMappedAddr)
|
|
{
|
|
pci_unregister_driver (&pci_driver);
|
|
return -ENODEV;
|
|
}
|
|
return 0;
|
|
}
|
|
*/
|
|
|
|
#endif //#if 0
|
|
|
|
|
|
int synopGMAC_init_pci_bus_interface (void)
|
|
{
|
|
TR ("Now Going to Call pci_register_driver\n");
|
|
TR ("===we do nothing in pci config\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Function to De-initialize the Linux Pci Bus Interface.
|
|
*
|
|
* Unregisters the pci_driver
|
|
*
|
|
* \return Returns 0 on success and Error code on failure.
|
|
*/
|
|
|
|
/* sw
|
|
void __exit synopGMAC_exit_pci_bus_interface (void)
|
|
{
|
|
TR0 ("Now Calling pci_unregister_driver\n");
|
|
pci_unregister_driver (&pci_driver);
|
|
}
|
|
*/
|
|
|
|
|
|
/*
|
|
module_init(synopGMAC_init_pci_bus_interface);
|
|
module_exit(synopGMAC_exit_pci_bus_interface);
|
|
|
|
MODULE_AUTHOR("Synopsys India");
|
|
MODULE_LICENSE("GPL/BSD");
|
|
MODULE_DESCRIPTION("SYNOPSYS GMAC DRIVER PCI INTERFACE");
|
|
|
|
EXPORT_SYMBOL(synopGMAC_init_pci_bus_interface);
|
|
*/
|
|
|