static irqreturn_t _scale_isr_root(int irq, void *dev_id)
{
	uint32_t                status;
	struct scale_frame      frame;
	uint32_t                flag;
	
	(void)irq; (void)dev_id;
	status = REG_RD(SCALE_INT_STS);

	if (unlikely(0 == (status & SCALE_IRQ_BIT))) {
		return IRQ_HANDLED;
	}

	SCALE_TRACE("SCALE DRV: _scale_isr_root \n");
	spin_lock_irqsave(&scale_lock, flag);
	if (g_path->user_func) {
		frame.yaddr = g_path->output_addr.yaddr;
		frame.uaddr = g_path->output_addr.uaddr;
		frame.vaddr = g_path->output_addr.vaddr;
		frame.width = g_path->output_size.w;
		if (SCALE_MODE_SLICE == g_path->scale_mode) {
			frame.height = g_path->slice_out_height;
			g_path->slice_out_height = REG_RD(SCALE_SLICE_VER);
			g_path->slice_out_height = (g_path->slice_out_height >> 16) & 0xFFF;
			frame.height = g_path->slice_out_height - frame.height;
		} else {
示例#2
0
void epd_enable(void)
{
	char temp = TEMP_USE_DEFAULT;
	debug("epd_enable\n");
	
	//epdc_power_on();
	/* Draw data to display */
	//draw_mode0();

	/* Enable clock gating (clear to enable) */
	REG_CLR(EPDC_BASE, EPDC_CTRL, EPDC_CTRL_CLKGATE);
	while (REG_RD(EPDC_BASE, EPDC_CTRL) &
	       (EPDC_CTRL_SFTRST | EPDC_CTRL_CLKGATE))
		;

	REG_WR(EPDC_BASE, EPDC_TEMP, TEMP_USE_DEFAULT);
	temp = read_temperature();
//	temp = do_read_temperature_via_i2c();
	temp_set_index(temp);
	
	/* Set Waveform Bufferr register to real waveform address */
	REG_WR(EPDC_BASE, EPDC_WVADDR, panel_info.epdc_data.waveform_buf_addr);

	debug("epdc_irq's value %08x\nEPDC_IRQ_CLR's value %08x\n",REG_RD(EPDC_BASE, EPDC_IRQ), REG_RD(EPDC_BASE, EPDC_IRQ_CLR));
	debug("EPDC LUT STATUS %08x\n",REG_RD(EPDC_BASE,EPDC_STATUS_LUTS));
	draw_splash_screen();
	debug("epdc_irq's value %08x\nEPDC_IRQ_CLR's value %08x\n",REG_RD(EPDC_BASE, EPDC_IRQ), REG_RD(EPDC_BASE, EPDC_IRQ_CLR));
	debug("EPDC LUT STATUS %08x\n",REG_RD(EPDC_BASE,EPDC_STATUS_LUTS));
}
int32_t    scale_continue(void)
{
	enum scale_drv_rtn      rtn = SCALE_RTN_SUCCESS;
	uint32_t                slice_h = g_path->slice_height;

	SCALE_TRACE("SCALE DRV: continue %d, %d, %d \n",
		g_path->slice_height, g_path->slice_in_height, g_path->scale_mode);

	if (SCALE_MODE_SLICE == g_path->scale_mode) {
		if (g_path->slice_in_height +  g_path->slice_height >= g_path->input_rect.h) {
			slice_h = g_path->input_rect.h - g_path->slice_in_height;
			g_path->is_last_slice = 1;
			REG_MWR(SCALE_SLICE_VER, 0x3FF, slice_h);
			REG_OWR(SCALE_SLICE_VER, (1 << 12));
			SCALE_TRACE("SCALE DRV: continue, last slice, 0x%x \n", REG_RD(SCALE_SLICE_VER));
		} else {
			g_path->is_last_slice = 0;
			REG_MWR(SCALE_SLICE_VER, (1 << 12), (0 << 12));
		}
		g_path->slice_in_height += g_path->slice_height;
	}

	REG_WR(SCALE_FRM_SWAP_Y, g_path->temp_buf_addr.yaddr);
	REG_WR(SCALE_FRM_SWAP_U, g_path->temp_buf_addr.uaddr);
	REG_WR(SCALE_FRM_LINE,   g_path->temp_buf_addr.vaddr);
	
	_scale_reg_trace();
	REG_OWR(SCALE_CFG, 1);
	atomic_inc(&g_path->start_flag);
	SCALE_TRACE("SCALE DRV: continue %x.\n", REG_RD(SCALE_CFG));

	return rtn;
}
示例#4
0
/*
void sunxi_gpio_do_tasklet(unsigned long data)
{
	printk("this is irp donw dispuse !\n");
}
DECLARE_TASKLET(sunxi_tasklet,sunxi_gpio_do_tasklet,0);
*/
irqreturn_t sunxi_interrupt(int irq,void *dev_id)
{
    unsigned int PIC, PIS,tmp;
    int i = 0;
    PIC = REG_RD(GPIO_TEST_BASE + 0x210 ) ;
    PIS = REG_RD(GPIO_TEST_BASE + 0x214 ) ;
    tmp	= PIS;

    while(tmp) {
        if(tmp & 0x1) {
            /*if (tmp & 0x1) is true, the i represent NO.i EINT interrupt take place.
            you can through the value of i to decide to do what*/
            printk("this is NO.%d gpio INT \n",i);
        }
        tmp >>= 1;
        i++;
    }

    GPIO_SW_DEBUG("0 PIC is %x \n PIS is %x \n",PIC,PIS);
    __raw_writel(PIS, GPIO_TEST_BASE + 0x214);
    GPIO_SW_DEBUG("1 PIC is %x \n PIS is %x \n",PIC,PIS);

    /*this is a interface to connect interrupt top half and bottom half,if want to use bottom half,you can open fanctions sunxi_gpio_do_tasklet and tasklet_schedule*/

    /*
    tasklet_schedule(&sunxi_tasklet);
    */
    return IRQ_HANDLED;
}
示例#5
0
static void
console_write_direct(struct console *co, const char *buf, unsigned int len)
{
	int i;
	reg_ser_r_stat_din stat;
	reg_ser_rw_tr_dma_en tr_dma_en, old;

	/* Switch to manual mode */
	tr_dma_en = old = REG_RD (ser, port->instance, rw_tr_dma_en);
	if (tr_dma_en.en == regk_ser_yes) {
		tr_dma_en.en = regk_ser_no;
		REG_WR(ser, port->instance, rw_tr_dma_en, tr_dma_en);
	}

	/* Send data */
	for (i = 0; i < len; i++) {
		/* LF -> CRLF */
		if (buf[i] == '\n') {
			do {
				stat = REG_RD (ser, port->instance, r_stat_din);
			} while (!stat.tr_rdy);
			REG_WR_INT (ser, port->instance, rw_dout, '\r');
		}
		/* Wait until transmitter is ready and send.*/
		do {
			stat = REG_RD (ser, port->instance, r_stat_din);
		} while (!stat.tr_rdy);
		REG_WR_INT (ser, port->instance, rw_dout, buf[i]);
	}

	/* Restore mode */
	if (tr_dma_en.en != old.en)
		REG_WR(ser, port->instance, rw_tr_dma_en, old);
}
/* Called with ints off */
inline void start_timer_trig(unsigned long delay_us)
{
  reg_timer_rw_ack_intr ack_intr = { 0 };
  reg_timer_rw_intr_mask intr_mask;
  reg_timer_rw_trig trig;
  reg_timer_rw_trig_cfg trig_cfg = { 0 };
	reg_timer_r_time r_time0;
	reg_timer_r_time r_time1;
	unsigned char trig_wrap;
	unsigned char time_wrap;

	r_time0 = REG_RD(timer, regi_timer0, r_time);

  D1(printk("start_timer_trig : %d us freq: %i div: %i\n",
            delay_us, freq_index, div));
  /* Clear trig irq */
	intr_mask = REG_RD(timer, regi_timer0, rw_intr_mask);
  intr_mask.trig = 0;
	REG_WR(timer, regi_timer0, rw_intr_mask, intr_mask);

	/* Set timer values and check if trigger wraps. */
	/* r_time is 100MHz (10 ns resolution) */
	trig_wrap = (trig = r_time0 + delay_us*(1000/10)) < r_time0;

  timer_div_settings[fast_timers_started % NUM_TIMER_STATS] = trig;
  timer_delay_settings[fast_timers_started % NUM_TIMER_STATS] = delay_us;

  /* Ack interrupt */
  ack_intr.trig = 1;
	REG_WR(timer, regi_timer0, rw_ack_intr, ack_intr);

  /* Start timer */
	REG_WR(timer, regi_timer0, rw_trig, trig);
  trig_cfg.tmr = regk_timer_time;
	REG_WR(timer, regi_timer0, rw_trig_cfg, trig_cfg);

  /* Check if we have already passed the trig time */
	r_time1 = REG_RD(timer, regi_timer0, r_time);
	time_wrap = r_time1 < r_time0;

	if ((trig_wrap && !time_wrap) || (r_time1 < trig)) {
    /* No, Enable trig irq */
		intr_mask = REG_RD(timer, regi_timer0, rw_intr_mask);
    intr_mask.trig = 1;
		REG_WR(timer, regi_timer0, rw_intr_mask, intr_mask);
    fast_timers_started++;
    fast_timer_running = 1;
	} else {
    /* We have passed the time, disable trig point, ack intr */
    trig_cfg.tmr = regk_timer_off;
		REG_WR(timer, regi_timer0, rw_trig_cfg, trig_cfg);
		REG_WR(timer, regi_timer0, rw_ack_intr, ack_intr);
		/* call the int routine */
		INIT_WORK(&fast_work, timer_trig_handler);
		schedule_work(&fast_work);
  }

}
示例#7
0
int epdc_ctrl_init(void *lcdbase)
{
	/*
	 * We rely on lcdbase being a physical address, i.e., either MMU off,
	 * or 1-to-1 mapping. Might want to add some virt2phys here.
	 */
	if (!lcdbase)
		return -1;

	eink_color_fg = 0xFF;
	eink_color_bg = 0xFF;

	/* Reset */
	REG_SET(EPDC_BASE, EPDC_CTRL, EPDC_CTRL_SFTRST);
	while (!(REG_RD(EPDC_BASE, EPDC_CTRL) & EPDC_CTRL_CLKGATE))
		;
	REG_CLR(EPDC_BASE, EPDC_CTRL, EPDC_CTRL_SFTRST);

	/* Enable clock gating (clear to enable) */
	REG_CLR(EPDC_BASE, EPDC_CTRL, EPDC_CTRL_CLKGATE);
	while (REG_RD(EPDC_BASE, EPDC_CTRL) &
	       (EPDC_CTRL_SFTRST | EPDC_CTRL_CLKGATE))
		;

	debug("resolution %dx%d, bpp %d\n", (int)panel_info.vl_col,
		(int)panel_info.vl_row, NBITS(panel_info.vl_bpix));


	/* Set framebuffer pointer */
	REG_WR(EPDC_BASE, EPDC_UPD_ADDR, (u32)lcdbase);

#if 0
	/* Set Working Buffer pointer */
	REG_WR(EPDC_BASE, EPDC_WB_ADDR, panel_info.epdc_data.working_buf_addr);
	/* Set Waveform Buffer pointer */
	REG_WR(EPDC_BASE, EPDC_WVADDR, panel_info.epdc_data.waveform_buf_addr);
#endif 

	/* Set waveform and working buffer, they will be changed later */
	REG_WR(EPDC_BASE, EPDC_WVADDR, (unsigned long)CONFIG_TEMP_INIT_WAVEFORM_ADDR);
	REG_WR(EPDC_BASE, EPDC_WB_ADDR, (unsigned long)CONFIG_WORKING_BUF_ADDR);
	
#if 0
	/* Get waveform data address and offset */
	int data_offs = setup_waveform_file();
	if(data_offs == -1) {
		printf("Can't load waveform data!\n");
		return -1;
	}
#endif

	/* Initialize EPDC, passing pointer to EPDC registers */
	epdc_init_settings();

	epdc_initialized = 1;

	return;
}
示例#8
0
/* Receive character */
int serial_getc(void)
{
	/* Wait while TX FIFO is empty */
	while (REG_RD(DBGUART_BASE + UARTDBGFR) & RXFE)
		;

	/* Read data byte */
	return REG_RD(DBGUART_BASE + UARTDBGDR) & 0xff;
}
示例#9
0
/* Called with ints off */
void __INLINE__ start_timer_trig(unsigned long delay_us)
{
  reg_timer_rw_ack_intr ack_intr = { 0 };
  reg_timer_rw_intr_mask intr_mask;
  reg_timer_rw_trig trig;
  reg_timer_rw_trig_cfg trig_cfg = { 0 };
  reg_timer_r_time r_time;

  r_time = REG_RD(timer, regi_timer, r_time);

  D1(printk("start_timer_trig : %d us freq: %i div: %i\n",
            delay_us, freq_index, div));
  /* Clear trig irq */
  intr_mask = REG_RD(timer, regi_timer, rw_intr_mask);
  intr_mask.trig = 0;
  REG_WR(timer, regi_timer, rw_intr_mask, intr_mask);

  /* Set timer values */
  /* r_time is 100MHz (10 ns resolution) */
  trig = r_time + delay_us*(1000/10);

  timer_div_settings[fast_timers_started % NUM_TIMER_STATS] = trig;
  timer_delay_settings[fast_timers_started % NUM_TIMER_STATS] = delay_us;

  /* Ack interrupt */
  ack_intr.trig = 1;
  REG_WR(timer, regi_timer, rw_ack_intr, ack_intr);

  /* Start timer */
  REG_WR(timer, regi_timer, rw_trig, trig);
  trig_cfg.tmr = regk_timer_time;
  REG_WR(timer, regi_timer, rw_trig_cfg, trig_cfg);

  /* Check if we have already passed the trig time */
  r_time = REG_RD(timer, regi_timer, r_time);
  if (r_time < trig) {
    /* No, Enable trig irq */
    intr_mask = REG_RD(timer, regi_timer, rw_intr_mask);
    intr_mask.trig = 1;
    REG_WR(timer, regi_timer, rw_intr_mask, intr_mask);
    fast_timers_started++;
    fast_timer_running = 1;
  }
  else
  {
    /* We have passed the time, disable trig point, ack intr */
    trig_cfg.tmr = regk_timer_off;
    REG_WR(timer, regi_timer, rw_trig_cfg, trig_cfg);
    REG_WR(timer, regi_timer, rw_ack_intr, ack_intr);
    /* call the int routine directly */
    timer_trig_handler();
  }

}
示例#10
0
/* Maps the specified queue to the specified COS */
void ecore_map_q_cos(struct _lm_device_t *pdev, u32_t q_num, u32_t new_cos)
{
	/* find current COS mapping */
	u32_t curr_cos = REG_RD(pdev, QM_REG_QVOQIDX_0 + q_num * 4);

	/* check if queue->COS mapping has changed */
	if (curr_cos != new_cos) {
		u32_t num_vnics = ECORE_PORT2_MODE_NUM_VNICS;
		u32_t reg_addr, reg_bit_map, vnic;

		/* update parameters for 4port mode */
		if (INIT_MODE_FLAGS(pdev) & MODE_PORT4) {
			num_vnics = ECORE_PORT4_MODE_NUM_VNICS;
			if (PORT_ID(pdev)) {
				curr_cos += ECORE_E3B0_PORT1_COS_OFFSET;
				new_cos += ECORE_E3B0_PORT1_COS_OFFSET;
			}
		}

		/* change queue mapping for each VNIC */
		for (vnic = 0; vnic < num_vnics; vnic++) {
			u32_t pf_q_num =
				ECORE_PF_Q_NUM(q_num, PORT_ID(pdev), vnic);
			u32_t q_bit_map = 1 << (pf_q_num & 0x1f);

			/* overwrite queue->VOQ mapping */
			REG_WR(pdev, ECORE_Q_VOQ_REG_ADDR(pf_q_num), new_cos);

			/* clear queue bit from current COS bit map */
			reg_addr = ECORE_VOQ_Q_REG_ADDR(curr_cos, pf_q_num);
			reg_bit_map = REG_RD(pdev, reg_addr);
			REG_WR(pdev, reg_addr, reg_bit_map & (~q_bit_map));

			/* set queue bit in new COS bit map */
			reg_addr = ECORE_VOQ_Q_REG_ADDR(new_cos, pf_q_num);
			reg_bit_map = REG_RD(pdev, reg_addr);
			REG_WR(pdev, reg_addr, reg_bit_map | q_bit_map);

			/* set/clear queue bit in command-queue bit map
			(E2/E3A0 only, valid COS values are 0/1) */
			if (!(INIT_MODE_FLAGS(pdev) & MODE_E3_B0)) {
				reg_addr = ECORE_Q_CMDQ_REG_ADDR(pf_q_num);
				reg_bit_map = REG_RD(pdev, reg_addr);
				q_bit_map = 1 << (2 * (pf_q_num & 0xf));
				reg_bit_map = new_cos ?
					      (reg_bit_map | q_bit_map) :
					      (reg_bit_map & (~q_bit_map));
				REG_WR(pdev, reg_addr, reg_bit_map);
			}
		}
	}
}
示例#11
0
static inline void etraxfs_uart_start_tx_bottom(struct uart_port *port)
{
	struct uart_cris_port *up = (struct uart_cris_port *)port;
	void __iomem *regi_ser = up->regi_ser;
	reg_ser_rw_tr_ctrl tr_ctrl;
	reg_ser_rw_intr_mask intr_mask;

	tr_ctrl = REG_RD(ser, regi_ser, rw_tr_ctrl);
	tr_ctrl.stop = regk_ser_no;
	REG_WR(ser, regi_ser, rw_tr_ctrl, tr_ctrl);
	intr_mask = REG_RD(ser, regi_ser, rw_intr_mask);
	intr_mask.tr_rdy = regk_ser_yes;
	REG_WR(ser, regi_ser, rw_intr_mask, intr_mask);
}
示例#12
0
static void sync_serial_start_port(struct sync_port *port)
{
	reg_sser_rw_cfg cfg = REG_RD(sser, port->regi_sser, rw_cfg);
	reg_sser_rw_tr_cfg tr_cfg =
		REG_RD(sser, port->regi_sser, rw_tr_cfg);
	reg_sser_rw_rec_cfg rec_cfg =
		REG_RD(sser, port->regi_sser, rw_rec_cfg);
	cfg.en = regk_sser_yes;
	tr_cfg.tr_en = regk_sser_yes;
	rec_cfg.rec_en = regk_sser_yes;
	REG_WR(sser, port->regi_sser, rw_cfg, cfg);
	REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg);
	REG_WR(sser, port->regi_sser, rw_rec_cfg, rec_cfg);
	port->started = 1;
}
示例#13
0
void lcd_ctrl_init(void *lcdbase)
{
	/*
	 * We rely on lcdbase being a physical address, i.e., either MMU off,
	 * or 1-to-1 mapping. Might want to add some virt2phys here.
	 */
	if (!lcdbase)
		return;

	lcd_color_fg = 0xFF;
	lcd_color_bg = 0xFF;

	/* Reset */
	REG_SET(EPDC_BASE, EPDC_CTRL, EPDC_CTRL_SFTRST);
	while (!(REG_RD(EPDC_BASE, EPDC_CTRL) & EPDC_CTRL_CLKGATE))
		;
	REG_CLR(EPDC_BASE, EPDC_CTRL, EPDC_CTRL_SFTRST);

	/* Enable clock gating (clear to enable) */
	REG_CLR(EPDC_BASE, EPDC_CTRL, EPDC_CTRL_CLKGATE);
	while (REG_RD(EPDC_BASE, EPDC_CTRL) &
	       (EPDC_CTRL_SFTRST | EPDC_CTRL_CLKGATE))
		;

	debug("resolution %dx%d, bpp %d\n", (int)panel_info.vl_col,
		(int)panel_info.vl_row, NBITS(panel_info.vl_bpix));

	/* Set framebuffer pointer */
	REG_WR(EPDC_BASE, EPDC_UPD_ADDR, (u32)lcdbase);

	/* Set Working Buffer pointer */
	REG_WR(EPDC_BASE, EPDC_WB_ADDR, panel_info.epdc_data.working_buf_addr);

	/* Get waveform data address and offset */
	if (setup_waveform_file()) {
		printf("Can't load waveform data!\n");
		return;
	}

	/* Set Waveform Buffer pointer */
	REG_WR(EPDC_BASE, EPDC_WVADDR,
		panel_info.epdc_data.waveform_buf_addr);

	/* Initialize EPDC, passing pointer to EPDC registers */
	epdc_init_settings();

	return;
}
示例#14
0
static inline int epdc_is_lut_active(u32 lut_num)
{
	u32 val = REG_RD(EPDC_BASE, EPDC_STATUS_LUTS);
	int is_active = val & (1 << lut_num) ? TRUE : FALSE;

	return is_active;
}
示例#15
0
文件: time.c 项目: robacklin/ts7800
void __init
cris_timer_init(void)
{
	int cpu = smp_processor_id();
  	reg_timer_rw_tmr0_ctrl tmr0_ctrl = { 0 };
       	reg_timer_rw_tmr0_div tmr0_div = TIMER0_DIV;
	reg_timer_rw_intr_mask timer_intr_mask;

	/* Setup the etrax timers
	 * Base frequency is 100MHz, divider 1000000 -> 100 HZ
	 * We use timer0, so timer1 is free.
	 * The trig timer is used by the fasttimer API if enabled.
	 */

       	tmr0_ctrl.op = regk_timer_ld;
	tmr0_ctrl.freq = regk_timer_f100;
       	REG_WR(timer, timer_regs[cpu], rw_tmr0_div, tmr0_div);
       	REG_WR(timer, timer_regs[cpu], rw_tmr0_ctrl, tmr0_ctrl); /* Load */
       	tmr0_ctrl.op = regk_timer_run;
       	REG_WR(timer, timer_regs[cpu], rw_tmr0_ctrl, tmr0_ctrl); /* Start */

       	/* enable the timer irq */
       	timer_intr_mask = REG_RD(timer, timer_regs[cpu], rw_intr_mask);
       	timer_intr_mask.tmr0 = 1;
       	REG_WR(timer, timer_regs[cpu], rw_intr_mask, timer_intr_mask);
}
示例#16
0
static irqreturn_t
ser_interrupt(int irq, void *dev_id)
{
	struct uart_cris_port *up = (struct uart_cris_port *)dev_id;
	void __iomem *regi_ser;
	int handled = 0;

	spin_lock(&up->port.lock);

	regi_ser = up->regi_ser;

	if (regi_ser) {
		reg_ser_r_masked_intr masked_intr;

		masked_intr = REG_RD(ser, regi_ser, r_masked_intr);
		/*
		 * Check what interrupts are active before taking
		 * actions. If DMA is used the interrupt shouldn't
		 * be enabled.
		 */
		if (masked_intr.dav) {
			receive_chars_no_dma(up);
			handled = 1;
		}

		if (masked_intr.tr_rdy) {
			transmit_chars_no_dma(up);
			handled = 1;
		}
	}
	spin_unlock(&up->port.lock);
	return IRQ_RETVAL(handled);
}
示例#17
0
static inline int crisv32_serial_get_cts(struct uart_cris_port *up)
{
	void __iomem *regi_ser = up->regi_ser;
	reg_ser_r_stat_din rstat = REG_RD(ser, regi_ser, r_stat_din);

	return (rstat.cts_n == regk_ser_active);
}
示例#18
0
/*
 *	hardware specific access to control-lines
*/
static void crisv32_hwcontrol(struct mtd_info *mtd, int cmd)
{
	unsigned long flags;
	reg_gio_rw_pa_dout dout = REG_RD(gio, regi_gio, rw_pa_dout);

	local_irq_save(flags);
	switch(cmd){
		case NAND_CTL_SETCLE:
		     dout.data |= (1<<CLE_BIT);
		     break;
		case NAND_CTL_CLRCLE:
		     dout.data &= ~(1<<CLE_BIT);
		     break;
		case NAND_CTL_SETALE:
		     dout.data |= (1<<ALE_BIT);
		     break;
		case NAND_CTL_CLRALE:
		     dout.data &= ~(1<<ALE_BIT);
		     break;
		case NAND_CTL_SETNCE:
		     dout.data |= (1<<CE_BIT);
		     break;
		case NAND_CTL_CLRNCE:
		     dout.data &= ~(1<<CE_BIT);
		     break;
	}
	REG_WR(gio, regi_gio, rw_pa_dout, dout);
	local_irq_restore(flags);
}
示例#19
0
int crisv32_arbiter_unwatch(int id)
{
	reg_marb_rw_intr_mask intr_mask = REG_RD(marb, regi_marb, rw_intr_mask);

	crisv32_arbiter_init();

	spin_lock(&arbiter_lock);

	if ((id < 0) || (id >= NUMBER_OF_BP) || (!watches[id].used)) {
		spin_unlock(&arbiter_lock);
		return -EINVAL;
	}

	memset(&watches[id], 0, sizeof(struct crisv32_watch_entry));

	if (id == 0)
		intr_mask.bp0 = regk_marb_no;
	else if (id == 1)
		intr_mask.bp1 = regk_marb_no;
	else if (id == 2)
		intr_mask.bp2 = regk_marb_no;
	else if (id == 3)
		intr_mask.bp3 = regk_marb_no;

	REG_WR(marb, regi_marb, rw_intr_mask, intr_mask);

	spin_unlock(&arbiter_lock);
	return 0;
}
示例#20
0
/*
 * This function handles both the DMA and non-DMA case by ordering the
 * transmitter to stop of after the current character.  We don't need to wait
 * for any such character to be completely transmitted; we do that where it
 * matters, like in etraxfs_uart_set_termios.  Don't busy-wait here; see
 * Documentation/serial/driver: this function is called within
 * spin_lock_irq{,save} and thus separate ones would be disastrous (when SMP).
 * There's no documented need to set the txd pin to any particular value;
 * break setting is controlled solely by etraxfs_uart_break_ctl.
 */
static void etraxfs_uart_stop_tx(struct uart_port *port)
{
	struct uart_cris_port *up = (struct uart_cris_port *)port;
	void __iomem *regi_ser = up->regi_ser;
	reg_ser_rw_tr_ctrl tr_ctrl;
	reg_ser_rw_intr_mask intr_mask;
	reg_ser_rw_tr_dma_en tr_dma_en = {0};
	reg_ser_rw_xoff_clr xoff_clr = {0};

	/*
	 * For the non-DMA case, we'd get a tr_rdy interrupt that we're not
	 * interested in as we're not transmitting any characters.  For the
	 * DMA case, that interrupt is already turned off, but no reason to
	 * waste code on conditionals here.
	 */
	intr_mask = REG_RD(ser, regi_ser, rw_intr_mask);
	intr_mask.tr_rdy = regk_ser_no;
	REG_WR(ser, regi_ser, rw_intr_mask, intr_mask);

	tr_ctrl = REG_RD(ser, regi_ser, rw_tr_ctrl);
	tr_ctrl.stop = 1;
	REG_WR(ser, regi_ser, rw_tr_ctrl, tr_ctrl);

	/*
	 * Always clear possible hardware xoff-detected state here, no need to
	 * unnecessary consider mctrl settings and when they change.  We clear
	 * it here rather than in start_tx: both functions are called as the
	 * effect of XOFF processing, but start_tx is also called when upper
	 * levels tell the driver that there are more characters to send, so
	 * avoid adding code there.
	 */
	xoff_clr.clr = 1;
	REG_WR(ser, regi_ser, rw_xoff_clr, xoff_clr);

	/*
	 * Disable transmitter DMA, so that if we're in XON/XOFF, we can send
	 * those single characters without also giving go-ahead for queued up
	 * DMA data.
	 */
	tr_dma_en.en = 0;
	REG_WR(ser, regi_ser, rw_tr_dma_en, tr_dma_en);

	/*
	 * Make sure that write_ongoing is reset when stopping tx.
	 */
	up->write_ongoing = 0;
}
示例#21
0
void wait_for_update_complete(void) 
{
	int i;
	u32 status, activeluts;

	for (i = 0; i < 30; i++) {
		status = REG_RD(EPDC_BASE, EPDC_STATUS);
        	activeluts = REG_RD(EPDC_BASE, EPDC_STATUS_LUTS);
		if ((status & 1) == 0 && activeluts == 0) {
			printf("wait_for_update_complete: %d ms\n", i*100);
			return;
		}
		msleep(100);
	}
	printf("wait_for_update_complete: operation timeout!\n");

}
示例#22
0
static void set_clocks(void)
{
	u32 ssp_source_clk, ssp_clk;
	u32 ssp_div = 1;
	u32 val = 0;

	/*
	 * Configure 480Mhz IO clock
	 */

	/* Ungate IO_CLK and set divider */
	REG_CLR(CLKCTRL_BASE + CLKCTRL_FRAC, FRAC_CLKGATEIO);
	REG_CLR(CLKCTRL_BASE + CLKCTRL_FRAC, 0x3f << FRAC_IOFRAC);
	REG_SET(CLKCTRL_BASE + CLKCTRL_FRAC, IO_DIVIDER << FRAC_IOFRAC);

	/*
	 * Set SSP CLK to desired value
	 */

	/* Calculate SSP_CLK divider relatively to 480Mhz IO_CLK*/
	ssp_source_clk = 480 * MHz;
	ssp_clk = CONFIG_SSP_CLK;
	ssp_div = (ssp_source_clk + ssp_clk - 1) / ssp_clk;

	/* Enable SSP clock */
	val = REG_RD(CLKCTRL_BASE + CLKCTRL_SSP);
	val &= ~SSP_CLKGATE;
	REG_WR(CLKCTRL_BASE + CLKCTRL_SSP, val);

	/* Wait while clock is gated */
	while (REG_RD(CLKCTRL_BASE + CLKCTRL_SSP) & SSP_CLKGATE)
		;

	/* Set SSP clock divider */
	val &= ~(0x1ff << SSP_DIV);
	val |= ssp_div << SSP_DIV;
	REG_WR(CLKCTRL_BASE + CLKCTRL_SSP, val);

	/* Wait until new divider value is set */
	while (REG_RD(CLKCTRL_BASE + CLKCTRL_SSP) & SSP_BUSY)
		;

	/* Set SSP clock source to IO_CLK */
	REG_SET(CLKCTRL_BASE + CLKCTRL_CLKSEQ, CLKSEQ_BYPASS_SSP);
	REG_CLR(CLKCTRL_BASE + CLKCTRL_CLKSEQ, CLKSEQ_BYPASS_SSP);
}
示例#23
0
static void etraxfs_uart_stop_rx(struct uart_port *port)
{
	struct uart_cris_port *up = (struct uart_cris_port *)port;
	void __iomem *regi_ser = up->regi_ser;
	reg_ser_rw_rec_ctrl rec_ctrl = REG_RD(ser, regi_ser, rw_rec_ctrl);

	rec_ctrl.en = regk_ser_no;
	REG_WR(ser, regi_ser, rw_rec_ctrl, rec_ctrl);
}
示例#24
0
void epd_disable(void)
{
	debug("epd_disable\n");
	u32 val;
#if 1 
	/*clear the INT*/
	val = REG_RD(EPDC_BASE, EPDC_IRQ_MASK);
	val |= (1<<0);
	REG_WR(EPDC_BASE, EPDC_IRQ_MASK, val);

	val = REG_RD(EPDC_BASE, EPDC_IRQ_CLR);
	val |= (1<<0);
	REG_WR(EPDC_BASE, EPDC_IRQ_CLR,val);
#endif
	/* Disable clocks to EPDC */
	REG_SET(EPDC_BASE, EPDC_CTRL, EPDC_CTRL_CLKGATE);
	debug("EPDC LUT STATUS %08x\n",REG_RD(EPDC_BASE,EPDC_STATUS_LUTS));
}
示例#25
0
/* Use polling to put a single character to the kernel debug port */
void
putDebugChar(int val)
{
	reg_ser_r_status_data stat;
	do {
		stat = REG_RD (ser, kgdb_instance, r_status_data);
	} while (!stat.tr_ready);
	REG_WR (ser, kgdb_instance, rw_data_out, REG_TYPE_CONV(reg_ser_rw_data_out, int, val));
}
示例#26
0
/* Receive character */
int mxs_serial_getc(void)
{
	/* Wait while RX FIFO is empty */
	while (!mxs_serial_tstc())
		;

	/* Read data byte */
	return REG_RD(MXS_UARTAPP_BASE, HW_UARTAPP_DATA) & 0xff;
}
int32_t dcam_reset(enum dcam_rst_mode reset_mode)
{
	enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
	uint32_t                time_out = 0;

	if (atomic_read(&s_dcam_users)) {
		/* firstly, stop AXI writing */
		REG_OWR(DCAM_BURST_GAP, BIT_18);
	}

	/* then wait for AHB busy cleared */
	while (++time_out < DCAM_AXI_STOP_TIMEOUT) {
		if (0 == (REG_RD(DCAM_AHBM_STS) & BIT_0))
			break;
	}
	if (time_out >= DCAM_AXI_STOP_TIMEOUT)
		return DCAM_RTN_TIMEOUT;

	/* do reset action */
	switch (reset_mode) {
	case DCAM_RST_PATH1:
		sci_glb_set(DCAM_RST, PATH1_RST_BIT);
		sci_glb_set(DCAM_RST, CCIR_RST_BIT);
		sci_glb_clr(DCAM_RST, PATH1_RST_BIT);
		sci_glb_clr(DCAM_RST, CCIR_RST_BIT);
/*
		REG_OWR(DCAM_RST, DCAM_MOD_RST_BIT);
		REG_OWR(DCAM_RST, CCIR_RST_BIT);
		REG_AWR(DCAM_RST, ~DCAM_MOD_RST_BIT);
		REG_AWR(DCAM_RST, ~CCIR_RST_BIT);
*/
		DCAM_TRACE("DCAM DRV: reset path1 \n");
		break;
	case DCAM_RST_PATH2:
		sci_glb_set(DCAM_RST, PATH2_RST_BIT);
		sci_glb_clr(DCAM_RST, PATH2_RST_BIT);
		DCAM_TRACE("DCAM DRV: reset path2 \n");
		break;
	case DCAM_RST_ALL:
		sci_glb_set(DCAM_RST, DCAM_MOD_RST_BIT);
		sci_glb_set(DCAM_RST, CCIR_RST_BIT);
		sci_glb_clr(DCAM_RST, DCAM_MOD_RST_BIT);
		sci_glb_clr(DCAM_RST, CCIR_RST_BIT);
		DCAM_TRACE("DCAM DRV: reset all \n");
		break;
	default:
		rtn = DCAM_RTN_PARA_ERR;
		break;
	}

	if (atomic_read(&s_dcam_users)) {
		/* the end, enable AXI writing */
		REG_AWR(DCAM_BURST_GAP, ~BIT_18);
	}

	return -rtn;
}
示例#28
0
/* Use polling to put a single character to the kernel debug port */
void
putDebugChar(int val)
{
	reg_ser_r_stat_din stat;
	do {
		stat = REG_RD(ser, kgdb_port->instance, r_stat_din);
	} while (!stat.tr_rdy);
	REG_WR_INT(ser, kgdb_port->instance, rw_dout, val);
}
示例#29
0
文件: time.c 项目: robacklin/ts7800
unsigned long get_ns_in_jiffie(void)
{
	reg_timer_r_tmr0_data data;
	unsigned long ns;

	data = REG_RD(timer, regi_timer, r_tmr0_data);
	ns = (TIMER0_DIV - data) * 10;
	return ns;
}
示例#30
0
int timer_init(void)
{
	u32 val;

	/*
	 * Reset Timers and Rotary Encoder module
	 */

	/* Clear SFTRST */
	REG_CLR(TIMROT_BASE + ROTCTRL, 1 << 31);
	while (REG_RD(TIMROT_BASE + ROTCTRL) & (1 << 31))
		;

	/* Clear CLKGATE */
	REG_CLR(TIMROT_BASE + ROTCTRL, 1 << 30);

	/* Set SFTRST and wait until CLKGATE is set */
	REG_SET(TIMROT_BASE + ROTCTRL, 1 << 31);
	while (!(REG_RD(TIMROT_BASE + ROTCTRL) & (1 << 30)))
		;

	/* Clear SFTRST and CLKGATE */
	REG_CLR(TIMROT_BASE + ROTCTRL, 1 << 31);
	REG_CLR(TIMROT_BASE + ROTCTRL, 1 << 30);

	/*
	* Now initialize timer
	*/

	/* Set fixed_count to 0 */
	REG_WR(TIMROT_BASE + TIMCOUNT, 0);

	/* set UPDATE bit and 1Khz frequency */
	REG_WR(TIMROT_BASE + TIMCTRL,
	       TIMCTRL_RELOAD | TIMCTRL_UPDATE | TIMCTRL_SELECT_1KHZ);

	/* Set fixed_count to maximal value */
	REG_WR(TIMROT_BASE + TIMCOUNT, TIMER_LOAD_VAL);

	/* init the timestamp and lastdec value */
	reset_timer_masked();

	return 0;
}