mirror of
git://projects.qi-hardware.com/xburst-tools.git
synced 2024-11-26 03:16:15 +02:00
qi-fix-slow-first-bulk.patch
This patch performs the equivalent init actions to the SDHC slow unitl first bulk patch in kernel, it allows us to work with large SDHC cards which exceed Glamo timeout capability at 16MHz for first access. Signed-off-by: Andy Green <andy@openmoko.com>
This commit is contained in:
parent
b2995f8b39
commit
2e2480ff21
@ -106,12 +106,16 @@ unsigned long mmc_bread(int dev_num, unsigned long blknr, unsigned long blkcnt,
|
|||||||
void *dst)
|
void *dst)
|
||||||
{
|
{
|
||||||
unsigned long src = blknr * MMC_BLOCK_SIZE;
|
unsigned long src = blknr * MMC_BLOCK_SIZE;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (!blkcnt)
|
if (!blkcnt)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* printf("mmc_bread(%d, %ld, %ld, %p)\n", dev_num, blknr, blkcnt, dst); */
|
/* printf("mmc_bread(%d, %ld, %ld, %p)\n", dev_num, blknr, blkcnt, dst); */
|
||||||
mmc_read(src, dst, blkcnt * MMC_BLOCK_SIZE);
|
ret = mmc_read(src, dst, blkcnt * MMC_BLOCK_SIZE);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
return blkcnt;
|
return blkcnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,6 +447,8 @@ int mmc_read(unsigned long src, u8 *dst, int size)
|
|||||||
resp = mmc_cmd(MMC_SET_BLOCKLEN, MMC_BLOCK_SIZE,
|
resp = mmc_cmd(MMC_SET_BLOCKLEN, MMC_BLOCK_SIZE,
|
||||||
MMC_CMD_AC | MMC_RSP_R1, 0, 0, 0,
|
MMC_CMD_AC | MMC_RSP_R1, 0, 0, 0,
|
||||||
(u16 *)&response[0]);
|
(u16 *)&response[0]);
|
||||||
|
if (resp)
|
||||||
|
return resp;
|
||||||
|
|
||||||
while (size) {
|
while (size) {
|
||||||
switch (card_type) {
|
switch (card_type) {
|
||||||
@ -460,6 +466,15 @@ int mmc_read(unsigned long src, u8 *dst, int size)
|
|||||||
(u16 *)&response[0]);
|
(u16 *)&response[0]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (resp)
|
||||||
|
return resp;
|
||||||
|
|
||||||
|
/* final speed 16MHz */
|
||||||
|
glamo_reg_write((glamo_reg_read(GLAMO_REG_CLOCK_GEN8) &
|
||||||
|
0xff00) | 2, GLAMO_REG_CLOCK_GEN8);
|
||||||
|
|
||||||
|
|
||||||
do_pio_read((u16 *)dst, MMC_BLOCK_SIZE >> 1);
|
do_pio_read((u16 *)dst, MMC_BLOCK_SIZE >> 1);
|
||||||
|
|
||||||
if (size >= MMC_BLOCK_SIZE)
|
if (size >= MMC_BLOCK_SIZE)
|
||||||
@ -824,9 +839,9 @@ int mmc_init(int verbose)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* crank the clock to the final speed, 16MHz */
|
/* set the clock to slow until first bulk completes (for slow SDHC) */
|
||||||
|
|
||||||
glamo_reg_write((glamo_reg_read(GLAMO_REG_CLOCK_GEN8) & 0xff00) | 2,
|
glamo_reg_write((glamo_reg_read(GLAMO_REG_CLOCK_GEN8) & 0xff00) | 32,
|
||||||
GLAMO_REG_CLOCK_GEN8);
|
GLAMO_REG_CLOCK_GEN8);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -453,9 +453,18 @@ static int ext2fs_iterate_dir(ext2fs_node_t dir, char *name, ext2fs_node_t * fno
|
|||||||
if (!diro->inode_read) {
|
if (!diro->inode_read) {
|
||||||
status = ext2fs_read_inode(diro->data, diro->ino,
|
status = ext2fs_read_inode(diro->data, diro->ino,
|
||||||
&diro->inode);
|
&diro->inode);
|
||||||
if (status == 0)
|
if (status == 0) {
|
||||||
|
printdec(diro->ino);
|
||||||
|
puts("failed to read inode\n");
|
||||||
return(0);
|
return(0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
puts("fail\n");
|
||||||
}
|
}
|
||||||
|
printdec(fpos);
|
||||||
|
puts(" ");
|
||||||
|
printdec(diro->inode.size);
|
||||||
|
puts("\n");
|
||||||
/* Search the file. */
|
/* Search the file. */
|
||||||
while (fpos < __le32_to_cpu(diro->inode.size)) {
|
while (fpos < __le32_to_cpu(diro->inode.size)) {
|
||||||
struct ext2_dirent dirent;
|
struct ext2_dirent dirent;
|
||||||
@ -463,8 +472,10 @@ static int ext2fs_iterate_dir(ext2fs_node_t dir, char *name, ext2fs_node_t * fno
|
|||||||
status = ext2fs_read_file(diro, fpos,
|
status = ext2fs_read_file(diro, fpos,
|
||||||
sizeof(struct ext2_dirent),
|
sizeof(struct ext2_dirent),
|
||||||
(char *) &dirent);
|
(char *) &dirent);
|
||||||
if (status < 1)
|
if (status < 1) {
|
||||||
|
puts("ext2fs_read_file ret < 1\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (dirent.namelen != 0) {
|
if (dirent.namelen != 0) {
|
||||||
char filename[256];
|
char filename[256];
|
||||||
@ -474,12 +485,16 @@ static int ext2fs_iterate_dir(ext2fs_node_t dir, char *name, ext2fs_node_t * fno
|
|||||||
status = ext2fs_read_file(diro,
|
status = ext2fs_read_file(diro,
|
||||||
fpos + sizeof(struct ext2_dirent),
|
fpos + sizeof(struct ext2_dirent),
|
||||||
dirent.namelen, filename);
|
dirent.namelen, filename);
|
||||||
if (status < 1)
|
if (status < 1) {
|
||||||
|
puts("ext2fs_read_file fail 2\n");
|
||||||
return(0);
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
fdiro = malloc(sizeof(struct ext2fs_node));
|
fdiro = malloc(sizeof(struct ext2fs_node));
|
||||||
if (!fdiro)
|
if (!fdiro) {
|
||||||
|
puts("malloc fail\n");
|
||||||
return(0);
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fdiro->data = diro->data;
|
fdiro->data = diro->data;
|
||||||
@ -505,6 +520,7 @@ static int ext2fs_iterate_dir(ext2fs_node_t dir, char *name, ext2fs_node_t * fno
|
|||||||
__le32_to_cpu(dirent.inode),
|
__le32_to_cpu(dirent.inode),
|
||||||
&fdiro->inode);
|
&fdiro->inode);
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
|
puts("inner ext2fs_read_inode fail\n");
|
||||||
free(fdiro);
|
free(fdiro);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
@ -540,6 +556,7 @@ static int ext2fs_iterate_dir(ext2fs_node_t dir, char *name, ext2fs_node_t * fno
|
|||||||
__le32_to_cpu(dirent.inode),
|
__le32_to_cpu(dirent.inode),
|
||||||
&fdiro->inode);
|
&fdiro->inode);
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
|
puts("ext2fs_read_inode 3 fail\n");
|
||||||
free(fdiro);
|
free(fdiro);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
@ -720,7 +737,7 @@ int ext2fs_find_file
|
|||||||
|
|
||||||
symlinknest = 0;
|
symlinknest = 0;
|
||||||
if (!path)
|
if (!path)
|
||||||
return(0);
|
return 0;
|
||||||
|
|
||||||
status = ext2fs_find_file1(path, rootnode, foundnode, &foundtype);
|
status = ext2fs_find_file1(path, rootnode, foundnode, &foundtype);
|
||||||
if (status == 0)
|
if (status == 0)
|
||||||
@ -760,29 +777,35 @@ int ext2fs_open(const char *filename) {
|
|||||||
ext2fs_node_t fdiro = NULL;
|
ext2fs_node_t fdiro = NULL;
|
||||||
int status;
|
int status;
|
||||||
int len;
|
int len;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
if (ext2fs_root == NULL)
|
if (ext2fs_root == NULL)
|
||||||
return -1;
|
goto fail;
|
||||||
|
|
||||||
ext2fs_file = NULL;
|
ext2fs_file = NULL;
|
||||||
status = ext2fs_find_file(filename, &ext2fs_root->diropen, &fdiro,
|
status = ext2fs_find_file(filename, &ext2fs_root->diropen, &fdiro,
|
||||||
FILETYPE_REG);
|
FILETYPE_REG);
|
||||||
if (status == 0)
|
if (status == 0) {
|
||||||
|
ret = -2;
|
||||||
goto fail;
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
if (!fdiro->inode_read) {
|
if (!fdiro->inode_read) {
|
||||||
status = ext2fs_read_inode(fdiro->data, fdiro->ino,
|
status = ext2fs_read_inode(fdiro->data, fdiro->ino,
|
||||||
&fdiro->inode);
|
&fdiro->inode);
|
||||||
if (status == 0)
|
if (status == 0) {
|
||||||
|
ret = -3;
|
||||||
goto fail;
|
goto fail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
len = __le32_to_cpu(fdiro->inode.size);
|
len = __le32_to_cpu(fdiro->inode.size);
|
||||||
ext2fs_file = fdiro;
|
ext2fs_file = fdiro;
|
||||||
|
|
||||||
return(len);
|
return(len);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
ext2fs_free_node(fdiro, &ext2fs_root->diropen);
|
ext2fs_free_node(fdiro, &ext2fs_root->diropen);
|
||||||
return -1;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -81,7 +81,8 @@ void bootloader_second_phase(void)
|
|||||||
if (this_kernel->partition_index) {
|
if (this_kernel->partition_index) {
|
||||||
unsigned char *p = kernel_dram;
|
unsigned char *p = kernel_dram;
|
||||||
|
|
||||||
if (this_kernel->block_read(kernel_dram, 0, 4) < 0) {
|
if ((int)this_kernel->block_read(kernel_dram, 0, 4)
|
||||||
|
< 0) {
|
||||||
puts("Bad partition read\n");
|
puts("Bad partition read\n");
|
||||||
this_kernel = &this_board->
|
this_kernel = &this_board->
|
||||||
kernel_source[kernel++];
|
kernel_source[kernel++];
|
||||||
|
Loading…
Reference in New Issue
Block a user