示例#1
0
bool hal_timer_pit_active_get(pitid_t pit_id) {
    // if bit two in the status register of the timer is 1, the timer is running
    switch (pit_id) {
    case IGNITION_DWELL_PIT:
        return (IORD32(A_TIMER_1, NIOS2_TIMER_STATUS) & 0x2) == 0x2;
    case IGNITION_FIRE_PIT:
        return (IORD32(A_TIMER_2, NIOS2_TIMER_STATUS) & 0x2) == 0x2;
    default:
        log_printf(
            "ERROR: invalid pit ID (%d) for hal_timer_pit_active_get\r\n",
            pit_id);
        break;
    }
    return false;
}
示例#2
0
void hal_timer_oc_output_set(channelid_t channel_id, ocmode_t mode) {
    uint32_t modeFlags = IORD32(A_SCCT, SCCT_CH_AS);
    switch (channel_id) {
    case INJECTION1_OUTPUT:
        hal_internal_calculate_mode_flags(2, mode, modeFlags)
        ;
        break;
    case INJECTION2_OUTPUT:
        hal_internal_calculate_mode_flags(3, mode, modeFlags)
        ;
        break;
    case INJECTION3_OUTPUT:
        hal_internal_calculate_mode_flags(4, mode, modeFlags)
        ;
        break;
    case INJECTION4_OUTPUT:
        hal_internal_calculate_mode_flags(5, mode, modeFlags)
        ;
        break;
    case INJECTION5_OUTPUT:
        hal_internal_calculate_mode_flags(6, mode, modeFlags)
        ;
        break;
    case INJECTION6_OUTPUT:
        hal_internal_calculate_mode_flags(7, mode, modeFlags)
        ;
        break;
    default:
        log_printf(
            "ERROR: invalid channel ID (%d) for hal_timer_oc_active_set\r\n",
            channel_id);
        break;
    }
    IOWR32(A_SCCT, SCCT_CH_AS, modeFlags);
}
示例#3
0
uint16_t hal_timer_pit_current_get(pitid_t pit_id) {
    /**
     * The NIOS2 PITs do not have a prescaler. The EMS code assumes all timers to
     * runn at 1.25MHz, so all scaling has to be done in software.
     */
    switch (pit_id) {
    case IGNITION_DWELL_PIT:
        return (IORD32(A_TIMER_1, NIOS2_TIMER_SNAPL) / TIMER_0_PERIOD);
    case IGNITION_FIRE_PIT:
        return (IORD32(A_TIMER_2, NIOS2_TIMER_SNAPL) / TIMER_0_PERIOD);
    default:
        log_printf(
            "ERROR: invalid pit ID (%d) for hal_timer_pit_current_get\r\n",
            pit_id);
        break;
    }
    return -1;
}
示例#4
0
void hal_timer_pit_active_set(pitid_t pit_id, bool active) {
    // set bit two of the control register of the timer to start it, or
    // set bit three to stop it
    uint32_t bitToSet = active ? 0x4 : 0x8;
    switch (pit_id) {
    case IGNITION_DWELL_PIT:
        IOWR32(A_TIMER_1, NIOS2_TIMER_CONTROL,
               ((IORD32(A_TIMER_1, NIOS2_TIMER_CONTROL) & 0x3) | bitToSet));
        break;
    case IGNITION_FIRE_PIT:
        IOWR32(A_TIMER_2, NIOS2_TIMER_CONTROL,
               ((IORD32(A_TIMER_2, NIOS2_TIMER_CONTROL) & 0x3) | bitToSet));
        break;
    default:
        log_printf(
            "ERROR: invalid pit ID (%d) for hal_timer_pit_active_set\r\n",
            pit_id);
        break;
    }
}
示例#5
0
bool hal_timer_oc_active_get(channelid_t channel_id) {
    switch (channel_id) {
    case INJECTION1_OUTPUT:
        return IORD32(A_SCCT, SCCT_CH_IE) & SCCT_CH_BITS_1(2, 1);
        break;
    case INJECTION2_OUTPUT:
        return IORD32(A_SCCT, SCCT_CH_IE) & SCCT_CH_BITS_1(3, 1);
        break;
    case INJECTION3_OUTPUT:
        return IORD32(A_SCCT, SCCT_CH_IE) & SCCT_CH_BITS_1(4, 1);
        break;
    case INJECTION4_OUTPUT:
        return IORD32(A_SCCT, SCCT_CH_IE) & SCCT_CH_BITS_1(5, 1);
        break;
    case INJECTION5_OUTPUT:
        return IORD32(A_SCCT, SCCT_CH_IE) & SCCT_CH_BITS_1(6, 1);
        break;
    case INJECTION6_OUTPUT:
        return IORD32(A_SCCT, SCCT_CH_IE) & SCCT_CH_BITS_1(7, 1);
        break;
    default:
        log_printf(
            "ERROR: invalid channel ID (%d) for hal_timer_oc_active_get\r\n",
            channel_id);
        break;
    }
    return false;
}
示例#6
0
void hal_timer_oc_active_set(channelid_t channel_id, bool active) {
    int32_t interruptEnableFlags = IORD32(A_SCCT, SCCT_CH_IE);
    int32_t newFlags = 0;
    switch (channel_id) {
    case INJECTION1_OUTPUT:
        newFlags =
            active ?
            interruptEnableFlags | SCCT_CH_BITS_1(2, 1) :
            interruptEnableFlags & ~SCCT_CH_BITS_1(2, 1);
        break;
    case INJECTION2_OUTPUT:
        newFlags =
            active ?
            interruptEnableFlags | SCCT_CH_BITS_1(3, 1) :
            interruptEnableFlags & ~SCCT_CH_BITS_1(3, 1);
        break;
    case INJECTION3_OUTPUT:
        newFlags =
            active ?
            interruptEnableFlags | SCCT_CH_BITS_1(4, 1) :
            interruptEnableFlags & ~SCCT_CH_BITS_1(4, 1);
        break;
    case INJECTION4_OUTPUT:
        newFlags =
            active ?
            interruptEnableFlags | SCCT_CH_BITS_1(5, 1) :
            interruptEnableFlags & ~SCCT_CH_BITS_1(5, 1);
        break;
    case INJECTION5_OUTPUT:
        newFlags =
            active ?
            interruptEnableFlags | SCCT_CH_BITS_1(6, 1) :
            interruptEnableFlags & ~SCCT_CH_BITS_1(6, 1);
        break;
    case INJECTION6_OUTPUT:
        newFlags =
            active ?
            interruptEnableFlags | SCCT_CH_BITS_1(7, 1) :
            interruptEnableFlags & ~SCCT_CH_BITS_1(7, 1);
        break;
    default:
        log_printf(
            "ERROR: invalid channel ID (%d) for hal_timer_oc_active_set\r\n",
            channel_id);
        break;
    }
    IOWR32(A_SCCT, SCCT_CH_IE, newFlags);
}
示例#7
0
int32_t uart_puts(char *p) {
  uint32_t ctr = 0;
  if (p == NULL) {
    return -1;
  }
  do {
    // need to wait until UART gets ready to transmit
    if (IORD32(A_UART, UART_ST) & UART_ST_TRDY) {
      IOWR8(A_UART, UART_TX, *p);
      ++p;
      ++ctr;
    }
  } while (*p);
  
  return ctr;
}
/*
 * inits all omap h/w
 */
uint32_t cy_as_hal_processor_hw_init(cy_as_omap_dev_kernel *dev_p)
{
	int i, err;

	cy_as_hal_print_message(KERN_INFO "init OMAP3430 hw...\n");

	iomux_vma = (u32)ioremap_nocache(
				(u32)CTLPADCONF_BASE_ADDR, CTLPADCONF_SIZE);
	cy_as_hal_print_message(KERN_INFO "PADCONF_VMA=%x val=%x\n",
				iomux_vma, IORD32(iomux_vma));

	/*
	 * remap gpio banks
	 */
	for (i = 0; i < 6; i++) {
		gpio_vma_tab[i].virt_addr = (u32)ioremap_nocache(
					gpio_vma_tab[i].phy_addr,
					gpio_vma_tab[i].size);

		cy_as_hal_print_message(KERN_INFO "%s virt_addr=%x\n",
					gpio_vma_tab[i].name,
					(u32)gpio_vma_tab[i].virt_addr);
	};

	/*
	 * force OMAP_GPIO_126  to rleased state,
	 * will be configured to drive reset
	 */
	gpio_free(AST_RESET);

	/*
	 *same thing with AStoria CS pin
	 */
	gpio_free(AST_CS);

	/*
	 * initialize all the OMAP pads connected to astoria
	 */
	cy_as_hal_init_user_pads(user_pad_cfg);

	err = cy_as_hal_gpmc_init(dev_p);
	
	cy_as_hal_config_c_s_mux();

	return err;
}
示例#9
0
pinstate_t hal_timer_oc_pin_get(channelid_t channel_id) {
    switch (channel_id) {
    case INJECTION1_OUTPUT:
        if (IORD32(A_SCCT, SCCT_CH_OUT) & SCCT_CH_BITS_1(2, 1)) {
            return HIGH;
        }
        else {
            return LOW;
        }
    case INJECTION2_OUTPUT:
        if (IORD32(A_SCCT, SCCT_CH_OUT) & SCCT_CH_BITS_1(3, 1)) {
            return HIGH;
        }
        else {
            return LOW;
        }
    case INJECTION3_OUTPUT:
        if (IORD32(A_SCCT, SCCT_CH_OUT) & SCCT_CH_BITS_1(4, 1)) {
            return HIGH;
        }
        else {
            return LOW;
        }
    case INJECTION4_OUTPUT:
        if (IORD32(A_SCCT, SCCT_CH_OUT) & SCCT_CH_BITS_1(5, 1)) {
            return HIGH;
        }
        else {
            return LOW;
        }
    case INJECTION5_OUTPUT:
        if (IORD32(A_SCCT, SCCT_CH_OUT) & SCCT_CH_BITS_1(6, 1)) {
            return HIGH;
        }
        else {
            return LOW;
        }
    case INJECTION6_OUTPUT:
        if (IORD32(A_SCCT, SCCT_CH_OUT) & SCCT_CH_BITS_1(7, 1)) {
            return HIGH;
        }
        else {
            return LOW;
        }
    default:
        log_printf(
            "ERROR: invalid channel ID (%d) for hal_timer_oc_pin_get\r\n",
            channel_id);
        break;
    }
    return LOW;
}
示例#10
0
/**
 * @author Andreas Meixner
 * @brief The one ISR NIOS calls
 * Whenever an interrupt is pending, NIOS2 will call this ISR.
 * This function will check which interrupts are pending and will call the
 * appropriate handler functions of FreeEMS.
 */
void do_irq() {

  uint32_t pending = __rdctl_ipending();

  // if the flag for a pending timer event ist set
  if(pending & 0x40) {
    // see if timer 0 (RTC) is the interrupt source
    uint32_t timerFlag = IORD16(A_TIMER_0, NIOS2_TIMER_STATUS);
    //log_printf("t0F: %X\r\n", timerFlag);
    if((timerFlag & NIOS2_TIMER_STATUS_TO)) {
      // FreeEMS internaly keeps track of time. For this purpose it assumes the
      // hardware has a 16bit clock running at 1.25MHz, which generates a tick
      // interrupt on every tick, and an overflow interrupt everytime the 16bit
      // counter overflows (every 65536 ticks) NIOS2 has a 32 bit counter, so
      // the overflow has to be simulated, by generating the interrupt in the
      // software. check if the high word of the counter value has changed since
      // the last tick, if so call TimerOverfolw()
      uint16_t currentTickHighWord = IORD16(A_TIMER_0, NIOS2_TIMER_SNAPH);
      if(currentTickHighWord != lastTickHighWord) {
        lastTickHighWord = currentTickHighWord;
        TimerOverflow();
      }
      // advance the internal RTC
      RTIISR();

      // clear the flag
      IOWR16(A_TIMER_0, NIOS2_TIMER_STATUS, timerFlag & ~NIOS2_TIMER_STATUS_TO);
    }

    // see if Timer_1 (ignition dwell) is the interrupt source
    timerFlag = IORD16(A_TIMER_1, NIOS2_TIMER_STATUS);
    if((timerFlag & NIOS2_TIMER_STATUS_TO)) {
      IgnitionDwellISR();
      // clear the flag
      IOWR16(A_TIMER_1, NIOS2_TIMER_STATUS, timerFlag & ~(NIOS2_TIMER_STATUS_TO));
    }

    // see if Timer_2 (ignition fire) is the interrupt source
    timerFlag = IORD16(A_TIMER_2, NIOS2_TIMER_STATUS);
    if((timerFlag & NIOS2_TIMER_STATUS_TO)) {
      IgnitionFireISR();
      IOWR16(A_TIMER_2, NIOS2_TIMER_STATUS, timerFlag & ~(NIOS2_TIMER_STATUS_TO));
    }
  }
  // if the flag for a pending SCCT timer event is set
  if(pending & 0x400) {
    // external interrupt (SCCT)
    // see if the oc channel 0 (scct) was the interrupt source
    uint32_t isFlags = IORD32(A_SCCT, SCCT_CH_IS);
    // if IC channel 0 has a pending interrupt, call PrimaryRPMISR
    if(isFlags & SCCT_CH_BITS_1(0,1)) {
      // clear interrupt flags
      IOWR32(A_SCCT, SCCT_CH_IS, SCCT_CH_BITS_1(0,1));
      PrimaryRPMISR();
    }
    // if IC channel 1 has a pending interrupt, call SecondaryRPMISR
    if(isFlags & SCCT_CH_BITS_1(1,1)) {
      // clear interrupt flags
      IOWR32(A_SCCT, SCCT_CH_IS, SCCT_CH_BITS_1(1,1));
      SecondaryRPMISR();
    }
    // if OC channel 2 has a pending interrupt, call Injector1ISR
    if(isFlags & SCCT_CH_BITS_1(2,1)) {
      // clear interrupt flags
      IOWR32(A_SCCT, SCCT_CH_IS, SCCT_CH_BITS_1(2,1));
      Injector1ISR();
    }
    // if OC channel 3 has a pending interrupt, call Injector2ISR
    if(isFlags & SCCT_CH_BITS_1(3,1)) {
      // clear interrupt flags
      IOWR32(A_SCCT, SCCT_CH_IS, SCCT_CH_BITS_1(3,1));
      Injector2ISR();
    }
    // if OC channel 4 has a pending interrupt, call Injector3ISR
    if(isFlags & SCCT_CH_BITS_1(4,1)) {
      // clear interrupt flags
      IOWR32(A_SCCT, SCCT_CH_IS, SCCT_CH_BITS_1(4,1));
      Injector3ISR();
    }
    // if OC channel 5 has a pending interrupt, call Injector4ISR
    if(isFlags & SCCT_CH_BITS_1(5,1)) {
      // clear interrupt flags
      IOWR32(A_SCCT, SCCT_CH_IS, SCCT_CH_BITS_1(5,1));
      Injector4ISR();
    }
    // if OC channel 6 has a pending interrupt, call Injector5ISR
    if(isFlags & SCCT_CH_BITS_1(6,1)) {
      // clear interrupt flags
      IOWR32(A_SCCT, SCCT_CH_IS, SCCT_CH_BITS_1(6,1));
      Injector5ISR();
    }
    // if OC channel 7 has a pending interrupt, call Injector6ISR
    if(isFlags & SCCT_CH_BITS_1(7,1)) {
      // clear interrupt flags
      IOWR32(A_SCCT, SCCT_CH_IS, SCCT_CH_BITS_1(7,1));
      Injector6ISR();
    }
  }
}
示例#11
0
文件: timer.c 项目: unia-sik/emsbench
uint32_t timer_getsnap(void) {
  IOWR16(A_TIMER, NIOS2_TIMER_SNAPL, 1);
  return IORD32(A_TIMER, NIOS2_TIMER_SNAPL);
}
示例#12
0
int32_t uart_read_byte(void){
  char b = -1;
  while ( !(IORD32(A_UART, UART_ST) & UART_ST_RRDY) );
  b = IORD8(A_UART, UART_RX);
  return (int32_t)b;
}
示例#13
0
void uart_write_byte(char b){
  while ( !(IORD32(A_UART, UART_ST) & UART_ST_TRDY) );
  IOWR8(A_UART, UART_TX, b);
}
示例#14
0
int32_t uart_putchar(int32_t c) {
  char vc = (char) (c & 0xff);
  while ( !(IORD32(A_UART, UART_ST) & UART_ST_TRDY) );
  IOWR8(A_UART, UART_TX, vc);
  return (int32_t) vc;
}
示例#15
0
pinstate_t hal_io_get(channelid_t channel_id) {
    pinstate_t retVal = LOW;
    switch (channel_id) {
    case IGNITION1_OUTPUT:
        retVal = (IORD32(A_PIO_IGN, 0) & 0x1) ? HIGH : LOW;
        break;
    case IGNITION2_OUTPUT:
        retVal = (IORD32(A_PIO_IGN, 0) & 0x2) ? HIGH : LOW;
        break;
    case IGNITION3_OUTPUT:
        retVal = (IORD32(A_PIO_IGN, 0) & 0x4) ? HIGH : LOW;
        break;
    case IGNITION4_OUTPUT:
        retVal = (IORD32(A_PIO_IGN, 0) & 0x8) ? HIGH : LOW;
        break;
    case IGNITION5_OUTPUT:
        retVal = (IORD32(A_PIO_IGN, 0) & 0x10) ? HIGH : LOW;
        break;
    case IGNITION6_OUTPUT:
        retVal = (IORD32(A_PIO_IGN, 0) & 0x20) ? HIGH : LOW;
        break;
    case IGNITION7_OUTPUT:
        retVal = (IORD32(A_PIO_IGN, 0) & 0x40) ? HIGH : LOW;
        break;
    case IGNITION8_OUTPUT:
        retVal = (IORD32(A_PIO_IGN, 0) & 0x80) ? HIGH : LOW;
        break;
    case DEBUG_OUTPUT_1:
        retVal = (IORD32(A_PIO_IGN, 0) & 0x100) ? HIGH : LOW;
        break;
    case DEBUG_OUTPUT_2:
        retVal = (IORD32(A_PIO_IGN, 0) & 0x200) ? HIGH : LOW;
        break;
    case DEBUG_OUTPUT_3:
        retVal = (IORD32(A_PIO_IGN, 0) & 0x400) ? HIGH : LOW;
        break;
    case DEBUG_OUTPUT_4:
        retVal = (IORD32(A_PIO_IGN, 0) & 0x800) ? HIGH : LOW;
        break;
    case DEBUG_OUTPUT_5:
        retVal = (IORD32(A_PIO_IGN, 0) & 0x1000) ? HIGH : LOW;
        break;
    case DEBUG_OUTPUT_6:
        retVal = (IORD32(A_PIO_IGN, 0) & 0x2000) ? HIGH : LOW;
        break;
    case DEBUG_OUTPUT_7:
        retVal = (IORD32(A_PIO_IGN, 0) & 0x4000) ? HIGH : LOW;
        break;
    case DEBUG_OUTPUT_8:
        retVal = (IORD32(A_PIO_IGN, 0) & 0x8000) ? HIGH : LOW;
        break;
    default:
        log_printf("ERROR: invalid channel ID (%d) for hal_io_get\r\n",
                   channel_id);
        break;
    }
    return false;
}
示例#16
0
void hal_io_set(channelid_t channel_id, pinstate_t value) {

    uint32_t registerValue = IORD32(A_PIO_IGN, 0);
    switch (channel_id) {
    case IGNITION1_OUTPUT:
        if (value == HIGH) {
            registerValue = registerValue | 0x1;
        }
        else {
            registerValue = registerValue & (~0x1);
        }
        break;
    case IGNITION2_OUTPUT:
        if (value == HIGH) {
            registerValue = registerValue | 0x2;
        }
        else {
            registerValue = registerValue & (~0x2);
        }
        break;
    case IGNITION3_OUTPUT:
        if (value == HIGH) {
            registerValue = registerValue | 0x4;
        }
        else {
            registerValue = registerValue & (~0x4);
        }
        break;
    case IGNITION4_OUTPUT:
        if (value == HIGH) {
            registerValue = registerValue | 0x8;
        }
        else {
            registerValue = registerValue & (~0x8);
        }
        break;
    case IGNITION5_OUTPUT:
        if (value == HIGH) {
            registerValue = registerValue | 0x10;
        }
        else {
            registerValue = registerValue & (~0x10);
        }
        break;
    case IGNITION6_OUTPUT:
        if (value == HIGH) {
            registerValue = registerValue | 0x20;
        }
        else {
            registerValue = registerValue & (~0x20);
        }
        break;
    case IGNITION7_OUTPUT:
        if (value == HIGH) {
            registerValue = registerValue | 0x40;
        }
        else {
            registerValue = registerValue & (~0x40);
        }
        break;
    case IGNITION8_OUTPUT:
        if (value == HIGH) {
            registerValue = registerValue | 0x80;
        }
        else {
            registerValue = registerValue & (~0x80);
        }
        break;

    case DEBUG_OUTPUT_1:
        if (value == HIGH) {
            registerValue = registerValue | 0x100;
        }
        else {
            registerValue = registerValue & (~0x100);
        }
        break;
    case DEBUG_OUTPUT_2:
        if (value == HIGH) {
            registerValue = registerValue | 0x200;
        }
        else {
            registerValue = registerValue & (~0x200);
        }
        break;
    case DEBUG_OUTPUT_3:
        if (value == HIGH) {
            registerValue = registerValue | 0x400;
        }
        else {
            registerValue = registerValue & (~0x400);
        }
        break;
    case DEBUG_OUTPUT_4:
        if (value == HIGH) {
            registerValue = registerValue | 0x800;
        }
        else {
            registerValue = registerValue & (~0x800);
        }
        break;
    case DEBUG_OUTPUT_5:
        if (value == HIGH) {
            registerValue = registerValue | 0x1000;
        }
        else {
            registerValue = registerValue & (~0x1000);
        }
        break;
    case DEBUG_OUTPUT_6:
        if (value == HIGH) {
            registerValue = registerValue | 0x2000;
        }
        else {
            registerValue = registerValue & (~0x2000);
        }
        break;
    case DEBUG_OUTPUT_7:
        if (value == HIGH) {
            registerValue = registerValue | 0x4000;
        }
        else {
            registerValue = registerValue & (~0x4000);
        }
        break;
    case DEBUG_OUTPUT_8:
        if (value == HIGH) {
            registerValue = registerValue | 0x8000;
        }
        else {
            registerValue = registerValue & (~0x8000);
        }
        break;
    default:
        log_printf("ERROR: invalid channel ID (%d) for hal_io_set\r\n",
                   channel_id);
        break;
    }
}
uint32_t cy_as_hal_gpmc_init(cy_as_omap_dev_kernel *dev_p)
{
	u32 tmp32;
	int err;
	struct gpmc_timings	timings;
	unsigned int cs_mem_base;
	unsigned int cs_vma_base;
	
	/*
	 * get GPMC i/o registers base(already been i/o mapped
	 * in kernel, no need for separate i/o remap)
	 */
	cy_as_hal_print_message(KERN_INFO "%s: mapping phys_to_virt\n", __func__);
					
	gpmc_base = (u32)ioremap_nocache(OMAP34XX_GPMC_BASE, SZ_16K);
	cy_as_hal_print_message(KERN_INFO "kernel has gpmc_base=%x , val@ the base=%x",
		gpmc_base, __raw_readl(gpmc_base)
	);
	
	cy_as_hal_print_message(KERN_INFO "%s: calling gpmc_cs_request\n", __func__);
	/*
	 * request GPMC CS for ASTORIA request
	 */
	if (gpmc_cs_request(AST_GPMC_CS, SZ_16M, (void *)&cs_mem_base) < 0) {
		cy_as_hal_print_message(KERN_ERR "error failed to request"
					"ncs4 for ASTORIA\n");
			return -1;
	} else {
		cy_as_hal_print_message(KERN_INFO "got phy_addr:%x for "
				"GPMC CS%d GPMC_CFGREG7[CS4]\n",
				 cs_mem_base, AST_GPMC_CS);
	}
	
	cy_as_hal_print_message(KERN_INFO "%s: calling request_mem_region\n", __func__);
	/*
	 * request VM region for 4K addr space for chip select 4 phy address
	 * technically we don't need it for NAND devices, but do it anyway
	 * so that data read/write bus cycle can be triggered by reading
	 * or writing this mem region
	 */
	if (!request_mem_region(cs_mem_base, SZ_16K, "AST_OMAP_HAL")) {
		err = -EBUSY;
		cy_as_hal_print_message(KERN_ERR "error MEM region "
					"request for phy_addr:%x failed\n",
					cs_mem_base);
			goto out_free_cs;
	}
	
	cy_as_hal_print_message(KERN_INFO "%s: calling ioremap_nocache\n", __func__);
	
	/* REMAP mem region associated with our CS */
	cs_vma_base = (u32)ioremap_nocache(cs_mem_base, SZ_16K);
	if (!cs_vma_base) {
		err = -ENOMEM;
		cy_as_hal_print_message(KERN_ERR "error- ioremap()"
					"for phy_addr:%x failed", cs_mem_base);

		goto out_release_mem_region;
	}
	cy_as_hal_print_message(KERN_INFO "ioremap(%x) returned vma=%x\n",
							cs_mem_base, cs_vma_base);

	dev_p->m_phy_addr_base = (void *) cs_mem_base;
	dev_p->m_vma_addr_base = (void *) cs_vma_base;

	memset(&timings, 0, sizeof(timings));

	/* cs timing */
	timings.cs_on = WB_GPMC_CS_t_on;
	timings.cs_wr_off = WB_GPMC_BUSCYC_t;
	timings.cs_rd_off = WB_GPMC_BUSCYC_t;

	/* adv timing */
	timings.adv_on = WB_GPMC_ADV_t_on;
	timings.adv_rd_off = WB_GPMC_ADV_t_off;
	timings.adv_wr_off = WB_GPMC_ADV_t_off;

	/* oe timing */
	timings.oe_on = WB_GPMC_OE_t_on;
	timings.oe_off = WB_GPMC_OE_t_off;
	timings.access = WB_GPMC_RD_t_a_c_c;
	timings.rd_cycle = WB_GPMC_BUSCYC_t;

	/* we timing */
	timings.we_on = WB_GPMC_WE_t_on;
	timings.we_off = WB_GPMC_WE_t_off;
	timings.wr_access = WB_GPMC_WR_t_a_c_c;
	timings.wr_cycle = WB_GPMC_BUSCYC_t;

	timings.page_burst_access = WB_GPMC_BUSCYC_t;
	timings.wr_data_mux_bus = WB_GPMC_BUSCYC_t;
	gpmc_cs_set_timings(AST_GPMC_CS, &timings);

	/*
	 * by default configure GPMC into 8 bit mode
	 * (to match astoria default mode)
	 */
	gpmc_cs_write_reg(AST_GPMC_CS, GPMC_CS_CONFIG1,
					(GPMC_CONFIG1_DEVICETYPE(0) |
					 GPMC_CONFIG1_DEVICESIZE_16
					| 0x10 //twhs
					));

	/*
	 * No method currently exists to write this register through GPMC APIs
	 * need to change WAIT2 polarity
	 */
	tmp32 = IORD32(GPMC_VMA(GPMC_CONFIG_REG));
	tmp32 = tmp32 | NAND_FORCE_POSTED_WRITE_B | 0x40;
	IOWR32(GPMC_VMA(GPMC_CONFIG_REG), tmp32);

	tmp32 = IORD32(GPMC_VMA(GPMC_CONFIG_REG));
	cy_as_hal_print_message("GPMC_CONFIG_REG=0x%x\n", tmp32);

	cy_as_hal_print_omap_regs("GPMC_CONFIG", 1,
			GPMC_VMA(GPMC_CFG_REG(1, AST_GPMC_CS)), 7);

	return 0;

out_release_mem_region:
	release_mem_region(cs_mem_base, SZ_16K);

out_free_cs:
	gpmc_cs_free(AST_GPMC_CS);

	return err;
}