int wait_for_pll_align(void) { int i = 10000; while (i-- && (bfin_read32(CGU0_STAT) & CGU0_STAT_CLKSALGN)); if (bfin_read32(CGU0_STAT) & CGU0_STAT_CLKSALGN) { printk(KERN_DEBUG "fail to align clk\n"); return -1; } return 0; }
unsigned long pll_get_rate(struct clk *clk) { u32 df; u32 msel; u32 ctl = bfin_read32(CGU0_CTL); u32 stat = bfin_read32(CGU0_STAT); if (stat & CGU0_STAT_PLLBP) return 0; msel = (ctl & CGU0_CTL_MSEL_MASK) >> CGU0_CTL_MSEL_SHIFT; df = (ctl & CGU0_CTL_DF); clk->parent->rate = clk_get_rate(clk->parent); return clk->parent->rate / (df + 1) * msel * 2; }
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); }
ulong bootcount_load(void) { ulong magic = bfin_read32(CONFIG_SYS_BOOTCOUNT_ADDR); if ((magic & MAGIC_MASK) == (BOOTCOUNT_MAGIC & MAGIC_MASK)) return magic & COUNT_MASK; else return 0; }
static void clk_reg_set_bits(u32 reg, uint32_t mask) { u32 val; val = bfin_read32(reg); val |= mask; bfin_write32(reg, val); }
static void clk_reg_clear_bits(u32 reg, uint32_t mask) { u32 val; val = bfin_read32(reg); val &= ~mask; bfin_write32(reg, val); }
static void clk_reg_write_mask(u32 reg, uint32_t val, uint32_t mask) { u32 val2; val2 = bfin_read32(reg); val2 &= ~mask; val2 |= val; bfin_write32(reg, val2); }
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; }
unsigned long sys_clk_get_rate(struct clk *clk) { unsigned long drate; u32 msel; u32 df; u32 ctl = bfin_read32(CGU0_CTL); u32 div = bfin_read32(CGU0_DIV); div = (div & clk->mask) >> clk->shift; msel = (ctl & CGU0_CTL_MSEL_MASK) >> CGU0_CTL_MSEL_SHIFT; df = (ctl & CGU0_CTL_DF); if (!strcmp(clk->parent->name, "SYS_CLKIN")) { drate = clk->parent->rate / (df + 1); drate *= msel; drate /= div; return drate; } else { clk->parent->rate = clk_get_rate(clk->parent); return clk->parent->rate / div; } }
static int spi_pio_xfer(struct bfin_spi_slave *bss, const u8 *tx, u8 *rx, uint bytes) { /* discard invalid rx data and empty rfifo */ while (!(bfin_read32(&bss->regs->status) & SPI_STAT_RFE)) bfin_read32(&bss->regs->rfifo); while (bytes--) { u8 value = (tx ? *tx++ : CONFIG_BFIN_SPI_IDLE_VAL); debug("%s: tx:%x ", __func__, value); bfin_write32(&bss->regs->tfifo, value); SSYNC(); while (bfin_read32(&bss->regs->status) & SPI_STAT_RFE) if (ctrlc()) return -1; value = bfin_read32(&bss->regs->rfifo); if (rx) *rx++ = value; debug("rx:%x\n", value); } return 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(®->status); if (status & 0x3000) ppi->err = true; bfin_write16(®->status, 0xff00); break; } case PPI_TYPE_EPPI: { struct bfin_eppi_regs *reg = info->base; unsigned short status; status = bfin_read16(®->status); if (status & 0x2) ppi->err = true; bfin_write16(®->status, 0xffff); break; } case PPI_TYPE_EPPI3: { struct bfin_eppi3_regs *reg = info->base; unsigned long stat; stat = bfin_read32(®->stat); if (stat & 0x2) ppi->err = true; bfin_write32(®->stat, 0xc0ff); break; } default: break; } return IRQ_HANDLED; }
int pll_set_rate(struct clk *clk, unsigned long rate) { u32 msel; u32 stat = bfin_read32(CGU0_STAT); if (!(stat & CGU0_STAT_PLLEN)) return -EBUSY; if (!(stat & CGU0_STAT_PLLLK)) return -EBUSY; if (wait_for_pll_align()) return -EBUSY; msel = rate / clk->parent->rate / 2; clk_reg_write_mask(CGU0_CTL, msel << CGU0_CTL_MSEL_SHIFT, CGU0_CTL_MSEL_MASK); clk->rate = rate; return 0; }
int sys_clk_set_rate(struct clk *clk, unsigned long rate) { u32 div = bfin_read32(CGU0_DIV); div = (div & clk->mask) >> clk->shift; rate = clk_round_rate(clk, rate); if (!rate) return -EINVAL; div = (clk_get_rate(clk) * div) / rate; if (wait_for_pll_align()) return -EBUSY; clk_reg_write_mask(CGU0_DIV, div << clk->shift, clk->mask); clk->rate = rate; return 0; }
void spi_cs_activate(struct spi_slave *slave) { struct bfin_spi_slave *bss = to_bfin_spi_slave(slave); if (is_gpio_cs(slave->cs)) { unsigned int cs = gpio_cs(slave->cs); gpio_set_value(cs, bss->cs_pol); } else { u32 ssel; ssel = bfin_read32(&bss->regs->ssel); ssel |= 1 << slave->cs; if (bss->cs_pol) ssel |= BIT(8) << slave->cs; else ssel &= ~(BIT(8) << slave->cs); bfin_write32(&bss->regs->ssel, ssel); } SSYNC(); }
void bfin_core1_start(void) { #ifdef BF561_FAMILY /* Enable core 1 */ bfin_write_SYSCR(bfin_read_SYSCR() & ~0x0020); #else /* Enable core 1 */ bfin_write32(RCU0_SVECT1, COREB_L1_CODE_START); bfin_write32(RCU0_CRCTL, 0); bfin_write32(RCU0_CRCTL, 0x2); /* Check if core 1 starts */ while (!(bfin_read32(RCU0_CRSTAT) & 0x2)) continue; bfin_write32(RCU0_CRCTL, 0); /* flag to notify cces core 1 application */ bfin_write32(SDU0_MSG_SET, (1 << 19)); #endif }
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; }
unsigned long sys_clk_round_rate(struct clk *clk, unsigned long rate) { unsigned long max_rate; unsigned long drate; int i; u32 msel; u32 df; u32 ctl = bfin_read32(CGU0_CTL); msel = (ctl & CGU0_CTL_MSEL_MASK) >> CGU0_CTL_MSEL_SHIFT; df = (ctl & CGU0_CTL_DF); max_rate = clk->parent->rate / (df + 1) * msel; if (rate > max_rate) return 0; for (i = 1; i < clk->mask; i++) { drate = max_rate / i; if (rate >= drate) return drate; } return 0; }
MGR_ATTR static noinline int dcplb_protection_fault(int cpu) { int status = bfin_read_DCPLB_STATUS(); nr_dcplb_prot[cpu]++; if (likely(status & FAULT_RW)) { int idx = faulting_cplb_index(status); unsigned long regaddr = DCPLB_DATA0 + idx * 4; unsigned long data = bfin_read32(regaddr); /* Check if fault is to dirty a clean page */ if (!(data & CPLB_WT) && !(data & CPLB_DIRTY) && write_permitted(status, data)) { dcplb_tbl[cpu][idx].data = data; bfin_write32(regaddr, data); return CPLB_RELOADED; } } return CPLB_PROT_VIOL; }
void spi_cs_deactivate(struct spi_slave *slave) { struct bfin_spi_slave *bss = to_bfin_spi_slave(slave); if (is_gpio_cs(slave->cs)) { unsigned int cs = gpio_cs(slave->cs); gpio_set_value(cs, !bss->cs_pol); } else { u32 ssel; ssel = bfin_read32(&bss->regs->ssel); if (bss->cs_pol) ssel &= ~((1 << 8) << slave->cs); else ssel |= (1 << 8) << slave->cs; /* deassert cs */ bfin_write32(&bss->regs->ssel, ssel); SSYNC(); /* disable cs */ ssel &= ~(1 << slave->cs); bfin_write32(&bss->regs->ssel, ssel); } SSYNC(); }
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)); }
int bfin_get_ether_addr(char *addr) { *(u32 *)(&(addr[0])) = bfin_read32(FLASH_MAC); *(u16 *)(&(addr[4])) = bfin_read16(FLASH_MAC + 4); return 0; }
void show_regs(struct pt_regs *fp) { char buf [150]; struct irqaction *action; unsigned int i; unsigned long flags; printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\t\t%s\n", print_tainted()); printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", (long)fp->seqstat, fp->ipend, fp->syscfg); printk(KERN_NOTICE " HWERRCAUSE: 0x%lx\n", (fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14); printk(KERN_NOTICE " EXCAUSE : 0x%lx\n", fp->seqstat & SEQSTAT_EXCAUSE); for (i = 6; i <= 15 ; i++) { if (fp->ipend & (1 << i)) { decode_address(buf, bfin_read32(EVT0 + 4*i)); printk(KERN_NOTICE " physical IVG%i asserted : %s\n", i, buf); } } /* if no interrupts are going off, don't print this out */ if (fp->ipend & ~0x3F) { for (i = 0; i < (NR_IRQS - 1); i++) { spin_lock_irqsave(&irq_desc[i].lock, flags); action = irq_desc[i].action; if (!action) goto unlock; decode_address(buf, (unsigned int)action->handler); printk(KERN_NOTICE " logical irq %3d mapped : %s", i, buf); for (action = action->next; action; action = action->next) { decode_address(buf, (unsigned int)action->handler); printk(", %s", buf); } printk("\n"); unlock: spin_unlock_irqrestore(&irq_desc[i].lock, flags); } } decode_address(buf, fp->rete); printk(KERN_NOTICE " RETE: %s\n", buf); decode_address(buf, fp->retn); printk(KERN_NOTICE " RETN: %s\n", buf); decode_address(buf, fp->retx); printk(KERN_NOTICE " RETX: %s\n", buf); decode_address(buf, fp->rets); printk(KERN_NOTICE " RETS: %s\n", buf); decode_address(buf, fp->pc); printk(KERN_NOTICE " PC : %s\n", buf); if (((long)fp->seqstat & SEQSTAT_EXCAUSE) && (((long)fp->seqstat & SEQSTAT_EXCAUSE) != VEC_HWERR)) { decode_address(buf, saved_dcplb_fault_addr); printk(KERN_NOTICE "DCPLB_FAULT_ADDR: %s\n", buf); decode_address(buf, saved_icplb_fault_addr); printk(KERN_NOTICE "ICPLB_FAULT_ADDR: %s\n", buf); } printk(KERN_NOTICE "\n" KERN_NOTICE "PROCESSOR STATE:\n"); printk(KERN_NOTICE " R0 : %08lx R1 : %08lx R2 : %08lx R3 : %08lx\n", fp->r0, fp->r1, fp->r2, fp->r3); printk(KERN_NOTICE " R4 : %08lx R5 : %08lx R6 : %08lx R7 : %08lx\n", fp->r4, fp->r5, fp->r6, fp->r7); printk(KERN_NOTICE " P0 : %08lx P1 : %08lx P2 : %08lx P3 : %08lx\n", fp->p0, fp->p1, fp->p2, fp->p3); printk(KERN_NOTICE " P4 : %08lx P5 : %08lx FP : %08lx SP : %08lx\n", fp->p4, fp->p5, fp->fp, (long)fp); printk(KERN_NOTICE " LB0: %08lx LT0: %08lx LC0: %08lx\n", fp->lb0, fp->lt0, fp->lc0); printk(KERN_NOTICE " LB1: %08lx LT1: %08lx LC1: %08lx\n", fp->lb1, fp->lt1, fp->lc1); printk(KERN_NOTICE " B0 : %08lx L0 : %08lx M0 : %08lx I0 : %08lx\n", fp->b0, fp->l0, fp->m0, fp->i0); printk(KERN_NOTICE " B1 : %08lx L1 : %08lx M1 : %08lx I1 : %08lx\n", fp->b1, fp->l1, fp->m1, fp->i1); printk(KERN_NOTICE " B2 : %08lx L2 : %08lx M2 : %08lx I2 : %08lx\n", fp->b2, fp->l2, fp->m2, fp->i2); printk(KERN_NOTICE " B3 : %08lx L3 : %08lx M3 : %08lx I3 : %08lx\n", fp->b3, fp->l3, fp->m3, fp->i3); printk(KERN_NOTICE "A0.w: %08lx A0.x: %08lx A1.w: %08lx A1.x: %08lx\n", fp->a0w, fp->a0x, fp->a1w, fp->a1x); printk(KERN_NOTICE "USP : %08lx ASTAT: %08lx\n", rdusp(), fp->astat); printk(KERN_NOTICE "\n"); }
static u64 bfin_pfmon_read(int idx) { return bfin_read32(PFCNTR0 + (idx * 4)); }