Files
cLK/lk/target/htcleo/init.c
2011-11-06 23:26:22 +00:00

206 lines
5.0 KiB
C

/*
* author: cedesmith
* license: GPL
*/
#include <string.h>
#include <debug.h>
#include <dev/keys.h>
#include <dev/gpio_keypad.h>
#include <lib/ptable.h>
#include <dev/flash.h>
#define LINUX_MACHTYPE 2524
#define HTCLEO_FLASH_OFFSET 0x219
static struct ptable flash_ptable;
// align data on a 512 boundary so will not be interrupted in nbh
#if 1
//generic partition table
static struct ptentry board_part_list[MAX_PTABLE_PARTS] __attribute__ ((aligned (512))) = {
{
.name = "PTABLE-MB", // PTABLE-BLK or PTABLE-MB for length in MB or BLOCKS
},
{
.name = "recovery",
.length = 5 /* In MB */,
},
{
.name = "boot",
.length = 5 /* In MB */,
},
{
.name = "system",
.length = 250 /* In MB */,
},
{
.length = 10 /* In MB */,
.name = "cache",
},
{
.name = "userdata",
},
};
#else
// partition table matching cotulla's build
static struct ptentry board_part_list[MAX_PTABLE_PARTS] __attribute__ ((aligned (512))) = {
{
.name = "PTABLE-BLK", // or PTABLE-MB for len in MB
},
{
.name = "boot",
.start = 0x219,
.length = 0x25 /* In blocks */,
},
{
.name = "system",
.start = 0x23E,
.length = 0x831 /* In blocks */,
},
{
.name = "cache",
.start = 0xA70,
.length = 0x140 /* In blocks */,
},
{
.name = "userdata",
.start = 0xBB0,
.length = 0x390,
},
};
#endif
static unsigned num_parts = sizeof(board_part_list)/sizeof(struct ptentry);
//#define part_empty(p) (p->name[0]==0 && p->start==0 && p->length==0 && p->flags==0 && p->type==0 && p->perm==0)
#define IS_PART_EMPTY(p) (p->name[0]==0)
void keypad_init(void);
void display_init(void);
void htcleo_ptable_dump(struct ptable *ptable);
void cmd_dmesg(const char *arg, void *data, unsigned sz);
void reboot(unsigned reboot_reason);
void target_display_init();
void target_init(void)
{
struct flash_info *flash_info;
unsigned start_block;
unsigned blocks_per_plen = 1; //blocks per partition length
unsigned nand_num_blocks;
keys_init();
keypad_init();
uint16_t keys[] = {KEY_VOLUMEUP, KEY_VOLUMEDOWN, KEY_SOFT1, KEY_SEND, KEY_CLEAR, KEY_BACK, KEY_HOME};
for(unsigned i=0; i< sizeof(keys)/sizeof(uint16_t); i++)
if (keys_get_state(keys[i]) != 0)
{
display_init();
_dputs("cedesmith's LK (CLK) v1.1\n");
break;
}
dprintf(INFO, "htcleo_init\n");
// SPL seams to pass something somehow to kernel.
// Without this it hangs on 1st boot and when battery charger is pluged
// with this it just auto restarts
char* cold_boot=(char*)(MEMBASE-1);
if(*cold_boot==0)
{
*cold_boot=1;
dprintf(INFO, "cold boot detected... reboot\n");
reboot(0);
}
/**
* cedesmith notes:
* DON'T use smem_ptable_init and smem_get_apps_flash_start as 0:APPS points to wrong place
*/
dprintf(INFO, "flash init\n");
flash_init();
flash_info = flash_get_info();
ASSERT(flash_info);
ASSERT(flash_info->num_blocks);
nand_num_blocks = flash_info->num_blocks;
ptable_init(&flash_ptable);
// cedesmith:DON'T USE SMEM ptable
if( strcmp(board_part_list[0].name,"PTABLE-BLK")==0 ) blocks_per_plen =1 ;
else if( strcmp(board_part_list[0].name,"PTABLE-MB")==0 ) blocks_per_plen = (1024*1024) /flash_info->block_size;
else panic("Invalid partition table\n");
start_block = HTCLEO_FLASH_OFFSET;
for (unsigned i = 1; i < num_parts; i++)
{
struct ptentry *ptn = &board_part_list[i];
if( IS_PART_EMPTY(ptn) ) break;
int len = ((ptn->length) * blocks_per_plen);
if( ptn->start == 0 ) ptn->start = start_block;
else if( ptn->start < start_block) panic("Partition %s start %x < %x\n", ptn->name, ptn->start, start_block);
if(ptn->length == 0)
{
unsigned length_for_prt = 0;
if( i<num_parts && !IS_PART_EMPTY((&board_part_list[i+1])) && board_part_list[i+1].start!=0)
{
length_for_prt = board_part_list[i+1].start - ptn->start;
}
else
{
for (unsigned j = i+1; j < num_parts; j++)
{
struct ptentry *temp_ptn = &board_part_list[j];
if( IS_PART_EMPTY(temp_ptn) ) break;
if( temp_ptn->length==0 ) panic("partition %s and %s have variable length\n", ptn->name, temp_ptn->name);
length_for_prt += ((temp_ptn->length) * blocks_per_plen);
}
}
len = (nand_num_blocks - 1 - 186 - 4) - (ptn->start + length_for_prt);
ASSERT(len >= 0);
}
start_block = ptn->start + len;
ptable_add(&flash_ptable, ptn->name, ptn->start, len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE);
}
htcleo_ptable_dump(&flash_ptable);
flash_set_ptable(&flash_ptable);
}
unsigned board_machtype(void)
{
return LINUX_MACHTYPE;
}
void reboot_device(unsigned reboot_reason)
{
reboot(reboot_reason);
}
int target_is_emmc_boot(void)
{
return 0;
}
void htcleo_ptable_dump(struct ptable *ptable)
{
struct ptentry *ptn;
int i;
for (i = 0; i < ptable->count; ++i) {
ptn = &ptable->parts[i];
dprintf(INFO, "ptn %d name='%s' start=%08x len=%08x end=%08x \n",i, ptn->name, ptn->start, ptn->length, ptn->start+ptn->length);
}
}
//cedesmith: current version of qsd8k platform missing display_shutdown so add it
void lcdc_shutdown(void);
void display_shutdown(void)
{
lcdc_shutdown();
}