/* HW Initialization, if return 0, initialization is successful. */
static int mx6q_sabreauto_sata_init(struct device *dev, void __iomem *addr)
{
	u32 tmpdata;
	int ret = 0;
	struct clk *clk;

	sata_clk = clk_get(dev, "imx_sata_clk");
	if (IS_ERR(sata_clk)) {
		dev_err(dev, "no sata clock.\n");
		return PTR_ERR(sata_clk);
	}
	ret = clk_enable(sata_clk);
	if (ret) {
		dev_err(dev, "can't enable sata clock.\n");
		goto put_sata_clk;
	}

	/* Set PHY Paremeters, two steps to configure the GPR13,
	 * one write for rest of parameters, mask of first write is 0x07FFFFFD,
	 * and the other one write for setting the mpll_clk_off_b
	 *.rx_eq_val_0(iomuxc_gpr13[26:24]),
	 *.los_lvl(iomuxc_gpr13[23:19]),
	 *.rx_dpll_mode_0(iomuxc_gpr13[18:16]),
	 *.sata_speed(iomuxc_gpr13[15]),
	 *.mpll_ss_en(iomuxc_gpr13[14]),
	 *.tx_atten_0(iomuxc_gpr13[13:11]),
	 *.tx_boost_0(iomuxc_gpr13[10:7]),
	 *.tx_lvl(iomuxc_gpr13[6:2]),
	 *.mpll_ck_off(iomuxc_gpr13[1]),
	 *.tx_edgerate_0(iomuxc_gpr13[0]),
	 */
	tmpdata = readl(IOMUXC_GPR13);
	writel(((tmpdata & ~0x07FFFFFD) | 0x0593A044), IOMUXC_GPR13);

	/* enable SATA_PHY PLL */
	tmpdata = readl(IOMUXC_GPR13);
	writel(((tmpdata & ~0x2) | 0x2), IOMUXC_GPR13);

	/* Get the AHB clock rate, and configure the TIMER1MS reg later */
	clk = clk_get(NULL, "ahb");
	if (IS_ERR(clk)) {
		dev_err(dev, "no ahb clock.\n");
		ret = PTR_ERR(clk);
		goto release_sata_clk;
	}
	tmpdata = clk_get_rate(clk) / 1000;
	clk_put(clk);

#ifdef CONFIG_SATA_AHCI_PLATFORM
	ret = sata_init(addr, tmpdata);
	if (ret == 0)
		return ret;
#else
	usleep_range(1000, 2000);
	/* AHCI PHY enter into PDDQ mode if the AHCI module is not enabled */
	tmpdata = readl(addr + PORT_PHY_CTL);
	writel(tmpdata | PORT_PHY_CTL_PDDQ_LOC, addr + PORT_PHY_CTL);
	pr_info("No AHCI save PWR: PDDQ %s\n", ((readl(addr + PORT_PHY_CTL)
					>> 20) & 1) ? "enabled" : "disabled");
#endif

release_sata_clk:
	/* disable SATA_PHY PLL */
	writel((readl(IOMUXC_GPR13) & ~0x2), IOMUXC_GPR13);
	clk_disable(sata_clk);
put_sata_clk:
	clk_put(sata_clk);

	return ret;
}
示例#2
0
文件: dma.c 项目: ivucica/linux
static inline void
dma_wrreg(struct s3c2410_dma_chan *chan, int reg, unsigned long val)
{
	pr_debug("writing %08x to register %08x\n",(unsigned int)val,reg);
	writel(val, dma_regaddr(chan, reg));
}
示例#3
0
文件: offb.c 项目: CSCLOG/beaglebone
static int offb_set_par(struct fb_info *info)
{
	struct offb_par *par = (struct offb_par *) info->par;

	/* On avivo, initialize palette control */
	if (par->cmap_type == cmap_avivo) {
		writel(0, par->cmap_adr + AVIVO_DC_LUTA_CONTROL);
		writel(0, par->cmap_adr + AVIVO_DC_LUTA_BLACK_OFFSET_BLUE);
		writel(0, par->cmap_adr + AVIVO_DC_LUTA_BLACK_OFFSET_GREEN);
		writel(0, par->cmap_adr + AVIVO_DC_LUTA_BLACK_OFFSET_RED);
		writel(0x0000ffff, par->cmap_adr + AVIVO_DC_LUTA_WHITE_OFFSET_BLUE);
		writel(0x0000ffff, par->cmap_adr + AVIVO_DC_LUTA_WHITE_OFFSET_GREEN);
		writel(0x0000ffff, par->cmap_adr + AVIVO_DC_LUTA_WHITE_OFFSET_RED);
		writel(0, par->cmap_adr + AVIVO_DC_LUTB_CONTROL);
		writel(0, par->cmap_adr + AVIVO_DC_LUTB_BLACK_OFFSET_BLUE);
		writel(0, par->cmap_adr + AVIVO_DC_LUTB_BLACK_OFFSET_GREEN);
		writel(0, par->cmap_adr + AVIVO_DC_LUTB_BLACK_OFFSET_RED);
		writel(0x0000ffff, par->cmap_adr + AVIVO_DC_LUTB_WHITE_OFFSET_BLUE);
		writel(0x0000ffff, par->cmap_adr + AVIVO_DC_LUTB_WHITE_OFFSET_GREEN);
		writel(0x0000ffff, par->cmap_adr + AVIVO_DC_LUTB_WHITE_OFFSET_RED);
		writel(1, par->cmap_adr + AVIVO_DC_LUT_RW_SELECT);
		writel(0, par->cmap_adr + AVIVO_DC_LUT_RW_MODE);
		writel(0x0000003f, par->cmap_adr + AVIVO_DC_LUT_WRITE_EN_MASK);
		writel(0, par->cmap_adr + AVIVO_DC_LUT_RW_SELECT);
		writel(0, par->cmap_adr + AVIVO_DC_LUT_RW_MODE);
		writel(0x0000003f, par->cmap_adr + AVIVO_DC_LUT_WRITE_EN_MASK);
	}
	return 0;
}
示例#4
0
static inline void
ad1889_writel(struct snd_ad1889 *chip, unsigned reg, u32 val)
{
	writel(val, chip->iobase + reg);
}
示例#5
0
static inline void mxr_write(struct mxr_device *mdev, u32 reg_id, u32 val)
{
	writel(val, mdev->res.mxr_regs + reg_id);
}
示例#6
0
/*
 * Routine: misc_init_r
 * Description: Configure board specific parts
 */
int misc_init_r(void)
{
	struct gpio *gpio5_base = (struct gpio *)OMAP34XX_GPIO5_BASE;
	struct gpio *gpio6_base = (struct gpio *)OMAP34XX_GPIO6_BASE;

	beagle_identify();

	printf("\nProbing for expansion boards, if none are connected you'll see a harmless I2C error.\n");
	printf("u-boot TAMATAR!\n\n");
	switch (get_expansion_id()) {
		case TINCANTOOLS_ZIPPY:
			printf("Recognized Tincantools Zippy expansion board (rev %d %s)\n",
				expansion_config.revision, expansion_config.fab_revision);
			MUX_TINCANTOOLS_ZIPPY();
			setenv("buddy", "zippy");
			break;
		case TINCANTOOLS_ZIPPY2:
			printf("Recognized Tincantools Zippy2 expansion board (rev %d %s)\n",
				expansion_config.revision, expansion_config.fab_revision);
			MUX_TINCANTOOLS_ZIPPY();
			setenv("buddy", "zippy2");
			break;
		case TINCANTOOLS_TRAINER:
			printf("Recognized Tincantools Trainer expansion board (rev %d %s)\n",
				expansion_config.revision, expansion_config.fab_revision);
			MUX_TINCANTOOLS_ZIPPY();
			MUX_TINCANTOOLS_TRAINER();
			setenv("buddy", "trainer");
			break;
		case TINCANTOOLS_SHOWDOG:
			printf("Recognized Tincantools Showdow expansion board (rev %d %s)\n",
				expansion_config.revision, expansion_config.fab_revision);
			/* Place holder for DSS2 definition for showdog lcd */
			setenv("defaultdisplay", "showdoglcd");
			setenv("buddy", "showdog");
			break;
		case KBADC_BEAGLEFPGA:
			printf("Recognized KBADC Beagle FPGA board\n");
			MUX_KBADC_BEAGLEFPGA();
			setenv("buddy", "beaglefpga");
			break;
		case BEAGLE_NO_EEPROM:
			printf("No EEPROM on expansion board\n");
			setenv("buddy", "none");
			break;
		default:
			printf("Unrecognized expansion board: %x\n", expansion_config.device_vendor);
			setenv("buddy", "unknown");
	}

	if (expansion_config.content == 1)
		setenv(expansion_config.env_var, expansion_config.env_setting);

	i2c_set_bus_num(TWL4030_I2C_BUS);

	twl4030_power_init();
	twl4030_led_init(TWL4030_LED_LEDEN_LEDAON | TWL4030_LED_LEDEN_LEDBON);
	display_init();

	switch (beagle_revision) {
	case REVISION_AXBX:
		printf("Beagle Rev Ax/Bx\n");
		setenv("mpurate", "600");
		setenv("beaglerev", "AxBx");
		break;
	case REVISION_CX:
		printf("Beagle Rev C1/C2/C3\n");
		MUX_BEAGLE_C();
		setenv("mpurate", "600");
		setenv("beaglerev", "Cx");
		break;
	case REVISION_C4:
		printf("Beagle Rev C4\n");
		setenv("beaglerev", "Cx");
		MUX_BEAGLE_C();
		/* Set VAUX2 to 1.8V for EHCI PHY */
		twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VAUX2_DEDICATED,
					TWL4030_PM_RECEIVER_VAUX2_VSEL_18,
					TWL4030_PM_RECEIVER_VAUX2_DEV_GRP,
					TWL4030_PM_RECEIVER_DEV_GRP_P1);
		setenv("mpurate", "720");
		break;
	case REVISION_XM:
		printf("Beagle xM Rev A\n");
		setenv("beaglerev", "xMA");
		MUX_BEAGLE_XM();
		/* Set VAUX2 to 1.8V for EHCI PHY */
		twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VAUX2_DEDICATED,
					TWL4030_PM_RECEIVER_VAUX2_VSEL_18,
					TWL4030_PM_RECEIVER_VAUX2_DEV_GRP,
					TWL4030_PM_RECEIVER_DEV_GRP_P1);
		setenv("mpurate", "1000");
		break;
	default:
		printf("Beagle unknown 0x%02x\n", beagle_revision);
	}

	/* Configure GPIOs to output */
	writel(~(GPIO23 | GPIO10 | GPIO8 | GPIO2 | GPIO1), &gpio6_base->oe);
	writel(~(GPIO31 | GPIO30 | GPIO29 | GPIO28 | GPIO22 | GPIO21 |
		GPIO15 | GPIO14 | GPIO13 | GPIO12), &gpio5_base->oe);

	/* Set GPIOs */
	writel(GPIO23 | GPIO10 | GPIO8 | GPIO2 | GPIO1,
		&gpio6_base->setdataout);
	writel(GPIO31 | GPIO30 | GPIO29 | GPIO28 | GPIO22 | GPIO21 |
		GPIO15 | GPIO14 | GPIO13 | GPIO12, &gpio5_base->setdataout);

	dieid_num_r();
	omap3_dss_enable();

	return 0;
}
示例#7
0
文件: pcm043.c 项目: tteay/barebox
static int pcm043_core_setup(void)
{
    u32 tmp;

    /* AIPS setup - Only setup MPROTx registers. The PACR default values are good.*/
    /*
     * Set all MPROTx to be non-bufferable, trusted for R/W,
     * not forced to user-mode.
     */
    writel(0x77777777, MX35_AIPS1_BASE_ADDR);
    writel(0x77777777, MX35_AIPS1_BASE_ADDR + 0x4);
    writel(0x77777777, MX35_AIPS2_BASE_ADDR);
    writel(0x77777777, MX35_AIPS2_BASE_ADDR + 0x4);

    /*
     * Clear the on and off peripheral modules Supervisor Protect bit
     * for SDMA to access them. Did not change the AIPS control registers
     * (offset 0x20) access type
     */
    writel(0x0, MX35_AIPS1_BASE_ADDR + 0x40);
    writel(0x0, MX35_AIPS1_BASE_ADDR + 0x44);
    writel(0x0, MX35_AIPS1_BASE_ADDR + 0x48);
    writel(0x0, MX35_AIPS1_BASE_ADDR + 0x4C);
    tmp = readl(MX35_AIPS1_BASE_ADDR + 0x50);
    tmp &= 0x00FFFFFF;
    writel(tmp, MX35_AIPS1_BASE_ADDR + 0x50);

    writel(0x0, MX35_AIPS2_BASE_ADDR + 0x40);
    writel(0x0, MX35_AIPS2_BASE_ADDR + 0x44);
    writel(0x0, MX35_AIPS2_BASE_ADDR + 0x48);
    writel(0x0, MX35_AIPS2_BASE_ADDR + 0x4C);
    tmp = readl(MX35_AIPS2_BASE_ADDR + 0x50);
    tmp &= 0x00FFFFFF;
    writel(tmp, MX35_AIPS2_BASE_ADDR + 0x50);

    /* MAX (Multi-Layer AHB Crossbar Switch) setup */

    /* MPR - priority is M4 > M2 > M3 > M5 > M0 > M1 */
#define MAX_PARAM1 0x00302154
    writel(MAX_PARAM1, MX35_MAX_BASE_ADDR + 0x0);   /* for S0 */
    writel(MAX_PARAM1, MX35_MAX_BASE_ADDR + 0x100); /* for S1 */
    writel(MAX_PARAM1, MX35_MAX_BASE_ADDR + 0x200); /* for S2 */
    writel(MAX_PARAM1, MX35_MAX_BASE_ADDR + 0x300); /* for S3 */
    writel(MAX_PARAM1, MX35_MAX_BASE_ADDR + 0x400); /* for S4 */

    /* SGPCR - always park on last master */
    writel(0x10, MX35_MAX_BASE_ADDR + 0x10);	/* for S0 */
    writel(0x10, MX35_MAX_BASE_ADDR + 0x110);	/* for S1 */
    writel(0x10, MX35_MAX_BASE_ADDR + 0x210);	/* for S2 */
    writel(0x10, MX35_MAX_BASE_ADDR + 0x310);	/* for S3 */
    writel(0x10, MX35_MAX_BASE_ADDR + 0x410);	/* for S4 */

    /* MGPCR - restore default values */
    writel(0x0, MX35_MAX_BASE_ADDR + 0x800);	/* for M0 */
    writel(0x0, MX35_MAX_BASE_ADDR + 0x900);	/* for M1 */
    writel(0x0, MX35_MAX_BASE_ADDR + 0xa00);	/* for M2 */
    writel(0x0, MX35_MAX_BASE_ADDR + 0xb00);	/* for M3 */
    writel(0x0, MX35_MAX_BASE_ADDR + 0xc00);	/* for M4 */
    writel(0x0, MX35_MAX_BASE_ADDR + 0xd00);	/* for M5 */

    /*
     * M3IF Control Register (M3IFCTL)
     * MRRP[0] = L2CC0 not on priority list (0 << 0)	= 0x00000000
     * MRRP[1] = MAX1 not on priority list (0 << 0)		= 0x00000000
     * MRRP[2] = L2CC1 not on priority list (0 << 0)	= 0x00000000
     * MRRP[3] = USB  not on priority list (0 << 0)		= 0x00000000
     * MRRP[4] = SDMA not on priority list (0 << 0)		= 0x00000000
     * MRRP[5] = GPU not on priority list (0 << 0)		= 0x00000000
     * MRRP[6] = IPU1 on priority list (1 << 6)		= 0x00000040
     * MRRP[7] = IPU2 not on priority list (0 << 0)		= 0x00000000
     *                                                       ------------
     *                                                        0x00000040
     */
    writel(0x40, MX35_M3IF_BASE_ADDR);

    return 0;
}
示例#8
0
static int exynos_resume(void)
{
	writel(0, sysram_ns_base_addr + EXYNOS_BOOT_FLAG);

	return 0;
}
示例#9
0
static inline void ipc_write_data_high(IPC_DEV *ipcdev, IPC_TYPE type, u32 data)
{
	writel(data, ipcdev->base[type][BASE_DATA] + OFFSET_DATA_HIGH);
}
示例#10
0
static inline void otg_writel(struct tegra_otg_data *tegra, unsigned long val,
			      unsigned int offset)
{
	writel(val, tegra->regs + offset);
}
示例#11
0
static inline void ipc_write_cmd(IPC_DEV *ipcdev, IPC_TYPE type, u32 cmd)
{
	writel(cmd, ipcdev->base[type][BASE_IFACE]);
}
static inline void das_writel(unsigned long value, unsigned long offset)
{
	writel(value, IO_ADDRESS(TEGRA_APB_MISC_BASE) + offset);
}
示例#13
0
文件: ehci-omap.c 项目: UAVXP/A10
/**
 * ehci_hcd_omap_probe - initialize TI-based HCDs
 *
 * Allocates basic resources for this USB host controller, and
 * then invokes the start() method for the HCD associated with it
 * through the hotplug entry's driver_data.
 */
static int ehci_hcd_omap_probe(struct platform_device *pdev)
{
	struct ehci_hcd_omap_platform_data *pdata = pdev->dev.platform_data;
	struct ehci_hcd_omap *omap;
	struct resource *res;
	struct usb_hcd *hcd;

	int irq = platform_get_irq(pdev, 0);
	int ret = -ENODEV;

	printk(KERN_DEBUG " ehci_hcd_omap_probe\n");

	if (!pdata) {
		dev_dbg(&pdev->dev, "missing platform_data\n");
		goto err_pdata;
	}

	if (usb_disabled())
	{
		printk(KERN_DEBUG " usb_disabled\n");
		goto err_disabled;
	}

	omap = kzalloc(sizeof(*omap), GFP_KERNEL);
	printk(KERN_DEBUG " kzalloc done\n");
	
	if (!omap) {
		printk(KERN_DEBUG " problem with memory allocation\n");
		ret = -ENOMEM;
		goto err_disabled;
	}

	hcd = usb_create_hcd(&ehci_omap_hc_driver, &pdev->dev,
			dev_name(&pdev->dev));
	printk(KERN_DEBUG " usb_create hcd done\n");
	if (!hcd) {
		printk(KERN_DEBUG " failed to create HCD\n");
		dev_dbg(&pdev->dev, "failed to create hcd with err %d\n", ret);
		ret = -ENOMEM;
		goto err_create_hcd;
	}

	platform_set_drvdata(pdev, omap);
	omap->dev		= &pdev->dev;
	omap->phy_reset		= pdata->phy_reset;
	omap->reset_gpio_port[0]	= pdata->reset_gpio_port[0];
	omap->reset_gpio_port[1]	= pdata->reset_gpio_port[1];
	omap->reset_gpio_port[2]	= pdata->reset_gpio_port[2];
	omap->port_mode[0]		= pdata->port_mode[0];
	omap->port_mode[1]		= pdata->port_mode[1];
	omap->port_mode[2]		= pdata->port_mode[2];
	omap->ehci		= hcd_to_ehci(hcd);
	omap->ehci->sbrn	= 0x20;
	omap->suspended = 0;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	printk(KERN_DEBUG " platform get ressources 0 done\n");

	hcd->rsrc_start = res->start;
	hcd->rsrc_len = resource_size(res);

	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
	if (!hcd->regs) {
		printk(KERN_DEBUG " EHCI ioremap failed\n");
		dev_err(&pdev->dev, "EHCI ioremap failed\n");
		ret = -ENOMEM;
		goto err_ioremap;
	}

	/* we know this is the memory we want, no need to ioremap again */
	omap->ehci->caps = hcd->regs;
	omap->ehci_base = hcd->regs;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	printk(KERN_DEBUG " platform get ressources 1 done\n");
	
	omap->uhh_base = ioremap(res->start, resource_size(res));
	if (!omap->uhh_base) {
		printk(KERN_DEBUG " UHH ioremap failed\n");
		dev_err(&pdev->dev, "UHH ioremap failed\n");
		ret = -ENOMEM;
		goto err_uhh_ioremap;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
	printk(KERN_DEBUG " platform get ressources 2 done\n");
	

	ret = omap_start_ehc(omap, hcd);
	if (ret) {
		dev_dbg(&pdev->dev, "failed to start ehci\n");
		printk(KERN_DEBUG " failed to start ehci\n");
		goto err_start;
	}

	omap->ehci->regs = hcd->regs
		+ HC_LENGTH(readl(&omap->ehci->caps->hc_capbase));

	dbg_hcs_params(omap->ehci, "reset");
	dbg_hcc_params(omap->ehci, "reset");

	/* cache this readonly data; minimize chip reads */
	omap->ehci->hcs_params = readl(&omap->ehci->caps->hcs_params);

	/* SET 1 micro-frame Interrupt interval */
	writel(readl(&omap->ehci->regs->command) | (1 << 16),
			&omap->ehci->regs->command);

	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
	if (ret) {
		dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret);
		goto err_add_hcd;
	}
   EP10_HW_ID=ep_get_hardware_id();
   if(EP10_HW_ID==BOARD_VERSION_UNKNOWN)
   {
      EP10_HW_ID = BOARD_ID_DVT1 ;
   }
	printk(KERN_DEBUG " add hcd done\n");

	return 0;

err_add_hcd:
	omap_stop_ehc(omap, hcd);

err_start:
	//iounmap(omap->tll_base);

err_tll_ioremap:
	iounmap(omap->uhh_base);

err_uhh_ioremap:
	iounmap(hcd->regs);

err_ioremap:
	usb_put_hcd(hcd);

err_create_hcd:
	kfree(omap);
err_disabled:
err_pdata:
	return ret;
}
示例#14
0
static void dw_wdt_keepalive(void)
{
    writel(WDOG_COUNTER_RESTART_KICK_VALUE, dw_wdt.regs +
           WDOG_COUNTER_RESTART_REG_OFFSET);
}
示例#15
0
static int pc300_pci_init_one(struct pci_dev *pdev,
			      const struct pci_device_id *ent)
{
	card_t *card;
	u32 __iomem *p;
	int i;
	u32 ramsize;
	u32 ramphys;		/* buffer memory base */
	u32 scaphys;		/* SCA memory base */
	u32 plxphys;		/* PLX registers memory base */

	i = pci_enable_device(pdev);
	if (i)
		return i;

	i = pci_request_regions(pdev, "PC300");
	if (i) {
		pci_disable_device(pdev);
		return i;
	}

	card = kzalloc(sizeof(card_t), GFP_KERNEL);
	if (card == NULL) {
		pci_release_regions(pdev);
		pci_disable_device(pdev);
		return -ENOBUFS;
	}
	pci_set_drvdata(pdev, card);

	if (pci_resource_len(pdev, 0) != PC300_PLX_SIZE ||
	    pci_resource_len(pdev, 2) != PC300_SCA_SIZE ||
	    pci_resource_len(pdev, 3) < 16384) {
		pr_err("invalid card EEPROM parameters\n");
		pc300_pci_remove_one(pdev);
		return -EFAULT;
	}

	plxphys = pci_resource_start(pdev, 0) & PCI_BASE_ADDRESS_MEM_MASK;
	card->plxbase = ioremap(plxphys, PC300_PLX_SIZE);

	scaphys = pci_resource_start(pdev, 2) & PCI_BASE_ADDRESS_MEM_MASK;
	card->scabase = ioremap(scaphys, PC300_SCA_SIZE);

	ramphys = pci_resource_start(pdev, 3) & PCI_BASE_ADDRESS_MEM_MASK;
	card->rambase = pci_ioremap_bar(pdev, 3);

	if (card->plxbase == NULL ||
	    card->scabase == NULL ||
	    card->rambase == NULL) {
		pr_err("ioremap() failed\n");
		pc300_pci_remove_one(pdev);
	}

	/* PLX PCI 9050 workaround for local configuration register read bug */
	pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, scaphys);
	card->init_ctrl_value = readl(&((plx9050 __iomem *)card->scabase)->init_ctrl);
	pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, plxphys);

	if (pdev->device == PCI_DEVICE_ID_PC300_TE_1 ||
	    pdev->device == PCI_DEVICE_ID_PC300_TE_2)
		card->type = PC300_TE; /* not fully supported */
	else if (card->init_ctrl_value & PC300_CTYPE_MASK)
		card->type = PC300_X21;
	else
		card->type = PC300_RSV;

	if (pdev->device == PCI_DEVICE_ID_PC300_RX_1 ||
	    pdev->device == PCI_DEVICE_ID_PC300_TE_1)
		card->n_ports = 1;
	else
		card->n_ports = 2;

	for (i = 0; i < card->n_ports; i++)
		if (!(card->ports[i].netdev = alloc_hdlcdev(&card->ports[i]))) {
			pr_err("unable to allocate memory\n");
			pc300_pci_remove_one(pdev);
			return -ENOMEM;
		}

	/* Reset PLX */
	p = &card->plxbase->init_ctrl;
	writel(card->init_ctrl_value | 0x40000000, p);
	readl(p);		/* Flush the write - do not use sca_flush */
	udelay(1);

	writel(card->init_ctrl_value, p);
	readl(p);		/* Flush the write - do not use sca_flush */
	udelay(1);

	/* Reload Config. Registers from EEPROM */
	writel(card->init_ctrl_value | 0x20000000, p);
	readl(p);		/* Flush the write - do not use sca_flush */
	udelay(1);

	writel(card->init_ctrl_value, p);
	readl(p);		/* Flush the write - do not use sca_flush */
	udelay(1);

	ramsize = sca_detect_ram(card, card->rambase,
				 pci_resource_len(pdev, 3));

	if (use_crystal_clock)
		card->init_ctrl_value &= ~PC300_CLKSEL_MASK;
	else
		card->init_ctrl_value |= PC300_CLKSEL_MASK;

	writel(card->init_ctrl_value, &card->plxbase->init_ctrl);
	/* number of TX + RX buffers for one port */
	i = ramsize / (card->n_ports * (sizeof(pkt_desc) + HDLC_MAX_MRU));
	card->tx_ring_buffers = min(i / 2, MAX_TX_BUFFERS);
	card->rx_ring_buffers = i - card->tx_ring_buffers;

	card->buff_offset = card->n_ports * sizeof(pkt_desc) *
		(card->tx_ring_buffers + card->rx_ring_buffers);

	pr_info("PC300/%s, %u KB RAM at 0x%x, IRQ%u, using %u TX + %u RX packets rings\n",
		card->type == PC300_X21 ? "X21" :
		card->type == PC300_TE ? "TE" : "RSV",
		ramsize / 1024, ramphys, pdev->irq,
		card->tx_ring_buffers, card->rx_ring_buffers);

	if (card->tx_ring_buffers < 1) {
		pr_err("RAM test failed\n");
		pc300_pci_remove_one(pdev);
		return -EFAULT;
	}

	/* Enable interrupts on the PCI bridge, LINTi1 active low */
	writew(0x0041, &card->plxbase->intr_ctrl_stat);

	/* Allocate IRQ */
	if (request_irq(pdev->irq, sca_intr, IRQF_SHARED, "pc300", card)) {
		pr_warn("could not allocate IRQ%d\n", pdev->irq);
		pc300_pci_remove_one(pdev);
		return -EBUSY;
	}
	card->irq = pdev->irq;

	sca_init(card, 0);

	// COTE not set - allows better TX DMA settings
	// sca_out(sca_in(PCR, card) | PCR_COTE, PCR, card);

	sca_out(0x10, BTCR, card);

	for (i = 0; i < card->n_ports; i++) {
		port_t *port = &card->ports[i];
		struct net_device *dev = port->netdev;
		hdlc_device *hdlc = dev_to_hdlc(dev);
		port->chan = i;

		spin_lock_init(&port->lock);
		dev->irq = card->irq;
		dev->mem_start = ramphys;
		dev->mem_end = ramphys + ramsize - 1;
		dev->tx_queue_len = 50;
		dev->netdev_ops = &pc300_ops;
		hdlc->attach = sca_attach;
		hdlc->xmit = sca_xmit;
		port->settings.clock_type = CLOCK_EXT;
		port->card = card;
		if (card->type == PC300_X21)
			port->iface = IF_IFACE_X21;
		else
			port->iface = IF_IFACE_V35;

		sca_init_port(port);
		if (register_hdlc_device(dev)) {
			pr_err("unable to register hdlc device\n");
			port->card = NULL;
			pc300_pci_remove_one(pdev);
			return -ENOBUFS;
		}

		netdev_info(dev, "PC300 channel %d\n", port->chan);
	}
	return 0;
}
示例#16
0
static int rx_sync_cmd(struct aac_dev *dev, u32 command,
	u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6,
	u32 *status, u32 * r1, u32 * r2, u32 * r3, u32 * r4)
{
	unsigned long start;
	int ok;
	/*
	 *	Write the command into Mailbox 0
	 */
	writel(command, &dev->IndexRegs->Mailbox[0]);
	/*
	 *	Write the parameters into Mailboxes 1 - 6
	 */
	writel(p1, &dev->IndexRegs->Mailbox[1]);
	writel(p2, &dev->IndexRegs->Mailbox[2]);
	writel(p3, &dev->IndexRegs->Mailbox[3]);
	writel(p4, &dev->IndexRegs->Mailbox[4]);
	/*
	 *	Clear the synch command doorbell to start on a clean slate.
	 */
	rx_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
	/*
	 *	Disable doorbell interrupts
	 */
	rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff);
	/*
	 *	Force the completion of the mask register write before issuing
	 *	the interrupt.
	 */
	rx_readb (dev, MUnit.OIMR);
	/*
	 *	Signal that there is a new synch command
	 */
	rx_writel(dev, InboundDoorbellReg, INBOUNDDOORBELL_0);

	ok = 0;
	start = jiffies;

	/*
	 *	Wait up to 30 seconds
	 */
	while (time_before(jiffies, start+30*HZ))
	{
		udelay(5);	/* Delay 5 microseconds to let Mon960 get info. */
		/*
		 *	Mon960 will set doorbell0 bit when it has completed the command.
		 */
		if (rx_readl(dev, OutboundDoorbellReg) & OUTBOUNDDOORBELL_0) {
			/*
			 *	Clear the doorbell.
			 */
			rx_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
			ok = 1;
			break;
		}
		/*
		 *	Yield the processor in case we are slow
		 */
		msleep(1);
	}
	if (unlikely(ok != 1)) {
		/*
		 *	Restore interrupt mask even though we timed out
		 */
		aac_adapter_enable_int(dev);
		return -ETIMEDOUT;
	}
	/*
	 *	Pull the synch status from Mailbox 0.
	 */
	if (status)
		*status = readl(&dev->IndexRegs->Mailbox[0]);
	if (r1)
		*r1 = readl(&dev->IndexRegs->Mailbox[1]);
	if (r2)
		*r2 = readl(&dev->IndexRegs->Mailbox[2]);
	if (r3)
		*r3 = readl(&dev->IndexRegs->Mailbox[3]);
	if (r4)
		*r4 = readl(&dev->IndexRegs->Mailbox[4]);
	/*
	 *	Clear the synch command doorbell.
	 */
	rx_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
	/*
	 *	Restore interrupt mask
	 */
	aac_adapter_enable_int(dev);
	return 0;

}
static void cmx2xx_pci_preinit(void)
{
	pr_info("Initializing CM-X2XX PCI subsystem\n");

	__raw_writel(0x800, IT8152_PCI_CFG_ADDR);
	if (__raw_readl(IT8152_PCI_CFG_DATA) == 0x81521283) {
		pr_info("PCI Bridge found.\n");

		/* set PCI I/O base at 0 */
		writel(0x848, IT8152_PCI_CFG_ADDR);
		writel(0, IT8152_PCI_CFG_DATA);

		/* set PCI memory base at 0 */
		writel(0x840, IT8152_PCI_CFG_ADDR);
		writel(0, IT8152_PCI_CFG_DATA);

		writel(0x20, IT8152_GPIO_GPDR);

		/* CardBus Controller on ATXbase baseboard */
		writel(0x4000, IT8152_PCI_CFG_ADDR);
		if (readl(IT8152_PCI_CFG_DATA) == 0xAC51104C) {
			pr_info("CardBus Bridge found.\n");

			/* Configure socket 0 */
			writel(0x408C, IT8152_PCI_CFG_ADDR);
			writel(0x1022, IT8152_PCI_CFG_DATA);

			writel(0x4080, IT8152_PCI_CFG_ADDR);
			writel(0x3844d060, IT8152_PCI_CFG_DATA);

			writel(0x4090, IT8152_PCI_CFG_ADDR);
			writel(((readl(IT8152_PCI_CFG_DATA) & 0xffff) |
				0x60440000),
			       IT8152_PCI_CFG_DATA);

			writel(0x4018, IT8152_PCI_CFG_ADDR);
			writel(0xb0000000, IT8152_PCI_CFG_DATA);

			/* Configure socket 1 */
			writel(0x418C, IT8152_PCI_CFG_ADDR);
			writel(0x1022, IT8152_PCI_CFG_DATA);

			writel(0x4180, IT8152_PCI_CFG_ADDR);
			writel(0x3844d060, IT8152_PCI_CFG_DATA);

			writel(0x4190, IT8152_PCI_CFG_ADDR);
			writel(((readl(IT8152_PCI_CFG_DATA) & 0xffff) |
				0x60440000),
			       IT8152_PCI_CFG_DATA);

			writel(0x4118, IT8152_PCI_CFG_ADDR);
			writel(0xb0000000, IT8152_PCI_CFG_DATA);
		}
	}
}
示例#18
0
static void vic_unmask_irq(unsigned int irq)
{
	void __iomem *base = get_irq_chip_data(irq);
	irq &= 31;
	writel(1 << irq, base + VIC_INT_ENABLE);
}
示例#19
0
static inline void b1dma_writel(avmcard *card, u32 value, int off)
{
	writel(value, card->mbase + off);
}
示例#20
0
static inline void img_spdif_in_writel(struct img_spdif_in *spdif,
					u32 val, u32 reg)
{
	writel(val, spdif->base + reg);
}
示例#21
0
/*
 * The block needs writes in both MSW and LSW in order
 * for all data lines to reach their destination.
 */
static inline void stu300_wr8(u32 value, void __iomem *address)
{
	writel((value << 16) | value, address);
}
示例#22
0
static inline void snor_tegra_writel(struct tegra_gmi_pca_info *tsnor,
					unsigned long val, unsigned long reg)
{
	writel(val, tsnor->base + reg);
}
示例#23
0
static inline void snd_bt87x_writel(bt87x_t *chip, u32 reg, u32 value)
{
	writel(value, chip->mmio + reg);
}
示例#24
0
文件: offb.c 项目: CSCLOG/beaglebone
static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
			  u_int transp, struct fb_info *info)
{
	struct offb_par *par = (struct offb_par *) info->par;
	int i, depth;
	u32 *pal = info->pseudo_palette;

	depth = info->var.bits_per_pixel;
	if (depth == 16)
		depth = (info->var.green.length == 5) ? 15 : 16;

	if (regno > 255 ||
	    (depth == 16 && regno > 63) ||
	    (depth == 15 && regno > 31))
		return 1;

	if (regno < 16) {
		switch (depth) {
		case 15:
			pal[regno] = (regno << 10) | (regno << 5) | regno;
			break;
		case 16:
			pal[regno] = (regno << 11) | (regno << 5) | regno;
			break;
		case 24:
			pal[regno] = (regno << 16) | (regno << 8) | regno;
			break;
		case 32:
			i = (regno << 8) | regno;
			pal[regno] = (i << 16) | i;
			break;
		}
	}

	red >>= 8;
	green >>= 8;
	blue >>= 8;

	if (!par->cmap_adr)
		return 0;

	switch (par->cmap_type) {
	case cmap_m64:
		writeb(regno, par->cmap_adr);
		writeb(red, par->cmap_data);
		writeb(green, par->cmap_data);
		writeb(blue, par->cmap_data);
		break;
	case cmap_M3A:
		/* Clear PALETTE_ACCESS_CNTL in DAC_CNTL */
		out_le32(par->cmap_adr + 0x58,
			 in_le32(par->cmap_adr + 0x58) & ~0x20);
	case cmap_r128:
		/* Set palette index & data */
		out_8(par->cmap_adr + 0xb0, regno);
		out_le32(par->cmap_adr + 0xb4,
			 (red << 16 | green << 8 | blue));
		break;
	case cmap_M3B:
		/* Set PALETTE_ACCESS_CNTL in DAC_CNTL */
		out_le32(par->cmap_adr + 0x58,
			 in_le32(par->cmap_adr + 0x58) | 0x20);
		/* Set palette index & data */
		out_8(par->cmap_adr + 0xb0, regno);
		out_le32(par->cmap_adr + 0xb4, (red << 16 | green << 8 | blue));
		break;
	case cmap_radeon:
		/* Set palette index & data (could be smarter) */
		out_8(par->cmap_adr + 0xb0, regno);
		out_le32(par->cmap_adr + 0xb4, (red << 16 | green << 8 | blue));
		break;
	case cmap_gxt2000:
		out_le32(((unsigned __iomem *) par->cmap_adr) + regno,
			 (red << 16 | green << 8 | blue));
		break;
	case cmap_avivo:
		/* Write to both LUTs for now */
		writel(1, par->cmap_adr + AVIVO_DC_LUT_RW_SELECT);
		writeb(regno, par->cmap_adr + AVIVO_DC_LUT_RW_INDEX);
		writel(((red) << 22) | ((green) << 12) | ((blue) << 2),
		       par->cmap_adr + AVIVO_DC_LUT_30_COLOR);
		writel(0, par->cmap_adr + AVIVO_DC_LUT_RW_SELECT);
		writeb(regno, par->cmap_adr + AVIVO_DC_LUT_RW_INDEX);
		writel(((red) << 22) | ((green) << 12) | ((blue) << 2),
		       par->cmap_adr + AVIVO_DC_LUT_30_COLOR);
		break;
	}

	return 0;
}
示例#25
0
static int zynq_gem_init(struct udevice *dev)
{
	u32 i, nwconfig;
	int ret;
	unsigned long clk_rate = 0;
	struct zynq_gem_priv *priv = dev_get_priv(dev);
	struct zynq_gem_regs *regs = priv->iobase;
	struct emac_bd *dummy_tx_bd = &priv->tx_bd[TX_FREE_DESC];
	struct emac_bd *dummy_rx_bd = &priv->tx_bd[TX_FREE_DESC + 2];

	if (!priv->init) {
		/* Disable all interrupts */
		writel(0xFFFFFFFF, &regs->idr);

		/* Disable the receiver & transmitter */
		writel(0, &regs->nwctrl);
		writel(0, &regs->txsr);
		writel(0, &regs->rxsr);
		writel(0, &regs->phymntnc);

		/* Clear the Hash registers for the mac address
		 * pointed by AddressPtr
		 */
		writel(0x0, &regs->hashl);
		/* Write bits [63:32] in TOP */
		writel(0x0, &regs->hashh);

		/* Clear all counters */
		for (i = 0; i < STAT_SIZE; i++)
			readl(&regs->stat[i]);

		/* Setup RxBD space */
		memset(priv->rx_bd, 0, RX_BUF * sizeof(struct emac_bd));

		for (i = 0; i < RX_BUF; i++) {
			priv->rx_bd[i].status = 0xF0000000;
			priv->rx_bd[i].addr =
					((ulong)(priv->rxbuffers) +
							(i * PKTSIZE_ALIGN));
		}
		/* WRAP bit to last BD */
		priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK;
		/* Write RxBDs to IP */
		writel((ulong)priv->rx_bd, &regs->rxqbase);

		/* Setup for DMA Configuration register */
		writel(ZYNQ_GEM_DMACR_INIT, &regs->dmacr);

		/* Setup for Network Control register, MDIO, Rx and Tx enable */
		setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK);

		/* Disable the second priority queue */
		dummy_tx_bd->addr = 0;
		dummy_tx_bd->status = ZYNQ_GEM_TXBUF_WRAP_MASK |
				ZYNQ_GEM_TXBUF_LAST_MASK|
				ZYNQ_GEM_TXBUF_USED_MASK;

		dummy_rx_bd->addr = ZYNQ_GEM_RXBUF_WRAP_MASK |
				ZYNQ_GEM_RXBUF_NEW_MASK;
		dummy_rx_bd->status = 0;
		flush_dcache_range((ulong)&dummy_tx_bd, (ulong)&dummy_tx_bd +
				   sizeof(dummy_tx_bd));
		flush_dcache_range((ulong)&dummy_rx_bd, (ulong)&dummy_rx_bd +
				   sizeof(dummy_rx_bd));

		writel((ulong)dummy_tx_bd, &regs->transmit_q1_ptr);
		writel((ulong)dummy_rx_bd, &regs->receive_q1_ptr);

		priv->init++;
	}

	ret = phy_startup(priv->phydev);
	if (ret)
		return ret;

	if (!priv->phydev->link) {
		printf("%s: No link.\n", priv->phydev->dev->name);
		return -1;
	}

	nwconfig = ZYNQ_GEM_NWCFG_INIT;

	if (priv->interface == PHY_INTERFACE_MODE_SGMII) {
		nwconfig |= ZYNQ_GEM_NWCFG_SGMII_ENBL |
			    ZYNQ_GEM_NWCFG_PCS_SEL;
#ifdef CONFIG_ARM64
		writel(readl(&regs->pcscntrl) | ZYNQ_GEM_PCS_CTL_ANEG_ENBL,
		       &regs->pcscntrl);
#endif
	}

	switch (priv->phydev->speed) {
	case SPEED_1000:
		writel(nwconfig | ZYNQ_GEM_NWCFG_SPEED1000,
		       &regs->nwcfg);
		clk_rate = ZYNQ_GEM_FREQUENCY_1000;
		break;
	case SPEED_100:
		writel(nwconfig | ZYNQ_GEM_NWCFG_SPEED100,
		       &regs->nwcfg);
		clk_rate = ZYNQ_GEM_FREQUENCY_100;
		break;
	case SPEED_10:
		clk_rate = ZYNQ_GEM_FREQUENCY_10;
		break;
	}

	/* Change the rclk and clk only not using EMIO interface */
	if (!priv->emio)
		zynq_slcr_gem_clk_setup((ulong)priv->iobase !=
					ZYNQ_GEM_BASEADDR0, clk_rate);

	setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK |
					ZYNQ_GEM_NWCTRL_TXEN_MASK);

	return 0;
}
/* These registers settings are just valid for Numonyx M29W256GL7AN6E. */
static void mx6q_setup_weimcs(void)
{
	void __iomem *nor_reg = MX6_IO_ADDRESS(WEIM_BASE_ADDR);
	void __iomem *ccm_reg = MX6_IO_ADDRESS(CCM_BASE_ADDR);
	unsigned int reg;
	struct clk *clk;
	u32 rate;

	/* CLKCTL_CCGR6: Set emi_slow_clock to be on in all modes */
	reg = readl(ccm_reg + 0x80);
	reg |= 0x00000C00;
	writel(reg, ccm_reg + 0x80);

	/* Timing settings below based upon datasheet for M29W256GL7AN6E
	   These setting assume that the EIM_SLOW_CLOCK is set to 132 MHz */
	clk = clk_get(NULL, "emi_slow_clk");
	if (IS_ERR(clk))
		printk(KERN_ERR "emi_slow_clk not found\n");

	rate = clk_get_rate(clk);
	if (rate != 132000000)
		printk(KERN_ERR "Warning: emi_slow_clk not set to 132 MHz!"
		       " WEIM NOR timing may be incorrect!\n");

	/*
	 * For EIM General Configuration registers.
	 *
	 * CS0GCR1:
	 *	GBC = 0; CSREC = 6; DSZ = 2; BL = 0;
	 *	CREP = 1; CSEN = 1;
	 *
	 *	EIM Operation Mode: MUM = SRD = SWR = 0.
	 *		(Async write/Async page read, none multiplexed)
	 *
	 * CS0GCR2:
	 *	ADH = 1
	 */
	writel(0x00620081, nor_reg);
	writel(0x00000001, nor_reg + 0x00000004);

	/*
	 * For EIM Read Configuration registers.
	 *
	 * CS0RCR1:
	 *	RWSC = 1C;
	 *	RADVA = 0; RADVN = 2;
	 *	OEA = 2; OEN = 0;
	 *	RCSA = 0; RCSN = 0
	 *
	 * CS0RCR2:
	 *	APR = 1 (Async Page Read);
	 *	PAT = 4 (6 EIM clock sycles)
	 */
	writel(0x1C022000, nor_reg + 0x00000008);
	writel(0x0000C000, nor_reg + 0x0000000C);

	/*
	 * For EIM Write Configuration registers.
	 *
	 * CS0WCR1:
	 *	WWSC = 20;
	 *	WADVA = 0; WADVN = 1;
	 *	WBEA = 1; WBEN = 2;
	 *	WEA = 1; WEN = 6;
	 *	WCSA = 1; WCSN = 2;
	 *
	 * CS0WCR2:
	 *	WBCDD = 0
	 */
	writel(0x1404a38e, nor_reg + 0x00000010);
	writel(0x00000000, nor_reg + 0x00000014);
}
示例#27
0
void simple_lcd_init(void)
{

	writel(0xaaaaaaaa, 0x20E100c4);
	writel(0xaaaaaaaa, 0x20E100d4);


	writel(0, 0x20cd1000);
	writel(1, 0x20cd1004);
	writel(0x16, 0x20cd1080);
	writel(0, 0x20cd1084);
	writel(((IMAPFB_HRES - 1) << 16) |
	   ((IMAPFB_VRES - 1) << 0), 0x20cd1088);
	writel(CONFIG_RESV_LCD_BASE_1, 0x20cd108c);
	writel(IMAPFB_HRES, 0x20cd1094);
	writel(0x17, 0x20cd1080);
	writel((IMAP_LCDCON2_VBPD(IMAPFB_VBP - 1) |
		   IMAP_LCDCON2_LINEVAL(IMAPFB_VRES - 1) |
		   IMAP_LCDCON2_VFPD(IMAPFB_VFP - 1) |
		   IMAP_LCDCON2_VSPW(IMAPFB_VSW - 1)), 0x20cd0004);
	writel((IMAP_LCDCON3_HBPD(IMAPFB_HBP - 1) |
		   IMAP_LCDCON3_HOZVAL(IMAPFB_HRES - 1) |
		   IMAP_LCDCON3_HFPD(IMAPFB_HFP - 1)), 0x20cd0008);
	writel(IMAP_LCDCON4_HSPW(IMAPFB_HSW - 1), 0x20cd000c);
	writel(CONFIG_LCDCON5, 0x20cd0010);
	writel((1 << 8) | 1, 0x20cd0000);

	writel(readl(CONFIG_LCD_BL_GPIO + 4) | (1 << (CONFIG_LCD_BL_GPIO_Bit*2)),
	   CONFIG_LCD_BL_GPIO + 4);
	writel(readl(CONFIG_LCD_BL_GPIO) | (1 << CONFIG_LCD_BL_GPIO_Bit),
	   CONFIG_LCD_BL_GPIO);
	writel(readl(GPFCON) | (0x1 << (CONFIG_LCD_TOUT_PIN * 2 + 0xc)),
	   GPFCON);
#ifdef CONFIG_LCD_BL_LOW
	writel(readl(GPFDAT) & ~(1 << (CONFIG_LCD_TOUT_PIN + 6)), GPFDAT);
#else
	writel(readl(GPFDAT) | (1 << (CONFIG_LCD_TOUT_PIN + 6)), GPFDAT);
#endif

}
示例#28
0
static void enable_idgnd(struct msm_otg *dev)
{
	ulpi_write(dev, (1<<4), 0x0E);
	ulpi_write(dev, (1<<4), 0x11);
	writel(readl(USB_OTGSC) | OTGSC_IDIE, USB_OTGSC);
}
示例#29
0
文件: dma.c 项目: ivucica/linux
static inline int
s3c2410_dma_loadbuffer(struct s3c2410_dma_chan *chan,
		       struct s3c2410_dma_buf *buf)
{
	unsigned long reload;

	pr_debug("s3c2410_chan_loadbuffer: loading buff %p (0x%08lx,0x%06x)\n",
		 buf, (unsigned long)buf->data, buf->size);

	if (buf == NULL) {
		dmawarn("buffer is NULL\n");
		return -EINVAL;
	}

	/* check the state of the channel before we do anything */

	if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
		dmawarn("load_state is S3C2410_DMALOAD_1LOADED\n");
	}

	if (chan->load_state == S3C2410_DMALOAD_1LOADED_1RUNNING) {
		dmawarn("state is S3C2410_DMALOAD_1LOADED_1RUNNING\n");
	}

	/* it would seem sensible if we are the last buffer to not bother
	 * with the auto-reload bit, so that the DMA engine will not try
	 * and load another transfer after this one has finished...
	 */
	if (chan->load_state == S3C2410_DMALOAD_NONE) {
		pr_debug("load_state is none, checking for noreload (next=%p)\n",
			 buf->next);
		reload = (buf->next == NULL) ? S3C2410_DCON_NORELOAD : 0;
	} else {
		//pr_debug("load_state is %d => autoreload\n", chan->load_state);
		reload = S3C2410_DCON_AUTORELOAD;
	}

	if ((buf->data & 0xf0000000) != 0x30000000) {
		dmawarn("dmaload: buffer is %p\n", (void *)buf->data);
	}

	writel(buf->data, chan->addr_reg);

	dma_wrreg(chan, S3C2410_DMA_DCON,
		  chan->dcon | reload | (buf->size/chan->xfer_unit));

	chan->next = buf->next;

	/* update the state of the channel */

	switch (chan->load_state) {
	case S3C2410_DMALOAD_NONE:
		chan->load_state = S3C2410_DMALOAD_1LOADED;
		break;

	case S3C2410_DMALOAD_1RUNNING:
		chan->load_state = S3C2410_DMALOAD_1LOADED_1RUNNING;
		break;

	default:
		dmawarn("dmaload: unknown state %d in loadbuffer\n",
			chan->load_state);
		break;
	}

	return 0;
}