#include #include #include #include #include #include #include #include #include #include #include "xmedia_mmz.h" #include "pm_aux.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #include "pm_flash.h" /* note: size must be 2k alignment */ #define AUX_TOTAL_MEM_SIZE (UBOOT_HEADER_PARAM_LEN + AUX_AREA_SIZE) #define AUX_TOTAL_MEM_NAME "AUX_MEM" static xmedia_u64 aux_mem_addr = XMEDIA_NULL; const char nand_uboot_part[] = "/dev/mtd0"; const char spi_uboot_part[] = "/dev/mtd0"; const char emmc_uboot_part[] = "/dev/mmcblk0p0"; const char *uboot_name[PM_FLASH_TYPE_MAX] = {spi_uboot_part, nand_uboot_part, emmc_uboot_part}; static struct flash_part_dev *flash_uboot_init(void) { struct flash_part_dev *uboot_part_dev; xmedia_s32 ret = XMEDIA_SUCCESS; uboot_part_dev = alloc_flash_part(); if (uboot_part_dev == XMEDIA_NULL) return XMEDIA_NULL; memcpy(uboot_part_dev->part.devname, uboot_name[uboot_part_dev->part.flash_type], strlen(uboot_name[uboot_part_dev->part.flash_type])); ret = flash_open(uboot_part_dev, ACCESS_RD); if (ret != XMEDIA_SUCCESS) { PM_USR_TRACE(MODULE_DBG_ERR, "open error\n"); free_flash_part(uboot_part_dev); return XMEDIA_NULL; } ret = flash_get_info(uboot_part_dev); if (ret != XMEDIA_SUCCESS) { PM_USR_TRACE(MODULE_DBG_ERR, "get info err\n"); uboot_part_dev->part_opt->close(uboot_part_dev); free_flash_part(uboot_part_dev); return XMEDIA_NULL; } ret = flash_init(uboot_part_dev); if (ret != XMEDIA_SUCCESS) { PM_USR_TRACE(MODULE_DBG_ERR, "flash init err\n"); uboot_part_dev->part_opt->close(uboot_part_dev); free_flash_part(uboot_part_dev); return XMEDIA_NULL; } return uboot_part_dev; } static xmedia_s32 flash_uboot_read(struct flash_part_dev *part_dev, xmedia_u32 addr, xmedia_u32 size, xmedia_char *buf) { return flash_read(part_dev, addr, size, buf); } static xmedia_s32 flash_uboot_deinit(struct flash_part_dev *part_dev) { flash_close(part_dev); free_flash_part(part_dev); return XMEDIA_SUCCESS; } xmedia_s32 aux_free_mem(void) { if (aux_mem_addr != XMEDIA_NULL) { xmedia_mmz_free(aux_mem_addr); aux_mem_addr = XMEDIA_NULL; } return XMEDIA_SUCCESS; } xmedia_s32 aux_read(xmedia_char *buf, xmedia_u32 size) { struct flash_part_dev *uboot_part_dev; xmedia_u32 aux_len; xmedia_s32 ret = XMEDIA_SUCCESS; uboot_part_dev = flash_uboot_init(); if (uboot_part_dev == XMEDIA_NULL) { PM_USR_TRACE(MODULE_DBG_ERR, "uboot init error\n"); return XMEDIA_ERRCODE_OPEN_FAILED; } if (size < UBOOT_HEADER_PARAM_LEN) { PM_USR_TRACE(MODULE_DBG_ERR, "%s bufsize(0x%x) < headersize(0x%x)\n", __func__, size, UBOOT_HEADER_PARAM_LEN); flash_uboot_deinit(uboot_part_dev); return XMEDIA_ERRCODE_INVALID_PARAM; } ret = flash_uboot_read(uboot_part_dev, 0, UBOOT_HEADER_PARAM_LEN, buf); if (ret != UBOOT_HEADER_PARAM_LEN) { PM_USR_TRACE(MODULE_DBG_ERR, "%s read header error ret:%d\n", __func__, ret); flash_uboot_deinit(uboot_part_dev); return ret; } aux_len = *(xmedia_u32 *)(buf + AUX_LEN_POS); if (aux_len > size - UBOOT_HEADER_PARAM_LEN) { PM_USR_TRACE(MODULE_DBG_ERR, "%s aux len(0x%x) > bufsize(0x%x) - headersize(0x%x)\n", __func__, aux_len, size, UBOOT_HEADER_PARAM_LEN); flash_uboot_deinit(uboot_part_dev); return XMEDIA_ERRCODE_INVALID_PARAM; } ret = flash_uboot_read(uboot_part_dev, UBOOT_HEADER_PARAM_LEN, aux_len, buf + UBOOT_HEADER_PARAM_LEN); if (ret != aux_len) { PM_USR_TRACE(MODULE_DBG_ERR, "%s read aux len(0x%x) error ret:%d\n", __func__, aux_len, ret); flash_uboot_deinit(uboot_part_dev); return ret; } flash_uboot_deinit(uboot_part_dev); return XMEDIA_SUCCESS; } xmedia_s32 read_aux_to_ddr(struct aux_mem *paux) { xmedia_void *pbuf = NULL; if (aux_mem_addr != XMEDIA_NULL) { PM_USR_TRACE(MODULE_DBG_ERR, "aux exist in ddr now\n"); paux->phy_addr = aux_mem_addr; paux->size = AUX_TOTAL_MEM_SIZE; return XMEDIA_SUCCESS; } aux_mem_addr = xmedia_mmz_alloc(NULL, AUX_TOTAL_MEM_NAME, AUX_TOTAL_MEM_SIZE); if (aux_mem_addr == XMEDIA_NULL) return XMEDIA_ERRCODE_NOT_ENOUGH_MEMORY; pbuf = xmedia_mmz_map(aux_mem_addr, AUX_TOTAL_MEM_SIZE, XMEDIA_TRUE); if (pbuf == XMEDIA_NULL) { aux_free_mem(); return XMEDIA_ERRCODE_NOT_ENOUGH_MEMORY; } PM_USR_TRACE(MODULE_DBG_INFO, "aux_mem phy addr:0x%llx vir addr: 0x%x\n", aux_mem_addr, (xmedia_u32)paux); if (aux_read(pbuf, AUX_TOTAL_MEM_SIZE) != XMEDIA_SUCCESS) { PM_USR_TRACE(MODULE_DBG_ERR, "read aux error\n"); xmedia_mmz_unmap(pbuf); aux_free_mem(); return XMEDIA_ERRCODE_COPY_DATA_ERROR; } xmedia_mmz_flush_cache(aux_mem_addr, pbuf, AUX_TOTAL_MEM_SIZE); xmedia_mmz_unmap(pbuf); paux->phy_addr = aux_mem_addr; paux->size = AUX_TOTAL_MEM_SIZE; return XMEDIA_SUCCESS; } #ifdef __cplusplus } #endif /* __cplusplus */