1
0
mirror of git://projects.qi-hardware.com/xburst-tools.git synced 2024-11-25 20:04:03 +02:00

more cleanup

This commit is contained in:
Lars-Peter Clausen 2010-01-08 03:35:59 +01:00
parent 836fade868
commit 9aa52b7947
12 changed files with 434 additions and 378 deletions

View File

@ -31,76 +31,69 @@
#include "ingenic_usb.h"
#include "usb_boot_defines.h"
struct hand hand;
struct sdram_in sdram_in;
unsigned int total_size;
static char code_buf[4 * 512 * 1024];
static char ret[8];
static int load_file(struct ingenic_dev *ingenic_dev, const char *file_path)
static int load_file(struct ingenic_dev *dev, const char *file_path, char *buf)
{
struct stat fstat;
int fd, status, res = -1;
int fd, status;
status = stat(file_path, &fstat);
if (status < 0) {
fprintf(stderr, "Error - can't get file size from '%s': %s\n",
file_path, strerror(errno));
goto out;
return errno;
}
ingenic_dev->file_len = fstat.st_size;
ingenic_dev->file_buff = code_buf;
fd = open(file_path, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "Error - can't open file '%s': %s\n",
fprintf(stderr, "Error - can't open file '%s': %s\n",
file_path, strerror(errno));
goto out;
return errno;
}
status = read(fd, ingenic_dev->file_buff, ingenic_dev->file_len);
status = read(fd, buf, fstat.st_size);
if (status < (int)ingenic_dev->file_len) {
fprintf(stderr, "Error - can't read file '%s': %s\n",
if (status < (int)fstat.st_size) {
fprintf(stderr, "Error - can't read file '%s': %s\n",
file_path, strerror(errno));
goto close;
}
/* write args to code */
memcpy(ingenic_dev->file_buff + 8, &hand.fw_args,
sizeof(struct fw_args));
res = 1;
memcpy(buf + 8, &dev->config.fw_args, sizeof(struct fw_args));
close:
close(fd);
out:
return res;
return fstat.st_size;
}
/* after upload stage2. must init device */
void init_cfg(struct ingenic_dev *dev)
{
if (usb_get_ingenic_cpu(dev) < 3) {
printf(" XBurst CPU not booted yet, boot it first!\n");
printf("XBurst CPU not booted yet, boot it first!\n");
return;
}
if (usb_send_data_to_ingenic(dev, (char*)&hand, sizeof(hand)) != 1)
if (usb_send_data_to_ingenic(dev, (char*)&dev->config, sizeof(dev->config))
< 0)
goto xout;
if (usb_ingenic_configration(dev, DS_hand) != 1)
if (usb_ingenic_configration(dev, DS_hand) < 0)
goto xout;
if (usb_read_data_from_ingenic(dev, ret, 8) != 1)
if (usb_read_data_from_ingenic(dev, ret, 8) < 0)
goto xout;
printf(" Configuring XBurst CPU succeeded.\n");
printf("Configuring XBurst CPU succeeded.\n");
return;
xout:
printf("Configuring XBurst CPU failed.\n");
@ -109,57 +102,62 @@ xout:
int boot(struct ingenic_dev *dev, const char *stage1_path, const char *stage2_path)
{
int status;
int size;
status = usb_get_ingenic_cpu(dev);
switch (status) {
case 1: /* Jz4740v1 */
case INGENIC_CPU_JZ4740V1:
status = 0;
hand.fw_args.cpu_id = 0x4740;
dev->config.fw_args.cpu_id = 0x4740;
break;
case 2: /* Jz4750v1 */
case INGENIC_CPU_JZ4750V1:
status = 0;
hand.fw_args.cpu_id = 0x4750;
dev->config.fw_args.cpu_id = 0x4750;
break;
case 3: /* Boot4740 */
case INGENIC_CPU_JZ4740:
status = 1;
hand.fw_args.cpu_id = 0x4740;
dev->config.fw_args.cpu_id = 0x4740;
break;
case 4: /* Boot4750 */
case INGENIC_CPU_JZ4750:
status = 1;
hand.fw_args.cpu_id = 0x4750;
dev->config.fw_args.cpu_id = 0x4750;
break;
default:
return 1;
return (status < 0) ? status : -1;
}
if (status) {
printf(" Already booted.\n");
return 1;
printf("Already booted.\n");
return 0;
} else {
printf(" CPU not yet booted, now booting...\n");
printf("CPU not yet booted, now booting...\n");
/* now we upload the boot stage1 */
printf(" Loading stage1 from '%s'\n", stage1_path);
if (load_file(dev, stage1_path) < 1)
return -1;
printf("Loading stage1 from '%s'\n", stage1_path);
size = load_file(dev, stage1_path, code_buf);
if (size < 0)
return size;
if (usb_ingenic_upload(dev, 1) < 1)
if (usb_ingenic_upload(dev, 1, code_buf, size) < 0)
return -1;
/* now we upload the boot stage2 */
usleep(100);
printf(" Loading stage2 from '%s'\n", stage2_path);
if (load_file(dev, stage2_path) < 1)
printf("Loading stage2 from '%s'\n", stage2_path);
size = load_file(dev, stage2_path, code_buf);
if (size < 0) {
printf("FOOBAR");
return size;
}
if (usb_ingenic_upload(dev, 2, code_buf, size) < 0)
return -1;
if (usb_ingenic_upload(dev, 2) < 1)
return -1;
printf(" Booted successfully!\n");
printf("Booted successfully!\n");
}
usleep(100);
init_cfg(dev);
return 1;
return 0;
}
@ -171,51 +169,50 @@ int debug_memory(struct ingenic_dev *dev, int obj, unsigned int start, unsigned
tmp = usb_get_ingenic_cpu(dev);
if (tmp > 2) {
printf(" This command only run under UNBOOT state!\n");
printf("This command only run under UNBOOT state!\n");
return -1;
}
switch (tmp) {
case 1:
tmp = 0;
hand.fw_args.cpu_id = 0x4740;
dev->config.fw_args.cpu_id = 0x4740;
break;
case 2:
tmp = 0;
hand.fw_args.cpu_id = 0x4750;
dev->config.fw_args.cpu_id = 0x4750;
break;
}
hand.fw_args.debug_ops = 1;/* tell device it's memory debug */
hand.fw_args.start = start;
dev->config.fw_args.debug_ops = 1;/* tell device it's memory debug */
dev->config.fw_args.start = start;
if (size == 0)
hand.fw_args.size = total_size;
dev->config.fw_args.size = total_size;
else
hand.fw_args.size = size;
dev->config.fw_args.size = size;
printf(" Now test memory from 0x%x to 0x%x: \n",
start, start + hand.fw_args.size);
printf("Now test memory from 0x%x to 0x%x: \n",
start, start + dev->config.fw_args.size);
if (load_file(dev, STAGE1_FILE_PATH) < 1)
return -1;
if (usb_ingenic_upload(dev, 1) < 1)
size = load_file(dev, STAGE1_FILE_PATH, code_buf);
if (size < 0)
return size;
if (usb_ingenic_upload(dev, 1, code_buf, size) < 1)
return -1;
usleep(100);
usb_read_data_from_ingenic(dev, buffer, 8);
if (buffer[0] != 0)
printf(" Test memory fail! Last error address is 0x%x !\n",
printf("Test memory fail! Last error address is 0x%x !\n",
buffer[0]);
else
printf(" Test memory pass!\n");
printf("Test memory pass!\n");
return 1;
}
int debug_go(struct ingenic_dev *dev, size_t argc, char *argv[])
{
unsigned int addr,obj;
unsigned int addr, obj;
if (argc < 3) {
printf(" Usage: go (1) (2) \n"
" 1:start SDRAM address\n"
@ -226,7 +223,7 @@ int debug_go(struct ingenic_dev *dev, size_t argc, char *argv[])
addr = strtoul(argv[1], NULL, 0);
obj = atoi(argv[2]);
printf(" Executing No.%d device at address 0x%x\n", obj, addr);
printf("Executing No.%d device at address 0x%x\n", obj, addr);
if (usb_ingenic_start(dev, VR_PROGRAM_START2, addr) < 1)
return -1;
@ -237,12 +234,12 @@ int debug_go(struct ingenic_dev *dev, size_t argc, char *argv[])
int sdram_load(struct ingenic_dev *dev, struct sdram_in *sdram_in)
{
if (usb_get_ingenic_cpu(dev) < 3) {
printf(" Device unboot! Boot it first!\n");
printf("Device unboot! Boot it first!\n");
return -1;
}
if (sdram_in->length > (unsigned int) MAX_LOAD_SIZE) {
printf(" Image length too long!\n");
printf("Image length too long!\n");
return -1;
}
@ -252,7 +249,7 @@ int sdram_load(struct ingenic_dev *dev, struct sdram_in *sdram_in)
/* usb_ingenic_sdram_ops(dev, sdram_in);*/
usb_read_data_from_ingenic(dev, ret, 8);
printf(" Load last address at 0x%x\n",
printf("Load last address at 0x%x\n",
((ret[3]<<24)|(ret[2]<<16)|(ret[1]<<8)|(ret[0]<<0)));
return 1;
@ -283,8 +280,8 @@ int sdram_load_file(struct ingenic_dev *dev, struct sdram_in *sdram_in, char *fi
j = flen % MAX_LOAD_SIZE;
offset = 0;
printf(" Total size to send in byte is :%d\n", flen);
printf(" Loading data to SDRAM :\n");
printf("Total size to send in byte is :%d\n", flen);
printf("Loading data to SDRAM :\n");
for (k = 0; k < m; k++) {
status = read(fd, sdram_in->buf, MAX_LOAD_SIZE);

View File

@ -20,6 +20,9 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include "usb_boot_defines.h"
#include "ingenic_usb.h"
#include "cmd.h"
@ -323,6 +326,11 @@ static size_t command_parse(char *cmd, char *argv[])
return argc;
}
static int nand_read_callback(void *data, const char *buf, size_t size)
{
return 0;
}
static int handle_nand_read(size_t argc, char *argv[])
{
int mode;
@ -354,27 +362,37 @@ static int handle_nand_read(size_t argc, char *argv[])
if (err)
return err;
return nand_read(&ingenic_dev, nand_idx, mode, start_page, num_pages, 0);
return nand_read(&ingenic_dev, nand_idx, mode, start_page, num_pages, 0,
nand_read_callback, NULL);
}
static int nand_dump_callback(void *data, const char *buf, size_t size)
{
int fd = *(int*)(data);
write(fd, buf, size);
return 0;
}
static int handle_nand_dump(size_t argc, char *argv[])
{
int mode;
uint32_t start_page, num_pages;
unsigned int device_idx;
uint8_t nand_idx;
int err = 0;
int fd;
if (argc != 5) {
printf("Usage: %s <start page> <length> <filename> <mode>\n", argv[0]);
return -1;
}
if (strcmp(argv[5], "-n") == 0) {
if (strcmp(argv[4], "-n") == 0) {
mode = NAND_READ;
} else if (strcmp(argv[5], "-e") == 0) {
} else if (strcmp(argv[4], "-e") == 0) {
mode = NAND_READ_RAW;
} else if (strcmp(argv[5], "-o") == 0) {
} else if (strcmp(argv[4], "-o") == 0) {
mode = NAND_READ_OOB;
} else {
return -1;
@ -382,13 +400,19 @@ static int handle_nand_dump(size_t argc, char *argv[])
start_page = parse_number_print_error(argv[1], &err);
num_pages = parse_number_print_error(argv[2], &err);
device_idx = parse_number_print_error(argv[3], &err);
nand_idx = parse_number_print_error(argv[4], &err);
/* device_idx = parse_number_print_error(argv[3], &err);*/
nand_idx = 0;
if (err)
return err;
return nand_read(&ingenic_dev, nand_idx, mode, start_page, num_pages, 0);
fd = creat(argv[3], 0644);
err = nand_read(&ingenic_dev, nand_idx, mode, start_page, num_pages, 0,
nand_dump_callback, &fd);
close(fd);
return err;
}
static int handle_nand_query(size_t argc, char *argv[])
@ -417,7 +441,7 @@ static int handle_nand_prog(size_t argc, char *argv[])
uint8_t nand_idx, mode = -1;
int err = 0;
if (argc != 5) {
if (argc != 6) {
printf("Usage: %s <start page> <filename> <device index> <nand chip index> <mode>\n", argv[0]);
return -1;
}

View File

@ -213,5 +213,5 @@ int parse_configure(struct hand *hand, char * file_path)
if (check_dump_cfg(hand) < 1)
return -1;
return 1;
return 0;
}

View File

@ -41,7 +41,7 @@ static int get_ingenic_device(struct ingenic_dev *ingenic_dev)
(usb_dev->descriptor.idProduct == PRODUCT_ID)) {
ingenic_dev->usb_dev = usb_dev;
count++;
break;
break;
}
}
@ -63,27 +63,27 @@ static int get_ingenic_interface(struct ingenic_dev *ingenic_dev)
usb_config_desc = &ingenic_dev->usb_dev->config[config_index];
if (!usb_config_desc)
return 0;
return -1;
for (if_index = 0; if_index < usb_config_desc->bNumInterfaces;
if_index++) {
usb_if = &usb_config_desc->interface[if_index];
if (!usb_if)
return 0;
return -1;
for (alt_index = 0; alt_index < usb_if->num_altsetting;
alt_index++) {
usb_if_desc = &usb_if->altsetting[alt_index];
if (!usb_if_desc)
return 0;
return -1;
if ((usb_if_desc->bInterfaceClass == 0xff) &&
(usb_if_desc->bInterfaceSubClass == 0)) {
ingenic_dev->interface =
usb_if_desc->bInterfaceNumber;
return 1;
return 0;
}
}
}
@ -94,7 +94,8 @@ static int get_ingenic_interface(struct ingenic_dev *ingenic_dev)
int usb_ingenic_init(struct ingenic_dev *ingenic_dev)
{
int num_ingenic, status = -1;
int num_ingenic;
int ret = -1;
memset(ingenic_dev, 0, sizeof(struct ingenic_dev));
@ -107,319 +108,310 @@ int usb_ingenic_init(struct ingenic_dev *ingenic_dev)
if (num_ingenic == 0) {
fprintf(stderr, "Error - no XBurst device found\n");
goto out;
goto err;
}
if (num_ingenic > 1) {
fprintf(stderr, "Error - too many XBurst devices found: %i\n",
fprintf(stderr, "Error - too many XBurst devices found: %d\n",
num_ingenic);
goto out;
goto err;
}
ingenic_dev->usb_handle = usb_open(ingenic_dev->usb_dev);
if (!ingenic_dev->usb_handle) {
fprintf(stderr, "Error - can't open XBurst device: %s\n",
usb_strerror());
goto out;
goto err;
}
if (get_ingenic_interface(ingenic_dev) < 1) {
ret = get_ingenic_interface(ingenic_dev);
if (ret < 0) {
fprintf(stderr, "Error - can't find XBurst interface\n");
goto out;
goto err;
}
if (usb_claim_interface(ingenic_dev->usb_handle, ingenic_dev->interface)
< 0) {
ret = usb_claim_interface(ingenic_dev->usb_handle, ingenic_dev->interface);
if (ret < 0) {
fprintf(stderr, "Error - can't claim XBurst interface: %s\n",
usb_strerror());
goto out;
goto err;
}
status = 1;
out:
return status;
return 0;
err:
return ret;
}
int usb_get_ingenic_cpu(struct ingenic_dev *ingenic_dev)
{
int status;
memset(&ingenic_dev->cpu_info_buff, 0,
ARRAY_SIZE(ingenic_dev->cpu_info_buff));
int ret;
char buf[9];
sleep(1);
status = usb_control_msg(ingenic_dev->usb_handle,
/* bmRequestType */ USB_ENDPOINT_IN | USB_TYPE_VENDOR |USB_RECIP_DEVICE,
/* bRequest */ VR_GET_CPU_INFO,
/* wValue */ 0,
/* wIndex */ 0,
/* Data */ ingenic_dev->cpu_info_buff,
/* wLength */ 8,
USB_TIMEOUT);
ret = usb_control_msg(ingenic_dev->usb_handle,
/* bmRequestType */ USB_ENDPOINT_IN | USB_TYPE_VENDOR |USB_RECIP_DEVICE,
/* bRequest */ VR_GET_CPU_INFO,
/* wValue */ 0,
/* wIndex */ 0,
/* Data */ buf,
/* wLength */ 8,
USB_TIMEOUT);
if (status != sizeof(ingenic_dev->cpu_info_buff) - 1 ) {
if (ret != 8) {
fprintf(stderr, "Error - "
"can't retrieve XBurst CPU information: %i\n", status);
return status;
"can't retrieve XBurst CPU information: %d\n", ret);
return ret;
}
ingenic_dev->cpu_info_buff[8] = '\0';
printf(" CPU data: %s\n", ingenic_dev->cpu_info_buff);
buf[8] = '\0';
printf(" CPU data: %s\n", buf);
if (!strcmp(ingenic_dev->cpu_info_buff,"JZ4740V1")) return 1;
if (!strcmp(ingenic_dev->cpu_info_buff,"JZ4750V1")) return 2;
if (!strcmp(ingenic_dev->cpu_info_buff,"Boot4740")) return 3;
if (!strcmp(ingenic_dev->cpu_info_buff,"Boot4750")) return 4;
if (!strcmp(buf, "JZ4740V1"))
return INGENIC_CPU_JZ4740V1;
if (!strcmp(buf, "JZ4750V1"))
return INGENIC_CPU_JZ4750V1;
if (!strcmp(buf, "Boot4740"))
return INGENIC_CPU_JZ4740;
if (!strcmp(buf, "Boot4750"))
return INGENIC_CPU_JZ4750;
return 0;
}
int usb_ingenic_flush_cache(struct ingenic_dev *ingenic_dev)
{
int status;
status = usb_control_msg(ingenic_dev->usb_handle,
/* bmRequestType */ USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
/* bRequest */ VR_FLUSH_CACHES,
/* wValue */ 0,
/* wIndex */ 0,
/* Data */ 0,
/* wLength */ 0,
USB_TIMEOUT);
if (status != 0) {
fprintf(stderr, "Error - can't flush cache: %i\n", status);
return status;
}
return 1;
}
int usb_send_data_length_to_ingenic(struct ingenic_dev *ingenic_dev, unsigned int len)
{
int status;
/* tell the device the length of the file to be uploaded */
status = usb_control_msg(ingenic_dev->usb_handle,
/* bmRequestType */ USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
/* bRequest */ VR_SET_DATA_LENGTH,
/* wValue */ STAGE_ADDR_MSB(len),
/* wIndex */ STAGE_ADDR_LSB(len),
/* Data */ 0,
/* wLength */ 0,
USB_TIMEOUT);
if (status != 0) {
fprintf(stderr, "Error - "
"can't set data length on Ingenic device: %i\n", status);
return -1;
}
return 1;
}
int usb_send_data_address_to_ingenic(struct ingenic_dev *ingenic_dev, uint32_t addr)
{
int status;
/* tell the device the RAM address to store the file */
status = usb_control_msg(ingenic_dev->usb_handle,
/* bmRequestType */ USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
/* bRequest */ VR_SET_DATA_ADDRESS,
/* wValue */ STAGE_ADDR_MSB(addr),
/* wIndex */ STAGE_ADDR_LSB(addr),
/* Data */ 0,
/* wLength */ 0,
USB_TIMEOUT);
if (status != 0) {
fprintf(stderr, "Error - "
"can't set the address on Ingenic device: %i\n", status);
return -1;
}
return 1;
return INGENIC_CPU_UNKOWN;
}
int usb_send_data_to_ingenic(struct ingenic_dev *ingenic_dev, const char *data,
int size)
{
int status;
status = usb_bulk_write(ingenic_dev->usb_handle,
/* endpoint */ INGENIC_OUT_ENDPOINT,
/* bulk data */ data,
/* bulk data length */ size,
int ret;
ret = usb_bulk_write(ingenic_dev->usb_handle,
/* endpoint */ INGENIC_OUT_ENDPOINT,
/* bulk data */ data,
/* bulk data length */ size,
USB_TIMEOUT);
if (status < size) {
if (ret < 0) {
fprintf(stderr, "Error - "
"can't send bulk data to Ingenic CPU: %i\n", status);
return -1;
"Can't send bulk data to Ingenic CPU: %d\n", ret);
return ret;
}
return 1;
return size;
}
int usb_read_data_from_ingenic(struct ingenic_dev *ingenic_dev,
char *data, int size)
{
int status;
status = usb_bulk_read(ingenic_dev->usb_handle,
/* endpoint */ INGENIC_IN_ENDPOINT,
/* bulk data */ data,
/* bulk data length */ size,
int ret;
ret = usb_bulk_read(ingenic_dev->usb_handle,
/* endpoint */ INGENIC_IN_ENDPOINT,
/* bulk data */ data,
/* bulk data length */ size,
USB_TIMEOUT);
if (status < size) {
if (ret < 0) {
fprintf(stderr, "Error - "
"can't read bulk data from Ingenic device:%i\n", status);
return -1;
"Can't read bulk data from Ingenic device: %d\n", ret);
return ret;
}
return 1;
return size;
}
int usb_ingenic_start(struct ingenic_dev *ingenic_dev, int rqst, int stage_addr)
{
int status;
int ret;
/* tell the device to start the uploaded device */
status = usb_control_msg(ingenic_dev->usb_handle,
/* bmRequestType */ USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
ret = usb_control_msg(ingenic_dev->usb_handle,
/* bmRequestType */ USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
/* bRequest */ rqst,
/* wValue */ STAGE_ADDR_MSB(stage_addr),
/* wIndex */ STAGE_ADDR_LSB(stage_addr),
/* Data */ 0,
/* wLength */ 0,
USB_TIMEOUT);
/* wValue */ STAGE_ADDR_MSB(stage_addr),
/* wIndex */ STAGE_ADDR_LSB(stage_addr),
/* Data */ 0,
/* wLength */ 0,
USB_TIMEOUT);
if (status != 0) {
if (ret != 0) {
fprintf(stderr, "Error - can't start the uploaded binary "
"on the Ingenic device: %i\n", status);
return status;
"on the Ingenic device: %d\n", ret);
}
return 1;
return ret;
}
int usb_ingenic_upload(struct ingenic_dev *ingenic_dev, int stage)
int usb_send_data_length_to_ingenic(struct ingenic_dev *ingenic_dev, unsigned int len)
{
unsigned int stage2_addr;
stage2_addr = total_size + 0x80000000;
stage2_addr -= CODE_SIZE;
int ret;
int stage_addr = (stage == 1 ? 0x80002000 : stage2_addr);
int rqst = VR_PROGRAM_START1;
/* tell the device the length of the file to be uploaded */
ret = usb_control_msg(ingenic_dev->usb_handle,
/* bmRequestType */ USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
/* bRequest */ VR_SET_DATA_LENGTH,
/* wValue */ STAGE_ADDR_MSB(len),
/* wIndex */ STAGE_ADDR_LSB(len),
/* Data */ 0,
/* wLength */ 0,
USB_TIMEOUT);
usb_send_data_address_to_ingenic(ingenic_dev, stage_addr);
printf(" Download stage %d program and execute at 0x%08x\n",
stage, (stage_addr));
usb_send_data_to_ingenic(ingenic_dev, ingenic_dev->file_buff,
ingenic_dev->file_len);
if (stage == 2) {
if (usb_get_ingenic_cpu(ingenic_dev) < 1)
return -1;
usb_ingenic_flush_cache(ingenic_dev);
rqst = VR_PROGRAM_START2;
if (ret != 0) {
fprintf(stderr, "Error - "
"can't set data length on Ingenic device: %d\n", ret);
}
if (usb_ingenic_start(ingenic_dev, rqst, stage_addr) < 1)
return -1;
if (usb_get_ingenic_cpu(ingenic_dev) < 1)
return -1;
return ret;
}
return 1;
int usb_send_data_address_to_ingenic(struct ingenic_dev *ingenic_dev, uint32_t addr)
{
int ret;
/* tell the device the RAM address to store the file */
ret = usb_control_msg(ingenic_dev->usb_handle,
/* bmRequestType */ USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
/* bRequest */ VR_SET_DATA_ADDRESS,
/* wValue */ STAGE_ADDR_MSB(addr),
/* wIndex */ STAGE_ADDR_LSB(addr),
/* Data */ 0,
/* wLength */ 0,
USB_TIMEOUT);
if (ret != 0) {
fprintf(stderr, "Error - "
"Can't set the address on Ingenic device: %d\n", ret);
}
return ret;
}
int usb_ingenic_upload(struct ingenic_dev *ingenic_dev, int stage,
const char *buf, int size)
{
uint32_t stage_addr;
int request;
int ret;
if (stage == 1) {
stage_addr = 0x80002000;
request = VR_PROGRAM_START1;
} else {
stage_addr = 0x80000000 + total_size - CODE_SIZE;
request = VR_PROGRAM_START2;
}
usb_send_data_address_to_ingenic(ingenic_dev, stage_addr);
printf("Download stage %d program and execute at 0x%08x\n",
stage, stage_addr);
usb_send_data_to_ingenic(ingenic_dev, buf, size);
if (stage == 2) {
ret = usb_get_ingenic_cpu(ingenic_dev);
if (ret < 0)
return ret;
usb_ingenic_flush_cache(ingenic_dev);
}
ret = usb_ingenic_start(ingenic_dev, request, stage_addr);
if (ret)
return ret;
ret = usb_get_ingenic_cpu(ingenic_dev);
if (ret)
return ret;
return 0;
}
void usb_ingenic_cleanup(struct ingenic_dev *ingenic_dev)
{
if ((ingenic_dev->usb_handle) && (ingenic_dev->interface))
usb_release_interface(ingenic_dev->usb_handle,
ingenic_dev->interface);
if (ingenic_dev->usb_handle) {
if (ingenic_dev->interface) {
usb_release_interface(ingenic_dev->usb_handle,
ingenic_dev->interface);
}
if (ingenic_dev->usb_handle)
usb_close(ingenic_dev->usb_handle);
}
}
static int usb_ingenic_ops(struct ingenic_dev *ingenic_dev, uint32_t type,
uint32_t ops)
{
int ret;
ret = usb_control_msg(ingenic_dev->usb_handle,
/* bmRequestType */ USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
/* bRequest */ type,
/* wValue */ ops,
/* wIndex */ 0,
/* Data */ 0,
/* wLength */ 0,
USB_TIMEOUT);
return ret;
}
int usb_ingenic_flush_cache(struct ingenic_dev *ingenic_dev)
{
int ret;
ret = usb_ingenic_ops(ingenic_dev, VR_FLUSH_CACHES, 0);
if (ret != 0) {
fprintf(stderr, "Error - can't flush cache: %d\n", ret);
}
return ret;
}
int usb_ingenic_nand_ops(struct ingenic_dev *ingenic_dev, int ops)
{
int status;
status = usb_control_msg(ingenic_dev->usb_handle,
/* bmRequestType */ USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
/* bRequest */ VR_NAND_OPS,
/* wValue */ ops & 0xffff,
/* wIndex */ 0,
/* Data */ 0,
/* wLength */ 0,
USB_TIMEOUT);
int ret;
ret = usb_ingenic_ops(ingenic_dev, VR_NAND_OPS, ops);
if (status != 0) {
if (ret != 0) {
fprintf(stderr, "Error - "
"can't set Ingenic device nand ops: %i\n", status);
return -1;
"can't set Ingenic device nand ops: %d\n", ret);
}
return 1;
return ret;
}
int usb_ingenic_mem_ops(struct ingenic_dev *ingenic_dev, int ops)
{
int status;
status = usb_control_msg(ingenic_dev->usb_handle,
/* bmRequestType */ USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
/* bRequest */ VR_MEM_OPS,
/* wValue */ ops & 0xffff,
/* wIndex */ 0,
/* Data */ 0,
/* wLength */ 0,
USB_TIMEOUT);
int ret;
ret = usb_ingenic_ops(ingenic_dev, VR_MEM_OPS, ops);
if (status != 0) {
if (ret != 0) {
fprintf(stderr, "Error - "
"can't set Ingenic device nand ops: %i\n", status);
return -1;
"can't set Ingenic device nand ops: %d\n", ret);
}
return 1;
return ret;
}
int usb_ingenic_configration(struct ingenic_dev *ingenic_dev, int ops)
{
int status;
status = usb_control_msg(ingenic_dev->usb_handle,
/* bmRequestType */ USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
/* bRequest */ VR_CONFIGRATION,
/* wValue */ ops,
/* wIndex */ 0,
/* Data */ 0,
/* wLength */ 0,
USB_TIMEOUT);
int ret;
ret = usb_ingenic_ops(ingenic_dev, VR_CONFIGURATION, ops);
if (status != 0) {
if (ret != 0) {
fprintf(stderr, "Error - "
"can't init Ingenic configration: %i\n", status);
return -1;
"can't init Ingenic configration: %d\n", ret);
}
return 1;
return ret;
}
int usb_ingenic_sdram_ops(struct ingenic_dev *ingenic_dev, int ops)
{
int status;
status = usb_control_msg(ingenic_dev->usb_handle,
/* bmRequestType */ USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
/* bRequest */ VR_SDRAM_OPS,
/* wValue */ ops,
/* wIndex */ 0,
/* Data */ 0,
/* wLength */ 0,
USB_TIMEOUT);
int ret;
if (status != 0) {
ret = usb_ingenic_ops(ingenic_dev, VR_SDRAM_OPS, ops);
if (ret != 0) {
fprintf(stderr, "Error - "
"Device can't load file to sdram: %i\n", status);
return -1;
"Device can't load file to sdram: %d\n", ret);
}
return 1;
return ret;
}

View File

@ -21,6 +21,7 @@
#define __INGENIC_USB_H__
#include <stdint.h>
#include "usb_boot_defines.h"
#define INGENIC_OUT_ENDPOINT 0x01
#define INGENIC_IN_ENDPOINT 0x81
@ -34,7 +35,7 @@
#define VR_NOR_OPS 0x06
#define VR_NAND_OPS 0x07
#define VR_SDRAM_OPS 0x08
#define VR_CONFIGRATION 0x09
#define VR_CONFIGURATION 0x09
#define VR_MEM_OPS 0x0a
#define VR_GET_NUM 0x0b
@ -56,14 +57,21 @@ struct ingenic_dev {
struct usb_device *usb_dev;
struct usb_dev_handle *usb_handle;
uint8_t interface;
char cpu_info_buff[9];
char *file_buff;
int file_len;
struct hand config;
};
enum ingenic_cpu_type {
INGENIC_CPU_UNKOWN,
INGENIC_CPU_JZ4740V1,
INGENIC_CPU_JZ4750V1,
INGENIC_CPU_JZ4740,
INGENIC_CPU_JZ4750,
};
int usb_ingenic_init(struct ingenic_dev *ingenic_dev);
int usb_get_ingenic_cpu(struct ingenic_dev *ingenic_dev);
int usb_ingenic_upload(struct ingenic_dev *ingenic_dev, int stage);
int usb_ingenic_upload(struct ingenic_dev *ingenic_dev, int stage, const char *buf, int size);
void usb_ingenic_cleanup(struct ingenic_dev *ingenic_dev);
int usb_ingenic_nand_ops(struct ingenic_dev *ingenic_dev, int ops);
int usb_ingenic_mem_ops(struct ingenic_dev *ingenic_dev, int ops);
@ -78,6 +86,7 @@ int usb_read_data_from_ingenic(struct ingenic_dev *ingenic_dev, char *buffer,
int usb_ingenic_start(struct ingenic_dev *ingenic_dev, int rqst, int stage_addr);
int usb_ingenic_sdram_ops(struct ingenic_dev *ingenic_dev, int ops);
int usb_ingenic_configration(struct ingenic_dev *ingenic_dev, int ops);
int usb_ingenic_flush_cache(struct ingenic_dev *ingenic_dev);
#endif /* __INGENIC_USB_H__ */

View File

@ -29,7 +29,6 @@
#define CONFIG_FILE_PATH "/etc/xburst-tools/usbboot.cfg"
struct ingenic_dev ingenic_dev;
extern struct hand hand;
static void help(void)
{
@ -98,11 +97,15 @@ int main(int argc, char **argv)
return EXIT_FAILURE;
}*/
if (usb_ingenic_init(&ingenic_dev) < 1)
if (usb_ingenic_init(&ingenic_dev)) {
printf("A\n");
return EXIT_FAILURE;
}
if (parse_configure(&hand, cfgpath) < 1)
if (parse_configure(&ingenic_dev.config, cfgpath)) {
printf("B\n");
return EXIT_FAILURE;
}
if (cmdpt) { /* direct run command */
char *delim=";";

View File

@ -10,8 +10,6 @@
#include "ingenic_usb.h"
#include "usb_boot_defines.h"
extern struct hand hand;
#define NAND_OP(idx, op, mode) (((mode << 12) & 0xf000) | ((idx << 4) & 0xff0) | op)
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
@ -22,9 +20,13 @@ static const char IMAGE_TYPE[][30] = {
"without oob",
};
static int error_check(const char *org, const char *obj, unsigned int size)
static int error_check(const char *a, const char *b, unsigned int size)
{
unsigned int i;
const unsigned char *org = (const unsigned char *)a;
const unsigned char *obj= (const unsigned char *)b;
printf("Comparing %d bytes - ", size);
for (i = 0; i < size; i++) {
if (org[i] != obj[i]) {
@ -65,8 +67,8 @@ int nand_markbad(struct ingenic_dev *dev, uint8_t nand_idx, uint32_t block)
(void)nand_idx;
if (usb_get_ingenic_cpu(dev) < 3) {
printf("Device unboot! Boot it first!\n");
return -1;
fprintf(stderr, "Device unboot! Boot it first!\n");
return -ENODEV;
}
printf("Mark bad block : %d\n", block);
usb_send_data_address_to_ingenic(dev, block);
@ -75,7 +77,7 @@ int nand_markbad(struct ingenic_dev *dev, uint8_t nand_idx, uint32_t block)
printf("Mark bad block at %d\n",((ret[3] << 24) |
(ret[2] << 16) |
(ret[1] << 8) |
(ret[0] << 0)) / hand.nand_ppb);
(ret[0] << 0)) / dev->config.nand_ppb);
return 0;
}
@ -91,20 +93,20 @@ int nand_program_check(struct ingenic_dev *dev, uint8_t nand_idx,
printf("Writing NAND page %u len %u...\n", start_page, length);
if (length > (unsigned int)MAX_TRANSFER_SIZE) {
printf("Buffer size too long!\n");
return -ENOMEM;
fprintf(stderr, "Buffer size too long!\n");
return -EINVAL;
}
if (usb_get_ingenic_cpu(dev) < 3) {
printf("Device unboot! Boot it first!\n");
fprintf(stderr, "Device unboot! Boot it first!\n");
return -ENODEV;
}
usb_send_data_to_ingenic(dev, data, length);
if (mode == NO_OOB)
page_num = DIV_ROUND_UP(length, hand.nand_ps);
page_num = DIV_ROUND_UP(length, dev->config.nand_ps);
else
page_num = DIV_ROUND_UP(length, hand.nand_ps + hand.nand_os);
page_num = DIV_ROUND_UP(length, dev->config.nand_ps + dev->config.nand_os);
op = NAND_OP(nand_idx, NAND_PROGRAM, mode);
@ -117,14 +119,11 @@ int nand_program_check(struct ingenic_dev *dev, uint8_t nand_idx,
length, start_page, page_num);
switch(mode) {
case NAND_READ:
case NO_OOB:
op = NAND_OP(nand_idx, NAND_READ, NO_OOB);
break;
case NAND_READ_OOB:
op = NAND_OP(nand_idx, NAND_READ_OOB, 0);
break;
case NAND_READ_RAW:
op = NAND_OP(nand_idx, NAND_READ_RAW, NO_OOB);
default:
op = NAND_OP(nand_idx, NAND_READ_RAW, OOB_ECC);
break;
}
@ -135,16 +134,16 @@ int nand_program_check(struct ingenic_dev *dev, uint8_t nand_idx,
(ret[0] << 0);
if (start_page < 1 &&
hand.nand_ps == 4096 &&
hand.fw_args.cpu_id == 0x4740) {
dev->config.nand_ps == 4096 &&
dev->config.fw_args.cpu_id == 0x4740) {
printf("no check! End at Page: %d\n", cur_page);
}
if (!error_check(data, read_back_buf, length)) {
// tbd: doesn't the other side skip bad blocks too? Can we just deduct 1 from cur_page?
// tbd: why do we only mark a block as bad if the last page in the block was written?
if (cur_page % hand.nand_ppb == 0)
nand_markbad(dev, nand_idx, (cur_page - 1) / hand.nand_ppb);
if (cur_page % dev->config.nand_ppb == 0)
nand_markbad(dev, nand_idx, (cur_page - 1) / dev->config.nand_ppb);
}
printf("End at Page: %d\n", cur_page);
@ -161,17 +160,17 @@ int nand_erase(struct ingenic_dev *dev, uint8_t nand_idx, uint32_t start_block,
static char ret[8];
if (start_block > (unsigned int)NAND_MAX_BLK_NUM) {
printf("Start block number overflow!\n");
return -1;
fprintf(stderr, "Start block number overflow!\n");
return -EINVAL;
}
if (num_blocks > (unsigned int)NAND_MAX_BLK_NUM) {
printf("Length block number overflow!\n");
return -1;
fprintf(stderr, "Length block number overflow!\n");
return -EINVAL;
}
if (usb_get_ingenic_cpu(dev) < 3) {
printf("Device unboot! Boot it first!\n");
return -1;
fprintf(stderr, "Device unboot! Boot it first!\n");
return -ENODEV;
}
printf("Erasing No.%d device No.%d flash (start_blk %u blk_num %u)......\n",
@ -187,10 +186,10 @@ int nand_erase(struct ingenic_dev *dev, uint8_t nand_idx, uint32_t start_block,
printf("Finish!");
end_block = ((ret[3] << 24) | (ret[2] << 16) |
(ret[1] << 8) | (ret[0] << 0)) / hand.nand_ppb;
(ret[1] << 8) | (ret[0] << 0)) / dev->config.nand_ppb;
printf("Return: %02x %02x %02x %02x %02x %02x %02x %02x (position %d)\n",
ret[0], ret[1], ret[2], ret[3], ret[4], ret[5], ret[6], ret[7], end_block);
if (!hand.nand_force_erase) {
if (!dev->config.nand_force_erase) {
/* not force erase, show bad block infomation */
printf("There are marked bad blocks: %d\n",
end_block - start_block - num_blocks );
@ -217,7 +216,7 @@ int nand_program_file(struct ingenic_dev *dev, uint8_t nand_idx,
if (status < 0) {
fprintf(stderr, "Error - can't get file size from '%s': %s\n",
filename, strerror(errno));
return -1;
return -EEXIST;
}
flen = fstat.st_size;
@ -225,7 +224,7 @@ int nand_program_file(struct ingenic_dev *dev, uint8_t nand_idx,
if (fd < 0) {
fprintf(stderr, "Error - can't open file '%s': %s\n",
filename, strerror(errno));
return -1;
return errno;
}
printf("Programing No.%d device, flen %d, start page %d...\n", 0,
@ -233,11 +232,12 @@ int nand_program_file(struct ingenic_dev *dev, uint8_t nand_idx,
/* printf("length %d flen %d\n", n_in.length, flen); */
if (mode == NO_OOB)
transfer_size = (hand.nand_ppb * hand.nand_ps);
transfer_size = (dev->config.nand_ppb * dev->config.nand_ps);
else
transfer_size = (hand.nand_ppb * (hand.nand_ps + hand.nand_os));
transfer_size = (dev->config.nand_ppb * (dev->config.nand_ps +
dev->config.nand_os));
start_block = start_page / hand.nand_ppb;
start_block = start_page / dev->config.nand_ppb;
num_blocks = flen / (transfer_size - 1) + 1;
if (nand_erase(dev, nand_idx, start_block, num_blocks))
@ -247,13 +247,13 @@ int nand_program_file(struct ingenic_dev *dev, uint8_t nand_idx,
j = flen % transfer_size;
printf("Size to send %d, transfer_size %d\n", flen, transfer_size);
printf("Image type : %s\n", IMAGE_TYPE[mode]);
/* printf("Image type : %s\n", IMAGE_TYPE[mode]);*/
printf("It will cause %d times buffer transfer.\n", j == 0 ? m : m + 1);
if (mode == NO_OOB)
page_num = transfer_size / hand.nand_ps;
page_num = transfer_size / dev->config.nand_ps;
else
page_num = transfer_size / (hand.nand_ps + hand.nand_os);
page_num = transfer_size / (dev->config.nand_ps + dev->config.nand_os);
offset = 0;
@ -269,7 +269,7 @@ int nand_program_file(struct ingenic_dev *dev, uint8_t nand_idx,
if (nand_program_check(dev, nand_idx, start_page, code_buf, code_len, mode) == -1)
goto close;
/* if (start_page - nand_in->start > hand.nand_ppb)
/* if (start_page - nand_in->start > dev->config.nand_ppb)
printf("Skip a old bad block !\n");*/
offset += code_len ;
@ -277,8 +277,8 @@ int nand_program_file(struct ingenic_dev *dev, uint8_t nand_idx,
if (j) {
code_len = j;
if (j % hand.nand_ps)
j += hand.nand_ps - (j % hand.nand_ps);
if (j % dev->config.nand_ps)
j += dev->config.nand_ps - (j % dev->config.nand_ps);
memset(code_buf, 0, j); /* set all to null */
status = read(fd, code_buf, code_len);
@ -293,7 +293,7 @@ int nand_program_file(struct ingenic_dev *dev, uint8_t nand_idx,
goto close;
/*
if (start_page - nand_in->start > hand.nand_ppb)
if (start_page - nand_in->start > dev->config.nand_ppb)
printf("Skip a old bad block !");
*/
}
@ -305,7 +305,7 @@ close:
int nand_prog(struct ingenic_dev *dev, uint8_t nand_idx, uint32_t start_page,
const char *filename, int mode)
{
if (hand.nand_plane > 1)
if (dev->config.nand_plane > 1)
printf("ERROR");
else
nand_program_file(dev, nand_idx, start_page, filename, mode);
@ -316,11 +316,12 @@ int nand_prog(struct ingenic_dev *dev, uint8_t nand_idx, uint32_t start_page,
int nand_query(struct ingenic_dev *dev, uint8_t nand_idx)
{
uint16_t op;
char ret[8];
char ret[8] = {0,0,0,0,0,0,0,0};
int ret2;
if (usb_get_ingenic_cpu(dev) < 3) {
printf("Device unboot! Boot it first!\n");
return -1;
fprintf(stderr, "Device unboot! Boot it first!\n");
return -ENODEV;
}
printf("ID of No.%u device No.%u flash: \n", 0, nand_idx);
@ -328,7 +329,11 @@ int nand_query(struct ingenic_dev *dev, uint8_t nand_idx)
op = NAND_OP(nand_idx, NAND_QUERY, 0);
usb_ingenic_nand_ops(dev, op);
usb_read_data_from_ingenic(dev, ret, ARRAY_SIZE(ret));
ret2 = usb_read_data_from_ingenic(dev, ret, ARRAY_SIZE(ret));
if (ret2 < 0)
return ret2;
printf("Vendor ID :0x%x \n", (unsigned char)ret[0]);
printf("Product ID :0x%x \n", (unsigned char)ret[1]);
printf("Chip ID :0x%x \n", (unsigned char)ret[2]);
@ -342,7 +347,8 @@ int nand_query(struct ingenic_dev *dev, uint8_t nand_idx)
}
int nand_read(struct ingenic_dev *dev, uint8_t nand_idx, int mode,
uint32_t start_page, uint32_t length, uint32_t ram_addr)
uint32_t start_page, uint32_t length, uint32_t ram_addr,
nand_read_cb_t callback, void *userdata)
{
uint16_t op;
uint32_t page;
@ -350,18 +356,18 @@ int nand_read(struct ingenic_dev *dev, uint8_t nand_idx, int mode,
uint32_t pages_per_request;
char ret[8];
char *buf;
int fd;
int ret2;
if (start_page > NAND_MAX_PAGE_NUM) {
printf("Page number overflow!\n");
return -1;
fprintf(stderr, "Page number overflow!\n");
return -EINVAL;
}
if (usb_get_ingenic_cpu(dev) < 3) {
printf("Device unboot! Boot it first!\n");
return -1;
fprintf(stderr, "Device unboot! Boot it first!\n");
return -EINVAL;
}
if (nand_idx >= 16)
return -1;
return -EINVAL;
printf("Reading from No.%u device No.%u flash....\n", 0, nand_idx);
@ -374,46 +380,43 @@ int nand_read(struct ingenic_dev *dev, uint8_t nand_idx, int mode,
op = NAND_OP(nand_idx, NAND_READ_OOB, 0);
break;
case NAND_READ_RAW:
op = NAND_OP(nand_idx, NAND_READ_RAW, NO_OOB);
op = NAND_OP(nand_idx, NAND_READ_RAW, OOB_ECC);
break;
case NAND_READ_TO_RAM:
op = NAND_OP(nand_idx, NAND_READ_TO_RAM, NO_OOB);
printf("Reading nand to RAM: 0x%x\n", ram_addr);
usb_ingenic_start(dev, VR_PROGRAM_START1, ram_addr);
break;
default:
printf("unknow mode!\n");
return -1;
return -EINVAL;
}
pages_per_request = 1;
request_length = hand.nand_ps * pages_per_request;
if (mode == NAND_READ_OOB || mode == NAND_READ_RAW)
request_length = (dev->config.nand_ps + dev->config.nand_os) * pages_per_request;
else
request_length = dev->config.nand_ps * pages_per_request;
page = start_page;
buf = malloc(request_length);
fd = open("/tmp/dump.bin", O_WRONLY | O_TRUNC | O_CREAT);
if (fd < 0) {
printf("Failed to open file\n");
return errno;
}
while (length > 0) {
if (request_length > length)
request_length = length;
nand_read_pages(dev, page, pages_per_request, buf, request_length, op, ret);
write(fd, buf, request_length);
ret2 = callback(userdata, buf, request_length);
if (ret2)
return ret2;
length -= request_length;
page += pages_per_request;
}
close(fd);
printf("Operation end position : %u \n",
(ret[3]<<24)|(ret[2]<<16)|(ret[1]<<8)|(ret[0]<<0));
free(buf);
return 1;
return 0;
}

View File

@ -6,11 +6,12 @@
struct ingenic_dev;
typedef int (*nand_read_cb_t)(void *userdata, const char *buf, size_t size);
int nand_query(struct ingenic_dev *dev, uint8_t nand_idx);
int nand_read(struct ingenic_dev *dev, uint8_t nand_idx, int mode,
uint32_t start_page, uint32_t length, uint32_t ram_addr);
int nand_dump(struct ingenic_dev *dev, uint8_t nand_idx,
uint32_t start_page, uint32_t length, const char *filename);
uint32_t start_page, uint32_t length, uint32_t ram_addr,
nand_read_cb_t callbcallback, void *userdata);
int nand_erase(struct ingenic_dev *dev, uint8_t nand_idx,
uint32_t start_block, uint32_t num_blocks);
int nand_prog(struct ingenic_dev *dev, uint8_t nand_idx,

View File

@ -22,7 +22,7 @@
#ifndef __USB_BOOT_H__
#define __USB_BOOT_H__
#define BULK_BUF_SIZE (128 * 4096)
#define BULK_BUF_SIZE (128 * (4096 + 128))
enum UDC_STATE
{

View File

@ -121,17 +121,27 @@ void sdram_init_4740(void)
int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
if (SDRAM_BW16 == 0xff) {
serial_puts("hura");
return;
}
serial_put_hex(0xf00);
cpu_clk = CFG_CPU_SPEED;
mem_clk = cpu_clk * div[__cpm_get_cdiv()] / div[__cpm_get_mdiv()];
serial_put_hex(0xf01);
REG_EMC_BCR = 0; /* Disable bus release */
serial_put_hex(0xf02);
REG_EMC_RTCSR = 0; /* Disable clock for counting */
serial_put_hex(0xf03);
/* Fault DMCR value for mode register setting*/
#define SDRAM_ROW0 11
#define SDRAM_COL0 8
#define SDRAM_BANK40 0
serial_put_hex(0xf04);
dmcr0 = ((SDRAM_ROW0-11)<<EMC_DMCR_RA_BIT) |
((SDRAM_COL0-8)<<EMC_DMCR_CA_BIT) |
(SDRAM_BANK40<<EMC_DMCR_BA_BIT) |
@ -139,6 +149,7 @@ void sdram_init_4740(void)
EMC_DMCR_EPIN |
cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)];
serial_put_hex(0xf05);
/* Basic DMCR value */
dmcr = ((SDRAM_ROW-11)<<EMC_DMCR_RA_BIT) |
((SDRAM_COL-8)<<EMC_DMCR_CA_BIT) |
@ -147,6 +158,7 @@ void sdram_init_4740(void)
EMC_DMCR_EPIN |
cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)];
serial_put_hex(0xf06);
/* SDRAM timimg */
ns = 1000000000 / mem_clk;
tmp = SDRAM_TRAS/ns;
@ -172,23 +184,33 @@ void sdram_init_4740(void)
EMC_SDMR_BL_4 |
cas_latency_sdmr[((SDRAM_CASL == 3) ? 1 : 0)];
serial_put_hex(0xf07);
/* Stage 1. Precharge all banks by writing SDMR with DMCR.MRSET=0 */
serial_put_hex(dmcr);
serial_put_hex(REG_EMC_DMCR);
REG_EMC_DMCR = dmcr;
REG8(EMC_SDMR0|sdmode) = 0;
/* Wait for precharge, > 200us */
tmp = (cpu_clk / 1000000) * 1000;
while (tmp--);
serial_put_hex(0xf08);
/* Stage 2. Enable auto-refresh */
REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH;
serial_put_hex(0xf09);
tmp = SDRAM_TREF/ns;
serial_put_hex(0xf10);
tmp = tmp/64 + 1;
serial_put_hex(0xf11);
if (tmp > 0xff) tmp = 0xff;
REG_EMC_RTCOR = tmp;
serial_put_hex(tmp);
/* REG_EMC_RTCOR = tmp;*/
serial_put_hex(0xf10);
REG_EMC_RTCNT = 0;
serial_put_hex(0xf11);
REG_EMC_RTCSR = EMC_RTCSR_CKS_64; /* Divisor is 64, CKO/64 */
serial_put_hex(0xf12);
/* Wait for number of auto-refresh cycles */
tmp = (cpu_clk / 1000000) * 1000;
@ -198,9 +220,10 @@ void sdram_init_4740(void)
REG_EMC_DMCR = dmcr0 | EMC_DMCR_RFSH | EMC_DMCR_MRSET;
REG8(EMC_SDMR0|sdmode) = 0;
serial_put_hex(0xf11);
/* Set back to basic DMCR value */
REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET;
serial_put_hex(0xf12);
/* everything is ok now */
}

View File

@ -68,7 +68,7 @@ void load_args(void)
CFG_CPU_SPEED = 192000000;
}
PHM_DIV = fw_args->phm_div;
if (fw_args->use_uart > 3)
if (fw_args->use_uart > 3)
fw_args->use_uart = 0;
UART_BASE = UART0_BASE + fw_args->use_uart * 0x1000;
CONFIG_BAUDRATE = fw_args->boudrate;
@ -88,10 +88,12 @@ void c_main(void)
do_debug();
return ;
}
/* serial_put_hex(0xf00);*/
switch (CPU_ID) {
case 0x4740:
gpio_init_4740();
/* serial_put_hex(0xf01);*/
pll_init_4740();
serial_init();
sdram_init_4740();

View File

@ -440,6 +440,8 @@ u32 nand_read_4740(void *buf, u32 startpage, u32 pagecount, int option)
tmpbuf = buf;
handshake_PKT[3] = 0;
return cur_page + pagecount;
while (cnt < pagecount) {
select_chip(cnt / ppb);
/* If this is the first page of the block, check for bad. */