void __flush_invalidate_region(void *start, int size) { #ifdef CONFIG_CACHE_WRITEBACK /* * SH-2 does not support individual line invalidation, only a * global invalidate. */ unsigned long ccr; unsigned long flags; local_irq_save(flags); jump_to_uncached(); ccr = ctrl_inl(CCR); ccr |= CCR_CACHE_INVALIDATE; ctrl_outl(ccr, CCR); back_to_cached(); local_irq_restore(flags); #else unsigned long v; unsigned long begin, end; begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); end = ((unsigned long)start + size + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1); for (v = begin; v < end; v+=L1_CACHE_BYTES) ctrl_outl((v & CACHE_PHYSADDR_MASK), CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0) | 0x00000008); #endif }
void __flush_invalidate_region(void *start, int size) { unsigned long v; unsigned long begin, end; unsigned long flags; begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); end = ((unsigned long)start + size + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1); local_irq_save(flags); jump_to_uncached(); #ifdef CONFIG_CACHE_WRITEBACK ctrl_outl(ctrl_inl(CCR) | CCR_OCACHE_INVALIDATE, CCR); /* I-cache invalidate */ for (v = begin; v < end; v+=L1_CACHE_BYTES) { ctrl_outl((v & CACHE_PHYSADDR_MASK), CACHE_IC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008); } #else for (v = begin; v < end; v+=L1_CACHE_BYTES) { ctrl_outl((v & CACHE_PHYSADDR_MASK), CACHE_IC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008); ctrl_outl((v & CACHE_PHYSADDR_MASK), CACHE_OC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008); } #endif back_to_cached(); local_irq_restore(flags); }
/*********************************************************************** * pwm_set_frequency() * * Set the interrupt generation of the PWM1 counter. The frequency is * specified in HZ. * use. */ void pwm_set_frequency(unsigned int freq_hz) { u32 reg = 0; u32 psc; printk(KERN_INFO "oprofile: Setting profiler frequency to %d Hz\n", freq_hz); /* * The input clock top the capture-compare is the CPU Clock which is 100MHz. * We can use this as-is for profiling. */ /* Set initial capture counter clock prescale value to x1. */ psc = 0x00; reg &= ~(PWM_CTRL_CPT_CLK_VAL_MASK << PWM_CTRL_CPT_CLK_VAL_SHIFT); reg |= (psc & PWM_CTRL_CPT_CLK_VAL_MASK) << PWM_CTRL_CPT_CLK_VAL_SHIFT; ctrl_outl(reg, pwm->base + PWM_CTRL_REG); /* PWM1 compare interrupt on value 0. */ results.compare_increment = CC_CLK_FREQ / freq_hz; reg = (u32)results.compare_increment; ctrl_outl(reg, pwm->base + PWM1_CMP_VAL_REG); return; }
/*********************************************************************** * pwm_irq_enable() * * Enable interrupt generation by the PWM counter. */ void pwm_irq_enable(void) { u32 reg = 0; /* * TODO : Just enable & ack all the sources for now! */ reg = ctrl_inl(pwm->base + PWM_INT_ACK_REG); reg |= CMP1_INT_EN; // reg |= CMP0_INT_EN; reg |= CPT1_INT_EN; // reg |= CPT0_INT_EN; // reg |= PWM_INT_EN; ctrl_outl(reg, pwm->base + PWM_INT_ACK_REG); reg = ctrl_inl(pwm->base + PWM_INT_EN_REG); reg |= CMP1_INT_EN; // reg |= CMP0_INT_EN; reg |= CPT1_INT_EN; // reg |= CPT0_INT_EN; // reg |= PWM_INT_EN; ctrl_outl(reg, pwm->base + PWM_INT_EN_REG); return; }
static int tmu_timer_init(void) { unsigned long interval; setup_irq(TIMER_IRQ, &tmu_irq); tmu0_clk.parent = clk_get("module_clk"); /* Start TMU0 */ ctrl_outb(0, TMU_TSTR); #if !defined(CONFIG_CPU_SUBTYPE_SH7300) && !defined(CONFIG_CPU_SUBTYPE_SH7760) ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); #endif clk_register(&tmu0_clk); clk_enable(&tmu0_clk); interval = (clk_get_rate(&tmu0_clk) + HZ / 2) / HZ; printk(KERN_INFO "Interval = %ld\n", interval); ctrl_outl(interval, TMU0_TCOR); ctrl_outl(interval, TMU0_TCNT); ctrl_outb(TMU_TSTR_INIT, TMU_TSTR); return 0; }
static void __init migor_setup(char **cmdline_p) { /* SMC91C111 - Enable IRQ0 */ ctrl_outw(ctrl_inw(PORT_PJCR) & ~0x0003, PORT_PJCR); /* KEYSC */ ctrl_outw(ctrl_inw(PORT_PYCR) & ~0x0fff, PORT_PYCR); ctrl_outw(ctrl_inw(PORT_PZCR) & ~0x0ff0, PORT_PZCR); ctrl_outw(ctrl_inw(PORT_PSELA) & ~0x4100, PORT_PSELA); ctrl_outw(ctrl_inw(PORT_HIZCRA) & ~0x4000, PORT_HIZCRA); ctrl_outw(ctrl_inw(PORT_HIZCRC) & ~0xc000, PORT_HIZCRC); ctrl_outl(ctrl_inl(MSTPCR2) & ~0x00004000, MSTPCR2); /* NAND Flash */ ctrl_outw(ctrl_inw(PORT_PXCR) & 0x0fff, PORT_PXCR); ctrl_outl((ctrl_inl(BSC_CS6ABCR) & ~0x00000600) | 0x00000200, BSC_CS6ABCR); /* I2C */ ctrl_outl(ctrl_inl(MSTPCR1) & ~0x00000200, MSTPCR1); /* Touch Panel - Enable IRQ6 */ ctrl_outw(ctrl_inw(PORT_PZCR) & ~0xc, PORT_PZCR); ctrl_outw((ctrl_inw(PORT_PSELA) | 0x8000), PORT_PSELA); ctrl_outw((ctrl_inw(PORT_HIZCRC) & ~0x4000), PORT_HIZCRC); }
static void setup_fast_timer() { unsigned long interval; #ifdef FAST_POLL_INTR interval = (current_cpu_data.module_clock/4 + FAST_POLL/2) / FAST_POLL; make_ipr_irq(FASTTIMER_IRQ, FASTTIMER_IPR_ADDR, FASTTIMER_IPR_POS, FASTTIMER_PRIORITY); printk("SnapGear: %dHz fast timer on IRQ %d\n",FAST_POLL,FASTTIMER_IRQ); if (request_irq(FASTTIMER_IRQ, fast_timer_irq, 0, "SnapGear fast timer", NULL) != 0) printk("%s(%d): request_irq() failed?\n", __FILE__, __LINE__); #else printk("SnapGear: fast timer running\n",FAST_POLL,FASTTIMER_IRQ); interval = 0xffffffff; #endif ctrl_outb(ctrl_inb(TMU_TSTR) & ~0x2, TMU_TSTR); /* disable timer 1 */ ctrl_outw(TMU1_TCR_INIT, TMU1_TCR); ctrl_outl(interval, TMU1_TCOR); ctrl_outl(interval, TMU1_TCNT); ctrl_outb(ctrl_inb(TMU_TSTR) | 0x2, TMU_TSTR); /* enable timer 1 */ printk("Timer count 1 = 0x%x\n", fast_timer_count()); udelay(1000); printk("Timer count 2 = 0x%x\n", fast_timer_count()); }
static void __init setup_chip_select(void) { /* CS2: LAN (0x08000000 - 0x0bffffff) */ /* no idle cycles, normal space, 8 bit data bus */ ctrl_outl(0x36db0400, CS2BCR); /* (SW:1.5 WR:3 HW:1.5), ext. wait */ ctrl_outl(0x000003c0, CS2WCR); /* CS4: CAN1 (0xb0000000 - 0xb3ffffff) */ /* no idle cycles, normal space, 8 bit data bus */ ctrl_outl(0x00000200, CS4BCR); /* (SW:1.5 WR:3 HW:1.5), ext. wait */ ctrl_outl(0x00100981, CS4WCR); /* CS5a: CAN2 (0xb4000000 - 0xb5ffffff) */ /* no idle cycles, normal space, 8 bit data bus */ ctrl_outl(0x00000200, CS5ABCR); /* (SW:1.5 WR:3 HW:1.5), ext. wait */ ctrl_outl(0x00100981, CS5AWCR); /* CS5b: CAN3 (0xb6000000 - 0xb7ffffff) */ /* no idle cycles, normal space, 8 bit data bus */ ctrl_outl(0x00000200, CS5BBCR); /* (SW:1.5 WR:3 HW:1.5), ext. wait */ ctrl_outl(0x00100981, CS5BWCR); /* CS6a: Rotary (0xb8000000 - 0xb9ffffff) */ /* no idle cycles, normal space, 8 bit data bus */ ctrl_outl(0x00000200, CS6ABCR); /* (SW:1.5 WR:3 HW:1.5), no ext. wait */ ctrl_outl(0x001009C1, CS6AWCR); }
/* * Must be in P2 for __set_pmb_entry() */ int __set_pmb_entry(unsigned long vpn, unsigned long ppn, unsigned long flags, int *entry) { unsigned int pos = *entry; if (unlikely(pos == PMB_NO_ENTRY)) pos = find_first_zero_bit(&pmb_map, NR_PMB_ENTRIES); repeat: if (unlikely(pos > NR_PMB_ENTRIES)) return -ENOSPC; if (test_and_set_bit(pos, &pmb_map)) { pos = find_first_zero_bit(&pmb_map, NR_PMB_ENTRIES); goto repeat; } ctrl_outl(vpn | PMB_V, mk_pmb_addr(pos)); #ifdef CONFIG_CACHE_WRITETHROUGH /* * When we are in 32-bit address extended mode, CCR.CB becomes * invalid, so care must be taken to manually adjust cacheable * translations. */ if (likely(flags & PMB_C)) flags |= PMB_WT; #endif ctrl_outl(ppn | flags | PMB_V, mk_pmb_data(pos)); *entry = pos; return 0; }
void __uses_jump_to_uncached clear_pmb_entry(struct pmb_entry *pmbe) { unsigned int entry = pmbe->entry; unsigned long addr; /* * Don't allow clearing of wired init entries, P1 or P2 access * without a corresponding mapping in the PMB will lead to reset * by the TLB. */ if (unlikely(entry < ARRAY_SIZE(pmb_init_map) || entry >= NR_PMB_ENTRIES)) return; jump_to_uncached(); /* Clear V-bit */ addr = mk_pmb_addr(entry); ctrl_outl(ctrl_inl(addr) & ~PMB_V, addr); addr = mk_pmb_data(entry); ctrl_outl(ctrl_inl(addr) & ~PMB_V, addr); back_to_cached(); clear_bit(entry, &pmb_map); }
/* WBack O-Cache and flush I-Cache */ void flush_icache_range(unsigned long start, unsigned long end) { unsigned long v; unsigned long flags; start = start & ~(L1_CACHE_BYTES-1); end = (end + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1); local_irq_save(flags); jump_to_uncached(); for (v = start; v < end; v+=L1_CACHE_BYTES) { unsigned long addr = (v & 0x000007f0); int way; /* O-Cache writeback */ for (way = 0; way < 4; way++) { unsigned long data = ctrl_inl(CACHE_OC_ADDRESS_ARRAY | addr | (way << 11)); if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) { data &= ~SH_CACHE_UPDATED; ctrl_outl(data, CACHE_OC_ADDRESS_ARRAY | addr | (way << 11)); } } /* I-Cache invalidate */ ctrl_outl(addr, CACHE_IC_ADDRESS_ARRAY | addr | 0x00000008); } back_to_cached(); local_irq_restore(flags); }
void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) { unsigned long flags, pteval, vpn; /* * Handle debugger faulting in for debugee. */ if (vma && current->active_mm != vma->vm_mm) return; local_irq_save(flags); /* Set PTEH register */ vpn = (address & MMU_VPN_MASK) | get_asid(); ctrl_outl(vpn, MMU_PTEH); pteval = pte_val(pte); /* Set PTEL register */ pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */ /* conveniently, we want all the software flags to be 0 anyway */ ctrl_outl(pteval, MMU_PTEL); /* Load the TLB */ asm volatile("ldtlb": /* no output */ : /* no input */ : "memory"); local_irq_restore(flags); }
static void dac_audio_set_rate(void) { unsigned long interval; interval = (current_cpu_data.module_clock / 4) / rate; ctrl_outl(interval, TMU1_TCOR); ctrl_outl(interval, TMU1_TCNT); }
/* Works for HARP and overdrive */ static void mach_led(int position, int value) { if (value) { ctrl_outl(EPLD_LED_ON, EPLD_LED); } else { ctrl_outl(EPLD_LED_OFF, EPLD_LED); } }
void titan_outl(u32 value, unsigned long port) { if (PXSEG(port)) ctrl_outl(value, port); else if (is_pci_ioaddr(port)) ctrl_outl(value, pci_ioaddr(port)); else maybebadio(port); }
void hs7751rvoip_outl(unsigned int value, unsigned long port) { if (PXSEG(port)) ctrl_outl(value, port); else if (is_pci_ioaddr(port) || shifted_port(port)) ctrl_outl(value, pci_ioaddr(port)); else maybebadio(port); }
/* * Program the hardware MAC address from dev->dev_addr. */ static void update_mac_address(struct net_device *ndev) { u32 ioaddr = ndev->base_addr; ctrl_outl((ndev->dev_addr[0] << 24) | (ndev->dev_addr[1] << 16) | (ndev->dev_addr[2] << 8) | (ndev->dev_addr[3]), ioaddr + MAHR); ctrl_outl((ndev->dev_addr[4] << 8) | (ndev->dev_addr[5]), ioaddr + MALR); }
void __init plat_irq_setup(void) { /* disable IRQ7-0 */ ctrl_outl(0xff000000, INTC_INTMSK0); /* disable IRL3-0 + IRL7-4 */ ctrl_outl(0xc0000000, INTC_INTMSK1); ctrl_outl(0xfffefffe, INTC_INTMSK2); register_intc_controller(&intc_desc); }
static int pvr2_xfer_dma(struct dma_info *info) { if (info->sar || !info->dar) return -EINVAL; ctrl_outl(info->dar, PVR2_DMA_ADDR); ctrl_outl(info->count, PVR2_DMA_COUNT); ctrl_outl(info->mode & DMA_MODE_MASK, PVR2_DMA_MODE); return 0; }
static void dac_audio_set_rate(void) { unsigned long interval; struct clk *clk; clk = clk_get(NULL, "module_clk"); interval = (clk_get_rate(clk) / 4) / rate; clk_put(clk); ctrl_outl(interval, TMU1_TCOR); ctrl_outl(interval, TMU1_TCNT); }
static int pvr2_xfer_dma(struct dma_channel *chan) { if (chan->sar || !chan->dar) return -EINVAL; xfer_complete = 0; ctrl_outl(chan->dar, PVR2_DMA_ADDR); ctrl_outl(chan->count, PVR2_DMA_COUNT); ctrl_outl(chan->mode & DMA_MODE_MASK, PVR2_DMA_MODE); return 0; }
static irqreturn_t dma_err(int irq, void *dev_id, struct pt_regs *regs) { unsigned long dmaor = ctrl_inl(DMAOR); printk("DMAE: DMAOR=%lx\n", dmaor); ctrl_outl(ctrl_inl(DMAOR)&~DMAOR_NMIF, DMAOR); ctrl_outl(ctrl_inl(DMAOR)&~DMAOR_AE, DMAOR); ctrl_outl(ctrl_inl(DMAOR)|DMAOR_DME, DMAOR); disable_irq(irq); return IRQ_HANDLED; }
static void __init pci_write_config(unsigned long busNo, unsigned long devNo, unsigned long fncNo, unsigned long cnfAdd, unsigned long cnfData) { ctrl_outl((0x80000000 + ((busNo & 0xff) << 16) + ((devNo & 0x1f) << 11) + ((fncNo & 0x07) << 8) + (cnfAdd & 0xfc)), PCIPAR); ctrl_outl(cnfData, PCIPDR); }
void __init plat_irq_setup(void) { /* disable IRQ3-0 + IRQ7-4 */ ctrl_outl(0xff000000, INTC_INTMSK0); /* disable IRL3-0 + IRL7-4 */ ctrl_outl(0xc0000000, INTC_INTMSK1); ctrl_outl(0xfffefffe, INTC_INTMSK2); /* select IRL mode for IRL3-0 + IRL7-4 */ ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0); register_intc_controller(&intc_desc); }
/* Multicast reception directions set */ static void sh_eth_set_multicast_list(struct net_device *ndev) { u32 ioaddr = ndev->base_addr; if (ndev->flags & IFF_PROMISC) { /* Set promiscuous. */ ctrl_outl((ctrl_inl(ioaddr + ECMR) & ~ECMR_MCT) | ECMR_PRM, ioaddr + ECMR); } else { /* Normal, unicast/broadcast-only mode. */ ctrl_outl((ctrl_inl(ioaddr + ECMR) & ~ECMR_PRM) | ECMR_MCT, ioaddr + ECMR); } }
/* * Hah! We'll see if this works (switching from usecs to nsecs). */ static unsigned long tmu_timer_get_frequency(void) { u32 freq; struct timespec ts1, ts2; unsigned long diff_nsec; unsigned long factor; /* Setup the timer: We don't want to generate interrupts, just * have it count down at its natural rate. */ ctrl_outb(0, TMU_TSTR); #if !defined(CONFIG_CPU_SUBTYPE_SH7300) && !defined(CONFIG_CPU_SUBTYPE_SH7760) ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); #endif ctrl_outw(TMU0_TCR_CALIB, TMU0_TCR); ctrl_outl(0xffffffff, TMU0_TCOR); ctrl_outl(0xffffffff, TMU0_TCNT); rtc_get_time(&ts2); do { rtc_get_time(&ts1); } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); /* actually start the timer */ ctrl_outb(TMU_TSTR_INIT, TMU_TSTR); do { rtc_get_time(&ts2); } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); freq = 0xffffffff - ctrl_inl(TMU0_TCNT); if (ts2.tv_nsec < ts1.tv_nsec) { ts2.tv_nsec += 1000000000; ts2.tv_sec--; } diff_nsec = (ts2.tv_sec - ts1.tv_sec) * 1000000000 + (ts2.tv_nsec - ts1.tv_nsec); /* this should work well if the RTC has a precision of n Hz, where * n is an integer. I don't think we have to worry about the other * cases. */ factor = (1000000000 + diff_nsec/2) / diff_nsec; if (factor * diff_nsec > 1100000000 || factor * diff_nsec < 900000000) panic("weird RTC (diff_nsec %ld)", diff_nsec); return freq * factor; }
static void disable_systemh_irq(unsigned int irq) { if (systemh_irq_mask_register) { unsigned long val, mask = 0x01 << 1; /* Clear the "irq"th bit in the mask and set it in the request */ val = ctrl_inl((unsigned long)systemh_irq_mask_register); val &= ~mask; ctrl_outl(val, (unsigned long)systemh_irq_mask_register); val = ctrl_inl((unsigned long)systemh_irq_request_register); val |= mask; ctrl_outl(val, (unsigned long)systemh_irq_request_register); } }
static void tmu0_timer_set_interval(unsigned long interval, unsigned int reload) { ctrl_outl(interval, TMU0_TCNT); /* * TCNT reloads from TCOR on underflow, clear it if we don't * intend to auto-reload */ if (reload) ctrl_outl(interval, TMU0_TCOR); else ctrl_outl(0, TMU0_TCOR); tmu_timer_start(); }
static struct dvb_frontend *init_stv090x_device(struct dvb_adapter *adapter, struct plat_tuner_config *tuner_cfg, int i) { struct dvb_frontend *frontend; struct core_config *cfg; unsigned int reg = 0; printk("> (bus = %d) %s\n", tuner_cfg->i2c_bus, __FUNCTION__); cfg = kmalloc(sizeof(struct core_config), GFP_KERNEL); if (cfg == NULL) { printk("stv090x: kmalloc failed\n"); return NULL; } /* initialize the config data */ cfg->tuner_enable_pin = NULL; cfg->i2c_adap = i2c_get_adapter(tuner_cfg->i2c_bus); printk("i2c adapter = 0x%0x\n", cfg->i2c_adap); cfg->i2c_addr = tuner_cfg->i2c_addr; printk("i2c addr = %02x\n", cfg->i2c_addr); if (cfg->i2c_adap == NULL) { printk("[stv090x] failed to allocate resources (i2c adapter)\n"); goto error; } /* SYS_CFG25[0] - FE900_SOFT_RESET */ ctrl_outl(1, 0xfe001164); /* reset ON */ msleep(250); ctrl_outl(0, 0xfe001164); /* reset OFF */ msleep(250); frontend = frontend_init(cfg, i); if (frontend == NULL) { printk("[stv090x] frontend init failed!\n"); goto error; } printk(KERN_INFO "%s: Call dvb_register_frontend (adapter = 0x%x)\n", __FUNCTION__, (unsigned int) adapter); if (dvb_register_frontend(adapter, frontend)) { printk("[stv090x] frontend registration failed !\n"); if (frontend->ops.release) frontend->ops.release(frontend); goto error; } return frontend; error: kfree(cfg); return NULL; }
/* * The 32KB cache on the SH7705 suffers from the same synonym problem * as SH4 CPUs */ static inline void cache_wback_all(void) { unsigned long ways, waysize, addrstart; ways = current_cpu_data.dcache.ways; waysize = current_cpu_data.dcache.sets; waysize <<= current_cpu_data.dcache.entry_shift; addrstart = CACHE_OC_ADDRESS_ARRAY; do { unsigned long addr; for (addr = addrstart; addr < addrstart + waysize; addr += current_cpu_data.dcache.linesz) { unsigned long data; int v = SH_CACHE_UPDATED | SH_CACHE_VALID; data = ctrl_inl(addr); if ((data & v) == v) ctrl_outl(data & ~v, addr); } addrstart += current_cpu_data.dcache.way_incr; } while (--ways); }