static int s6d78a0x_init(struct pxa168fb_info *fbi) { int board_id = get_board_id(); pxa168_dsi_cmd_array_tx(fbi, s6d78a0x_video_display_enable_access_register, ARRAY_SIZE(s6d78a0x_video_display_enable_access_register)); printk("%s, init s6d7aa0x\n", __func__); pxa168_dsi_cmd_array_tx(fbi, s6d78a0x_video_display_init_cmds, ARRAY_SIZE(s6d78a0x_video_display_init_cmds)); #if 0 if (board_id == BOARD_ID_REV00) { printk("%s, init s6d78a0x\n", __func__); pxa168_dsi_cmd_array_tx(fbi, s6d78a0x_video_display_init_cmds, ARRAY_SIZE(s6d78a0x_video_display_init_cmds)); } else { printk("%s, init s6d78a0x_es2\n", __func__); pxa168_dsi_cmd_array_tx(fbi, s6d78a0x_es2_video_display_init_cmds, ARRAY_SIZE(s6d78a0x_es2_video_display_init_cmds)); } #endif pxa168_dsi_cmd_array_tx(fbi, s6d78a0x_video_display_disable_access_register, ARRAY_SIZE(s6d78a0x_video_display_disable_access_register)); #ifdef CONFIG_LDI_SUPPORT_MDNIE isReadyTo_mDNIe = 1; set_mDNIe_Mode(&mDNIe_cfg); #endif /* CONFIG_LDI_SUPPORT_MDNIE */ return 0; }
uint8_t board_id(void) { if (board_id_value < 0) board_id_value = get_board_id(); return board_id_value; }
void send_version() { uint16 crc_value; uint8 buf[31]; buf[0] = CTRL_FRAME_START1; buf[1] = CTRL_FRAME_START2; buf[2] = get_aircraft_no()&0xFF; buf[3] = get_aircraft_no()>>8; *(uint16*)(buf+4) = 0x1F; buf[6] = 1; buf[7] = 0; buf[8] = 1; buf[9] = 0; buf[10] = CTRL_FRAME_TYPE_VERSION ; buf[11] = get_board_id(); *(uint32*)(buf+12) = 0x0; // kernel version *(uint32*)(buf+16) = 0x0; // app version *(uint32*)(buf+20) = get_fpga_version(); *(uint32*)(buf+24) = 0x0; // reserve crc_value = crc_checksum16(buf, 28); buf[28] = crc_value&0xFF; buf[29] = crc_value>>8; buf[30] = CTRL_FRAME_END; control_cmd_send(buf, 31); }
/*! * Program the board type and revision efuse * * @return 0 if successful; non-zero otherwise */ test_return_t program_board_id_fuses(const uint32_t board_type, const uint32_t board_rev, const char* const indent) { const uint32_t reg_word = ((board_type & 0xf) << 12) | ((board_rev & 0xF) << 8); /* TODO: Is it still needed? => ask design */ /* First, allow fuse programming in the CCM CGPR register by setting the 'efuse_prog_supply_gate' bit */ unsigned int temp = readl(CCM_BASE_ADDR + CCM_CGPR_OFFSET); temp |= 0x00000010; // set bit 4, efuse_prog_supply_gate bit writel(temp, (CCM_BASE_ADDR + CCM_CGPR_OFFSET)); debug_printf("%s ** Board ID Fuses before program 0x%x\n", indent, (get_board_id().B.BOARD_TYPE_ID << 4) | get_board_id().B.BOARD_REV); /* blow the fuse */ ocotp_fuse_blow_row(HW_OCOTP_GP1_BANK, HW_OCOTP_GP1_ROW, reg_word); if (ocotp_sense_fuse(HW_OCOTP_GP1_BANK, HW_OCOTP_GP1_ROW) != reg_word) { printf("%s ** Fuse read-back-verify failed, read back 0x%x, should be: 0x%x\n", indent, ocotp_sense_fuse(HW_OCOTP_GP1_BANK, HW_OCOTP_GP1_ROW), reg_word); /* TODO: Is it still needed? => ask design */ /* Disable fuse programming in the CCM CGPR register by clearing the 'efuse_prog_supply_gate' bit */ temp = readl(CCM_BASE_ADDR + CCM_CGPR_OFFSET); temp &= ~(0x00000010); // clear bit 4, efuse_prog_supply_gate bit writel(temp, (CCM_BASE_ADDR + CCM_CGPR_OFFSET)); return TEST_FAILED; } debug_printf("%s ** Fuses programmed successfully.\n\n", indent); debug_printf("%s ** Board ID Fuses after program 0x%x\n", indent, (get_board_id().B.BOARD_TYPE_ID << 4) | get_board_id().B.BOARD_REV); /* reload the otp shadow registers */ ocotp_reload_otp_shadow_registers(); debug_printf("%s ** Board ID Fuses after reload 0x%x\n", indent, (get_board_id().B.BOARD_TYPE_ID << 4) | get_board_id().B.BOARD_REV); /* TODO: Is it still needed? => ask design */ /* Disable fuse programming in the CCM CGPR register by clearing the 'efuse_prog_supply_gate' bit */ temp = readl(CCM_BASE_ADDR + CCM_CGPR_OFFSET); temp &= ~(0x00000010); // clear bit 4, efuse_prog_supply_gate bit writel(temp, (CCM_BASE_ADDR + CCM_CGPR_OFFSET)); return TEST_PASSED; }
//! You expected it: This routine is expected never to exit void main (void) { port_init(); watchdog_init(); timer_gpt3_init(); adc_init(); cursors_init(); power_init(); uart_init(); /* enable interrupts. */ EA = 1; get_board_id(); startup_message(); dump_xdata_sfr(); gpio_check_IO_direction(); dump_gpio(); dump_mcs51(); tx_drain(); // oops, UART routines seem not yet clean print_states_ruler(); print_states_enable = 1; print_states(); print_states_enable = 0; save_old_states(); states.number = 0; manufacturing_print_all(); ow_init(); timer1_init(); battery_charging_table_init(); LED_CHG_G_OFF(); LED_CHG_R_OFF(); LED_PWR_OFF(); /* The main loop contains several state machines handling various subsystems on the EC. The idea is to have each subroutine return as quickly as it can (no busy wait unless for a _very_ short delay). Also the subroutines should be pretty much self contained. Unless it is noted _here_ no state machine should need more than xxx microseconds before returning control. When a state machine returns control it is expected to have the variables it is working on in a consistent state. Period (just in case it was missed:^) If it helps: you may want to think of the main loop as a round-robin cooperative scheduler without the overhead this usually implies. This works well if, well, if _all_ routines within the main loop cooperate well. */ while(1) { STATES_TIMESTAMP(); busy = handle_command(); busy |= handle_cursors(); handle_leds(); handle_power(); handle_ds2756_requests(); handle_ds2756_readout(); busy |= handle_battery_charging_table(); watchdog_all_up_and_well |= WATCHDOG_MAIN_LOOP_IS_FINE; print_states(); monitor(); handle_debug(); sleep_if_allowed(); } }
/* Program the board ID fuses if not already done */ test_return_t program_board_id(void) { const char* const indent = menu_get_indent(); char chip_str[64]; char chip_str_full[64]; char chip_rev_str[64]; char board_str[64]; char board_rev_str[64]; fsl_board_id_t board_id = get_board_id(); chip_name(chip_str, board_id.B.CHIP_TYPE_ID, false); chip_name(chip_str_full, board_id.B.CHIP_TYPE_ID, true); chip_revision(chip_rev_str, board_id.B.CHIP_REV_MAJOR, board_id.B.CHIP_REV_MINOR); board_name(board_str, board_id.B.BOARD_TYPE_ID); board_revision(board_rev_str, board_id.B.BOARD_REV); uint32_t fw_board_type = BOARD_TYPE; uint32_t fw_board_rev = BOARD_REVISION; /* Special case for MX6SDL/DQ SMART_DEVICE/SABRE_AI REV_B boards. * Allow user to choose to program the board as a REV_C or a REV_BX board */ if ((CHIP_TYPE == CHIP_TYPE_MX6SDL || CHIP_TYPE == CHIP_TYPE_MX6DQ) && (BOARD_TYPE == BOARD_TYPE_SABRE_AI || BOARD_TYPE == BOARD_TYPE_SMART_DEVICE) && BOARD_REVISION == BOARD_REVISION_B) { printf("%sThis binary will work for REV_D, REV_C, REV_BX, and REV_B boards.\n", indent); printf("%sWould you like to use the REV_D board ID for this board?\n", indent); if (is_input_char('y', indent)) { printf("%sUsing REV_D board ID instead of REV_B board ID.\n\n", indent); fw_board_rev = BOARD_REVISION_D; } else { printf("%sWould you like to use the REV_C board ID for this board?\n", indent); if (is_input_char('y', indent)) { printf("%sUsing REV_C board ID instead of REV_B board ID.\n\n", indent); fw_board_rev = BOARD_REVISION_C; } else if(BOARD_TYPE == BOARD_TYPE_SABRE_AI){ printf("%sWould you like to use the REV_BX board ID for this board?\n", indent); if (is_input_char('y', indent)) { printf("%sUsing REV_BX board ID instead of REV_B board ID.\n\n", indent); fw_board_rev = BOARD_REVISION_BX; } } } } /* Special case for MX6SL EVB/EVK boards. * Allow user to choose to program the board as a EVK_EPDC or EVK_SPDC board */ if (CHIP_TYPE == CHIP_TYPE_MX6SL) { printf("%sThis binary will work for both EVB and EVK boards.\n", indent); printf("%sWould you like to use the EVK board ID for this board?\n", indent); if (is_input_char('y', indent)) { printf("%sUsing BOARD_TYPE_EVK board ID instead of BOARD_TYPE_EVB board ID.\n\n", indent); printf("%sUsing BOARD_REVISION_A board ID instead of BOARD_REVISION_B board ID.\n\n", indent); fw_board_type = BOARD_TYPE_EVK; fw_board_rev = BOARD_REVISION_A; } } if (board_id.B.BOARD_TYPE_ID == 0 || board_id.B.BOARD_REV == 0) { // Board is not programmed printf("%sNo Board ID found in the fuses.\n", indent); board_id.B.BOARD_TYPE_ID = fw_board_type; board_id.B.BOARD_REV = fw_board_rev; printf("%sThis OBDS binary will program Board ID to 0x%08X as detailed below:\n", indent, board_id.U); show_board_id(board_id, indent); printf_color(g_TextAttributeBold, g_TextColorRed, "%sContinue with irreversible operation to program Board ID?\n", indent); if (!is_input_char('y', indent)) { /* Do not program the suggested value to Board ID fuse bank */ printf("%sNOT programming board ID to fuses.\n", indent); return TEST_BYPASSED; } // DO THE PROGRAMMING test_return_t err = program_board_id_fuses(board_id.B.BOARD_TYPE_ID, board_id.B.BOARD_REV, indent); if (err == TEST_PASSED) { printf("%sFuses programmed successfully.\n\n", indent); show_board_id(get_board_id(), indent); } return err; } else if ((board_id.B.BOARD_TYPE_ID == BOARD_TYPE_SABRE_AI || board_id.B.BOARD_REV == BOARD_REVISION_B) && (fw_board_rev == BOARD_REVISION_BX) ) { // SABRE AI Board is programmed as REV_B , but we need it to be REV_BX printf("\n%sSABRE AI Rev. B board ID found in the fuses.\n", indent); board_id.B.BOARD_TYPE_ID = fw_board_type; board_id.B.BOARD_REV = fw_board_rev; printf("%sThis OBDS binary will program Board ID to 0x%08X as detailed below:\n", indent, board_id.U); show_board_id(board_id, indent); printf("\n"); printf_color(g_TextAttributeBold, g_TextColorRed, "%sContinue with irreversible operation to program Board ID?\n", indent); if (!is_input_char('y', indent)) { /* Do not program the suggested value to Board ID fuse bank */ printf("%sNOT programming board ID to fuses.\n", indent); return TEST_BYPASSED; } // DO THE PROGRAMMING test_return_t err = program_board_id_fuses(board_id.B.BOARD_TYPE_ID, board_id.B.BOARD_REV, indent); if (err == TEST_PASSED) { printf("%sFuses programmed successfully.\n\n", indent); show_board_id(get_board_id(), indent); } return err; } else if ( board_id.B.CHIP_TYPE_ID != CHIP_TYPE || board_id.B.BOARD_TYPE_ID != fw_board_type || board_id.B.BOARD_REV != fw_board_rev ) { // Software is not compiled for this board printf("\n%sSoftware is not compiled for this board.\n", indent); chip_name(chip_str, CHIP_TYPE, false); board_name(board_str, fw_board_type); board_revision(board_rev_str, fw_board_rev); printf("%sSoftware for %s %s %s.\n", indent, chip_str, board_str, board_rev_str); chip_name(chip_str, board_id.B.CHIP_TYPE_ID, false); board_name(board_str, board_id.B.BOARD_TYPE_ID); board_revision(board_rev_str, board_id.B.BOARD_REV); printf("%sBoard is %s %s %s.\n", indent, chip_str, board_str, board_rev_str); return TEST_FAILED; } else if ( board_id.B.CHIP_TYPE_ID == CHIP_TYPE && board_id.B.BOARD_TYPE_ID == fw_board_type && board_id.B.BOARD_REV == fw_board_rev ) { // Board ID fuses are already correct printf("\n%sBoard ID fuses are already programmed.\n\n", indent); show_board_id(board_id, indent); return TEST_PASSED; } else { // Unhandled cases printf("\n%sUnknown failure.\n\n", indent); show_board_id(board_id, indent); return TEST_FAILED; } }
int main(int argc, char** argv) { int fd, n; unsigned long loadaddr; char* p; char m4IsStopped = 0; char m4IsRunning = 0; int m4TraceFlags = 0; int m4Retry; char* filepath = argv[1]; int currentSoC = -1; if (argc < 2) { LogError(HEADER); LogError("-- %s -- \nUsage:\n" "%s [filename.bin] [0xLOADADDR] [--verbose] # loads new firmware\n" "or: %s stop # holds the auxiliary core in reset\n" "or: %s start # releases the auxiliary core from reset\n" "or: %s kick [n] # triggers interrupt on RPMsg virtqueue n\n", NAME_OF_UTILITY, argv[0], argv[0], argv[0], argv[0], argv[0]); return RETURN_CODE_ARGUMENTS_ERROR; } currentSoC = get_board_id(); if (currentSoC == -1) { LogError(HEADER); LogError("Board is not supported.\n"); return RETURN_CODE_ARGUMENTS_ERROR; } fd = open("/dev/mem", O_RDWR | O_SYNC); if (fd < 0) { LogError(HEADER); LogError("Could not open /dev/mem, are you root?\n"); return RETURN_CODE_ARGUMENTS_ERROR; } /* PARTIAL COMMANDS */ if (!strcmp(argv[1], "stop")) { stop_cpu(fd, currentSoC); return RETURN_CODE_OK; } else if (!strcmp(argv[1], "start")) { start_cpu(fd, currentSoC); return RETURN_CODE_OK; } else if (!strcmp(argv[1], "kick")) { if (argc < 3) { LogError(HEADER); LogError("%s - Usage: %s kick {vq_id to kick}\n", NAME_OF_UTILITY, argv[0]); return RETURN_CODE_ARGUMENTS_ERROR; } rpmsg_mu_kick(fd, currentSoC, strtoul(argv[2], &p, 16)); return RETURN_CODE_OK; } /* FW LOADING */ if (argc < 3) { LogError(HEADER); LogError("%s - Usage: %s [yourfwname.bin] [0xLOADADDR] [--verbose]\n", NAME_OF_UTILITY, argv[0]); return RETURN_CODE_ARGUMENTS_ERROR; } if (access(filepath, F_OK) == -1) { LogError("File %s not found.\n", argv[1]); return RETURN_CODE_ARGUMENTS_ERROR; } loadaddr = strtoul(argv[2], &p, 16); if (argc == 4) { if (!strcmp(argv[3], "--verbose")) { verbose = 1; } else { LogError(HEADER); LogError("%s - Usage: %s [yourfwname.bin] [0xLOADADDR] [--verbose]\n", NAME_OF_UTILITY, argv[0]); return RETURN_CODE_ARGUMENTS_ERROR; } } LogVerbose("LoadAddr is: %X\n", loadaddr); LogVerbose("Will stop CPU now...\n"); stop_cpu(fd, currentSoC); LogVerbose("Will ungate M4 clock source...\n"); ungate_m4_clk(fd, currentSoC); LogVerbose("Will load M4 firmware...\n"); load_m4_fw(fd, currentSoC, filepath, loadaddr); LogVerbose("Will start CPU now...\n"); start_cpu(fd, currentSoC); LogVerbose("Done!\n"); close(fd); return RETURN_CODE_OK; }