📄 sdregb.c
字号:
/*********************************************************************/
/* Solomon Systech Limited */
/*********************************************************************/
// Program Name: sdreg.c
// Description: Define routines to test Amazon SDHC
// Author: Sreedharan Bhaskaran
/*********************************************************************/
/*********************************************************************/
/* Change Log */
/*********************************************************************/
// 14 Jun 2004: Sreedharan, Wrote it
// 5 Jul 2004: Sreedharan,
// 1. To Test SDHC R105
// 10 Jul 2004: Sreedharan
// 1. To Test SDHC R20 (read/write tests not proven)
// 29 Oct 2004
// - modified sdhc_erase() to wait for INTR_DAT_COMPLETE
// 1 Nov 2004
// - modified sdhc_erase() to remove redundant check for INTR_DAT_COMPLETE
// because send_cmd with R48b will check for INTR_DAT_COMPLETE
// - added batchmode & scriptmode support
// - added SW_RESET_DATA and SW_RESET_CMD in read_cli() and write_cli()
// to allow batch and script mode tests to continue
/*********************************************************************/
#ifndef __KERNEL__
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#else
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/tqueue.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#endif
#define MMC_DEF_RCA 0x0001
#define CARDTYPE_SDMEM 1
#define CARDTYPE_SDIO 2
#define CARDTYPE_MMC 4
#define SD_PANASONIC 1
#define SD_TWINMOS 2
#define CARD_TYPE SD_TWINMOS
#define __SDHC_CARD_STATE__ // to instantiate card state
#define __REGINFO__ // to instantiate reginfo
#define __SDREG_C__
#include "endian.h"
#include "sdhcbase.h"
#include "sdhcmap.h"
#include "sdhcide.h"
#include "reginfo.h"
#include "amazon.h"
#include "db.h"
#include "ssd192X.h"
#ifdef __DEMO1923__
#include "ssd192X_io.h"
#endif
#ifdef __KERNEL__
#include "ssd192X.h" // for SDHC_MODULE_BASE definition
#endif
#define CEIL(x,y) {if ((x) > (y)) x = (y);}
#define SDHC_BASE_CLK 16 // units are in MHz
#if (CPU == MC68VZ328)
#define MAX_WAIT 1000
#else
#define MAX_WAIT 20000
#endif
#define MAX_PWR_UP 10
#define SDCLK_DIV_INIT (1 << 6) // at 33Mhz, this will generate
#define SDCLK_DIV_OPER 0
#define SDHC_OCR 0x00FC01C0 // 0000 0000 1111 1100 0000 0001 1100 0000
#define SDHC_OCR_33VRNG 0x00FC0000 // 3.6V - 3.0V
#define SDHC_OCR_33V 0x00200000 // 3.3V - 3.4V
#define SDHC_OCR_3V 0x00040000 // 3.0V - 3.1V
#define SDHC_OCR_3VRNG 0x001F8000 // 3.3V - 2.7V
#define MEM_PART 0
#define IO_PART 1
#define EXIT_ON_FAILURE 0
#define DO_CARD_RESET_TEST 1
#define DO_CARD_REG_TEST 1
#define DO_CARD_DETECT_TEST 1
#define DO_BUS_PWR 0
#define DO_CMD_TEST 1 // this will skip all card access tests
#define DO_READ_SCR 1
#define DO_SEND_ALL_CID 1
#define DO_SEND_RCA 1
#define DO_SEND_CID 1
#define DO_SEND_CSD 1
#define DO_CHANGE_RW_CLK 1
#define IGNORE_UPPER_SYSADDR 0 // sdhc_r303b requires this to be 1
#define MULTIPLE_BUFFER 1
#define PARANOID 0
// formula to calculate boundary => (2**HST_BNDRY x 4)KB
// eg.
// HST_BNDRY_32KB = 3, so boundary = 2**3 x 4KB = 32KB
#define HST_BNDRY_4KB 0 // 3'b000 (Host DMA Boundary) 0x01000
#define HST_BNDRY_8KB 1 // 3'b001 0x02000
#define HST_BNDRY_16KB 2 // 3'b010 0x04000
#define HST_BNDRY_32KB 3 // 3'b011 0x08000
#define HST_BNDRY_64KB 4 // 3'b100 0x10000
#define HST_BNDRY_128KB 5 // 3'b101 0x20000
#define HST_BNDRY_256KB 6 // 3'b110 0x40000
#define HST_BNDRY_512KB 7 // 3'b111 0x80000
#define HST_BNDRY_MASK 0x7000
// HST_BNDRY1 must always be 2*HST_BNDRY0
#define HST_BNDRY0 HST_BNDRY_4KB
#define HST_BNDRY1 HST_BNDRY_8KB
#define BNDRY0 HST_BNDRY_32KB
#define BNDRY1 HST_BNDRY_64KB
#define BNDRY_ALIGNMENT BNDRY0
//#define DMA_BASE_END 0x80000//#define DMA_BASE_ADDR 0x70000 // we use the top 64KB area#define DMA_ADDR(x) (g_dma_base + (1UL << (12+(x))))
#define HST_BNDRY_OFFSET(x) (1UL << (12+(x)))
#define NO_DATA_PRSNT 0
#define DATA_PRSNT 1
#define NO_CRC_CHECK 0
#define CRC_CHECK 1
#define NO_IDX_CHECK 0
#define IDX_CHECK 1
#define SINGLE_TRNSFR 0
#define INFINITE_TRNSFR 0
#define MULTIPLE_TRNSFR 1
#define NO_DMA_TRNSFR 0
#define DMA_TRNSFR 1
#define NO_AUTOCMD12 0
#define AUTOCMD12 1
#define DMA_MODE_PING_PONG 0
#define DMA_MODE_WRAP 1
#define DMA_END_ADDR (1 << 19) // 512KB
#define MAX_DATA_LEN 2048
#define FIFO_LEN 1024
#define MAX_CIS_LEN 256
#define MAX_SDIO_ADDR (1 << 17) // 128 K address space per function
//#define RegAddress 0xF6000000//#define MemAddress 0xF6080000//#define SDHC_MODULE_BASE (RegAddress+0x1100)//#define MX1_BASE 0xF0200000#define ssd192X_INTR_JPEG 0x04
#define ssd192X_INTR_SDHC 0x80
// for scripting support
int g_batchmode;
int g_scriptmode;
int g_autoreset = 1;
#ifndef __KERNEL__
FILE *g_script_fp;
#endif
/*typedef struct tagTASK_DATA {
SDHC_T *sdhc;
unsigned long start; // fifo start address
unsigned long size; // fifo size
unsigned long addr; // sdhc byte address
unsigned long ptr; // offset into jpeg fifo
unsigned long len; // length of data in fifo
unsigned long total; // total bytes written so far
unsigned long final; // final size of data
unsigned long flag; // bit0 = 1: ended
} TASK_DATA_T;
TASK_DATA_T sdhc_write_task_data; // private data for sdhc_write_task
*/#ifdef __KERNEL__
struct tq_struct tq_sdhc_write_th; // task queue element
struct tq_struct tq_sdhc_write_bh; // task queue element
#endif
int g_card_capacity;
CSD_T g_csd; // card specific data structure
CID_T g_cid; // card identification
SCR_T g_scr; // card configuration
CCCR_T g_cccr;
FBR_T g_fbr;
unsigned long g_cardtype; // bitmask of {(CARDTYPE_SDMEM | CARDTYPE_SDIO) ^ (CARDTYPE_MMC)}
unsigned short g_rca; // card rca
unsigned short g_cs; // card select status
unsigned long g_ocr; // card & sdhc common ocr
int g_io_num_fn; // number of io functions on card
int g_io_fn; // currently selected io function
int g_io_mp; // if memory is present on card
int g_io_mb;
int g_io_raw;
int g_width = 1;
unsigned long g_dma_base = 0xFFFFFF;
unsigned char g_data[MAX_DATA_LEN];
unsigned char g_cis[MAX_CIS_LEN];
unsigned long g_length = sizeof (g_data);
unsigned long g_swapsequence = 1;
unsigned long g_fifo_reset = 0;
unsigned long g_card_err = 0; // used by sdhc_ioctl, sdhc_read, sdhc_write
int g_irq = 0;
int g_dma = 0;
int g_autocmd12 = 0;
int g_xmode = 0;
int g_verbose = 0;
int g_use_sdhc = 0; // flag to indicate to jpeg encode routine to use sdhc
#ifndef __KERNEL__
int copy_to_user (void *to, void *from, long count)
{
memcpy (to, from, count);
return 0;
}
int copy_from_user (void *to, void *from, long count)
{
memcpy (from, to, count);
return 0;
}
#endif
#ifdef __KERNEL__
void sleep (int seconds);
#endif
unsigned long _sdhc_get_card_type();
unsigned long _sdhc_get_card_capacity();
int sdhc_dev_ioctl (unsigned long base, unsigned long arg);
int sdhc_ioctl (int fd, SDHC_IOCTL_ARG_T *arg);
int sdhc_init (unsigned short* prca);//int sdhc_reg_test (unsigned long base);//int sdhc_status_test ();//int sdhc_cmd_test ();int sdhc_read_scr (unsigned short rca, SCR_T *scr);int sdhc_get_wr_blk_count (unsigned short rca, long *nblk);int sdhc_set_width (unsigned short rca, int width);int sdhc_erase (unsigned long cardtype, unsigned short rca, unsigned long start_addr, int nblk);int sdhc_detect_test ();int sdhc_err_test ();int sdhc_reset_test (unsigned long base, unsigned char reset_type);
int sdhc_card_select (unsigned short rca, unsigned short select);int sdhc_card_init (unsigned short *rca, unsigned long *ocr, CID_T *cid, CSD_T *csd);
int sdhc_reset (unsigned char reset_type);
int io_reset ();int io_read_byte (int fn, unsigned long addr, unsigned char *data);int io_write_byte (int fn, int raw, unsigned long addr, unsigned char data);int io_read_direct (int fn, unsigned long addr, unsigned char *data, int len);int io_write_direct (int fn, unsigned long addr, unsigned char *data, int len);
int reg_test (
unsigned long addr, // address of register
unsigned short access_size, // access size: 8 | 16 | 32
unsigned short access_type, // 1=RW, 0=RO, WO
unsigned long def_val, // default POR value
unsigned long bitmask, // reserved bit mask, 0 = all bits are valid
unsigned char *name // register string name
);
int reg_def_test (unsigned long base);
int clock_cntl (unsigned short clocks, unsigned short div, int enable);int bus_pwr (int pwr);int card_detect ();int send_cmd ( unsigned short idx, unsigned short type,
unsigned short rsp,
int data_prsnt,
int crc_check,
int idx_check,
unsigned long arg[4]);
int send_app_cmd ( unsigned short idx,
unsigned short type,
unsigned short rsp,
int crc_check,
int idx_check,
unsigned long arg[4]);
int sdhc_read_ex ( unsigned long addr,
unsigned long data,
int blklen,
long nblk,
unsigned long flags,
void *param);
int sdhc_write_ex ( unsigned long addr,
unsigned long data,
int blklen,
long nblk,
unsigned long flags,
void *param);
int fifo_reset (SDHCEXT_T *);
int fifo_readback (SDHCEXT_T *ext, int n, unsigned char *data, int len);/*int sdhc_cli (unsigned long base, char *s);
int read_cli (SDHC_T *sdhc, char *s, unsigned long nblk, unsigned long iomem);
int write_cli (SDHC_T *sdhc, char *s, unsigned long nblk, unsigned long iomem);
int sdhc_io_cli (SDHC_T *sdhc, char *p);
*/// counter functions for timing
int counter_init (unsigned long base);
int counter_start (void);
int counter_stop (void);
int counter_reset (void);
unsigned long counter_read (void);
#if 0
int erase_data (SDHC_T *sdhc,
unsigned long addr,
int nblk);
#endif
int read_scr (unsigned short rca, SCR_T *scr);int get_wr_blk_count (unsigned short rca, long *nblk);int calc_dat_timeout (CSD_T *csd, int clk_div, int wr);
void decode_r1 (unsigned long);
void decode_r5 (unsigned long);
void decode_r6 (unsigned short);
void decode_csd (CSD_T *p, unsigned long cardtype);
void decode_cid (CID_T *p, unsigned long cardtype);
void decode_scr (SCR_T *p);
void decode_cis (unsigned char *p, unsigned long len);
void decode_cccr (CCCR_T *p);
void decode_fbr (FBR_T *p);
void decode_cardtype (unsigned long cardtype);
void decode_reg ();void decode_ext (SDHCEXT_T *ext);
void dump_data (unsigned char *p, int offset, int len);
void dump_extension (unsigned long base);
#ifdef __KERNEL__
void sleep (int seconds) {
unsigned long j = jiffies + seconds*HZ;
while (jiffies < j)
schedule ();
}
#endif
void delay_us (int cnt)
{
#ifdef __KERNEL__
udelay(cnt);
#else
unsigned long volatile i,j;
for (i = 0; i < cnt; i++)
for (j = 0; j < 25000; j++)
;
#endif
return;
}
/******************************************************************************
Set Interrupt Flag Here
******************************************************************************/
//#define ssd192X_REG_BYTE(index) *(volatile unsigned char *)(RegAddress + (index)) void amzn_unmask_intr (unsigned char intr)
{
//printk ("***********************************unmasking sdhc irq=0x%x\n", intr); // ssd192X_REG_BYTE(REG_INTERRUPT_ENABLE) |= intr; // enable the interrupt SSD_REGWB(REG_INTERRUPT_ENABLE,SSD_REGRB(REG_INTERRUPT_ENABLE)|intr);}
void amzn_mask_intr (unsigned char intr)
{
//printk ("***********************************masking sdhc irq=0x%x\n", intr); //ssd192X_REG_BYTE(REG_INTERRUPT_FLAG) = intr; // clear any status //ssd192X_REG_BYTE(REG_INTERRUPT_ENABLE) &= ~intr; // disable the interrupt SSD_REGWB(REG_INTERRUPT_FLAG,intr); SSD_REGWB(REG_INTERRUPT_ENABLE,SSD_REGRB(REG_INTERRUPT_ENABLE)& (~intr));}
int sdhc_init (unsigned short* prca){
int i;
//debug("sdhc_init\n"); if(g_dma_base!=0xFFFFFF)//if it has been initialized
{
ssd_mem_free(g_dma_base);//free the memory
}
//INT32 tempAddress = ssd_mem_malloc(64*1024); //if(tempAddress<0) //{ // debug("%s: NOT ENOUGH MEMORY\n",__FUNCTION__); // return -1; //} //g_dma_base = tempAddress; //debug("dma base=%X\n",g_dma_base); g_cs = 0; // reset card select status
g_dma = 0;
g_autocmd12 = 0;
g_cardtype = 0;
g_width = 1;
g_xmode = 0;
#ifdef __KERNEL__
void amzn_mask_intr (unsigned char intr);
#endif
for (i = 0; i < sizeof (g_data); i++)
g_data[i] = 0x55;
#ifdef __KERNEL__
// mask off the amazon interrupt
amzn_mask_intr (ssd192X_INTR_SDHC);
#endif
if (sdhc_reset (SW_RESET_ALL) < 0) { db ("sdhc_reset: failed\n");
return -1;
}
if (!(SSD_REGRL(REG_u32PrsntState) & PSR_CARD_DET_PIN)) { db ("No card present\n");
return -1;
}
if (sdhc_card_init (&g_rca, &g_ocr, &g_cid, &g_csd) < 0) { db ("sdhc_init: Card Initialisation failed\n");
return -1;
} else {
db ("rca(similar to address)=%d\n",g_rca);
*prca=g_rca;
db ("sdhc_init: Card initialisation successful\n");
}
if (g_cardtype & CARDTYPE_SDMEM) {
if (sdhc_read_scr (g_rca, &g_scr) < 0) { db ("sdhc_init: Read SCR Failed\n");
return -1;
} else {
db ("sdhc_init: Read SCR passed\n");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -