void __init board_setup(void) { u32 pin_func = 0; /* Not valid for Au1550 */ #if defined(CONFIG_IRDA) && \ (defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100)) /* Set IRFIRSEL instead of GPIO15 */ pin_func = au_readl(SYS_PINFUNC) | SYS_PF_IRF; au_writel(pin_func, SYS_PINFUNC); /* Power off until the driver is in use */ bcsr->resets &= ~BCSR_RESETS_IRDA_MODE_MASK; bcsr->resets |= BCSR_RESETS_IRDA_MODE_OFF; au_sync(); #endif bcsr->pcmcia = 0x0000; /* turn off PCMCIA power */ #ifdef CONFIG_MIPS_MIRAGE /* Enable GPIO[31:0] inputs */ au_writel(0, SYS_PININPUTEN); /* GPIO[20] is output, tristate the other input primary GPIOs */ au_writel(~(1 << 20), SYS_TRIOUTCLR); /* Set GPIO[210:208] instead of SSI_0 */ pin_func = au_readl(SYS_PINFUNC) | SYS_PF_S0; /* Set GPIO[215:211] for LEDs */ pin_func |= 5 << 2; /* Set GPIO[214:213] for more LEDs */ pin_func |= 5 << 12; /* Set GPIO[207:200] instead of PCMCIA/LCD */ pin_func |= SYS_PF_LCD | SYS_PF_PC; au_writel(pin_func, SYS_PINFUNC); /* * Enable speaker amplifier. This should * be part of the audio driver. */ au_writel(au_readl(GPIO2_DIR) | 0x200, GPIO2_DIR); au_writel(0x02000200, GPIO2_OUTPUT); #endif au_sync(); #ifdef CONFIG_MIPS_DB1000 printk(KERN_INFO "AMD Alchemy Au1000/Db1000 Board\n"); #endif #ifdef CONFIG_MIPS_DB1500 printk(KERN_INFO "AMD Alchemy Au1500/Db1500 Board\n"); #endif #ifdef CONFIG_MIPS_DB1100 printk(KERN_INFO "AMD Alchemy Au1100/Db1100 Board\n"); #endif #ifdef CONFIG_MIPS_BOSPORUS printk(KERN_INFO "AMD Alchemy Bosporus Board\n"); #endif #ifdef CONFIG_MIPS_MIRAGE printk(KERN_INFO "AMD Alchemy Mirage Board\n"); #endif #ifdef CONFIG_MIPS_DB1550 printk(KERN_INFO "AMD Alchemy Au1550/Db1550 Board\n"); #endif }
static void save_core_regs(void) { extern void save_au1xxx_intctl(void); extern void pm_eth0_shutdown(void); /* * Do the serial ports.....these really should be a pm_* * registered function by the driver......but of course the * standard serial driver doesn't understand our Au1xxx * unique registers. */ sleep_uart0_inten = au_readl(UART0_ADDR + UART_IER); sleep_uart0_fifoctl = au_readl(UART0_ADDR + UART_FCR); sleep_uart0_linectl = au_readl(UART0_ADDR + UART_LCR); sleep_uart0_clkdiv = au_readl(UART0_ADDR + UART_CLK); sleep_uart0_enable = au_readl(UART0_ADDR + UART_MOD_CNTRL); au_sync(); #ifndef CONFIG_SOC_AU1200 /* Shutdown USB host/device. */ sleep_usb[0] = au_readl(USB_HOST_CONFIG); /* There appears to be some undocumented reset register.... */ au_writel(0, 0xb0100004); au_sync(); au_writel(0, USB_HOST_CONFIG); au_sync(); sleep_usb[1] = au_readl(USBD_ENABLE); au_writel(0, USBD_ENABLE); au_sync(); #else /* AU1200 */ /* enable access to OTG mmio so we can save OTG CAP/MUX. * FIXME: write an OTG driver and move this stuff there! */ au_writel(au_readl(USB_MSR_BASE + 4) | (1 << 6), USB_MSR_BASE + 4); au_sync(); sleep_usb[0] = au_readl(0xb4020020); /* OTG_CAP */ sleep_usb[1] = au_readl(0xb4020024); /* OTG_MUX */ #endif /* Save interrupt controller state. */ save_au1xxx_intctl(); /* Clocks and PLLs. */ sleep_sys_clocks[0] = au_readl(SYS_FREQCTRL0); sleep_sys_clocks[1] = au_readl(SYS_FREQCTRL1); sleep_sys_clocks[2] = au_readl(SYS_CLKSRC); sleep_sys_clocks[3] = au_readl(SYS_CPUPLL); sleep_sys_clocks[4] = au_readl(SYS_AUXPLL); /* pin mux config */ sleep_sys_pinfunc = au_readl(SYS_PINFUNC); /* Save the static memory controller configuration. */ sleep_static_memctlr[0][0] = au_readl(MEM_STCFG0); sleep_static_memctlr[0][1] = au_readl(MEM_STTIME0); sleep_static_memctlr[0][2] = au_readl(MEM_STADDR0); sleep_static_memctlr[1][0] = au_readl(MEM_STCFG1); sleep_static_memctlr[1][1] = au_readl(MEM_STTIME1); sleep_static_memctlr[1][2] = au_readl(MEM_STADDR1); sleep_static_memctlr[2][0] = au_readl(MEM_STCFG2); sleep_static_memctlr[2][1] = au_readl(MEM_STTIME2); sleep_static_memctlr[2][2] = au_readl(MEM_STADDR2); sleep_static_memctlr[3][0] = au_readl(MEM_STCFG3); sleep_static_memctlr[3][1] = au_readl(MEM_STTIME3); sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3); #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) au1xxx_dbdma_suspend(); #endif }
unsigned long prid, cpufreq, bclk; set_cpuspec(); sp = cur_cpu_spec[0]; board_setup(); /* board specific setup */ prid = read_c0_prid(); if (sp->cpu_pll_wo) #ifdef CONFIG_SOC_AU1000_FREQUENCY cpufreq = CONFIG_SOC_AU1000_FREQUENCY / 1000000; #else cpufreq = 396; #endif else cpufreq = (au_readl(SYS_CPUPLL) & 0x3F) * 12; printk(KERN_INFO "(PRID %08lx) @ %ld MHz\n", prid, cpufreq); if (sp->cpu_bclk) { /* Enable BCLK switching */ bclk = au_readl(SYS_POWERCTRL); au_writel(bclk | 0x60, SYS_POWERCTRL); printk(KERN_INFO "BCLK switching enabled!\n"); } if (sp->cpu_od) /* Various early Au1xx0 errata corrected by this */ set_c0_config(1 << 19); /* Set Config[OD] */ else /* Clear to obtain best system bus performance */ clear_c0_config(1 << 19); /* Clear Config[OD] */
static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset) { return au_readl((unsigned long)up->port.membase + offset); }
static void restore_core_regs(void) { /* restore clock configuration. Writing CPUPLL last will * stall a bit and stabilize other clocks (unless this is * one of those Au1000 with a write-only PLL, where we dont * have a valid value) */ au_writel(sleep_sys_clocks[0], SYS_FREQCTRL0); au_writel(sleep_sys_clocks[1], SYS_FREQCTRL1); au_writel(sleep_sys_clocks[2], SYS_CLKSRC); au_writel(sleep_sys_clocks[4], SYS_AUXPLL); if (!au1xxx_cpu_has_pll_wo()) au_writel(sleep_sys_clocks[3], SYS_CPUPLL); au_sync(); au_writel(sleep_sys_pinfunc, SYS_PINFUNC); au_sync(); #ifndef CONFIG_SOC_AU1200 au_writel(sleep_usb[0], USB_HOST_CONFIG); au_writel(sleep_usb[1], USBD_ENABLE); au_sync(); #else /* enable accces to OTG memory */ au_writel(au_readl(USB_MSR_BASE + 4) | (1 << 6), USB_MSR_BASE + 4); au_sync(); /* restore OTG caps and port mux. */ au_writel(sleep_usb[0], 0xb4020020 + 0); /* OTG_CAP */ au_sync(); au_writel(sleep_usb[1], 0xb4020020 + 4); /* OTG_MUX */ au_sync(); #endif /* Restore the static memory controller configuration. */ au_writel(sleep_static_memctlr[0][0], MEM_STCFG0); au_writel(sleep_static_memctlr[0][1], MEM_STTIME0); au_writel(sleep_static_memctlr[0][2], MEM_STADDR0); au_writel(sleep_static_memctlr[1][0], MEM_STCFG1); au_writel(sleep_static_memctlr[1][1], MEM_STTIME1); au_writel(sleep_static_memctlr[1][2], MEM_STADDR1); au_writel(sleep_static_memctlr[2][0], MEM_STCFG2); au_writel(sleep_static_memctlr[2][1], MEM_STTIME2); au_writel(sleep_static_memctlr[2][2], MEM_STADDR2); au_writel(sleep_static_memctlr[3][0], MEM_STCFG3); au_writel(sleep_static_memctlr[3][1], MEM_STTIME3); au_writel(sleep_static_memctlr[3][2], MEM_STADDR3); /* * Enable the UART if it was enabled before sleep. * I guess I should define module control bits........ */ if (sleep_uart0_enable & 0x02) { au_writel(0, UART0_ADDR + UART_MOD_CNTRL); au_sync(); au_writel(1, UART0_ADDR + UART_MOD_CNTRL); au_sync(); au_writel(3, UART0_ADDR + UART_MOD_CNTRL); au_sync(); au_writel(sleep_uart0_inten, UART0_ADDR + UART_IER); au_sync(); au_writel(sleep_uart0_fifoctl, UART0_ADDR + UART_FCR); au_sync(); au_writel(sleep_uart0_linectl, UART0_ADDR + UART_LCR); au_sync(); au_writel(sleep_uart0_clkdiv, UART0_ADDR + UART_CLK); au_sync(); } restore_au1xxx_intctl(); #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) au1xxx_dbdma_resume(); #endif }
static void au1xmmc_receive_pio(struct au1xmmc_host *host) { struct mmc_data *data; int max, count, sg_len = 0; unsigned char *sg_ptr = NULL; u32 status, val; struct scatterlist *sg; data = host->mrq->data; if (!(host->flags & HOST_F_RECV)) return; max = host->pio.len; if (host->pio.index < host->dma.len) { sg = &data->sg[host->pio.index]; sg_ptr = sg_virt(sg) + host->pio.offset; /* This is the space left inside the buffer */ sg_len = sg_dma_len(&data->sg[host->pio.index]) - host->pio.offset; /* Check if we need less than the size of the sg_buffer */ if (sg_len < max) max = sg_len; } if (max > AU1XMMC_MAX_TRANSFER) max = AU1XMMC_MAX_TRANSFER; for (count = 0; count < max; count++) { status = au_readl(HOST_STATUS(host)); if (!(status & SD_STATUS_NE)) break; if (status & SD_STATUS_RC) { DBG("RX CRC Error [%d + %d].\n", host->pdev->id, host->pio.len, count); break; } if (status & SD_STATUS_RO) { DBG("RX Overrun [%d + %d]\n", host->pdev->id, host->pio.len, count); break; } else if (status & SD_STATUS_RU) { DBG("RX Underrun [%d + %d]\n", host->pdev->id, host->pio.len, count); break; } val = au_readl(HOST_RXPORT(host)); if (sg_ptr) *sg_ptr++ = (unsigned char)(val & 0xFF); } host->pio.len -= count; host->pio.offset += count; if (sg_len && count == sg_len) { host->pio.index++; host->pio.offset = 0; } if (host->pio.len == 0) { /* IRQ_OFF(host, SD_CONFIG_RA | SD_CONFIG_RF); */ IRQ_OFF(host, SD_CONFIG_NE); if (host->flags & HOST_F_STOP) SEND_STOP(host); tasklet_schedule(&host->data_task); } }
static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; unsigned long r, ro, stat; int chans, stype = SUBSTREAM_TYPE(substream); chans = params_channels(params); r = ro = au_readl(AC97_CFG(pscdata)); stat = au_readl(AC97_STAT(pscdata)); if (stat & (PSC_AC97STAT_TB | PSC_AC97STAT_RB)) { if ((PSC_AC97CFG_GET_LEN(r) != params->msbits) || (pscdata->rate != params_rate(params))) return -EINVAL; } else { r &= ~PSC_AC97CFG_LEN_MASK; r |= PSC_AC97CFG_SET_LEN(params->msbits); if (stype == PCM_TX) { r &= ~PSC_AC97CFG_TXSLOT_MASK; r |= PSC_AC97CFG_TXSLOT_ENA(3); r |= PSC_AC97CFG_TXSLOT_ENA(4); } else { r &= ~PSC_AC97CFG_RXSLOT_MASK; r |= PSC_AC97CFG_RXSLOT_ENA(3); r |= PSC_AC97CFG_RXSLOT_ENA(4); } if (!(r ^ ro)) goto out; mutex_lock(&pscdata->lock); au_writel(r & ~PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata)); au_sync(); while (au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR) asm volatile ("nop"); au_writel(r, AC97_CFG(pscdata)); au_sync(); au_writel(r | PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata)); au_sync(); while (!(au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) asm volatile ("nop"); mutex_unlock(&pscdata->lock); pscdata->cfg = r; pscdata->rate = params_rate(params); } out: return 0; }
static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, struct mmc_command *cmd, struct mmc_data *data) { u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT); switch (mmc_resp_type(cmd)) { case MMC_RSP_NONE: break; case MMC_RSP_R1: mmccmd |= SD_CMD_RT_1; break; case MMC_RSP_R1B: mmccmd |= SD_CMD_RT_1B; break; case MMC_RSP_R2: mmccmd |= SD_CMD_RT_2; break; case MMC_RSP_R3: mmccmd |= SD_CMD_RT_3; break; default: printk(KERN_INFO "au1xmmc: unhandled response type %02x\n", mmc_resp_type(cmd)); return -EINVAL; } if (data) { if (data->flags & MMC_DATA_READ) { if (data->blocks > 1) mmccmd |= SD_CMD_CT_4; else mmccmd |= SD_CMD_CT_2; } else if (data->flags & MMC_DATA_WRITE) { if (data->blocks > 1) mmccmd |= SD_CMD_CT_3; else mmccmd |= SD_CMD_CT_1; } } au_writel(cmd->arg, HOST_CMDARG(host)); au_sync(); if (wait) IRQ_OFF(host, SD_CONFIG_CR); au_writel((mmccmd | SD_CMD_GO), HOST_CMD(host)); au_sync(); /* Wait for the command to go on the line */ while (au_readl(HOST_CMD(host)) & SD_CMD_GO) /* nop */; /* Wait for the command to come back */ if (wait) { u32 status = au_readl(HOST_STATUS(host)); while (!(status & SD_STATUS_CR)) status = au_readl(HOST_STATUS(host)); /* Clear the CR status */ au_writel(SD_STATUS_CR, HOST_STATUS(host)); IRQ_ON(host, SD_CONFIG_CR); } return 0; }
* 128 bits, so we have to shift things up. */ for (i = 0; i < 4; i++) { cmd->resp[i] = (r[i] & 0x00FFFFFF) << 8; if (i != 3) cmd->resp[i] |= (r[i + 1] & 0xFF000000) >> 24; } } else { /* Techincally, we should be getting all 48 bits of * the response (SD_RESP1 + SD_RESP2), but because * our response omits the CRC, our data ends up * being shifted 8 bits to the right. In this case, * that means that the OSR data starts at bit 31, * so we can just read RESP0 and return that. */ cmd->resp[0] = au_readl(host->iobase + SD_RESP0); } } /* Figure out errors */ if (status & (SD_STATUS_SC | SD_STATUS_WC | SD_STATUS_RC)) cmd->error = -EILSEQ; trans = host->flags & (HOST_F_XMIT | HOST_F_RECV); if (!trans || cmd->error) { IRQ_OFF(host, SD_CONFIG_TH | SD_CONFIG_RA | SD_CONFIG_RF); tasklet_schedule(&host->finish_task); return; }
static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, struct mmc_command *cmd) { u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT); switch (mmc_resp_type(cmd)) { case MMC_RSP_R1: mmccmd |= SD_CMD_RT_1; break; case MMC_RSP_R1B: mmccmd |= SD_CMD_RT_1B; break; case MMC_RSP_R2: mmccmd |= SD_CMD_RT_2; break; case MMC_RSP_R3: mmccmd |= SD_CMD_RT_3; break; } switch(cmd->opcode) { case MMC_READ_SINGLE_BLOCK: case SD_APP_SEND_SCR: mmccmd |= SD_CMD_CT_2; break; case MMC_READ_MULTIPLE_BLOCK: mmccmd |= SD_CMD_CT_4; break; case MMC_WRITE_BLOCK: mmccmd |= SD_CMD_CT_1; break; case MMC_WRITE_MULTIPLE_BLOCK: mmccmd |= SD_CMD_CT_3; break; case MMC_STOP_TRANSMISSION: mmccmd |= SD_CMD_CT_7; break; } au_writel(cmd->arg, HOST_CMDARG(host)); au_sync(); if (wait) IRQ_OFF(host, SD_CONFIG_CR); au_writel((mmccmd | SD_CMD_GO), HOST_CMD(host)); au_sync(); /* Wait for the command to go on the line */ while(1) { if (!(au_readl(HOST_CMD(host)) & SD_CMD_GO)) break; } /* Wait for the command to come back */ if (wait) { u32 status = au_readl(HOST_STATUS(host)); while(!(status & SD_STATUS_CR)) status = au_readl(HOST_STATUS(host)); /* Clear the CR status */ au_writel(SD_STATUS_CR, HOST_STATUS(host)); IRQ_ON(host, SD_CONFIG_CR); } return MMC_ERR_NONE; }
void save_au1xxx_intctl(void) { sleep_intctl_config0[0] = au_readl(IC0_CFG0RD); sleep_intctl_config1[0] = au_readl(IC0_CFG1RD); sleep_intctl_config2[0] = au_readl(IC0_CFG2RD); sleep_intctl_src[0] = au_readl(IC0_SRCRD); sleep_intctl_assign[0] = au_readl(IC0_ASSIGNRD); sleep_intctl_wake[0] = au_readl(IC0_WAKERD); sleep_intctl_mask[0] = au_readl(IC0_MASKRD); sleep_intctl_config0[1] = au_readl(IC1_CFG0RD); sleep_intctl_config1[1] = au_readl(IC1_CFG1RD); sleep_intctl_config2[1] = au_readl(IC1_CFG2RD); sleep_intctl_src[1] = au_readl(IC1_SRCRD); sleep_intctl_assign[1] = au_readl(IC1_ASSIGNRD); sleep_intctl_wake[1] = au_readl(IC1_WAKERD); sleep_intctl_mask[1] = au_readl(IC1_MASKRD); }
static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev) { struct resource *iores, *dmares; unsigned long sel; int ret; struct au1xpsc_audio_data *wd; wd = kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL); if (!wd) return -ENOMEM; iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!iores) { ret = -ENODEV; goto out0; } ret = -EBUSY; if (!request_mem_region(iores->start, resource_size(iores), pdev->name)) goto out0; wd->mmio = ioremap(iores->start, resource_size(iores)); if (!wd->mmio) goto out1; dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); if (!dmares) goto out2; wd->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start; dmares = platform_get_resource(pdev, IORESOURCE_DMA, 1); if (!dmares) goto out2; wd->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start; /* preserve PSC clock source set up by platform (dev.platform_data * is already occupied by soc layer) */ sel = au_readl(PSC_SEL(wd)) & PSC_SEL_CLK_MASK; au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); au_sync(); au_writel(PSC_SEL_PS_I2SMODE | sel, PSC_SEL(wd)); au_writel(0, I2S_CFG(wd)); au_sync(); /* preconfigure: set max rx/tx fifo depths */ wd->cfg |= PSC_I2SCFG_RT_FIFO8 | PSC_I2SCFG_TT_FIFO8; /* don't wait for I2S core to become ready now; clocks may not * be running yet; depending on clock input for PSC a wait might * time out. */ /* name the DAI like this device instance ("au1xpsc-i2s.PSCINDEX") */ memcpy(&wd->dai_drv, &au1xpsc_i2s_dai_template, sizeof(struct snd_soc_dai_driver)); wd->dai_drv.name = dev_name(&pdev->dev); platform_set_drvdata(pdev, wd); ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv); if (!ret) return 0; out2: iounmap(wd->mmio); out1: release_mem_region(iores->start, resource_size(iores)); out0: kfree(wd); return ret; }