Ejemplo n.º 1
0
void __init early_dma_memcpy(void *pdst, const void *psrc, size_t size)
{
	unsigned long dst = (unsigned long)pdst;
	unsigned long src = (unsigned long)psrc;
	struct dma_register *dst_ch, *src_ch;

	early_shadow_stamp();

	/* We assume that everything is 4 byte aligned, so include
	 * a basic sanity check
	 */
	BUG_ON(dst % 4);
	BUG_ON(src % 4);
	BUG_ON(size % 4);

	src_ch = 0;
	/* Find an avalible memDMA channel */
	while (1) {
		if (src_ch == (struct dma_register *)MDMA_S0_NEXT_DESC_PTR) {
			dst_ch = (struct dma_register *)MDMA_D1_NEXT_DESC_PTR;
			src_ch = (struct dma_register *)MDMA_S1_NEXT_DESC_PTR;
		} else {
			dst_ch = (struct dma_register *)MDMA_D0_NEXT_DESC_PTR;
			src_ch = (struct dma_register *)MDMA_S0_NEXT_DESC_PTR;
		}

		if (!bfin_read16(&src_ch->cfg))
			break;
		else if (bfin_read16(&dst_ch->irq_status) & DMA_DONE) {
			bfin_write16(&src_ch->cfg, 0);
			break;
		}
	}

	/* Force a sync in case a previous config reset on this channel
	 * occurred.  This is needed so subsequent writes to DMA registers
	 * are not spuriously lost/corrupted.
	 */
	__builtin_bfin_ssync();

	/* Destination */
	bfin_write32(&dst_ch->start_addr, dst);
	bfin_write16(&dst_ch->x_count, size >> 2);
	bfin_write16(&dst_ch->x_modify, 1 << 2);
	bfin_write16(&dst_ch->irq_status, DMA_DONE | DMA_ERR);

	/* Source */
	bfin_write32(&src_ch->start_addr, src);
	bfin_write16(&src_ch->x_count, size >> 2);
	bfin_write16(&src_ch->x_modify, 1 << 2);
	bfin_write16(&src_ch->irq_status, DMA_DONE | DMA_ERR);

	/* Enable */
	bfin_write16(&src_ch->cfg, DMAEN | WDSIZE_32);
	bfin_write16(&dst_ch->cfg, WNR | DI_EN | DMAEN | WDSIZE_32);

	/* Since we are atomic now, don't use the workaround ssync */
	__builtin_bfin_ssync();
}
Ejemplo n.º 2
0
int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	if (argc != 3) {
 show_usage:
		printf("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}

	/* parse the behavior */
	ulong port_cmd = 0;
	switch (argv[1][0]) {
		case 'i': break;
		case 's': port_cmd = (PORTFIO_SET - PORTFIO); break;
		case 'c': port_cmd = (PORTFIO_CLEAR - PORTFIO); break;
		case 't': port_cmd = (PORTFIO_TOGGLE - PORTFIO); break;
		default:  goto show_usage;
	}

	/* parse the pin with format: [p]<fgh><#> */
	const char *str_pin = argv[2];

	/* grab the [p]<fgh> portion */
	ulong port_base;
	if (*str_pin == 'p') ++str_pin;
	switch (*str_pin) {
		case 'f': port_base = PORTFIO; break;
		case 'g': port_base = PORTGIO; break;
		case 'h': port_base = PORTHIO; break;
		default:  goto show_usage;
	}

	/* grab the <#> portion */
	ulong pin = simple_strtoul(str_pin+1, NULL, 10);
	ulong pin_mask = (1 << pin);
	if (pin > 15)
		goto show_usage;

	/* finally, let's do it: set direction and exec command */
	switch (*str_pin) {
		case 'f': bfin_write_PORTF_FER(bfin_read_PORTF_FER() & ~pin_mask); break;
		case 'g': bfin_write_PORTG_FER(bfin_read_PORTG_FER() & ~pin_mask); break;
		case 'h': bfin_write_PORTH_FER(bfin_read_PORTH_FER() & ~pin_mask); break;
	}

	ulong port_dir = port_base + (PORTFIO_DIR - PORTFIO);
	if (argv[1][0] == 'i')
		bfin_write16(port_dir, bfin_read16(port_dir) & ~pin_mask);
	else {
		bfin_write16(port_dir, bfin_read16(port_dir) | pin_mask);
		bfin_write16(port_base + port_cmd, pin_mask);
	}

	printf("gpio: pin %li on port %c has been %c\n", pin, *str_pin, argv[1][0]);

	return 0;
}
Ejemplo n.º 3
0
void __init early_dma_memcpy(void *pdst, const void *psrc, size_t size)
{
	unsigned long dst = (unsigned long)pdst;
	unsigned long src = (unsigned long)psrc;
	struct dma_register *dst_ch, *src_ch;

	early_shadow_stamp();

	BUG_ON(dst % 4);
	BUG_ON(src % 4);
	BUG_ON(size % 4);

	src_ch = 0;
	
	while (1) {
		if (src_ch == (struct dma_register *)MDMA_S0_NEXT_DESC_PTR) {
			dst_ch = (struct dma_register *)MDMA_D1_NEXT_DESC_PTR;
			src_ch = (struct dma_register *)MDMA_S1_NEXT_DESC_PTR;
		} else {
			dst_ch = (struct dma_register *)MDMA_D0_NEXT_DESC_PTR;
			src_ch = (struct dma_register *)MDMA_S0_NEXT_DESC_PTR;
		}

		if (!bfin_read16(&src_ch->cfg))
			break;
		else if (bfin_read16(&dst_ch->irq_status) & DMA_DONE) {
			bfin_write16(&src_ch->cfg, 0);
			break;
		}
	}

	__builtin_bfin_ssync();

	
	bfin_write32(&dst_ch->start_addr, dst);
	bfin_write16(&dst_ch->x_count, size >> 2);
	bfin_write16(&dst_ch->x_modify, 1 << 2);
	bfin_write16(&dst_ch->irq_status, DMA_DONE | DMA_ERR);

	
	bfin_write32(&src_ch->start_addr, src);
	bfin_write16(&src_ch->x_count, size >> 2);
	bfin_write16(&src_ch->x_modify, 1 << 2);
	bfin_write16(&src_ch->irq_status, DMA_DONE | DMA_ERR);

	
	bfin_write16(&src_ch->cfg, DMAEN | WDSIZE_32);
	bfin_write16(&dst_ch->cfg, WNR | DI_EN | DMAEN | WDSIZE_32);

	
	__builtin_bfin_ssync();
}
Ejemplo n.º 4
0
static irqreturn_t ppi_irq_err(int irq, void *dev_id)
{
	struct ppi_if *ppi = dev_id;
	const struct ppi_info *info = ppi->info;

	switch (info->type) {
	case PPI_TYPE_PPI:
	{
		struct bfin_ppi_regs *reg = info->base;
		unsigned short status;

		/* register on bf561 is cleared when read 
		 * others are W1C
		 */
		status = bfin_read16(&reg->status);
		if (status & 0x3000)
			ppi->err = true;
		bfin_write16(&reg->status, 0xff00);
		break;
	}
	case PPI_TYPE_EPPI:
	{
		struct bfin_eppi_regs *reg = info->base;
		unsigned short status;

		status = bfin_read16(&reg->status);
		if (status & 0x2)
			ppi->err = true;
		bfin_write16(&reg->status, 0xffff);
		break;
	}
	case PPI_TYPE_EPPI3:
	{
		struct bfin_eppi3_regs *reg = info->base;
		unsigned long stat;

		stat = bfin_read32(&reg->stat);
		if (stat & 0x2)
			ppi->err = true;
		bfin_write32(&reg->stat, 0xc0ff);
		break;
	}
	default:
		break;
	}

	return IRQ_HANDLED;
}
Ejemplo n.º 5
0
void get_bf537_ether_addr(char *addr)
{
	unsigned int flash_mac = (unsigned int) FLASH_MAC;
	*(u32 *)(&(addr[0])) = bfin_read32(flash_mac);
	flash_mac += 4;
	*(u16 *)(&(addr[4])) = bfin_read16(flash_mac);
}
Ejemplo n.º 6
0
static irqreturn_t ppi_irq_err(int irq, void *dev_id)
{
	struct ppi_if *ppi = dev_id;
	const struct ppi_info *info = ppi->info;

	switch (info->type) {
	case PPI_TYPE_PPI:
	{
		struct bfin_ppi_regs *reg = info->base;
		unsigned short status;

		status = bfin_read16(&reg->status);
		bfin_write16(&reg->status, 0xff00);
		break;
	}
	case PPI_TYPE_EPPI:
	{
		struct bfin_eppi_regs *reg = info->base;
		bfin_write16(&reg->status, 0xffff);
		break;
	}
	default:
		break;
	}

	return IRQ_HANDLED;
}
Ejemplo n.º 7
0
static int sport_get(void *mmr, u64 *val)
{
	unsigned long flags;
	local_irq_save(flags);
	if (sport_width(mmr) <= 16)
		*val = bfin_read16(mmr);
	else
		*val = bfin_read32(mmr);
	local_irq_restore(flags);
	return 0;
}
Ejemplo n.º 8
0
static inline int sport_width(void *mmr)
{
	unsigned long lmmr = (unsigned long)mmr;
	if ((lmmr & 0xff) == 0x10)
		
		lmmr -= 0xc;
	else
		
		lmmr += 0xc;
	
	return (bfin_read16(lmmr) & 0x1f) + 1;
}
Ejemplo n.º 9
0
int serial_getc(void)
{
	uint16_t uart_rbr_val;

	/* wait for data ! */
	while (!serial_tstc())
		continue;

	/* grab the new byte */
	uart_rbr_val = bfin_read16(&pUART->rbr);

#ifdef CONFIG_DEBUG_SERIAL
	/* grab & clear the LSR */
	uint16_t uart_lsr_val = uart_lsr_read();

	cached_lsr[cache_count] = uart_lsr_val;
	cached_rbr[cache_count] = uart_rbr_val;
	cache_count = (cache_count + 1) % ARRAY_SIZE(cached_lsr);

	if (uart_lsr_val & (OE|PE|FE|BI)) {
		uint16_t dll, dlh;
		printf("\n[SERIAL ERROR]\n");
		ACCESS_LATCH();
		dll = bfin_read16(&pUART->dll);
		dlh = bfin_read16(&pUART->dlh);
		ACCESS_PORT_IER();
		printf("\tDLL=0x%x DLH=0x%x\n", dll, dlh);
		do {
			--cache_count;
			printf("\t%3i: RBR=0x%02x LSR=0x%02x\n", cache_count,
				cached_rbr[cache_count], cached_lsr[cache_count]);
		} while (cache_count > 0);
		return -1;
	}
#endif
	uart_lsr_clear();

	return uart_rbr_val;
}
Ejemplo n.º 10
0
static inline void serial_init(void)
{
#ifdef __ADSPBF54x__
# ifdef BFIN_BOOT_UART_USE_RTS
#  define BFIN_UART_USE_RTS 1
# else
#  define BFIN_UART_USE_RTS 0
# endif
	if (BFIN_UART_USE_RTS && CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_UART) {
		size_t i;

		/* force RTS rather than relying on auto RTS */
		bfin_write16(&pUART->mcr, bfin_read16(&pUART->mcr) | FCPOL);

		/* Wait for the line to clear up.  We cannot rely on UART
		 * registers as none of them reflect the status of the RSR.
		 * Instead, we'll sleep for ~10 bit times at 9600 baud.
		 * We can precalc things here by assuming boot values for
		 * PLL rather than loading registers and calculating.
		 *	baud    = SCLK / (16 ^ (1 - EDBO) * Divisor)
		 *	EDB0    = 0
		 *	Divisor = (SCLK / baud) / 16
		 *	SCLK    = baud * 16 * Divisor
		 *	SCLK    = (0x14 * CONFIG_CLKIN_HZ) / 5
		 *	CCLK    = (16 * Divisor * 5) * (9600 / 10)
		 * In reality, this will probably be just about 1 second delay,
		 * so assuming 9600 baud is OK (both as a very low and too high
		 * speed as this will buffer things enough).
		 */
#define _NUMBITS (10)                                   /* how many bits to delay */
#define _LOWBAUD (9600)                                 /* low baud rate */
#define _SCLK    ((0x14 * CONFIG_CLKIN_HZ) / 5)         /* SCLK based on PLL */
#define _DIVISOR ((_SCLK / _LOWBAUD) / 16)              /* UART DLL/DLH */
#define _NUMINS  (3)                                    /* how many instructions in loop */
#define _CCLK    (((16 * _DIVISOR * 5) * (_LOWBAUD / _NUMBITS)) / _NUMINS)
		i = _CCLK;
		while (i--)
			asm volatile("" : : : "memory");
	}
Ejemplo n.º 11
0
long probe_kernel_read(void *dst, const void *src, size_t size)
{
	unsigned long lsrc = (unsigned long)src;
	int mem_type;

	mem_type = validate_memory_access_address(lsrc, size);
	if (mem_type < 0)
		return mem_type;

	if (lsrc >= SYSMMR_BASE) {
		if (size == 2 && lsrc % 2 == 0) {
			u16 mmr = bfin_read16(src);
			memcpy(dst, &mmr, sizeof(mmr));
			return 0;
		} else if (size == 4 && lsrc % 4 == 0) {
			u32 mmr = bfin_read32(src);
			memcpy(dst, &mmr, sizeof(mmr));
			return 0;
		}
	} else {
		switch (mem_type) {
		case BFIN_MEM_ACCESS_CORE:
		case BFIN_MEM_ACCESS_CORE_ONLY:
			return __probe_kernel_read(dst, src, size);
			
		case BFIN_MEM_ACCESS_DMA:
			if (dma_memcpy(dst, src, size))
				return 0;
			break;
		case BFIN_MEM_ACCESS_ITEST:
			if (isram_memcpy(dst, src, size))
				return 0;
			break;
		}
	}

	return -EFAULT;
}
Ejemplo n.º 12
0
/* When debugging is disabled, we only care about the DR bit, so if other
 * bits get set/cleared, we don't really care since we don't read them
 * anyways (and thus anomaly 05000099 is irrelevant).
 */
static uint16_t uart_lsr_read(void)
{
	return bfin_read16(&pUART->lsr);
}
Ejemplo n.º 13
0
static uint16_t uart_lsr_read(void)
{
	uint16_t lsr = bfin_read16(&pUART->lsr);
	uart_lsr_save |= (lsr & (OE|PE|FE|BI));
	return lsr | uart_lsr_save;
}
Ejemplo n.º 14
0
static int
bfmdma_read_proc(char *buffer, char **start, off_t offset, int cnt,
		 int *eof, void *data)
{
	char *head = buffer;
	unsigned short s0_irqstat = bfin_read16(MDMA_S0_IRQ_STATUS);
	unsigned short d0_irqstat = bfin_read16(MDMA_D0_IRQ_STATUS);
	unsigned short s1_irqstat = bfin_read16(MDMA_S1_IRQ_STATUS);
	unsigned short d1_irqstat = bfin_read16(MDMA_D1_IRQ_STATUS);
	if (offset == 0) {
		head += sprintf(head, "MDMA Status\n");
		head +=
		    sprintf(head, "S0:    (RUN:%d DFETCH:%d ERR:%d DONE:%d)\n",
			    (s0_irqstat >> 3) & 1, (s0_irqstat >> 2) & 1,
			    (s0_irqstat >> 1) & 1, (s0_irqstat) & 1);
		head +=
		    sprintf(head,
			    "(S0) CFG: %04x IRQ: %04x CUR: %08x NXT: %08x\n",
			    bfin_read16(MDMA_S0_CONFIG),
			    bfin_read16(MDMA_S0_IRQ_STATUS),
			    bfin_read32(MDMA_S0_CURR_DESC_PTR),
			    bfin_read32(MDMA_S0_NEXT_DESC_PTR));
		head +=
		    sprintf(head,
			    "SAH/L: %08x X(%d,+%d) Y(%d,+%d)  current %08x cx: %d cy: %d\n",
			    bfin_read32(MDMA_S0_START_ADDR),
			    bfin_read16(MDMA_S0_X_COUNT),
			    bfin_read16(MDMA_S0_X_MODIFY),
			    bfin_read16(MDMA_S0_Y_COUNT),
			    bfin_read16(MDMA_S0_Y_MODIFY),
			    bfin_read32(MDMA_S0_CURR_ADDR),
			    bfin_read16(MDMA_S0_CURR_X_COUNT),
			    bfin_read16(MDMA_S0_CURR_Y_COUNT));
		head += sprintf(head, "\n");

		head +=
		    sprintf(head, "D0:    (RUN:%d DFETCH:%d ERR:%d DONE:%d)\n",
			    (d0_irqstat >> 3) & 1, (d0_irqstat >> 2) & 1,
			    (d0_irqstat >> 1) & 1, (d0_irqstat) & 1);
		head +=
		    sprintf(head,
			    "(D0) CFG: %04x IRQ: %04x CUR: %08x NXT: %08x\n",
			    bfin_read16(MDMA_D0_CONFIG),
			    bfin_read16(MDMA_D0_IRQ_STATUS),
			    bfin_read32(MDMA_D0_CURR_DESC_PTR),
			    bfin_read32(MDMA_D0_NEXT_DESC_PTR));
		head +=
		    sprintf(head,
			    "SAH/L: %08x X(%d,+%d) Y(%d,+%d)  current %08x cx: %d cy: %d\n",
			    bfin_read32(MDMA_D0_START_ADDR),
			    bfin_read16(MDMA_D0_X_COUNT),
			    bfin_read16(MDMA_D0_X_MODIFY),
			    bfin_read16(MDMA_D0_Y_COUNT),
			    bfin_read16(MDMA_D0_Y_MODIFY),
			    bfin_read32(MDMA_D0_CURR_ADDR),
			    bfin_read16(MDMA_D0_CURR_X_COUNT),
			    bfin_read16(MDMA_D0_CURR_Y_COUNT));
		head += sprintf(head, "\n");

		head +=
		    sprintf(head, "S1:    (RUN:%d DFETCH:%d ERR:%d DONE:%d)\n",
			    (s1_irqstat >> 3) & 1, (s1_irqstat >> 2) & 1,
			    (s1_irqstat >> 1) & 1, (s1_irqstat) & 1);
		head +=
		    sprintf(head,
			    "(S1) CFG: %04x IRQ: %04x CUR: %08x NXT: %08x\n",
			    bfin_read16(MDMA_S1_CONFIG),
			    bfin_read16(MDMA_S1_IRQ_STATUS),
			    bfin_read32(MDMA_S1_CURR_DESC_PTR),
			    bfin_read32(MDMA_S1_NEXT_DESC_PTR));
		head +=
		    sprintf(head,
			    "SAH/L: %08x X(%d,+%d) Y(%d,+%d)  current %08x cx: %d cy: %d\n",
			    bfin_read32(MDMA_S1_START_ADDR),
			    bfin_read16(MDMA_S1_X_COUNT),
			    bfin_read16(MDMA_S1_X_MODIFY),
			    bfin_read16(MDMA_S1_Y_COUNT),
			    bfin_read16(MDMA_S1_Y_MODIFY),
			    bfin_read32(MDMA_S1_CURR_ADDR),
			    bfin_read16(MDMA_S1_CURR_X_COUNT),
			    bfin_read16(MDMA_S1_CURR_Y_COUNT));
		head += sprintf(head, "\n");

		head +=
		    sprintf(head, "D1:    (RUN:%d DFETCH:%d ERR:%d DONE:%d)\n",
			    (d1_irqstat >> 3) & 1, (d1_irqstat >> 2) & 1,
			    (d1_irqstat >> 1) & 1, (d1_irqstat) & 1);
		head +=
		    sprintf(head,
			    "(D1) CFG: %04x IRQ: %04x CUR: %08x NXT: %08x\n",
			    bfin_read16(MDMA_D1_CONFIG),
			    bfin_read16(MDMA_D1_IRQ_STATUS),
			    bfin_read32(MDMA_D1_CURR_DESC_PTR),
			    bfin_read32(MDMA_D1_NEXT_DESC_PTR));

		head +=
		    sprintf(head,
			    "SAH/L: %08x X(%d,+%d) Y(%d,+%d)  current %08x cx: %d cy: %d\n",
			    bfin_read32(MDMA_D1_START_ADDR),
			    bfin_read16(MDMA_D1_X_COUNT),
			    bfin_read16(MDMA_D1_X_MODIFY),
			    bfin_read16(MDMA_D1_Y_COUNT),
			    bfin_read16(MDMA_D1_Y_MODIFY),
			    bfin_read32(MDMA_D1_CURR_ADDR),
			    bfin_read16(MDMA_D1_CURR_X_COUNT),
			    bfin_read16(MDMA_D1_CURR_Y_COUNT));
	}
Ejemplo n.º 15
0
int bfin_get_ether_addr(char *addr)
{
	*(u32 *)(&(addr[0])) = bfin_read32(FLASH_MAC);
	*(u16 *)(&(addr[4])) = bfin_read16(FLASH_MAC + 4);
	return 0;
}
Ejemplo n.º 16
0
void init_clocks(void)
{
	/* Kill any active DMAs as they may trigger external memory accesses
	 * in the middle of reprogramming things, and that'll screw us up.
	 * For example, any automatic DMAs left by U-Boot for splash screens.
	 */
	size_t i;
	for (i = 0; i < MAX_DMA_CHANNELS; ++i) {
		struct dma_register *dma = dma_io_base_addr[i];
		dma->cfg = 0;
	}

	do_sync();

#ifdef SIC_IWR0
	bfin_write_SIC_IWR0(IWR_ENABLE(0));
# ifdef SIC_IWR1
	/* BF52x system reset does not properly reset SIC_IWR1 which
	 * will screw up the bootrom as it relies on MDMA0/1 waking it
	 * up from IDLE instructions.  See this report for more info:
	 * http://blackfin.uclinux.org/gf/tracker/4323
	 */
	if (ANOMALY_05000435)
		bfin_write_SIC_IWR1(IWR_ENABLE(10) | IWR_ENABLE(11));
	else
		bfin_write_SIC_IWR1(IWR_DISABLE_ALL);
# endif
# ifdef SIC_IWR2
	bfin_write_SIC_IWR2(IWR_DISABLE_ALL);
# endif
#else
	bfin_write_SIC_IWR(IWR_ENABLE(0));
#endif
	do_sync();
#ifdef EBIU_SDGCTL
	bfin_write_EBIU_SDGCTL(bfin_read_EBIU_SDGCTL() | SRFS);
	do_sync();
#endif

#ifdef CLKBUFOE
	bfin_write16(VR_CTL, bfin_read_VR_CTL() | CLKBUFOE);
	do_sync();
	__asm__ __volatile__("IDLE;");
#endif
	bfin_write_PLL_LOCKCNT(0x300);
	do_sync();
	bfin_write16(PLL_CTL, PLL_CTL_VAL);
	__asm__ __volatile__("IDLE;");
	bfin_write_PLL_DIV(CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
#ifdef EBIU_SDGCTL
	bfin_write_EBIU_SDRRC(mem_SDRRC);
	bfin_write_EBIU_SDGCTL((bfin_read_EBIU_SDGCTL() & SDGCTL_WIDTH) | mem_SDGCTL);
#else
	bfin_write_EBIU_RSTCTL(bfin_read_EBIU_RSTCTL() & ~(SRREQ));
	do_sync();
	bfin_write_EBIU_RSTCTL(bfin_read_EBIU_RSTCTL() | 0x1);
	bfin_write_EBIU_DDRCTL0(mem_DDRCTL0);
	bfin_write_EBIU_DDRCTL1(mem_DDRCTL1);
	bfin_write_EBIU_DDRCTL2(mem_DDRCTL2);
#ifdef CONFIG_MEM_EBIU_DDRQUE
	bfin_write_EBIU_DDRQUE(CONFIG_MEM_EBIU_DDRQUE);
#endif
#endif
	do_sync();
	bfin_read16(0);
}
Ejemplo n.º 17
0
static void uart_lsr_clear(void)
{
	bfin_write16(&pUART->lsr, bfin_read16(&pUART->lsr) | -1);
}