void *plat_alloc_consistent_dmaable_memory(struct device *dev, u32 size,
					   dma_addr_t * addr)
{
#ifdef CONFIG_GMAC_COHERENT
	return (dma_alloc_noncoherent(dev, size, addr, GFP_ATOMIC));
#else
	return (dma_alloc_coherent(dev, size, addr, GFP_ATOMIC));
#endif
}
Ejemplo n.º 2
0
void *dma_alloc_coherent(struct device *dev, size_t size,
	dma_addr_t * dma_handle, int gfp)
{
	void *ret;

	ret = dma_alloc_noncoherent(dev, size, dma_handle, gfp);
	if (ret) {
		dma_cache_wback_inv((unsigned long) ret, size);
		ret = UNCAC_ADDR(ret);
	}

	return ret;
}
Ejemplo n.º 3
0
void *dma_alloc_coherent(struct device *dev, size_t size,
			 dma_addr_t *dma_handle, gfp_t gfp)
{
	void *paddr, *kvaddr;

	/*
	 * IOC relies on all data (even coherent DMA data) being in cache
	 * Thus allocate normal cached memory
	 *
	 * The gains with IOC are two pronged:
	 *   -For streaming data, elides needs for cache maintenance, saving
	 *    cycles in flush code, and bus bandwidth as all the lines of a
	 *    buffer need to be flushed out to memory
	 *   -For coherent data, Read/Write to buffers terminate early in cache
	 *   (vs. always going to memory - thus are faster)
	 */
	if (is_isa_arcv2() && ioc_exists)
		return dma_alloc_noncoherent(dev, size, dma_handle, gfp);

	/* This is linear addr (0x8000_0000 based) */
	paddr = alloc_pages_exact(size, gfp);
	if (!paddr)
		return NULL;

	/* This is kernel Virtual address (0x7000_0000 based) */
	kvaddr = ioremap_nocache((unsigned long)paddr, size);
	if (kvaddr == NULL)
		return NULL;

	/* This is bus address, platform dependent */
	*dma_handle = (dma_addr_t)paddr;

	/*
	 * Evict any existing L1 and/or L2 lines for the backing page
	 * in case it was used earlier as a normal "cached" page.
	 * Yeah this bit us - STAR 9000898266
	 *
	 * Although core does call flush_cache_vmap(), it gets kvaddr hence
	 * can't be used to efficiently flush L1 and/or L2 which need paddr
	 * Currently flush_cache_vmap nukes the L1 cache completely which
	 * will be optimized as a separate commit
	 */
	dma_cache_wback_inv((unsigned long)paddr, size);

	return kvaddr;
}
Ejemplo n.º 4
0
static int __devinit sgiseeq_probe(struct platform_device *pdev)
{
	struct sgiseeq_platform_data *pd = pdev->dev.platform_data;
	struct hpc3_regs *hpcregs = pd->hpc;
	struct sgiseeq_init_block *sr;
	unsigned int irq = pd->irq;
	struct sgiseeq_private *sp;
	struct net_device *dev;
	int err;

	dev = alloc_etherdev(sizeof (struct sgiseeq_private));
	if (!dev) {
		printk(KERN_ERR "Sgiseeq: Etherdev alloc failed, aborting.\n");
		err = -ENOMEM;
		goto err_out;
	}

	platform_set_drvdata(pdev, dev);
	sp = netdev_priv(dev);

	/* Make private data page aligned */
	sr = dma_alloc_noncoherent(&pdev->dev, sizeof(*sp->srings),
				&sp->srings_dma, GFP_KERNEL);
	if (!sr) {
		printk(KERN_ERR "Sgiseeq: Page alloc failed, aborting.\n");
		err = -ENOMEM;
		goto err_out_free_dev;
	}
	sp->srings = sr;
	sp->rx_desc = sp->srings->rxvector;
	sp->tx_desc = sp->srings->txvector;

	/* A couple calculations now, saves many cycles later. */
	setup_rx_ring(dev, sp->rx_desc, SEEQ_RX_BUFFERS);
	setup_tx_ring(dev, sp->tx_desc, SEEQ_TX_BUFFERS);

	memcpy(dev->dev_addr, pd->mac, ETH_ALEN);

#ifdef DEBUG
	gpriv = sp;
	gdev = dev;
#endif
	sp->sregs = (struct sgiseeq_regs *) &hpcregs->eth_ext[0];
	sp->hregs = &hpcregs->ethregs;
	sp->name = sgiseeqstr;
	sp->mode = SEEQ_RCMD_RBCAST;

	/* Setup PIO and DMA transfer timing */
	sp->hregs->pconfig = 0x161;
	sp->hregs->dconfig = HPC3_EDCFG_FIRQ | HPC3_EDCFG_FEOP |
			     HPC3_EDCFG_FRXDC | HPC3_EDCFG_PTO | 0x026;

	/* Setup PIO and DMA transfer timing */
	sp->hregs->pconfig = 0x161;
	sp->hregs->dconfig = HPC3_EDCFG_FIRQ | HPC3_EDCFG_FEOP |
			     HPC3_EDCFG_FRXDC | HPC3_EDCFG_PTO | 0x026;

	/* Reset the chip. */
	hpc3_eth_reset(sp->hregs);

	sp->is_edlc = !(sp->sregs->rw.rregs.collision_tx[0] & 0xff);
	if (sp->is_edlc)
		sp->control = SEEQ_CTRL_XCNT | SEEQ_CTRL_ACCNT |
			      SEEQ_CTRL_SFLAG | SEEQ_CTRL_ESHORT |
			      SEEQ_CTRL_ENCARR;

	dev->netdev_ops		= &sgiseeq_netdev_ops;
	dev->watchdog_timeo	= (200 * HZ) / 1000;
	dev->irq		= irq;

	if (register_netdev(dev)) {
		printk(KERN_ERR "Sgiseeq: Cannot register net device, "
		       "aborting.\n");
		err = -ENODEV;
		goto err_out_free_page;
	}

	printk(KERN_INFO "%s: %s %pM\n", dev->name, sgiseeqstr, dev->dev_addr);

	return 0;

err_out_free_page:
	free_page((unsigned long) sp->srings);
err_out_free_dev:
	kfree(dev);

err_out:
	return err;
}
Ejemplo n.º 5
0
static struct net_device * au1000_probe(int port_num)
{
	static unsigned version_printed = 0;
	struct au1000_private *aup = NULL;
	struct net_device *dev = NULL;
	db_dest_t *pDB, *pDBfree;
	char ethaddr[6];
	int irq, i, err;
	u32 base, macen;

	if (port_num >= NUM_ETH_INTERFACES)
		return NULL;

	base  = CPHYSADDR(iflist[port_num].base_addr );
	macen = CPHYSADDR(iflist[port_num].macen_addr);
	irq = iflist[port_num].irq;

	if (!request_mem_region( base, MAC_IOSIZE, "Au1x00 ENET") ||
	    !request_mem_region(macen, 4, "Au1x00 ENET"))
		return NULL;

	if (version_printed++ == 0)
		printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR);

	dev = alloc_etherdev(sizeof(struct au1000_private));
	if (!dev) {
		printk(KERN_ERR "%s: alloc_etherdev failed\n", DRV_NAME);
		return NULL;
	}

	dev->base_addr = base;
	dev->irq = irq;
	dev->netdev_ops = &au1000_netdev_ops;
	SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops);
	dev->watchdog_timeo = ETH_TX_TIMEOUT;

	err = register_netdev(dev);
	if (err != 0) {
		printk(KERN_ERR "%s: Cannot register net device, error %d\n",
				DRV_NAME, err);
		free_netdev(dev);
		return NULL;
	}

	printk("%s: Au1xx0 Ethernet found at 0x%x, irq %d\n",
		dev->name, base, irq);

	aup = netdev_priv(dev);

	spin_lock_init(&aup->lock);

	/* Allocate the data buffers */
	/* Snooping works fine with eth on all au1xxx */
	aup->vaddr = (u32)dma_alloc_noncoherent(NULL, MAX_BUF_SIZE *
						(NUM_TX_BUFFS + NUM_RX_BUFFS),
						&aup->dma_addr,	0);
	if (!aup->vaddr) {
		free_netdev(dev);
		release_mem_region( base, MAC_IOSIZE);
		release_mem_region(macen, 4);
		return NULL;
	}

	/* aup->mac is the base address of the MAC's registers */
	aup->mac = (volatile mac_reg_t *)iflist[port_num].base_addr;

	/* Setup some variables for quick register address access */
	aup->enable = (volatile u32 *)iflist[port_num].macen_addr;
	aup->mac_id = port_num;
	au_macs[port_num] = aup;

	if (port_num == 0) {
		if (prom_get_ethernet_addr(ethaddr) == 0)
			memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr));
		else {
			printk(KERN_INFO "%s: No MAC address found\n",
					 dev->name);
				/* Use the hard coded MAC addresses */
		}

		setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
	} else if (port_num == 1)
		setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);

	/*
	 * Assign to the Ethernet ports two consecutive MAC addresses
	 * to match those that are printed on their stickers
	 */
	memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr));
	dev->dev_addr[5] += port_num;

	*aup->enable = 0;
	aup->mac_enabled = 0;

	aup->mii_bus = mdiobus_alloc();
	if (aup->mii_bus == NULL)
		goto err_out;

	aup->mii_bus->priv = dev;
	aup->mii_bus->read = au1000_mdiobus_read;
	aup->mii_bus->write = au1000_mdiobus_write;
	aup->mii_bus->reset = au1000_mdiobus_reset;
	aup->mii_bus->name = "au1000_eth_mii";
	snprintf(aup->mii_bus->id, MII_BUS_ID_SIZE, "%x", aup->mac_id);
	aup->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
	if (aup->mii_bus->irq == NULL)
		goto err_out;

	for(i = 0; i < PHY_MAX_ADDR; ++i)
		aup->mii_bus->irq[i] = PHY_POLL;

	/* if known, set corresponding PHY IRQs */
#if defined(AU1XXX_PHY_STATIC_CONFIG)
# if defined(AU1XXX_PHY0_IRQ)
	if (AU1XXX_PHY0_BUSID == aup->mac_id)
		aup->mii_bus->irq[AU1XXX_PHY0_ADDR] = AU1XXX_PHY0_IRQ;
# endif
# if defined(AU1XXX_PHY1_IRQ)
	if (AU1XXX_PHY1_BUSID == aup->mac_id)
		aup->mii_bus->irq[AU1XXX_PHY1_ADDR] = AU1XXX_PHY1_IRQ;
# endif
#endif
	mdiobus_register(aup->mii_bus);

	if (mii_probe(dev) != 0) {
		goto err_out;
	}

	pDBfree = NULL;
	/* setup the data buffer descriptors and attach a buffer to each one */
	pDB = aup->db;
	for (i = 0; i < (NUM_TX_BUFFS+NUM_RX_BUFFS); i++) {
		pDB->pnext = pDBfree;
		pDBfree = pDB;
		pDB->vaddr = (u32 *)((unsigned)aup->vaddr + MAX_BUF_SIZE*i);
		pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr);
		pDB++;
	}
	aup->pDBfree = pDBfree;

	for (i = 0; i < NUM_RX_DMA; i++) {
		pDB = GetFreeDB(aup);
		if (!pDB) {
			goto err_out;
		}
		aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
		aup->rx_db_inuse[i] = pDB;
	}
	for (i = 0; i < NUM_TX_DMA; i++) {
		pDB = GetFreeDB(aup);
		if (!pDB) {
			goto err_out;
		}
		aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
		aup->tx_dma_ring[i]->len = 0;
		aup->tx_db_inuse[i] = pDB;
	}

	/*
	 * The boot code uses the ethernet controller, so reset it to start
	 * fresh.  au1000_init() expects that the device is in reset state.
	 */
	reset_mac(dev);

	return dev;

err_out:
	if (aup->mii_bus != NULL) {
		mdiobus_unregister(aup->mii_bus);
		mdiobus_free(aup->mii_bus);
	}

	/* here we should have a valid dev plus aup-> register addresses
	 * so we can reset the mac properly.*/
	reset_mac(dev);

	for (i = 0; i < NUM_RX_DMA; i++) {
		if (aup->rx_db_inuse[i])
			ReleaseDB(aup, aup->rx_db_inuse[i]);
	}
	for (i = 0; i < NUM_TX_DMA; i++) {
		if (aup->tx_db_inuse[i])
			ReleaseDB(aup, aup->tx_db_inuse[i]);
	}
	dma_free_noncoherent(NULL, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS),
			     (void *)aup->vaddr, aup->dma_addr);
	unregister_netdev(dev);
	free_netdev(dev);
	release_mem_region( base, MAC_IOSIZE);
	release_mem_region(macen, 4);
	return NULL;
}
Ejemplo n.º 6
0
static struct device_t * fb_f1c500s_probe(struct driver_t * drv, struct dtnode_t * n)
{
	struct fb_f1c500s_pdata_t * pdat;
	struct framebuffer_t * fb;
	struct device_t * dev;
	char * clkdefe = dt_read_string(n, "clock-name-defe", NULL);
	char * clkdebe = dt_read_string(n, "clock-name-debe", NULL);
	char * clktcon = dt_read_string(n, "clock-name-tcon", NULL);
	int i;

	if(!search_clk(clkdefe) || !search_clk(clkdebe) || !search_clk(clktcon))
		return NULL;

	pdat = malloc(sizeof(struct fb_f1c500s_pdata_t));
	if(!pdat)
		return NULL;

	fb = malloc(sizeof(struct framebuffer_t));
	if(!fb)
	{
		free(pdat);
		return NULL;
	}

	pdat->virtdefe = phys_to_virt(F1C500S_DEFE_BASE);
	pdat->virtdebe = phys_to_virt(F1C500S_DEBE_BASE);
	pdat->virttcon = phys_to_virt(F1C500S_TCON_BASE);
	pdat->virtgpio = phys_to_virt(F1C500S_GPIO_BASE);
	pdat->clkdefe = strdup(clkdefe);
	pdat->clkdebe = strdup(clkdebe);
	pdat->clktcon = strdup(clktcon);
	pdat->rstdefe = dt_read_int(n, "reset-defe", -1);
	pdat->rstdebe = dt_read_int(n, "reset-debe", -1);
	pdat->rsttcon = dt_read_int(n, "reset-tcon", -1);
	pdat->width = dt_read_int(n, "width", 320);
	pdat->height = dt_read_int(n, "height", 240);
	pdat->pwidth = dt_read_int(n, "physical-width", 216);
	pdat->pheight = dt_read_int(n, "physical-height", 135);
	pdat->bits_per_pixel = dt_read_int(n, "bits-per-pixel", 18);
	pdat->bytes_per_pixel = dt_read_int(n, "bytes-per-pixel", 4);
	pdat->index = 0;
	pdat->vram[0] = dma_alloc_noncoherent(pdat->width * pdat->height * pdat->bytes_per_pixel);
	pdat->vram[1] = dma_alloc_noncoherent(pdat->width * pdat->height * pdat->bytes_per_pixel);
	pdat->nrl = region_list_alloc(0);
	pdat->orl = region_list_alloc(0);

	pdat->timing.pixel_clock_hz = dt_read_long(n, "clock-frequency", 8000000);
	pdat->timing.h_front_porch = dt_read_int(n, "hfront-porch", 40);
	pdat->timing.h_back_porch = dt_read_int(n, "hback-porch", 87);
	pdat->timing.h_sync_len = dt_read_int(n, "hsync-len", 1);
	pdat->timing.v_front_porch = dt_read_int(n, "vfront-porch", 13);
	pdat->timing.v_back_porch = dt_read_int(n, "vback-porch", 31);
	pdat->timing.v_sync_len = dt_read_int(n, "vsync-len", 1);
	pdat->timing.h_sync_active = dt_read_bool(n, "hsync-active", 0);
	pdat->timing.v_sync_active = dt_read_bool(n, "vsync-active", 0);
	pdat->timing.den_active = dt_read_bool(n, "den-active", 0);
	pdat->timing.clk_active = dt_read_bool(n, "clk-active", 0);
	pdat->backlight = search_led(dt_read_string(n, "backlight", NULL));

	fb->name = alloc_device_name(dt_read_name(n), dt_read_id(n));
	fb->width = pdat->width;
	fb->height = pdat->height;
	fb->pwidth = pdat->pwidth;
	fb->pheight = pdat->pheight;
	fb->bytes = pdat->bytes_per_pixel;
	fb->setbl = fb_setbl;
	fb->getbl = fb_getbl;
	fb->create = fb_create;
	fb->destroy = fb_destroy;
	fb->present = fb_present;
	fb->priv = pdat;

	clk_enable(pdat->clkdefe);
	clk_enable(pdat->clkdebe);
	clk_enable(pdat->clktcon);
	if(pdat->rstdefe >= 0)
		reset_deassert(pdat->rstdefe);
	if(pdat->rstdebe >= 0)
		reset_deassert(pdat->rstdebe);
	if(pdat->rsttcon >= 0)
		reset_deassert(pdat->rsttcon);
	for(i = 0x0800; i < 0x1000; i += 4)
		write32(pdat->virtdebe + i, 0);
	fb_f1c500s_init(pdat);

	if(!register_framebuffer(&dev, fb))
	{
		clk_disable(pdat->clkdefe);
		clk_disable(pdat->clkdebe);
		clk_disable(pdat->clktcon);
		free(pdat->clkdefe);
		free(pdat->clkdebe);
		free(pdat->clktcon);
		dma_free_noncoherent(pdat->vram[0]);
		dma_free_noncoherent(pdat->vram[1]);
		region_list_free(pdat->nrl);
		region_list_free(pdat->orl);

		free_device_name(fb->name);
		free(fb->priv);
		free(fb);
		return NULL;
	}
	dev->driver = drv;

	return dev;
}
Ejemplo n.º 7
0
static int __devinit sgiwd93_probe(struct platform_device *pdev)
{
	struct sgiwd93_platform_data *pd = pdev->dev.platform_data;
	unsigned char *wdregs = pd->wdregs;
	struct hpc3_scsiregs *hregs = pd->hregs;
	struct ip22_hostdata *hdata;
	struct Scsi_Host *host;
	wd33c93_regs regs;
	unsigned int unit = pd->unit;
	unsigned int irq = pd->irq;
	int err;

	host = scsi_host_alloc(&sgiwd93_template, sizeof(struct ip22_hostdata));
	if (!host) {
		err = -ENOMEM;
		goto out;
	}

	host->base = (unsigned long) hregs;
	host->irq = irq;

	hdata = host_to_hostdata(host);
	hdata->dev = &pdev->dev;
	hdata->cpu = dma_alloc_noncoherent(&pdev->dev, HPC_DMA_SIZE,
					   &hdata->dma, GFP_KERNEL);
	if (!hdata->cpu) {
		printk(KERN_WARNING "sgiwd93: Could not allocate memory for "
		       "host %d buffer.\n", unit);
		err = -ENOMEM;
		goto out_put;
	}

	init_hpc_chain(hdata);

	regs.SASR = wdregs + 3;
	regs.SCMD = wdregs + 7;

	hdata->wh.no_sync = 0;
	hdata->wh.fast = 1;
	hdata->wh.dma_mode = CTRL_BURST;

	wd33c93_init(host, regs, dma_setup, dma_stop, WD33C93_FS_MHZ(20));

	err = request_irq(irq, sgiwd93_intr, 0, "SGI WD93", host);
	if (err) {
		printk(KERN_WARNING "sgiwd93: Could not register irq %d "
		       "for host %d.\n", irq, unit);
		goto out_free;
	}

	platform_set_drvdata(pdev, host);

	err = scsi_add_host(host, NULL);
	if (err)
		goto out_irq;

	scsi_scan_host(host);

	return 0;

out_irq:
	free_irq(irq, host);
out_free:
	dma_free_noncoherent(&pdev->dev, HPC_DMA_SIZE, hdata->cpu, hdata->dma);
out_put:
	scsi_host_put(host);
out:

	return err;
}
Ejemplo n.º 8
0
static struct net_device * au1000_probe(int port_num)
{
	static unsigned version_printed = 0;
	struct au1000_private *aup = NULL;
	struct net_device *dev = NULL;
	db_dest_t *pDB, *pDBfree;
	char ethaddr[6];
	int irq, i, err;
	u32 base, macen;

	if (port_num >= NUM_ETH_INTERFACES)
		return NULL;

	base  = CPHYSADDR(iflist[port_num].base_addr );
	macen = CPHYSADDR(iflist[port_num].macen_addr);
	irq = iflist[port_num].irq;

	if (!request_mem_region( base, MAC_IOSIZE, "Au1x00 ENET") ||
	    !request_mem_region(macen, 4, "Au1x00 ENET"))
		return NULL;

	if (version_printed++ == 0)
		printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR);

	dev = alloc_etherdev(sizeof(struct au1000_private));
	if (!dev) {
		printk(KERN_ERR "%s: alloc_etherdev failed\n", DRV_NAME);
		return NULL;
	}

	dev->base_addr = base;
	dev->irq = irq;
	dev->netdev_ops = &au1000_netdev_ops;
	SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops);
	dev->watchdog_timeo = ETH_TX_TIMEOUT;

	err = register_netdev(dev);
	if (err != 0) {
		printk(KERN_ERR "%s: Cannot register net device, error %d\n",
				DRV_NAME, err);
		free_netdev(dev);
		return NULL;
	}

	printk("%s: Au1xx0 Ethernet found at 0x%x, irq %d\n",
		dev->name, base, irq);

	aup = netdev_priv(dev);

	spin_lock_init(&aup->lock);

	
	
	aup->vaddr = (u32)dma_alloc_noncoherent(NULL, MAX_BUF_SIZE *
						(NUM_TX_BUFFS + NUM_RX_BUFFS),
						&aup->dma_addr,	0);
	if (!aup->vaddr) {
		free_netdev(dev);
		release_mem_region( base, MAC_IOSIZE);
		release_mem_region(macen, 4);
		return NULL;
	}

	
	aup->mac = (volatile mac_reg_t *)iflist[port_num].base_addr;

	
	aup->enable = (volatile u32 *)iflist[port_num].macen_addr;
	aup->mac_id = port_num;
	au_macs[port_num] = aup;

	if (port_num == 0) {
		if (prom_get_ethernet_addr(ethaddr) == 0)
			memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr));
		else {
			printk(KERN_INFO "%s: No MAC address found\n",
					 dev->name);
				
		}

		setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
	} else if (port_num == 1)
		setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);

	
	memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr));
	dev->dev_addr[5] += port_num;

	*aup->enable = 0;
	aup->mac_enabled = 0;

	aup->mii_bus = mdiobus_alloc();
	if (aup->mii_bus == NULL)
		goto err_out;

	aup->mii_bus->priv = dev;
	aup->mii_bus->read = au1000_mdiobus_read;
	aup->mii_bus->write = au1000_mdiobus_write;
	aup->mii_bus->reset = au1000_mdiobus_reset;
	aup->mii_bus->name = "au1000_eth_mii";
	snprintf(aup->mii_bus->id, MII_BUS_ID_SIZE, "%x", aup->mac_id);
	aup->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
	if (aup->mii_bus->irq == NULL)
		goto err_out;

	for(i = 0; i < PHY_MAX_ADDR; ++i)
		aup->mii_bus->irq[i] = PHY_POLL;

	
#if defined(AU1XXX_PHY_STATIC_CONFIG)
# if defined(AU1XXX_PHY0_IRQ)
	if (AU1XXX_PHY0_BUSID == aup->mac_id)
		aup->mii_bus->irq[AU1XXX_PHY0_ADDR] = AU1XXX_PHY0_IRQ;
# endif
# if defined(AU1XXX_PHY1_IRQ)
	if (AU1XXX_PHY1_BUSID == aup->mac_id)
		aup->mii_bus->irq[AU1XXX_PHY1_ADDR] = AU1XXX_PHY1_IRQ;
# endif
#endif
	mdiobus_register(aup->mii_bus);

	if (mii_probe(dev) != 0) {
		goto err_out;
	}

	pDBfree = NULL;
	
	pDB = aup->db;
	for (i = 0; i < (NUM_TX_BUFFS+NUM_RX_BUFFS); i++) {
		pDB->pnext = pDBfree;
		pDBfree = pDB;
		pDB->vaddr = (u32 *)((unsigned)aup->vaddr + MAX_BUF_SIZE*i);
		pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr);
		pDB++;
	}
	aup->pDBfree = pDBfree;

	for (i = 0; i < NUM_RX_DMA; i++) {
		pDB = GetFreeDB(aup);
		if (!pDB) {
			goto err_out;
		}
		aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
		aup->rx_db_inuse[i] = pDB;
	}
	for (i = 0; i < NUM_TX_DMA; i++) {
		pDB = GetFreeDB(aup);
		if (!pDB) {
			goto err_out;
		}
		aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
		aup->tx_dma_ring[i]->len = 0;
		aup->tx_db_inuse[i] = pDB;
	}

	
	reset_mac(dev);

	return dev;

err_out:
	if (aup->mii_bus != NULL) {
		mdiobus_unregister(aup->mii_bus);
		mdiobus_free(aup->mii_bus);
	}

	
	reset_mac(dev);

	for (i = 0; i < NUM_RX_DMA; i++) {
		if (aup->rx_db_inuse[i])
			ReleaseDB(aup, aup->rx_db_inuse[i]);
	}
	for (i = 0; i < NUM_TX_DMA; i++) {
		if (aup->tx_db_inuse[i])
			ReleaseDB(aup, aup->tx_db_inuse[i]);
	}
	dma_free_noncoherent(NULL, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS),
			     (void *)aup->vaddr, aup->dma_addr);
	unregister_netdev(dev);
	free_netdev(dev);
	release_mem_region( base, MAC_IOSIZE);
	release_mem_region(macen, 4);
	return NULL;
}
Ejemplo n.º 9
0
static struct device_t * fb_rk3288_probe(struct driver_t * drv, struct dtnode_t * n)
{
	struct fb_rk3288_pdata_t * pdat;
	struct fb_t * fb;
	struct device_t * dev;
	virtual_addr_t virt = phys_to_virt(dt_read_address(n));
	char * clk = dt_read_string(n, "clock-name", NULL);

	if(!search_clk(clk))
		return NULL;

	pdat = malloc(sizeof(struct fb_rk3288_pdata_t));
	if(!pdat)
		return NULL;

	fb = malloc(sizeof(struct fb_t));
	if(!fb)
	{
		free(pdat);
		return NULL;
	}

	pdat->virtvop = virt;
	pdat->virtgrf = phys_to_virt(RK3288_GRF_BASE);
	pdat->virtlvds = phys_to_virt(RK3288_LVDS_BASE);
	pdat->lcd_avdd_3v3 = strdup(dt_read_string(n, "regulator-lcd-avdd-3v3", NULL));
	pdat->lcd_avdd_1v8 = strdup(dt_read_string(n, "regulator-lcd-avdd-1v8", NULL));
	pdat->lcd_avdd_1v0 = strdup(dt_read_string(n, "regulator-lcd-avdd-1v0", NULL));
	pdat->clk = strdup(clk);
	pdat->width = dt_read_int(n, "width", 1024);
	pdat->height = dt_read_int(n, "height", 600);
	pdat->xdpi = dt_read_int(n, "dots-per-inch-x", 160);
	pdat->ydpi = dt_read_int(n, "dots-per-inch-y", 160);
	pdat->bits_per_pixel = dt_read_int(n, "bits-per-pixel", 32);
	pdat->bytes_per_pixel = dt_read_int(n, "bytes-per-pixel", 4);
	pdat->index = 0;
	pdat->vram[0] = dma_alloc_noncoherent(pdat->width * pdat->height * pdat->bytes_per_pixel);
	pdat->vram[1] = dma_alloc_noncoherent(pdat->width * pdat->height * pdat->bytes_per_pixel);

	pdat->interface = RK3288_VOP_INTERFACE_RGB_LVDS;
	pdat->output = RK3288_LVDS_OUTPUT_RGB;
	pdat->format = RK3288_LVDS_FORMAT_JEIDA;

	pdat->mode.mirrorx = 0;
	pdat->mode.mirrory = 0;
	pdat->mode.swaprg = 0;
	pdat->mode.swaprb = 0;
	pdat->mode.swapbg = 0;

	pdat->timing.pixel_clock_hz = dt_read_long(n, "clock-frequency", 52000000);
	pdat->timing.h_front_porch = dt_read_int(n, "hfront-porch", 1);
	pdat->timing.h_back_porch = dt_read_int(n, "hback-porch", 1);
	pdat->timing.h_sync_len = dt_read_int(n, "hsync-len", 1);
	pdat->timing.v_front_porch = dt_read_int(n, "vfront-porch", 1);
	pdat->timing.v_back_porch = dt_read_int(n, "vback-porch", 1);
	pdat->timing.v_sync_len = dt_read_int(n, "vsync-len", 1);
	pdat->timing.h_sync_active = dt_read_bool(n, "hsync-active", 0);
	pdat->timing.v_sync_active = dt_read_bool(n, "vsync-active", 0);
	pdat->timing.den_active = dt_read_bool(n, "den-active", 0);
	pdat->timing.clk_active = dt_read_bool(n, "clk-active", 0);
	pdat->backlight = search_led(dt_read_string(n, "backlight", NULL));

	fb->name = alloc_device_name(dt_read_name(n), -1);
	fb->width = pdat->width;
	fb->height = pdat->height;
	fb->xdpi = pdat->xdpi;
	fb->ydpi = pdat->ydpi;
	fb->bpp = pdat->bits_per_pixel;
	fb->setbl = fb_setbl,
	fb->getbl = fb_getbl,
	fb->create = fb_create,
	fb->destroy = fb_destroy,
	fb->present = fb_present,
	fb->priv = pdat;

	regulator_set_voltage(pdat->lcd_avdd_3v3, 3300000);
	regulator_enable(pdat->lcd_avdd_3v3);
	regulator_set_voltage(pdat->lcd_avdd_1v8, 1800000);
	regulator_enable(pdat->lcd_avdd_1v8);
	regulator_set_voltage(pdat->lcd_avdd_1v0, 1000000);
	regulator_enable(pdat->lcd_avdd_1v0);
	clk_enable(pdat->clk);
	rk3288_fb_init(pdat);

	if(!register_fb(&dev, fb))
	{
		regulator_disable(pdat->lcd_avdd_3v3);
		free(pdat->lcd_avdd_3v3);
		regulator_disable(pdat->lcd_avdd_1v8);
		free(pdat->lcd_avdd_1v8);
		regulator_disable(pdat->lcd_avdd_1v0);
		free(pdat->lcd_avdd_1v0);
		clk_disable(pdat->clk);
		free(pdat->clk);
		dma_free_noncoherent(pdat->vram[0]);
		dma_free_noncoherent(pdat->vram[1]);

		free_device_name(fb->name);
		free(fb->priv);
		free(fb);
		return NULL;
	}
	dev->driver = drv;

	return dev;
}