Beispiel #1
0
/***********************************************************************
 *
 * Function: c_entry
 *
 * Purpose: Application entry point from the startup code
 *
 * Processing:
 *     See function.
 *
 * Parameters: None
 *
 * Outputs: None
 *
 * Returns: Nothing
 *
 * Notes: None
 *
 **********************************************************************/
void c_entry(void) {
	UNS_8 *p8;
	INT_32 toread, idx;
	PFV execa = (PFV) STAGE1_LOAD_ADDR;

  /* Force SSP configuration, use GPIO_05 (SSP0_CS) in software
     control mode */
  GPIO->p2_dir_set = P2_DIR_GPIO(5);
  GPIO->p2_mux_clr = P2_GPIO05_SSEL0;
  GPIO->p_mux_set = P_SPI1CLK_SCK0 | P_SPI1DATAIN_SSP0_MISO |
	  P_SPI1DATAIO_SSP0_MOSI;

	board_spi_config();

	/* Read data into memory */
	toread = STAGE1_LOAD_SIZE;
	p8 = (UNS_8 *) STAGE1_LOAD_ADDR;
	idx = SPI_S1APP_OFFSET;

	while (toread > 0)
	{
		*p8 = board_spi_read(idx);
		p8++;
		idx++;
		toread--;
	}

#ifdef USE_MMU
	dcache_flush();
	dcache_inval();
	icache_inval();
#endif

	execa();
}
Beispiel #2
0
void dcache_disable(void)
{
    dcache_flush();
#ifndef CONFIG_SYS_NO_DCACHE
    cp15_dcache_disable();
#endif
#ifdef CONFIG_CACHE_L2X0
    l2x0_disable();
#endif
}
Beispiel #3
0
//==============================================================
unsigned test_w_l1cache(unsigned fill_value, unsigned modify_value)
{
	unsigned *addr;
	unsigned size, err_addr, val;
	int i;

	// current dcache is disable
	// clear no-cache memory block
	addr = (unsigned*)no_cache_mem_start;
	size = (cache_size)/sizeof(unsigned);
	for(i=0; i<size; i++, addr++)
		*addr = fill_value;
	
//	asm("dmb");
//	asm("isb");
	
	// map cache-memory data to cache
	addr = (unsigned*)cache_mem_start;
	size = cache_size/CONFIG_SYS_CACHE_LINE_SIZE;	
	dcache_enable();		
//	asm("dmb");
//	asm("isb");
	for(i=0; i<size; i++, addr+=CONFIG_SYS_CACHE_LINE_SIZE)
		val = *addr;
		
	// write to cache
	addr = (unsigned*)cache_mem_start;	
	size = cache_size/sizeof(unsigned);			
	for(i=0; i<size; i++, addr++){
		*addr = modify_value;			
	}		
	
	dcache_flush();
	dcache_clean();
	dcache_disable();
	dcache_invalid();
	
	asm("mov r0, r0");
	asm("mov r0, r0");
	asm("mov r0, r0");
		
	err_addr = 0;
	addr = (unsigned*)no_cache_mem_start;	
	for(i=0; i<size; i++, addr++){
		if(*addr != modify_value){							
			err_addr = (unsigned)addr;			
			break;
		}
	}	
	return err_addr;	
	
}
/***********************************************************************
 *
 * Function: c_entry
 *
 * Purpose: Application entry point from the startup code
 *
 * Processing:
 *     See function.
 *
 * Parameters: None
 *
 * Outputs: None
 *
 * Returns: Nothing
 *
 * Notes: None
 *
 **********************************************************************/
void c_entry(void) {
	UNS_8 *p8, ret;
	INT_32 toread, idx, blk, page, sector;
	PFV execa = (PFV) STAGE1_LOAD_ADDR;

	/* Initialize NAND FLASH */
	if (nand_sb_slc_init() != 1) 
	{
		while (1);
	}

	/* Read data into memory */
	toread = STAGE1_LOAD_SIZE;
	blk = 1;
	page = 0;
	p8 = (UNS_8 *) STAGE1_LOAD_ADDR;
	while (toread > 0) 
	{
		ret = nand_sb_slc_is_block_bad(blk);
		if (ret == 0)
		{
			while(page < nandgeom.pages_per_block)
			{
				sector = nand_bp_to_sector(blk, page);
				nand_sb_slc_read_sector(sector, tmpbuff,NULL);
				for (idx = 0; idx < 512; idx++) 
				{
					*p8 = tmpbuff [idx];
					p8++;
				}
				page++;
				toread = toread - 512;
			}
			blk++;
			page = 0;
		}
		else
		{
			blk++;	
		}
	}

#ifdef USE_MMU
	dcache_flush();
	dcache_inval();
	icache_inval();
#endif

	execa();
}
Beispiel #5
0
//==============================================================
int l1cache_post_test(int flags)
{
	int i;
	unsigned result, pattern=0;
	int status;
	
	status = dcache_status();
	if(dcache_status() == OFF)
		dcache_enable();	
	dcache_flush();	
	icache_invalid();		
	dcache_clean();
	dcache_disable();
	 // must invalid dcache after dcache_disable	
	 // if no valid dcache, dcache_enable() will jump here
	dcache_invalid();  
	asm("mov r0, r0");
	asm("mov r0, r0");
	asm("mov r0, r0");
	
	for(i=0; i<ARRAY_SIZE(L1_cache_pattern); i++){			
		result = test_w_l1cache(0x55555555, L1_cache_pattern[i]);			
		if(result != 0){						
			pattern = L1_cache_pattern[i];
			break;
		}		
		result = test_w_l1cache(0x55555555, ~L1_cache_pattern[i]);				
		if(result != 0){		
			pattern = ~L1_cache_pattern[i];
			break;
		}			
	}
	
	if(status == ON)
		dcache_enable();
		
	if(i<ARRAY_SIZE(L1_cache_pattern)){
		post_log("<%d>%s:%d: l1cache: test fail: Error address=0x%x, pattern=0x%x\n", SYSTEST_INFO_L2,
									__FUNCTION__, __LINE__, result, pattern);
		return -1;
	}
	else{		
		post_log("<%d>l1cache test pattern count=%d\n", SYSTEST_INFO_L2, ARRAY_SIZE(L1_cache_pattern));
		return 0;	
	}	
	
}
Beispiel #6
0
void  flush_cache (unsigned long dummy1, unsigned long dummy2)
{
 	dcache_flush();
	return;
}
Beispiel #7
0
/*
 * Sends a command out on the bus. Takes the mmc pointer,
 * a command pointer, and an optional data pointer.
 */
int aml_sd_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct	mmc_data *data)
{
	int ret = SD_NO_ERROR, num_res;
	unsigned buffer = 0;
	unsigned int cmd_send = 0;
	SDHW_CMD_Send_Reg_t *cmd_send_reg = (void *)&cmd_send;
    sd_debug("cmd=%d",cmd->cmdidx);
    cmd_send_reg->cmd_data = 0x40 | cmd->cmdidx;
	cmd_send_reg->use_int_window = 1;
	
	unsigned int cmd_ext = 0;
	SDHW_Extension_Reg_t *cmd_ext_reg = (void *)&cmd_ext;

	/* check read/write address overflow */
	switch (cmd->cmdidx) {
	case MMC_CMD_READ_SINGLE_BLOCK:
    case MMC_CMD_READ_MULTIPLE_BLOCK:
	case MMC_CMD_WRITE_SINGLE_BLOCK:
	case MMC_CMD_WRITE_MULTIPLE_BLOCK:
		if(mmc->high_capacity)
			ret = mmc->capacity/mmc->read_bl_len <= cmd->cmdarg;
		else
			ret = mmc->capacity <= cmd->cmdarg;
		if(ret)
			return -1;
		else
			break;
	}
	
	sd_inand_clear_response(cmd->response);
	switch (cmd->resp_type) {
	case MMC_RSP_R1:
	case MMC_RSP_R1b:
	case MMC_RSP_R3:
	case MMC_RSP_R6:
	case MMC_RSP_R7:
		cmd_send_reg->cmd_res_bits = 45;		// RESPONSE	have 7(cmd)+32(respnse)+7(crc)-1 data
		break;
	case MMC_RSP_R2:
		cmd_send_reg->cmd_res_bits = 133;		// RESPONSE	have 7(cmd)+120(respnse)+7(crc)-1 data
		cmd_send_reg->res_crc7_from_8 = 1;
		break;
	default:
		cmd_send_reg->cmd_res_bits = 0;			// NO_RESPONSE
		break;
	}

	switch (cmd->cmdidx) {
	case MMC_CMD_READ_SINGLE_BLOCK:
	case MMC_CMD_READ_MULTIPLE_BLOCK:
	case MMC_CMD_SEND_EXT_CSD:					//same as: SD_CMD_SEND_IF_COND
	case SD_CMD_SWITCH_FUNC:					//same as: MMC_CMD_SWITCH
		if(!data)
			break;
//        dcache_flush();
        
		cmd_send_reg->res_with_data = 1;
		cmd_send_reg->repeat_package_times = data->blocks - 1;
		if(mmc->bus_width == SD_BUS_WIDE)
			cmd_ext_reg->data_rw_number = data->blocksize * 8 + (16 - 1) * 4;
		else
			cmd_ext_reg->data_rw_number = data->blocksize * 8 + 16 - 1;		
		buffer = dma_map_single((void*)data->dest,data->blocks*data->blocksize,DMA_FROM_DEVICE);
		//buffer = data->dest;
		//dcache_invalid_range(buffer,data->blocks<<9);
		break;
	case MMC_CMD_WRITE_SINGLE_BLOCK:
	case MMC_CMD_WRITE_MULTIPLE_BLOCK:
	    
		cmd_send_reg->cmd_send_data = 1;
		cmd_send_reg->repeat_package_times = data->blocks - 1;
		if(mmc->bus_width == SD_BUS_WIDE)
			cmd_ext_reg->data_rw_number = data->blocksize * 8 + (16 - 1) * 4;
		else
			cmd_ext_reg->data_rw_number = data->blocksize * 8 + 16 - 1;
		buffer = dma_map_single((void*)data->src,data->blocks*data->blocksize,DMA_TO_DEVICE);//(char *)data->src;
//        dcache_clean_range(buffer,data->blocks<<9);
//        dcache_flush();
		break;
	case SD_CMD_APP_SEND_SCR:
		cmd_send_reg->res_with_data = 1;
		if(mmc->bus_width == SD_BUS_WIDE)
			cmd_ext_reg->data_rw_number = data->blocksize * 8 + (16 - 1) * 4;
		else
			cmd_ext_reg->data_rw_number = data->blocksize * 8 + 16 - 1;
		//buffer = (char *)data->src;
		//dcache_flush();
		buffer = dma_map_single(data->dest,cmd_ext_reg->data_rw_number,DMA_BIDIRECTIONAL);//(char *)data->src;
		break;
	default:
		break;
	}
	
	//cmd with R1b
	switch (cmd->cmdidx) {
	case MMC_CMD_STOP_TRANSMISSION:
		cmd_send_reg->check_dat0_busy =	1;
		break;
	default:
		break;
	}

	//cmd with R3
	switch (cmd->cmdidx) {
	case MMC_CMD_SEND_OP_COND:
	case SD_CMD_APP_SEND_OP_COND:
		cmd_send_reg->res_without_crc7 = 1;
		break;
	default:
		break;
	}

	#define	SD_READ_BUSY_COUNT		5000000//20
	#define	SD_WRITE_BUSY_COUNT		1000000//500000
	#define	SD_RETRY_COUNT			8
	unsigned int timeout, timeout_count, repeat_time = 0;
	
	if(cmd_send_reg->cmd_send_data){
		if(cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK)
			timeout = SD_WRITE_BUSY_COUNT *	(data->blocks);
		else
			timeout = SD_WRITE_BUSY_COUNT;
	} else {
		if(cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK)
			timeout = SD_READ_BUSY_COUNT * (data->blocks);
		else
			timeout = SD_READ_BUSY_COUNT;
	}
	
	if(cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
		timeout = 2000;

	unsigned int status_irq = 0;
	SDIO_Status_IRQ_Reg_t *status_irq_reg = (void *)&status_irq;
	unsigned int irq_config = 0;
	MSHW_IRQ_Config_Reg_t *irq_config_reg = (void *)&irq_config;   
	
CMD_RETRY:
	status_irq_reg->if_int = 1;
	status_irq_reg->cmd_int = 1;
	sd_debug("PREG_SDIO_STAT_IRQ=%x PREG_SDIO_MEM_ADDR=%x PREG_SDIO_CMD_SEND=%x",status_irq,buffer,cmd_send);
	sd_debug("PREG_SDIO_CMD_ARG =%x      PREG_SDIO_EXT=%x",cmd->cmdarg,cmd_ext);
	
	writel(status_irq|(0x1fff<<19), PREG_SDIO_STAT_IRQ);
	   
 
	writel(cmd->cmdarg, PREG_SDIO_CMD_ARG);
	writel(cmd_ext, PREG_SDIO_EXT);
	writel((unsigned int)buffer, PREG_SDIO_MEM_ADDR);
	writel(cmd_send, PREG_SDIO_CMD_SEND);
    
	timeout_count = 0;
	while (1) {
		status_irq = readl(PREG_SDIO_STAT_IRQ);
		if(!status_irq_reg->cmd_busy && status_irq_reg->cmd_int)
			break;

		if((++timeout_count) > timeout) {
			if(!cmd->flags)
				return TIMEOUT;
				
			irq_config_reg->soft_reset = 1;
			writel(irq_config, PREG_SDIO_IRQ_CFG);
				
			if((++repeat_time) > SD_RETRY_COUNT)
				return TIMEOUT;
			goto CMD_RETRY;
		}

		if(cmd_send_reg->cmd_send_data)
			udelay(100);
		if(cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
			udelay(1000);
	}
	
	if(cmd_send_reg->cmd_res_bits && !cmd_send_reg->res_without_crc7 && !status_irq_reg->res_crc7_ok)
		return SD_ERROR_COM_CRC;

	switch (cmd->resp_type) {
	case MMC_RSP_R1:
	case MMC_RSP_R1b:
	case MMC_RSP_R3:
	case MMC_RSP_R6:
	case MMC_RSP_R7:
		num_res = RESPONSE_R1_R3_R6_R7_LENGTH;
		break;
	case MMC_RSP_R2:
		num_res = RESPONSE_R2_CID_CSD_LENGTH;
		break;
	default:
		num_res = RESPONSE_R4_R5_NONE_LENGTH;
		break;
	 }
	 
/*	switch (cmd->cmdidx) {
	case MMC_CMD_READ_SINGLE_BLOCK:
	case MMC_CMD_READ_MULTIPLE_BLOCK:
	case MMC_CMD_SEND_EXT_CSD:					//same as: SD_CMD_SEND_IF_COND
	case SD_CMD_SWITCH_FUNC:					//same as: MMC_CMD_SWITCH
	case SD_CMD_APP_SEND_SCR:
		if(!data)
			break;
        dma_unmap_single((void*)data->dest,data->blocks*data->blocksize,buffer);
		break;
	case MMC_CMD_WRITE_SINGLE_BLOCK:
	case MMC_CMD_WRITE_MULTIPLE_BLOCK:
	    dma_unmap_single((void*)data->src,data->blocks*data->blocksize,buffer);
		break;
	default:
		break;
	}*/
    dcache_flush();
	if (num_res > 0) {
		unsigned int multi_config = 0;
		SDIO_Multi_Config_Reg_t *multi_config_reg = (void *)&multi_config;
		multi_config_reg->write_read_out_index = 1;
		writel(multi_config, PREG_SDIO_MULT_CFG);
		num_res--;							// Minus CRC byte
	}
	unsigned int data_temp;
	unsigned int loop_num = (num_res + 3 - 1) /4;
	while (num_res > 0) {
		data_temp = readl(PREG_SDIO_CMD_ARG);
		if(num_res <= 1)
			break;
		cmd->response[--num_res - 1] = data_temp & 0xFF;
		if(num_res <= 1)
			break;
		cmd->response[--num_res - 1] = (data_temp >> 8) & 0xFF;
		if(num_res <= 1)
			break;
		cmd->response[--num_res - 1] = (data_temp >> 16) & 0xFF;
		if(num_res <= 1)
			break;
		cmd->response[--num_res - 1] = (data_temp >> 24) & 0xFF;
	}
	while (loop_num--) {
		((uint *)cmd->response)[loop_num] = __be32_to_cpu(((uint *)cmd->response)[loop_num]);
	}
	
	//check_response
	ret = sd_inand_check_response(cmd);
	if(ret)
		return ret;

	//cmd with adtc
	switch (cmd->cmdidx) {
	case MMC_CMD_READ_SINGLE_BLOCK:
	case MMC_CMD_READ_MULTIPLE_BLOCK:
	case MMC_CMD_SEND_EXT_CSD:							//same as SD_CMD_SEND_IF_COND
	case SD_CMD_SWITCH_FUNC:							//same as: MMC_CMD_SWITCH
		if(!data)
			break;
		if(!status_irq_reg->data_read_crc16_ok)
			return SD_ERROR_DATA_CRC;
		break;
	case MMC_CMD_WRITE_SINGLE_BLOCK:
	case MMC_CMD_WRITE_MULTIPLE_BLOCK:
		if(!status_irq_reg->data_write_crc16_ok)
			return SD_ERROR_DATA_CRC;
		break;
	case SD_CMD_APP_SEND_SCR:
		if(!status_irq_reg->data_read_crc16_ok)
			return SD_ERROR_DATA_CRC;
		break;
	default:
		break;
	}

	
	return SD_NO_ERROR;
}